Version 2.9.0-16.0.dev

Merge commit 'b0d4c359d8ad5a4c63f09a95a094c73cec66e3d2' into dev
diff --git a/.gitattributes b/.gitattributes
index 6ac541d..3b5895d 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -14,6 +14,10 @@
 *.yaml text
 
 # File that should not be converted.
+tests/dart2js/eof_line_ending_test.dart -text
+tests/dart2js/string_interpolation_test.dart -text
+tests/dart2js/string_interpolation_dynamic_test.dart -text
+tests/dart2js/literal_string_juxtaposition_test.dart -text
 tests/dart2js_2/eof_line_ending_test.dart -text
 tests/dart2js_2/string_interpolation_test.dart -text
 tests/dart2js_2/string_interpolation_dynamic_test.dart -text
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 438fa0c..b58c4a0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -68,21 +68,24 @@
 
 #### Linter
 
-Updated the Linter to `0.1.116`, which includes:
+Updated the Linter to `0.1.117`, which includes:
 
-* New lint: `no_default_cases` (experimental).
+* New lint: `do_not_use_environment`.
 * New lint: `exhaustive_cases`.
-* Updated `type_annotate_public_apis` to allow inferred types in final field assignments.
-* Updated `prefer_mixin` to allow "legacy" SDK abstract class mixins.
-* New lint: `use_is_even_rather_than_modulo`.
-* Updated `unsafe_html` to use a `SecurityLintCode` (making it un-ignorable).
-* Improved `sized_box_for_whitespace` to address false-positives.
-* Fixed `unsafe_html` to check attributes and methods on extensions.
-* Extended `unsafe_html` to include `Window.open`, `Element.html` and
-  `DocumentFragment.html` in unsafe API checks.
-* Improved docs for `sort_child_properties_last`.
-* (internal) `package:analyzer` API updates.
+* New lint: `no_default_cases` (experimental).
 * New lint: `sized_box_for_whitespace`.
+* New lint: `use_is_even_rather_than_modulo`.
+* Updated `directives_ordering` to remove third party package special-casing.
+* Updated `prefer_is_empty` to special-case assert initializers and const
+  contexts.
+* Updated `prefer_mixin` to allow "legacy" SDK abstract class mixins.
+* Updated `sized_box_for_whitespace` to address false-positives.
+* Updated `type_annotate_public_apis` to allow inferred types in final field
+  assignments.
+* Updated `unnecessary_lambdas` to check for tear-off assignability.
+* Updated `unsafe_html` to use a `SecurityLintCode` (making it un-ignorable) and
+  to include `Window.open`, `Element.html` and `DocumentFragment.html` in unsafe
+  API checks. Also added checks for attributes and methods on extensions.
 
 ### Dart VM
 
diff --git a/DEPS b/DEPS
index ab45592..0ab9437 100644
--- a/DEPS
+++ b/DEPS
@@ -44,7 +44,7 @@
   # 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": "c6adf63baea76b1f7e7833482eec023fd244fc33",
+  "co19_rev": "b071a4729a57ee47dcc7330ab9ea3566ef58e5c2",
   "co19_2_rev": "620c1148c8b7a3d7f74afacf348c46f109eb64f2",
 
   # The internal benchmarks to use. See go/dart-benchmarks-internal
@@ -112,7 +112,7 @@
   "intl_tag": "0.16.1",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_rev": "d589e635d8ccb7cda6a804bd571f88abbabab146",
-  "linter_tag": "0.1.116",
+  "linter_tag": "0.1.117",
   "logging_rev": "9561ba016ae607747ae69b846c0e10958ca58ed4",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_rev": "dd150bb64c5f3b41d31f20f399ae2a855f7f8c00",
@@ -144,7 +144,7 @@
   "source_span_tag": "1.7.0",
   "stack_trace_tag": "1.9.3",
   "stagehand_tag": "v3.3.7",
-  "stream_channel_tag": "2.0.0",
+  "stream_channel_tag": "70433d577be02c48cb16d72d65654f3b4d82c6ed",
   "string_scanner_rev": "a918e7371af6b6e73bfd534ff9da6084741c1f99",
   "test_descriptor_tag": "1.1.1",
   "test_process_tag": "1.0.3",
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 80e6bc4..6db7f6d 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
@@ -2744,15 +2744,20 @@
 
   @override
   void tryCatchStatement_bodyEnd(Node body) {
-    AssignedVariablesNodeInfo<Variable> info =
-        _assignedVariables._getInfoForNode(body);
+    FlowModel<Variable, Type> afterBody = _current;
+
     _TryContext<Variable, Type> context =
         _stack.last as _TryContext<Variable, Type>;
     FlowModel<Variable, Type> beforeBody = context._previous;
-    FlowModel<Variable, Type> beforeCatch =
-        beforeBody.removePromotedAll(info._written, info._captured);
+
+    AssignedVariablesNodeInfo<Variable> info =
+        _assignedVariables._getInfoForNode(body);
+    FlowModel<Variable, Type> beforeCatch = beforeBody
+        .removePromotedAll(info._written, info._captured)
+        .joinUnassigned(other: afterBody);
+
     context._beforeCatch = beforeCatch;
-    context._afterBodyAndCatches = _current;
+    context._afterBodyAndCatches = afterBody;
   }
 
   @override
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index bd57ab1..e994086 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -1105,8 +1105,6 @@
     Token equals;
     TypeParamOrArgInfo typeParam =
         computeTypeParamOrArg(next, /* inDeclaration = */ true);
-    // Allow voidType here if the next is "=" as 'void' has then been used as
-    // an identifier (not legal, but an error will be given).
     if (typeInfo == noType && optional('=', typeParam.skip(next).next)) {
       // New style typedef, e.g. typedef foo = void Function();".
 
@@ -3043,11 +3041,13 @@
     Token replacement;
     if (next.isSynthetic) {
       replacement = link(
-          new SyntheticBeginToken(TokenType.OPEN_SQUARE_BRACKET, next.offset),
+          new SyntheticBeginToken(TokenType.OPEN_SQUARE_BRACKET, next.offset,
+              next.precedingComments),
           new SyntheticToken(TokenType.CLOSE_SQUARE_BRACKET, next.offset));
     } else {
       replacement = link(
-          new BeginToken(TokenType.OPEN_SQUARE_BRACKET, next.offset),
+          new BeginToken(TokenType.OPEN_SQUARE_BRACKET, next.offset,
+              next.precedingComments),
           new Token(TokenType.CLOSE_SQUARE_BRACKET, next.offset + 1));
     }
     rewriter.replaceTokenFollowing(token, replacement);
@@ -4545,12 +4545,7 @@
             token = parseArgumentOrIndexStar(
                 token, typeArg, /* checkedNullAware = */ true);
           } else if (identical(type, TokenType.INDEX)) {
-            BeginToken replacement = link(
-                new BeginToken(TokenType.OPEN_SQUARE_BRACKET, next.charOffset,
-                    next.precedingComments),
-                new Token(TokenType.CLOSE_SQUARE_BRACKET, next.charOffset + 1));
-            rewriter.replaceTokenFollowing(token, replacement);
-            replacement.endToken = replacement.next;
+            rewriteSquareBrackets(token);
             token = parseArgumentOrIndexStar(
                 token, noTypeParamOrArg, /* checkedNullAware = */ false);
           } else if (identical(type, TokenType.BANG)) {
@@ -4654,6 +4649,14 @@
         next = token.next;
         assert(optional('(', next));
       }
+      TokenType nextType = next.type;
+      if (identical(nextType, TokenType.INDEX)) {
+        // If we don't split the '[]' here we will stop parsing it as a cascade
+        // and either split it later (parsing it wrong) or inserting ; before it
+        // (also wrong).
+        // See also https://github.com/dart-lang/sdk/issues/42267.
+        rewriteSquareBrackets(token);
+      }
       token = parseArgumentOrIndexStar(
           token, typeArg, /* checkedNullAware = */ false);
       next = token.next;
diff --git a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/try.dart b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/try.dart
index 40e2c9d..faffac2 100644
--- a/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/try.dart
+++ b/pkg/_fe_analyzer_shared/test/flow_analysis/definite_unassignment/data/try.dart
@@ -35,6 +35,26 @@
   v;
 }
 
+tryCatch_none() {
+  late int v;
+  try {
+    /*unassigned*/ v;
+  } catch (_) {
+    /*unassigned*/ v;
+  }
+  /*unassigned*/ v;
+}
+
+tryCatch_try_catch() {
+  late int v;
+  try {
+    v = 0;
+  } catch (_) {
+    v;
+  }
+  v;
+}
+
 tryCatchFinally_catch() {
   late int v;
   try {
@@ -90,3 +110,23 @@
   }
   v;
 }
+
+tryFinally_none() {
+  late int v;
+  try {
+    /*unassigned*/ v;
+  } finally {
+    /*unassigned*/ v;
+  }
+  /*unassigned*/ v;
+}
+
+tryFinally_try_finally() {
+  late int v;
+  try {
+    v = 0;
+  } finally {
+    v;
+  }
+  v;
+}
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_out.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_out.dart
index 3fe9525..d8429c0 100644
--- a/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_out.dart
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/infer_parameter_opt_out.dart
@@ -66,7 +66,8 @@
 /*cfe|cfe:builder.member: C2._simpleInstanceOfTrue:bool* Function(dynamic)**/
 /*cfe|cfe:builder.member: C2.==:bool* Function(dynamic)**/
 class C2 extends B implements A {
-  /*member: C2.method:dynamic Function(dynamic, {dynamic named})**/
+  /*cfe|cfe:builder.member: C2.method:dynamic Function(dynamic, {dynamic named})**/
+  /*analyzer.member: C2.method:Object* Function(Object*, {Object* named})**/
   method(o, {named}) {}
 }
 
@@ -98,7 +99,8 @@
 /*cfe|cfe:builder.member: C4._simpleInstanceOfTrue:bool* Function(dynamic)**/
 /*cfe|cfe:builder.member: C4.==:bool* Function(dynamic)**/
 class C4 implements B, A {
-  /*member: C4.method:dynamic Function(dynamic, {dynamic named})**/
+  /*cfe|cfe:builder.member: C4.method:dynamic Function(dynamic, {dynamic named})**/
+  /*analyzer.member: C4.method:Object* Function(Object*, {Object* named})**/
   method(o, {named}) {}
 }
 
diff --git a/pkg/_js_interop_checks/lib/src/js_interop.dart b/pkg/_js_interop_checks/lib/src/js_interop.dart
index eb5c9f5..24ceac4 100644
--- a/pkg/_js_interop_checks/lib/src/js_interop.dart
+++ b/pkg/_js_interop_checks/lib/src/js_interop.dart
@@ -4,18 +4,21 @@
 
 import 'package:kernel/kernel.dart';
 
-/// Returns true iff the class has an `@JS(...)` annotation from `package:js`.
+/// Returns true iff the class has an `@JS(...)` annotation from `package:js`
+/// or from the internal `dart:_js_annotations`.
 bool hasJSInteropAnnotation(Class c) =>
     c.annotations.any(_isPublicJSAnnotation);
 
 final _packageJs = Uri.parse('package:js/js.dart');
+final _internalJs = Uri.parse('dart:_js_annotations');
 
 /// Returns [true] if [e] is the `JS` annotation from `package:js`.
 bool _isPublicJSAnnotation(Expression value) {
   var c = _annotationClass(value);
   return c != null &&
       c.name == 'JS' &&
-      c.enclosingLibrary.importUri == _packageJs;
+      (c.enclosingLibrary.importUri == _packageJs ||
+          c.enclosingLibrary.importUri == _internalJs);
 }
 
 /// Returns the class of the instance referred to by metadata annotation [node].
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index d9ffaca..1c63942 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -111,11 +111,11 @@
     // false) then send empty results
 
     //
-    // Add the fixes produced by plugins to the server-generated fixes.
+    // Add the completions produced by plugins to the server-generated list.
     //
     if (pluginFutures != null) {
       var responses = await waitForResponses(pluginFutures,
-          requestParameters: requestParams);
+          requestParameters: requestParams, timeout: 100);
       for (var response in responses) {
         var result =
             plugin.CompletionGetSuggestionsResult.fromResponse(response);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
index 923c796..9fa94a5 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/commands/organize_imports.dart
@@ -39,11 +39,13 @@
       final unit = result.unit;
 
       if (hasScanParseErrors(result.errors)) {
-        return ErrorOr.error(ResponseError(
-          ServerErrorCodes.FileHasErrors,
-          'Unable to $commandName because the file contains parse errors',
-          path,
-        ));
+        // It's not uncommon for editors to run this command automatically on-save
+        // so if the file in in an invalid state it's better to fail silently
+        // than trigger errors (VS Code recently started showing popups when
+        // LSP requests return errors).
+        server.instrumentationService.logInfo(
+            'Unable to $commandName because the file contains parse errors');
+        return success();
       }
 
       final organizer = DirectiveOrganizer(code, unit, result.errors);
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
index 45d9d1a..d9c1815 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_completion.dart
@@ -16,14 +16,17 @@
 import 'package:analysis_server/src/services/completion/completion_core.dart';
 import 'package:analysis_server/src/services/completion/completion_performance.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart';
+import 'package:analysis_server/src/services/completion/filtering/fuzzy_matcher.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart' show SimpleIdentifier;
+import 'package:analyzer/dart/ast/visitor.dart' show RecursiveAstVisitor;
 import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/services/available_declarations.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 
-// If the client does not provide capabilities.completion.completionItemKind.valueSet
-// then we must never send a kind that's not in this list.
+/// If the client does not provide capabilities.completion.completionItemKind.valueSet
+/// then we must never send a kind that's not in this list.
 final defaultSupportedCompletionKinds = HashSet<CompletionItemKind>.of([
   CompletionItemKind.Text,
   CompletionItemKind.Method,
@@ -88,26 +91,36 @@
     final offset =
         await lineInfo.mapResult((lineInfo) => toOffset(lineInfo, pos));
 
-    return offset.mapResult((offset) {
-      if (unit.isError) {
-        return _getItemsFromPluginsOnly(
-          completionCapabilities,
-          clientSupportedCompletionKinds,
-          lineInfo.result,
-          path.result,
-          offset,
-          token,
-        );
-      } else {
-        return _getItems(
-          completionCapabilities,
-          clientSupportedCompletionKinds,
-          includeSuggestionSets,
-          unit.result,
-          offset,
-          token,
-        );
-      }
+    return offset.mapResult((offset) async {
+      // For server results we need a valid unit, but if we don't have one
+      // we shouldn't consider this an error when merging with plugin results.
+      final serverResultsFuture = unit.isError
+          ? Future.value(success(const <CompletionItem>[]))
+          : _getServerItems(
+              completionCapabilities,
+              clientSupportedCompletionKinds,
+              includeSuggestionSets,
+              unit.result,
+              offset,
+              token,
+            );
+
+      final pluginResultsFuture = _getPluginResults(completionCapabilities,
+          clientSupportedCompletionKinds, lineInfo.result, path.result, offset);
+
+      // Await both server + plugin results together to allow async/IO to
+      // overlap.
+      final serverAndPluginResults =
+          await Future.wait([serverResultsFuture, pluginResultsFuture]);
+      final serverResults = serverAndPluginResults[0];
+      final pluginResults = serverAndPluginResults[1];
+
+      if (serverResults.isError) return serverResults;
+      if (pluginResults.isError) return pluginResults;
+
+      return success(
+        serverResults.result.followedBy(pluginResults.result).toList(),
+      );
     });
   }
 
@@ -142,7 +155,30 @@
   String _createImportedSymbolKey(String name, Uri declaringUri) =>
       '$name/$declaringUri';
 
-  Future<ErrorOr<List<CompletionItem>>> _getItems(
+  Future<ErrorOr<List<CompletionItem>>> _getPluginResults(
+    TextDocumentClientCapabilitiesCompletion completionCapabilities,
+    HashSet<CompletionItemKind> clientSupportedCompletionKinds,
+    LineInfo lineInfo,
+    String path,
+    int offset,
+  ) async {
+    final requestParams = plugin.CompletionGetSuggestionsParams(path, offset);
+    final pluginResponses =
+        await requestFromPlugins(path, requestParams, timeout: 100);
+
+    final pluginResults = pluginResponses
+        .map((e) => plugin.CompletionGetSuggestionsResult.fromResponse(e))
+        .toList();
+
+    return success(_pluginResultsToItems(
+      completionCapabilities,
+      clientSupportedCompletionKinds,
+      lineInfo,
+      pluginResults,
+    ).toList());
+  }
+
+  Future<ErrorOr<List<CompletionItem>>> _getServerItems(
     TextDocumentClientCapabilitiesCompletion completionCapabilities,
     HashSet<CompletionItemKind> clientSupportedCompletionKinds,
     bool includeSuggestionSets,
@@ -157,6 +193,10 @@
 
     final completionRequest = CompletionRequestImpl(
         unit, offset, server.options.useNewRelevance, performance);
+    final directiveInfo =
+        server.getDartdocDirectiveInfoFor(completionRequest.result);
+    final dartCompletionRequest =
+        await DartCompletionRequestImpl.from(completionRequest, directiveInfo);
 
     Set<ElementKind> includedElementKinds;
     Set<String> includedElementNames;
@@ -169,19 +209,14 @@
 
     try {
       CompletionContributor contributor = DartCompletionManager(
-        dartdocDirectiveInfo:
-            server.getDartdocDirectiveInfoFor(completionRequest.result),
+        dartdocDirectiveInfo: directiveInfo,
         includedElementKinds: includedElementKinds,
         includedElementNames: includedElementNames,
         includedSuggestionRelevanceTags: includedSuggestionRelevanceTags,
       );
 
-      final suggestions = await Future.wait([
-        contributor.computeSuggestions(completionRequest),
-        _getPluginSuggestions(unit.path, offset),
-      ]);
-      final serverSuggestions = suggestions[0];
-      final pluginSuggestions = suggestions[1];
+      final serverSuggestions =
+          await contributor.computeSuggestions(completionRequest);
 
       if (token.isCancellationRequested) {
         return cancelled();
@@ -198,14 +233,6 @@
               completionRequest.replacementLength,
             ),
           )
-          .followedBy(
-            _pluginResultsToItems(
-              completionCapabilities,
-              clientSupportedCompletionKinds,
-              unit.lineInfo,
-              pluginSuggestions,
-            ),
-          )
           .toList();
 
       // Now compute items in suggestion sets.
@@ -292,51 +319,26 @@
         results.addAll(setResults);
       });
 
+      // Perform fuzzy matching based on the identifier in front of the caret to
+      // reduce the size of the payload.
+      final fuzzyPattern = _prefixMatchingPattern(dartCompletionRequest);
+      final fuzzyMatcher =
+          FuzzyMatcher(fuzzyPattern, matchStyle: MatchStyle.TEXT);
+
+      final matchingResults =
+          results.where((e) => fuzzyMatcher.score(e.label) > 0).toList();
+
       performance.notificationCount = 1;
       performance.suggestionCountFirst = results.length;
       performance.suggestionCountLast = results.length;
       performance.complete();
 
-      return success(results);
+      return success(matchingResults);
     } on AbortCompletion {
       return success([]);
     }
   }
 
-  Future<ErrorOr<List<CompletionItem>>> _getItemsFromPluginsOnly(
-    TextDocumentClientCapabilitiesCompletion completionCapabilities,
-    HashSet<CompletionItemKind> clientSupportedCompletionKinds,
-    LineInfo lineInfo,
-    String path,
-    int offset,
-    CancellationToken token,
-  ) async {
-    final pluginResults = await _getPluginSuggestions(path, offset);
-
-    if (token.isCancellationRequested) {
-      return cancelled();
-    }
-
-    return success(_pluginResultsToItems(
-      completionCapabilities,
-      clientSupportedCompletionKinds,
-      lineInfo,
-      pluginResults,
-    ).toList());
-  }
-
-  Future<List<plugin.CompletionGetSuggestionsResult>> _getPluginSuggestions(
-    String path,
-    int offset,
-  ) async {
-    final requestParams = plugin.CompletionGetSuggestionsParams(path, offset);
-    final responses = await requestFromPlugins(path, requestParams);
-
-    return responses
-        .map((e) => plugin.CompletionGetSuggestionsResult.fromResponse(e))
-        .toList();
-  }
-
   Iterable<CompletionItem> _pluginResultsToItems(
     TextDocumentClientCapabilitiesCompletion completionCapabilities,
     HashSet<CompletionItemKind> clientSupportedCompletionKinds,
@@ -356,4 +358,29 @@
       );
     });
   }
+
+  /// Return the pattern to match suggestions against, from the identifier
+  /// to the left of the caret. Return the empty string if cannot find the
+  /// identifier.
+  String _prefixMatchingPattern(DartCompletionRequestImpl request) {
+    final nodeAtOffsetVisitor =
+        _IdentifierEndingAtOffsetVisitor(request.offset);
+    request.target.containingNode.accept(nodeAtOffsetVisitor);
+
+    return nodeAtOffsetVisitor.matchingNode?.name ?? '';
+  }
+}
+
+/// An AST visitor to locate a [SimpleIdentifier] that ends at the provided offset.
+class _IdentifierEndingAtOffsetVisitor extends RecursiveAstVisitor<void> {
+  final int offset;
+  SimpleIdentifier _matchingNode;
+  _IdentifierEndingAtOffsetVisitor(this.offset);
+  SimpleIdentifier get matchingNode => _matchingNode;
+  @override
+  void visitSimpleIdentifier(SimpleIdentifier node) {
+    if (node.end == offset) {
+      _matchingNode = node;
+    }
+  }
 }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
index b831ada..b378a96 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handler_definition.dart
@@ -92,7 +92,21 @@
           return navigationTargetToLocation(targetFilePath, target, lineInfo);
         }
 
-        return success(convert(mergedTargets, toLocation).toList());
+        final results = convert(mergedTargets, toLocation).toList();
+
+        // If we fetch navigation on a keyword like `var`, the results will include
+        // both the definition and also the variable name. This will cause the editor
+        // to show the user both options unnecessarily (the variable name is always
+        // adjacent to the var keyword, so providing navigation to it is not useful).
+        // To prevent this, filter the list to only those on different lines (or
+        // different files).
+        final otherResults = results
+            .where((element) =>
+                element.uri != params.textDocument.uri ||
+                element.range.start.line != pos.line)
+            .toList();
+
+        return success(otherResults.isNotEmpty ? otherResults : results);
       });
     });
   }
diff --git a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
index 55b9980..c87b9c7 100644
--- a/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
+++ b/pkg/analysis_server/lib/src/lsp/handlers/handlers.dart
@@ -82,12 +82,17 @@
 
 mixin LspPluginRequestHandlerMixin<T extends AbstractAnalysisServer>
     on RequestHandlerMixin<T> {
-  Future<List<Response>> requestFromPlugins(String path, RequestParams params) {
+  Future<List<Response>> requestFromPlugins(
+    String path,
+    RequestParams params, {
+    int timeout = 500,
+  }) {
     final driver = server.getAnalysisDriver(path);
     final pluginFutures = server.pluginManager
         .broadcastRequest(params, contextRoot: driver.contextRoot);
 
-    return waitForResponses(pluginFutures, requestParameters: params);
+    return waitForResponses(pluginFutures,
+        requestParameters: params, timeout: timeout);
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
index d38cd5b..e1d5b19b0 100644
--- a/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
+++ b/pkg/analysis_server/lib/src/provisional/completion/dart/completion_dart.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 
@@ -22,11 +21,9 @@
 /// An object that contributes results for the `completion.getSuggestions`
 /// request results.
 abstract class DartCompletionContributor {
-  /// Return a [Future] that completes with a list of suggestions
-  /// for the given completion [request].
-  // TODO(brianwilkerson) When all of the suggestions are being built using the
-  //  builder, change the return type to `Future<void>`.
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  /// Return a [Future] that completes when the suggestions appropriate for the
+  /// given completion [request] have been added to the [builder].
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder);
 }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
index 84c4bec..14fbe05 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/arglist_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
 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/flutter.dart';
@@ -29,11 +27,11 @@
   ArgumentList argumentList;
 
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var executable = request.target.executableElement;
     if (executable == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     var node = request.target.containingNode;
     if (node is ArgumentList) {
@@ -43,7 +41,6 @@
     this.request = request;
     this.builder = builder;
     _addSuggestions(executable.parameters);
-    return const <CompletionSuggestion>[];
   }
 
   void _addDefaultParamSuggestions(Iterable<ParameterElement> parameters,
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
index b559a08..ab2768d 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/combinator_contributor.dart
@@ -15,11 +15,11 @@
 /// when the completion is in a show or hide combinator of an import or export.
 class CombinatorContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var node = request.target.containingNode;
     if (node is! Combinator) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     // Build the list of suggestions.
     var directive = node.thisOrAncestorOfType<NamespaceDirective>();
@@ -35,7 +35,6 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 
   List<String> _getCombinatorNames(NamespaceDirective directive) {
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
index 0042028..f4d50d32 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/completion_manager.dart
@@ -19,7 +19,6 @@
 import 'package:analysis_server/src/services/completion/dart/feature_computer.dart';
 import 'package:analysis_server/src/services/completion/dart/field_formal_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/imported_reference_contributor.dart';
-import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/keyword_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/label_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/library_member_contributor.dart';
@@ -134,7 +133,6 @@
       CombinatorContributor(),
       ExtensionMemberContributor(),
       FieldFormalContributor(),
-      InheritedReferenceContributor(),
       KeywordContributor(),
       LabelContributor(),
       LibraryMemberContributor(),
@@ -186,14 +184,9 @@
         var contributorTag =
             'DartCompletionManager - ${contributor.runtimeType}';
         performance.logStartTime(contributorTag);
-        var contributorSuggestions =
-            await contributor.computeSuggestions(dartRequest, builder);
+        await contributor.computeSuggestions(dartRequest, builder);
         performance.logElapseTime(contributorTag);
         request.checkAborted();
-
-        for (var newSuggestion in contributorSuggestions) {
-          addSuggestionToMap(newSuggestion);
-        }
       }
       for (var newSuggestion in builder.suggestions) {
         addSuggestionToMap(newSuggestion);
@@ -273,6 +266,11 @@
   void _addIncludedSuggestionRelevanceTags(DartCompletionRequestImpl request) {
     var target = request.target;
 
+    if (request.inConstantContext && request.useNewRelevance) {
+      includedSuggestionRelevanceTags.add(IncludedSuggestionRelevanceTag(
+          'isConst', RelevanceBoost.constInConstantContext));
+    }
+
     void addTypeTag(DartType type) {
       if (type is InterfaceType) {
         var element = type.element;
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 7f16627..3ad8d5b 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
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -23,13 +21,13 @@
   MemberSuggestionBuilder memberBuilder;
 
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var containingLibrary = request.libraryElement;
     // Gracefully degrade if the library could not be determined, such as with a
     // detached part file or source change.
     if (containingLibrary == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     memberBuilder = MemberSuggestionBuilder(request, builder);
@@ -63,24 +61,23 @@
           }
         }
       }
-
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     if (expression.isSynthetic) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     if (expression is Identifier) {
       var elem = expression.staticElement;
       if (elem is ClassElement) {
         // Suggestions provided by StaticMemberContributor.
-        return const <CompletionSuggestion>[];
+        return;
       } else if (elem is ExtensionElement) {
         // Suggestions provided by StaticMemberContributor.
-        return const <CompletionSuggestion>[];
+        return;
       } else if (elem is PrefixElement) {
         // Suggestions provided by LibraryMemberContributor.
-        return const <CompletionSuggestion>[];
+        return;
       }
     }
     if (expression is ExtensionOverride) {
@@ -92,12 +89,11 @@
         // get to this point, but there's an NPE if we invoke
         // `_resolveExtendedType` when `type` is `null`, so we guard against it
         // to ensure that we can return the suggestions from other providers.
-        return const <CompletionSuggestion>[];
+        return;
       }
       _addExtensionMembers(containingLibrary, type);
       expression.staticType;
     }
-    return const <CompletionSuggestion>[];
   }
 
   void _addExtensionMembers(LibraryElement containingLibrary, DartType type) {
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 2b7bae3..4135698 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
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    hide Element, ElementKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -16,19 +14,19 @@
 /// expressions of the form `this.^` in a constructor's parameter list.
 class FieldFormalContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> 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>[];
+      return;
     }
 
     var constructor = node.thisOrAncestorOfType<ConstructorDeclaration>();
     if (constructor == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     // Compute the list of fields already referenced in the constructor.
@@ -52,7 +50,7 @@
 
     var enclosingClass = constructor.thisOrAncestorOfType<ClassDeclaration>();
     if (enclosingClass == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     // Add suggestions for fields that are not already referenced.
@@ -71,6 +69,5 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
index ffa17ea..d839ed3 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/imported_reference_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/local_library_contributor.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
@@ -15,15 +13,15 @@
 /// A contributor for calculating suggestions for imported top level members.
 class ImportedReferenceContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     var imports = request.libraryElement.imports;
     if (imports == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     // Traverse imports including dart:core
@@ -34,7 +32,6 @@
             prefix: importElement.prefix?.name);
       }
     }
-    return const <CompletionSuggestion>[];
   }
 
   void _buildSuggestions(DartCompletionRequest request,
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
deleted file mode 100644
index f1f1db2..0000000
--- a/pkg/analysis_server/lib/src/services/completion/dart/inherited_reference_contributor.dart
+++ /dev/null
@@ -1,127 +0,0 @@
-// Copyright (c) 2014, 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/src/protocol_server.dart'
-    show 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:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer/dart/element/type.dart';
-import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
-
-/// A contributor that produces suggestions based on the instance members from
-/// the supertypes of a given type. More concretely, this class produces
-/// suggestions for places where an inherited instance member might be invoked
-/// via an implicit target of `this`.
-class InheritedReferenceContributor extends DartCompletionContributor {
-  /// The builder used to build the suggestions.
-  MemberSuggestionBuilder memberBuilder;
-
-  /// The kind of suggestion to make.
-  CompletionSuggestionKind kind;
-
-  @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
-      DartCompletionRequest request, SuggestionBuilder builder) async {
-    if (!request.includeIdentifiers) {
-      return const <CompletionSuggestion>[];
-    }
-
-    var member = _enclosingMember(request.target);
-    if (member == null) {
-      return const <CompletionSuggestion>[];
-    }
-    var classOrMixin = member.parent;
-    if (classOrMixin is ClassOrMixinDeclaration &&
-        classOrMixin.declaredElement != null) {
-      memberBuilder = MemberSuggestionBuilder(request, builder);
-      _computeSuggestionsForClass(classOrMixin.declaredElement, request);
-    }
-    return const <CompletionSuggestion>[];
-  }
-
-  void _addSuggestionsForType(InterfaceType type, DartCompletionRequest request,
-      double inheritanceDistance,
-      {bool isFunctionalArgument = false}) {
-    var opType = request.opType;
-    if (!isFunctionalArgument) {
-      for (var accessor in type.accessors) {
-        if (accessor.isGetter) {
-          if (opType.includeReturnValueSuggestions) {
-            memberBuilder.addSuggestionForAccessor(
-                accessor: accessor, inheritanceDistance: inheritanceDistance);
-          }
-        } else {
-          if (opType.includeVoidReturnSuggestions) {
-            memberBuilder.addSuggestionForAccessor(
-                accessor: accessor, inheritanceDistance: inheritanceDistance);
-          }
-        }
-      }
-    }
-    for (var method in type.methods) {
-      if (method.returnType == null) {
-        memberBuilder.addSuggestionForMethod(
-            method: method,
-            inheritanceDistance: inheritanceDistance,
-            kind: kind);
-      } else if (!method.returnType.isVoid) {
-        if (opType.includeReturnValueSuggestions) {
-          memberBuilder.addSuggestionForMethod(
-              method: method,
-              inheritanceDistance: inheritanceDistance,
-              kind: kind);
-        }
-      } else {
-        if (opType.includeVoidReturnSuggestions) {
-          memberBuilder.addSuggestionForMethod(
-              method: method,
-              inheritanceDistance: inheritanceDistance,
-              kind: kind);
-        }
-      }
-    }
-  }
-
-  void _computeSuggestionsForClass(
-      ClassElement classElement, DartCompletionRequest request) {
-    var isFunctionalArgument = request.target.isFunctionalArgument();
-    kind = isFunctionalArgument
-        ? CompletionSuggestionKind.IDENTIFIER
-        : CompletionSuggestionKind.INVOCATION;
-    for (var type in classElement.allSupertypes) {
-      double inheritanceDistance;
-      if (request.useNewRelevance) {
-        inheritanceDistance = request.featureComputer
-            .inheritanceDistanceFeature(classElement, type.element);
-      }
-      _addSuggestionsForType(type, request, inheritanceDistance,
-          isFunctionalArgument: isFunctionalArgument);
-    }
-  }
-
-  /// Return the class member containing the target or `null` if the target is
-  /// in a static method or static field or not in a class member.
-  ClassMember _enclosingMember(CompletionTarget target) {
-    var node = target.containingNode;
-    while (node != null) {
-      if (node is MethodDeclaration) {
-        if (!node.isStatic) {
-          return node;
-        }
-      } else if (node is FieldDeclaration) {
-        if (!node.isStatic) {
-          return node;
-        }
-      } else if (node is ConstructorDeclaration) {
-        return node;
-      }
-      node = node.parent;
-    }
-    return null;
-  }
-}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
index 65f8f0b..fa4ff8f 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/keyword_contributor.dart
@@ -13,7 +13,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/ast/visitor.dart';
 import 'package:analyzer/src/dart/ast/token.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 
 const ASYNC_STAR = 'async*';
@@ -29,14 +28,13 @@
 /// are valid at the completion point.
 class KeywordContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     // Don't suggest anything right after double or integer literals.
     if (request.target.isDoubleOrIntLiteral()) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     request.target.containingNode.accept(_KeywordVisitor(request, builder));
-    return const <CompletionSuggestion>[];
   }
 }
 
@@ -760,11 +758,13 @@
 
   void _addExpressionKeywords(AstNode node) {
     _addSuggestions([
-      Keyword.CONST,
       Keyword.FALSE,
       Keyword.NULL,
       Keyword.TRUE,
     ]);
+    if (!request.inConstantContext) {
+      _addSuggestions([Keyword.CONST]);
+    }
     if (node.inClassMemberBody) {
       _addSuggestions([Keyword.SUPER, Keyword.THIS]);
     }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
index 097bfa7..463e66e 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/label_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/completion_manager.dart'
     show DartCompletionRequestImpl;
@@ -19,7 +17,7 @@
 /// `continue` statements.
 class LabelContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var optype = (request as DartCompletionRequestImpl).opType;
 
@@ -33,7 +31,6 @@
             .visit(request.target.containingNode);
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
index f011a42..d25bbb8 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_member_contributor.dart
@@ -4,21 +4,20 @@
 
 import 'dart:async';
 
+import 'package:analysis_server/src/protocol_server.dart'
+    show 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:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 
-import '../../../protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
-
 /// A contributor that produces suggestions based on the members of a library
 /// when the library was imported using a prefix. More concretely, this class
 /// produces suggestions for expressions of the form `p.^`, where `p` is a
 /// prefix.
 class LibraryMemberContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     // Determine if the target looks like a library prefix.
     var targetId = request.dotTarget;
@@ -31,15 +30,15 @@
         if (containingLibrary != null) {
           var imports = containingLibrary.imports;
           if (imports != null) {
-            return _buildSuggestions(request, builder, elem, imports);
+            _buildSuggestions(request, builder, elem, imports);
+            return;
           }
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 
-  List<CompletionSuggestion> _buildSuggestions(
+  void _buildSuggestions(
       DartCompletionRequest request,
       SuggestionBuilder builder,
       PrefixElement elem,
@@ -83,6 +82,5 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
index bd8674d..019aba1 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/library_prefix_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 
@@ -13,15 +11,15 @@
 /// import directives.
 class LibraryPrefixContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     var imports = request.libraryElement.imports;
     if (imports == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     for (var element in imports) {
@@ -33,6 +31,5 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
index 38c868a..ac04121 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/local_library_contributor.dart
@@ -5,7 +5,7 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
+    show CompletionSuggestionKind;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart'
     show SuggestionBuilder;
@@ -148,15 +148,15 @@
 /// which the completion is requested.
 class LocalLibraryContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     if (!request.includeIdentifiers) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     var libraryUnits = request.result.unit.declaredElement.library.units;
     if (libraryUnits == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     var visitor = LibraryElementSuggestionBuilder(request, builder);
@@ -165,6 +165,5 @@
         unit.accept(visitor);
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
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 1129301..abe46be 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
@@ -5,23 +5,39 @@
 import 'dart:async';
 
 import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion, CompletionSuggestionKind;
+    show 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/strings.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
+import 'package:analyzer_plugin/src/utilities/completion/completion_target.dart';
 import 'package:analyzer_plugin/src/utilities/completion/optype.dart';
 import 'package:analyzer_plugin/src/utilities/visitors/local_declaration_visitor.dart'
     show LocalDeclarationVisitor;
 import 'package:meta/meta.dart';
 
 /// A contributor that produces suggestions based on the declarations in the
-/// local file and containing library.
+/// local file and containing library.  This contributor also produces
+/// suggestions based on the instance members from the supertypes of a given
+/// type. More concretely, this class produces suggestions for places where an
+/// inherited instance member might be invoked via an implicit target of `this`.
 class LocalReferenceContributor extends DartCompletionContributor {
+  /// The builder used to build some suggestions.
+  MemberSuggestionBuilder memberBuilder;
+
+  /// The kind of suggestion to make.
+  CompletionSuggestionKind classMemberSuggestionKind;
+
+  /// The [_VisibilityTracker] tracks the set of elements already added in the
+  /// completion list, this object helps prevents suggesting elements that have
+  /// been shadowed by local declarations.
+  _VisibilityTracker visibilityTracker = _VisibilityTracker();
+
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var opType = request.opType;
     var node = request.target.containingNode;
@@ -30,6 +46,8 @@
     var suggestLocalFields = node is ConstructorDeclaration &&
         node.initializers.contains(request.target.entity);
 
+    var localVisitor;
+
     // Collect suggestions from the specific child [AstNode] that contains the
     // completion offset and all of its parents recursively.
     if (!opType.isPrefixed) {
@@ -51,18 +69,114 @@
           node = node.parent.parent;
         }
 
-        var visitor = _LocalVisitor(request, builder,
+        localVisitor = _LocalVisitor(request, builder, visibilityTracker,
             suggestLocalFields: suggestLocalFields);
         try {
           builder.laterReplacesEarlier = false;
-          visitor.visit(node);
+          localVisitor.visit(node);
         } finally {
           builder.laterReplacesEarlier = true;
         }
-        return visitor.suggestions;
       }
     }
-    return const <CompletionSuggestion>[];
+
+    // From this point forward the logic is for the inherited references.
+    if (request.includeIdentifiers) {
+      var member = _enclosingMember(request.target);
+      if (member != null) {
+        var classOrMixin = member.parent;
+        if (classOrMixin is ClassOrMixinDeclaration &&
+            classOrMixin.declaredElement != null) {
+          memberBuilder = MemberSuggestionBuilder(request, builder);
+          _computeSuggestionsForClass(classOrMixin.declaredElement, request);
+        }
+      }
+    }
+  }
+
+  void _addSuggestionsForType(InterfaceType type, DartCompletionRequest request,
+      double inheritanceDistance,
+      {bool isFunctionalArgument = false}) {
+    var opType = request.opType;
+    if (!isFunctionalArgument) {
+      for (var accessor in type.accessors) {
+        if (visibilityTracker._isVisible(accessor.declaration)) {
+          if (accessor.isGetter) {
+            if (opType.includeReturnValueSuggestions) {
+              memberBuilder.addSuggestionForAccessor(
+                  accessor: accessor, inheritanceDistance: inheritanceDistance);
+            }
+          } else {
+            if (opType.includeVoidReturnSuggestions) {
+              memberBuilder.addSuggestionForAccessor(
+                  accessor: accessor, inheritanceDistance: inheritanceDistance);
+            }
+          }
+        }
+      }
+    }
+    for (var method in type.methods) {
+      if (visibilityTracker._isVisible(method.declaration)) {
+        if (method.returnType == null) {
+          memberBuilder.addSuggestionForMethod(
+              method: method,
+              inheritanceDistance: inheritanceDistance,
+              kind: classMemberSuggestionKind);
+        } else if (!method.returnType.isVoid) {
+          if (opType.includeReturnValueSuggestions) {
+            memberBuilder.addSuggestionForMethod(
+                method: method,
+                inheritanceDistance: inheritanceDistance,
+                kind: classMemberSuggestionKind);
+          }
+        } else {
+          if (opType.includeVoidReturnSuggestions) {
+            memberBuilder.addSuggestionForMethod(
+                method: method,
+                inheritanceDistance: inheritanceDistance,
+                kind: classMemberSuggestionKind);
+          }
+        }
+      }
+    }
+  }
+
+  void _computeSuggestionsForClass(
+      ClassElement classElement, DartCompletionRequest request) {
+    var isFunctionalArgument = request.target.isFunctionalArgument();
+    classMemberSuggestionKind = isFunctionalArgument
+        ? CompletionSuggestionKind.IDENTIFIER
+        : CompletionSuggestionKind.INVOCATION;
+    for (var type in classElement.allSupertypes) {
+      double inheritanceDistance;
+      if (request.useNewRelevance) {
+        inheritanceDistance = request.featureComputer
+            .inheritanceDistanceFeature(classElement, type.element);
+      }
+      _addSuggestionsForType(type, request, inheritanceDistance,
+          isFunctionalArgument: isFunctionalArgument);
+    }
+  }
+
+  /// Return the class member containing the target or `null` if the target is
+  /// in a static method or static field or not in a class member.
+  ClassMember _enclosingMember(CompletionTarget target) {
+    var node = target.containingNode;
+    while (node != null) {
+      if (node is MethodDeclaration) {
+        if (!node.isStatic) {
+          return node;
+        }
+      } else if (node is FieldDeclaration) {
+        if (!node.isStatic) {
+          return node;
+        }
+      } else if (node is ConstructorDeclaration) {
+        return node;
+      }
+      node = node.parent;
+    }
+    return null;
   }
 }
 
@@ -89,18 +203,15 @@
   /// A flag indicating whether local fields should be suggested.
   final bool suggestLocalFields;
 
-  final Map<String, CompletionSuggestion> suggestionMap =
-      <String, CompletionSuggestion>{};
-
   /// Only used when [useNewRelevance] is `false`.
   int privateMemberRelevance = DART_RELEVANCE_DEFAULT;
 
-  /// As elements are added locally, walking up the AST structure, we don't add
-  /// completions if we have previously see some [Element] name.
-  final Set<String> declaredNames = {};
+  _VisibilityTracker visibilityTracker;
 
-  _LocalVisitor(this.request, this.builder, {@required this.suggestLocalFields})
-      : opType = request.opType,
+  _LocalVisitor(this.request, this.builder, this.visibilityTracker,
+      {@required this.suggestLocalFields})
+      : assert(visibilityTracker != null),
+        opType = request.opType,
         useNewRelevance = request.useNewRelevance,
         targetIsFunctionalArgument = request.target.isFunctionalArgument(),
         super(request.offset) {
@@ -131,9 +242,6 @@
     }
   }
 
-  /// Return the suggestions that have been computed.
-  List<CompletionSuggestion> get suggestions => suggestionMap.values.toList();
-
   TypeProvider get typeProvider => request.libraryElement.typeProvider;
 
   CompletionSuggestionKind get _defaultKind => targetIsFunctionalArgument
@@ -143,7 +251,7 @@
   @override
   void declaredClass(ClassDeclaration declaration) {
     var classElt = declaration.declaredElement;
-    if (shouldSuggest(classElt)) {
+    if (visibilityTracker._isVisible(classElt)) {
       if (opType.includeTypeNameSuggestions) {
         builder.suggestClass(classElt, kind: _defaultKind);
       }
@@ -176,7 +284,7 @@
 
   @override
   void declaredEnum(EnumDeclaration declaration) {
-    if (shouldSuggest(declaration.declaredElement) &&
+    if (visibilityTracker._isVisible(declaration.declaredElement) &&
         opType.includeTypeNameSuggestions) {
       builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
       for (var enumConstant in declaration.constants) {
@@ -189,7 +297,7 @@
 
   @override
   void declaredExtension(ExtensionDeclaration declaration) {
-    if (shouldSuggest(declaration.declaredElement) &&
+    if (visibilityTracker._isVisible(declaration.declaredElement) &&
         opType.includeReturnValueSuggestions &&
         declaration.name != null) {
       builder.suggestExtension(declaration.declaredElement, kind: _defaultKind);
@@ -199,7 +307,7 @@
   @override
   void declaredField(FieldDeclaration fieldDecl, VariableDeclaration varDecl) {
     var field = varDecl.declaredElement;
-    if ((shouldSuggest(field) &&
+    if ((visibilityTracker._isVisible(field) &&
             opType.includeReturnValueSuggestions &&
             (!opType.inStaticMethodBody || fieldDecl.isStatic)) ||
         suggestLocalFields) {
@@ -217,7 +325,7 @@
 
   @override
   void declaredFunction(FunctionDeclaration declaration) {
-    if (shouldSuggest(declaration.declaredElement) &&
+    if (visibilityTracker._isVisible(declaration.declaredElement) &&
         (opType.includeReturnValueSuggestions ||
             opType.includeVoidReturnSuggestions)) {
       if (declaration.isSetter) {
@@ -263,7 +371,7 @@
 
   @override
   void declaredLocalVar(SimpleIdentifier id, TypeAnnotation typeName) {
-    if (shouldSuggest(id.staticElement) &&
+    if (visibilityTracker._isVisible(id.staticElement) &&
         opType.includeReturnValueSuggestions) {
       builder.suggestLocalVariable(id.staticElement as LocalVariableElement);
     }
@@ -272,7 +380,7 @@
   @override
   void declaredMethod(MethodDeclaration declaration) {
     var element = declaration.declaredElement;
-    if (shouldSuggest(element) &&
+    if (visibilityTracker._isVisible(element) &&
         (opType.includeReturnValueSuggestions ||
             opType.includeVoidReturnSuggestions) &&
         (!opType.inStaticMethodBody || declaration.isStatic)) {
@@ -296,7 +404,7 @@
 
   @override
   void declaredMixin(MixinDeclaration declaration) {
-    if (shouldSuggest(declaration.declaredElement) &&
+    if (visibilityTracker._isVisible(declaration.declaredElement) &&
         opType.includeTypeNameSuggestions) {
       builder.suggestClass(declaration.declaredElement, kind: _defaultKind);
     }
@@ -305,7 +413,8 @@
   @override
   void declaredParam(SimpleIdentifier id, TypeAnnotation typeName) {
     var element = id.staticElement;
-    if (shouldSuggest(element) && opType.includeReturnValueSuggestions) {
+    if (visibilityTracker._isVisible(element) &&
+        opType.includeReturnValueSuggestions) {
       if (_isUnused(id.name)) {
         return;
       }
@@ -321,7 +430,7 @@
   void declaredTopLevelVar(
       VariableDeclarationList varList, VariableDeclaration varDecl) {
     var variableElement = varDecl.declaredElement;
-    if (shouldSuggest(variableElement) &&
+    if (visibilityTracker._isVisible(variableElement) &&
         opType.includeReturnValueSuggestions) {
       builder.suggestTopLevelPropertyAccessor(
           (variableElement as TopLevelVariableElement).getter);
@@ -330,18 +439,12 @@
 
   @override
   void declaredTypeParameter(TypeParameter node) {
-    if (shouldSuggest(node.declaredElement) &&
+    if (visibilityTracker._isVisible(node.declaredElement) &&
         opType.includeTypeNameSuggestions) {
       builder.suggestTypeParameter(node.declaredElement);
     }
   }
 
-  /// Before completions are added by this contributor, we verify with this
-  /// method if the element has already been added, this prevents suggesting
-  /// [Element]s that are shadowed.
-  bool shouldSuggest(Element element) =>
-      element != null && declaredNames.add(element.name);
-
   /// Return `true` if the [identifier] is composed of one or more underscore
   /// characters and nothing else.
   bool _isUnused(String identifier) => RegExp(r'^_+$').hasMatch(identifier);
@@ -356,3 +459,17 @@
     return false;
   }
 }
+
+/// This class tracks the set of elements already added in the completion list,
+/// this object helps prevents suggesting elements that have been shadowed by
+/// local declarations.
+class _VisibilityTracker {
+  /// The set of known previously declared names in this contributor.
+  final Set<String> declaredNames = {};
+
+  /// Before completions are added by this contributor, we verify with this
+  /// method if the element has already been added, this prevents suggesting
+  /// [Element]s that are shadowed.
+  bool _isVisible(Element element) =>
+      element != null && declaredNames.add(element.name);
+}
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
index 02b14e5..40e76cf 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/named_constructor_contributor.dart
@@ -8,7 +8,6 @@
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
-import 'package:analyzer_plugin/protocol/protocol_common.dart' hide Element;
 
 /// A contributor that produces suggestions based on the named constructors
 /// defined on a given class. More concretely, this class produces suggestions
@@ -16,13 +15,13 @@
 /// class.
 class NamedConstructorContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var node = request.target.containingNode;
     if (node is ConstructorName) {
       var libraryElement = request.libraryElement;
       if (libraryElement == null) {
-        return const <CompletionSuggestion>[];
+        return;
       }
       var typeName = node.type;
       if (typeName != null) {
@@ -35,7 +34,6 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 
   void _buildSuggestions(
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 f3210e7..de4912c 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
@@ -4,7 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart';
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -15,15 +14,15 @@
 /// inside a class declaration with templates for inherited members.
 class OverrideContributor implements DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var targetId = _getTargetId(request.target);
     if (targetId == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     var classDecl = targetId.thisOrAncestorOfType<ClassOrMixinDeclaration>();
     if (classDecl == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     var inheritance = InheritanceManager3();
@@ -36,7 +35,6 @@
         _namesToOverride(classElem.librarySource.uri, interface);
 
     // Build suggestions
-    var suggestions = <CompletionSuggestion>[];
     for (var name in namesToOverride) {
       var element = interfaceMap[name];
       // Gracefully degrade if the overridden element has not been resolved.
@@ -45,7 +43,6 @@
         await builder.suggestOverride(targetId, element, invokeSuper);
       }
     }
-    return suggestions;
   }
 
   /// If the target looks like a partial identifier inside a class declaration
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
index d7f8154..626db62 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/static_member_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -17,7 +15,7 @@
 /// class, enum, or extension.
 class StaticMemberContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var library = request.libraryElement;
     if (library == null) {
@@ -25,7 +23,7 @@
       // detached part file or source change.
       // TODO(brianwilkerson) Consider testing for this before invoking _any_ of
       //  the contributors.
-      return const <CompletionSuggestion>[];
+      return;
     }
     bool isVisible(Element element) => element.isAccessibleIn(library);
     var targetId = request.dotTarget;
@@ -76,6 +74,5 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 }
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 0afc33f..e416f0c 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
@@ -5,8 +5,6 @@
 import 'dart:async';
 import 'dart:collection';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -21,13 +19,13 @@
 /// instance of a type.
 class TypeMemberContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var containingLibrary = request.libraryElement;
     // Gracefully degrade if the library could not be determined, such as with a
     // detached part file or source change.
     if (containingLibrary == null) {
-      return const <CompletionSuggestion>[];
+      return;
     }
 
     // Recompute the target because resolution might have changed it.
@@ -35,17 +33,17 @@
     if (expression == null ||
         expression.isSynthetic ||
         expression is ExtensionOverride) {
-      return const <CompletionSuggestion>[];
+      return;
     }
     if (expression is Identifier) {
       var elem = expression.staticElement;
       if (elem is ClassElement) {
         // Suggestions provided by StaticMemberContributor.
-        return const <CompletionSuggestion>[];
+        return;
       }
       if (elem is PrefixElement) {
         // Suggestions provided by LibraryMemberContributor.
-        return const <CompletionSuggestion>[];
+        return;
       }
     }
 
@@ -96,8 +94,6 @@
       memberBuilder.buildSuggestions(type,
           mixins: mixins, superclassConstraints: superclassConstraints);
     }
-
-    return const <CompletionSuggestion>[];
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
index 06ea2a4..c27c960 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/uri_contributor.dart
@@ -5,8 +5,6 @@
 import 'dart:async';
 import 'dart:core';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 import 'package:analysis_server/src/provisional/completion/dart/completion_dart.dart';
 import 'package:analysis_server/src/services/completion/dart/suggestion_builder.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -25,11 +23,10 @@
   static bool suggestFilePaths = true;
 
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var visitor = _UriSuggestionBuilder(request, builder);
     request.target.containingNode.accept(visitor);
-    return const <CompletionSuggestion>[];
   }
 }
 
diff --git a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
index 3c87372..c8955d0 100644
--- a/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
+++ b/pkg/analysis_server/lib/src/services/completion/dart/variable_name_contributor.dart
@@ -4,8 +4,6 @@
 
 import 'dart:async';
 
-import 'package:analysis_server/src/protocol_server.dart'
-    show CompletionSuggestion;
 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/services/correction/name_suggestion.dart';
@@ -16,7 +14,7 @@
 /// static type of the variable.
 class VariableNameContributor extends DartCompletionContributor {
   @override
-  Future<List<CompletionSuggestion>> computeSuggestions(
+  Future<void> computeSuggestions(
       DartCompletionRequest request, SuggestionBuilder builder) async {
     var opType = request.opType;
 
@@ -65,7 +63,7 @@
         }
       }
       if (strName == null) {
-        return const <CompletionSuggestion>[];
+        return;
       }
 
       var doIncludePrivateVersion =
@@ -80,7 +78,6 @@
         }
       }
     }
-    return const <CompletionSuggestion>[];
   }
 
   /// Given some [name], add a suggestion with the name (unless the name is
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
index 5f490be..712ed76 100644
--- a/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
+++ b/pkg/analysis_server/lib/src/services/correction/dart/change_type_annotation.dart
@@ -23,7 +23,7 @@
 
   @override
   Future<void> compute(DartChangeBuilder builder) async {
-    var declaration = coveredNode.parent;
+    var declaration = coveredNode?.parent;
     if (declaration is VariableDeclaration &&
         declaration.initializer == coveredNode) {
       var variableList = declaration.parent;
diff --git a/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.dart
new file mode 100644
index 0000000..c369441
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/dart/replace_with_filled.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.
+
+import 'package:analysis_server/src/services/correction/dart/abstract_producer.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_dart.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+
+class ReplaceWithFilled extends CorrectionProducer {
+  @override
+  FixKind get fixKind => DartFixKind.REPLACE_WITH_FILLED;
+
+  @override
+  Future<void> compute(DartChangeBuilder builder) async {
+    var typeName = node is SimpleIdentifier ? node.parent : node;
+    var creation = typeName?.parent?.parent;
+    if (typeName is TypeName && creation is InstanceCreationExpression) {
+      var elementType = (typeName.type as InterfaceType).typeArguments[0];
+      if (typeSystem.isNullable(elementType)) {
+        var argumentList = creation.argumentList;
+        if (argumentList.arguments.length == 1) {
+          await builder.addFileEdit(file, (builder) {
+            builder.addSimpleInsertion(argumentList.offset, '.filled');
+            builder.addSimpleInsertion(
+                argumentList.arguments[0].end, ', null, growable: false');
+          });
+        }
+      }
+    }
+  }
+
+  /// Return an instance of this class. Used as a tear-off in `FixProcessor`.
+  static ReplaceWithFilled newInstance() => ReplaceWithFilled();
+}
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index ebba073..3983092 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -405,6 +405,8 @@
       appliedTogetherMessage: "Replace all 'boolean' with 'bool' in file");
   static const REPLACE_COLON_WITH_EQUALS =
       FixKind('dart.fix.replace.colonWithEquals', 50, "Replace ':' with '='");
+  static const REPLACE_WITH_FILLED = FixKind(
+      'dart.fix.replace.finalWithListFilled', 50, "Replace with 'List.filled'");
   static const REPLACE_FINAL_WITH_CONST = FixKind(
       'dart.fix.replace.finalWithConst', 50, "Replace 'final' with 'const'");
   static const REPLACE_NEW_WITH_CONST = FixKind(
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 3db208c..c398846 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -123,6 +123,7 @@
 import 'package:analysis_server/src/services/correction/dart/replace_with_conditional_assignment.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_eight_digit_hex.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_extension_name.dart';
+import 'package:analysis_server/src/services/correction/dart/replace_with_filled.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_identifier.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_interpolation.dart';
 import 'package:analysis_server/src/services/correction/dart/replace_with_is_empty.dart';
@@ -482,6 +483,9 @@
     CompileTimeErrorCode.CONST_WITH_NON_TYPE: [
       ImportLibrary.forType,
     ],
+    CompileTimeErrorCode.EXTENDS_NON_CLASS: [
+      ImportLibrary.forType,
+    ],
     CompileTimeErrorCode.EXTRA_POSITIONAL_ARGUMENTS: [
       AddMissingParameter.newInstance,
     ],
@@ -576,9 +580,16 @@
     CompileTimeErrorCode.CONST_WITH_NON_CONST: [
       RemoveConst.newInstance,
     ],
+    CompileTimeErrorCode.DEFAULT_LIST_CONSTRUCTOR: [
+      ReplaceWithFilled.newInstance,
+    ],
     CompileTimeErrorCode.CONST_WITH_NON_TYPE: [
       ChangeTo.classOrMixin,
     ],
+    CompileTimeErrorCode.EXTENDS_NON_CLASS: [
+      ChangeTo.classOrMixin,
+      CreateClass.newInstance,
+    ],
     CompileTimeErrorCode.EXTENSION_OVERRIDE_ACCESS_TO_STATIC_MEMBER: [
       ReplaceWithExtensionName.newInstance,
     ],
diff --git a/pkg/analysis_server/test/abstract_context.dart b/pkg/analysis_server/test/abstract_context.dart
index 338b521..d890e91 100644
--- a/pkg/analysis_server/test/abstract_context.dart
+++ b/pkg/analysis_server/test/abstract_context.dart
@@ -132,18 +132,29 @@
   }
 
   /// Create an analysis options file based on the given arguments.
-  void createAnalysisOptionsFile(
-      {List<String> experiments, List<String> lints}) {
+  void createAnalysisOptionsFile({
+    List<String> experiments,
+    bool implicitCasts,
+    List<String> lints,
+  }) {
     var buffer = StringBuffer();
 
-    if (experiments != null) {
+    if (experiments != null || implicitCasts != null) {
       buffer.writeln('analyzer:');
+    }
+
+    if (experiments != null) {
       buffer.writeln('  enable-experiment:');
       for (var experiment in experiments) {
         buffer.writeln('    - $experiment');
       }
     }
 
+    if (implicitCasts != null) {
+      buffer.writeln('  strong-mode:');
+      buffer.writeln('    implicit-casts: $implicitCasts');
+    }
+
     if (lints != null) {
       buffer.writeln('linter:');
       buffer.writeln('  rules:');
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index 3f0d69d..35894eb 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -677,7 +677,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
     });
   }
 
@@ -743,7 +744,8 @@
     return getSuggestions().then((_) {
       expect(replacementOffset, equals(completionOffset));
       expect(replacementLength, equals(0));
-      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm');
+      assertHasResult(CompletionSuggestionKind.INVOCATION, 'm',
+          relevance: DART_RELEVANCE_LOCAL_METHOD);
     });
   }
 
@@ -1092,27 +1094,24 @@
 }
 ''', [
       token('class', 0, null, null),
-      token('A', 6, 'Type',
-          ['declaration']), //token('A', 6, 'dart:core;Type', ['declaration']),
+      token('A', 6, 'Type', ['declaration']),
+      //token('A', 6, 'dart:core;Type', ['declaration']),
       token('{', 8, null, null),
-      token('String', 12, 'dart:core;Type<String>', [
-        'reference'
-      ]), //token('String', 12, 'dart:core;Type<dart:core;String>', ['reference']),
-      token('c', 19,
-          'String Function(int, int)', //'dart:core;String Function(dart:core;int, dart:core;int)',
+      token('String', 12, 'dart:core;Type<String>', ['reference']),
+      //token('String', 12, 'dart:core;Type<dart:core;String>', ['reference']),
+      token('c', 19, 'String Function(int, int)',
+          //'dart:core;String Function(dart:core;int, dart:core;int)',
           ['declaration']),
       token('(', 20, null, null),
-      token('int', 21, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 21, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('x', 25, 'int',
-          ['declaration']), //token('x', 25, 'dart:core;int', ['declaration']),
+      token('int', 21, 'dart:core;Type<int>', ['reference']),
+      //token('int', 21, 'dart:core;Type<dart:core;int>', ['reference']),
+      token('x', 25, 'int', ['declaration']),
+      //token('x', 25, 'dart:core;int', ['declaration']),
 //      token(',', null, null),
-      token('int', 28, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 28, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('y', 32, 'int',
-          ['declaration']), //token('y', 32, 'dart:core;int', ['declaration']),
+      token('int', 28, 'dart:core;Type<int>', ['reference']),
+      //token('int', 28, 'dart:core;Type<dart:core;int>', ['reference']),
+      token('y', 32, 'int', ['declaration']),
+      //token('y', 32, 'dart:core;int', ['declaration']),
       token(')', 33, null, null),
       token('{', 35, null, null),
       token('}', 36, null, null),
@@ -1131,8 +1130,8 @@
       token("'radar'", 8, 'String',
           null), //token("'radar'", 8, 'dart:core;String', null),
       token('.', 15, null, null),
-      token('indexOf', 16,
-          'int Function(Pattern, int)', //'dart:core;int Function(dart:core;Pattern, dart:core;int)',
+      token('indexOf', 16, 'int Function(Pattern, int)',
+          //'dart:core;int Function(dart:core;Pattern, dart:core;int)',
           ['reference']),
       token('(', 23, null, null),
       token("'r'", 24, 'String',
@@ -1182,23 +1181,20 @@
   return p;
 }
 ''', [
-      token('int', 0, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 0, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('f', 4, 'int Function(int)', [
-        'declaration'
-      ]), //token('f', 4, 'dart:core;int Function(dart:core;int)', ['declaration']),
+      token('int', 0, 'dart:core;Type<int>', ['reference']),
+      //token('int', 0, 'dart:core;Type<dart:core;int>', ['reference']),
+      token('f', 4, 'int Function(int)', ['declaration']),
+      //token('f', 4, 'dart:core;int Function(dart:core;int)', ['declaration']),
       token('(', 5, null, null),
-      token('int', 6, 'dart:core;Type<int>', [
-        'reference'
-      ]), //token('int', 6, 'dart:core;Type<dart:core;int>', ['reference']),
-      token('p', 10, 'int',
-          ['declaration']), //token('p', 10, 'dart:core;int', ['declaration']),
+      token('int', 6, 'dart:core;Type<int>', ['reference']),
+      //token('int', 6, 'dart:core;Type<dart:core;int>', ['reference']),
+      token('p', 10, 'int', ['declaration']),
+      //token('p', 10, 'dart:core;int', ['declaration']),
       token(')', 11, null, null),
       token('{', 13, null, null),
       token('return', 17, null, null),
-      token('p', 24, 'int',
-          ['reference']), //token('p', 24, 'dart:core;int', ['reference']),
+      token('p', 24, 'int', ['reference']),
+      //token('p', 24, 'dart:core;int', ['reference']),
       token(';', 25, null, null),
       token('}', 27, null, null),
     ]);
diff --git a/pkg/analysis_server/test/edit/fixes_test.dart b/pkg/analysis_server/test/edit/fixes_test.dart
index 738501c..d922b52 100644
--- a/pkg/analysis_server/test/edit/fixes_test.dart
+++ b/pkg/analysis_server/test/edit/fixes_test.dart
@@ -31,6 +31,24 @@
     handler = EditDomainHandler(server);
   }
 
+  Future<void> test_fixExtendsNonClass() async {
+    createProject();
+    addTestFile('''
+class MyCompleter extends Completer<String> {}
+
+class Completer2 {}
+''');
+    await waitForTasksFinished();
+    doAllDeclarationsTrackerWork();
+    var errorFixes = await _getFixesAt('extends Completer');
+    expect(errorFixes, hasLength(1));
+    var fixes = errorFixes[0].fixes;
+    expect(fixes, hasLength(3));
+    expect(fixes[0].message, matches('Import library'));
+    expect(fixes[1].message, matches("Change to 'Completer2'"));
+    expect(fixes[2].message, matches("Create class 'Completer'"));
+  }
+
   Future<void> test_fixUndefinedClass() async {
     createProject();
     addTestFile('''
diff --git a/pkg/analysis_server/test/integration/analysis/error_test.dart b/pkg/analysis_server/test/integration/analysis/error_test.dart
index 90dfb31..9d503a2 100644
--- a/pkg/analysis_server/test/integration/analysis/error_test.dart
+++ b/pkg/analysis_server/test/integration/analysis/error_test.dart
@@ -51,37 +51,6 @@
     });
   }
 
-  Future<void> test_super_mixins_disabled() async {
-    var pathname = sourcePath('test.dart');
-    writeFile(pathname, '''
-class Test extends Object with C {
-  void foo() {}
-}
-abstract class B {
-  void foo() {}
-}
-abstract class C extends B {
-  void bar() {
-    super.foo();
-  }
-}
-''');
-    standardAnalysisSetup();
-    await analysisFinished;
-    expect(currentAnalysisErrors[pathname], isList);
-    var errors = currentAnalysisErrors[pathname];
-    expect(errors, hasLength(2));
-    var allErrorMessages = errors.map((AnalysisError e) => e.message).toSet();
-    expect(
-        allErrorMessages,
-        contains(
-            "The class 'C' can't be used as a mixin because it extends a class other than Object."));
-    expect(
-        allErrorMessages,
-        contains(
-            "The class 'C' can't be used as a mixin because it references 'super'."));
-  }
-
   @failingTest
   Future<void> test_super_mixins_enabled() async {
     // We see errors here with the new driver (#28870).
diff --git a/pkg/analysis_server/test/lsp/code_actions_source_test.dart b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
index 676c9ba..08f227c 100644
--- a/pkg/analysis_server/test/lsp/code_actions_source_test.dart
+++ b/pkg/analysis_server/test/lsp/code_actions_source_test.dart
@@ -106,7 +106,7 @@
     );
   }
 
-  Future<void> test_failsIfFileHasErrors() async {
+  Future<void> test_failsSilentlyIfFileHasErrors() async {
     final content = 'invalid dart code';
     await newFile(mainFilePath, content: content);
     await initialize(
@@ -122,10 +122,10 @@
       (codeAction) => codeAction.command,
     );
 
-    // Ensure the request returned an error (error repsonses are thrown by
-    // the test helper to make consuming success results simpler).
-    await expectLater(executeCommand(command),
-        throwsA(isResponseError(ServerErrorCodes.FileHasErrors)));
+    final commandResponse = await executeCommand(command);
+    // Invalid code returns an empty success() response to avoid triggering
+    // errors in the editor if run automatically on every save.
+    expect(commandResponse, isNull);
   }
 
   Future<void> test_noEdits() async {
diff --git a/pkg/analysis_server/test/lsp/completion_test.dart b/pkg/analysis_server/test/lsp/completion_test.dart
index 8f11819..59b9095 100644
--- a/pkg/analysis_server/test/lsp/completion_test.dart
+++ b/pkg/analysis_server/test/lsp/completion_test.dart
@@ -192,6 +192,49 @@
     expect(suggestion.label, equals('id'));
   }
 
+  Future<void> test_fromPlugin_tooSlow() async {
+    final content = '''
+    void main() {
+      var x = '';
+      print(^);
+    }
+    ''';
+
+    final pluginResult = plugin.CompletionGetSuggestionsResult(
+      content.indexOf('^'),
+      0,
+      [
+        plugin.CompletionSuggestion(
+          plugin.CompletionSuggestionKind.INVOCATION,
+          100,
+          'x.toUpperCase()',
+          -1,
+          -1,
+          false,
+          false,
+        ),
+      ],
+    );
+    configureTestPlugin(
+      respondWith: pluginResult,
+      // Don't respond within an acceptable time
+      respondAfter: Duration(seconds: 1),
+    );
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    final fromServer = res.singleWhere((c) => c.label == 'x');
+    final fromPlugin = res.singleWhere((c) => c.label == 'x.toUpperCase()',
+        orElse: () => null);
+
+    // Server results should still be included.
+    expect(fromServer.kind, equals(CompletionItemKind.Variable));
+    // Plugin results are not because they didn't arrive in time.
+    expect(fromPlugin, isNull);
+  }
+
   Future<void> test_gettersAndSetters() async {
     final content = '''
     class MyClass {
@@ -374,6 +417,26 @@
     expect(updated, contains('a.abcdefghij'));
   }
 
+  Future<void> test_prefixFilter() async {
+    final content = '''
+    class UniqueNamedClassForLspOne {}
+    class UniqueNamedClassForLspTwo {}
+    class UniqueNamedClassForLspThree {}
+
+    main() {
+      // Should match only Two and Three
+      class UniqueNamedClassForLspT^
+    }
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(content));
+    final res = await getCompletion(mainFileUri, positionFromMarker(content));
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspOne'), isFalse);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspTwo'), isTrue);
+    expect(res.any((c) => c.label == 'UniqueNamedClassForLspThree'), isTrue);
+  }
+
   Future<void> test_suggestionSets() async {
     newFile(
       join(projectFolderPath, 'other_file.dart'),
diff --git a/pkg/analysis_server/test/lsp/definition_test.dart b/pkg/analysis_server/test/lsp/definition_test.dart
index 5c5fd36..3e3e414 100644
--- a/pkg/analysis_server/test/lsp/definition_test.dart
+++ b/pkg/analysis_server/test/lsp/definition_test.dart
@@ -86,6 +86,21 @@
     expect(res, isEmpty);
   }
 
+  Future<void> test_sameLine() async {
+    final contents = '''
+    int plusOne(int [[value]]) => 1 + val^ue;
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getDefinition(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    var loc = res.single;
+    expect(loc.range, equals(rangeFromMarkers(contents)));
+    expect(loc.uri, equals(mainFileUri.toString()));
+  }
+
   Future<void> test_singleFile() async {
     final contents = '''
     [[foo]]() {
@@ -119,4 +134,21 @@
     expect(loc.range, equals(rangeFromMarkers(contents)));
     expect(loc.uri, equals(mainFileUri.toString()));
   }
+
+  Future<void> test_varKeyword() async {
+    final contents = '''
+    va^r a = MyClass();
+
+    class [[MyClass]] {}
+    ''';
+
+    await initialize();
+    await openFile(mainFileUri, withoutMarkers(contents));
+    final res = await getDefinition(mainFileUri, positionFromMarker(contents));
+
+    expect(res, hasLength(1));
+    var loc = res.single;
+    expect(loc.range, equals(rangeFromMarkers(contents)));
+    expect(loc.uri, equals(mainFileUri.toString()));
+  }
 }
diff --git a/pkg/analysis_server/test/lsp/server_abstract.dart b/pkg/analysis_server/test/lsp/server_abstract.dart
index 3498d9e..bbf3ca1 100644
--- a/pkg/analysis_server/test/lsp/server_abstract.dart
+++ b/pkg/analysis_server/test/lsp/server_abstract.dart
@@ -52,13 +52,15 @@
   DiscoveredPluginInfo configureTestPlugin({
     plugin.ResponseResult respondWith,
     plugin.Notification notification,
+    Duration respondAfter = Duration.zero,
   }) {
     final info = DiscoveredPluginInfo('a', 'b', 'c', null, null);
     pluginManager.plugins.add(info);
 
     if (respondWith != null) {
       pluginManager.broadcastResults = <PluginInfo, Future<plugin.Response>>{
-        info: Future.value(respondWith.toResponse('-', 1))
+        info: Future.delayed(respondAfter)
+            .then((_) => respondWith.toResponse('-', 1))
       };
     }
 
diff --git a/pkg/analysis_server/test/mocks.dart b/pkg/analysis_server/test/mocks.dart
index ad4fa8c..11ad43c 100644
--- a/pkg/analysis_server/test/mocks.dart
+++ b/pkg/analysis_server/test/mocks.dart
@@ -39,6 +39,12 @@
   /// Completer that will be signalled when the input stream is closed.
   final Completer _closed = Completer();
 
+  /// Errors popups sent to the user.
+  final shownErrors = <lsp.ShowMessageParams>[];
+
+  /// Warning popups sent to the user.
+  final shownWarnings = <lsp.ShowMessageParams>[];
+
   MockLspServerChannel(bool _printMessages) {
     if (_printMessages) {
       _serverToClient.stream
@@ -46,6 +52,20 @@
       _clientToServer.stream
           .listen((message) => print('==> ' + jsonEncode(message)));
     }
+
+    // Keep track of any errors/warnings that are sent to the user with
+    // `window/showMessage`.
+    _serverToClient.stream.listen((message) {
+      if (message is lsp.NotificationMessage &&
+          message.method == Method.window_showMessage &&
+          message.params is lsp.ShowMessageParams) {
+        if (message.params?.type == MessageType.Error) {
+          shownErrors.add(message.params);
+        } else if (message.params?.type == MessageType.Warning) {
+          shownWarnings.add(message.params);
+        }
+      }
+    });
   }
 
   /// Future that will be completed when the input stream is closed.
@@ -167,7 +187,8 @@
         (message is lsp.ResponseMessage && message.id == request.id) ||
         (throwOnError &&
             message is lsp.NotificationMessage &&
-            message.method == Method.window_showMessage));
+            message.method == Method.window_showMessage &&
+            message.params?.type == MessageType.Error));
 
     if (response is lsp.ResponseMessage) {
       return response;
diff --git a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
index 5a1faf0..83b8b06 100644
--- a/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
+++ b/pkg/analysis_server/test/services/completion/dart/completion_contributor_util.dart
@@ -55,8 +55,8 @@
   Future<List<CompletionSuggestion>> computeContributedSuggestions(
       DartCompletionRequest request) async {
     var builder = SuggestionBuilder(request);
-    var suggestions = await contributor.computeSuggestions(request, builder);
-    return [...suggestions, ...builder.suggestions];
+    await contributor.computeSuggestions(request, builder);
+    return builder.suggestions.toList();
   }
 
   DartCompletionContributor createContributor();
diff --git a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart b/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
deleted file mode 100644
index 420da3c..0000000
--- a/pkg/analysis_server/test/services/completion/dart/inherited_reference_contributor_test.dart
+++ /dev/null
@@ -1,752 +0,0 @@
-// Copyright (c) 2014, 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/src/provisional/completion/dart/completion_dart.dart';
-import 'package:analysis_server/src/services/completion/dart/inherited_reference_contributor.dart';
-import 'package:test/test.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import 'completion_contributor_util.dart';
-
-void main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(InheritedReferenceContributorTest);
-  });
-}
-
-@reflectiveTest
-class InheritedReferenceContributorTest extends DartCompletionContributorTest {
-  @override
-  bool get isNullExpectedReturnTypeConsideredDynamic => false;
-
-  @override
-  DartCompletionContributor createContributor() {
-    return InheritedReferenceContributor();
-  }
-
-  /// Sanity check.  Permutations tested in local_ref_contributor.
-  Future<void> test_ArgDefaults_inherited_method_with_required_named() async {
-    addMetaPackage();
-    resolveSource('/home/test/lib/b.dart', '''
-import 'package:meta/meta.dart';
-
-lib libB;
-class A {
-   bool foo(int bar, {bool boo, @required int baz}) => false;
-}''');
-    addTestSource('''
-import "b.dart";
-class B extends A {
-  b() => f^
-}
-''');
-    await computeSuggestions();
-
-    assertSuggestMethod('foo', 'A', 'bool',
-        defaultArgListString: 'bar, baz: null');
-  }
-
-  Future<void> test_AwaitExpression_inherited() async {
-    // SimpleIdentifier  AwaitExpression  ExpressionStatement
-    resolveSource('/home/test/lib/b.dart', '''
-lib libB;
-class A {
-  Future y() async {return 0;}
-}''');
-    addTestSource('''
-import "b.dart";
-class B extends A {
-  Future a() async {return 0;}
-  foo() async {await ^}
-}
-''');
-
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('a');
-    assertNotSuggested('foo');
-    assertNotSuggested('B');
-    assertNotSuggested('A');
-    assertNotSuggested('Object');
-    assertSuggestMethod('y', 'A', 'Future<dynamic>');
-  }
-
-  Future<void> test_Block_inherited_imported_from_constructor() async {
-    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
-    resolveSource('/home/test/lib/b.dart', '''
-      lib B;
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }''');
-    addTestSource('''
-      import "b.dart";
-      class A extends E implements I with M {const A() {^}}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('e1', null);
-    assertSuggestField('f1', null);
-    assertSuggestField('i1', 'int');
-    assertSuggestField('m1', null);
-    assertSuggestGetter('f3', null);
-    assertSuggestSetter('f4');
-    assertSuggestMethod('e2', 'E', null);
-    assertSuggestMethod('f2', 'F', null);
-    assertSuggestMethod('i2', 'I', null);
-    assertSuggestMethod('m2', 'M', 'int');
-    assertNotSuggested('==');
-  }
-
-  Future<void> test_Block_inherited_imported_from_method() async {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    resolveSource('/home/test/lib/b.dart', '''
-      lib B;
-      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
-      class E extends F { var e1; e2() { } }
-      class I { int i1; i2() { } }
-      class M { var m1; int m2() { } }''');
-    addTestSource('''
-      import "b.dart";
-      class A extends E implements I with M {a() {^}}''');
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('e1', null);
-    assertSuggestField('f1', null);
-    assertSuggestField('i1', 'int');
-    assertSuggestField('m1', null);
-    assertSuggestGetter('f3', null);
-    assertSuggestSetter('f4');
-    assertSuggestMethod('e2', 'E', null);
-    assertSuggestMethod('f2', 'F', null);
-    assertSuggestMethod('i2', 'I', null);
-    assertSuggestMethod('m2', 'M', 'int');
-    assertNotSuggested('==');
-  }
-
-  Future<void> test_Block_inherited_local_from_constructor() async {
-    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
-    addTestSource('''
-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
-class E extends F { var e1; e2() { } }
-class I { int i1; i2() { } }
-class M { var m1; int m2() { } }
-class A extends E implements I with M {const A() {^}}''');
-    await computeSuggestions();
-
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('e1', null);
-    assertSuggestField('f1', null);
-    assertSuggestField('i1', 'int');
-    assertSuggestField('m1', null);
-    assertSuggestGetter('f3', null);
-    assertSuggestSetter('f4');
-    assertSuggestMethod('e2', 'E', null);
-    assertSuggestMethod('f2', 'F', null);
-    assertSuggestMethod('i2', 'I', null);
-    assertSuggestMethod('m2', 'M', 'int');
-  }
-
-  Future<void> test_Block_inherited_local_from_method() async {
-    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
-    addTestSource('''
-class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
-class E extends F { var e1; e2() { } }
-class I { int i1; i2() { } }
-class M { var m1; int m2() { } }
-class A extends E implements I with M {a() {^}}''');
-    await computeSuggestions();
-
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertSuggestField('e1', null);
-    assertSuggestField('f1', null);
-    assertSuggestField('i1', 'int');
-    assertSuggestField('m1', null);
-    assertSuggestGetter('f3', null);
-    assertSuggestSetter('f4');
-    assertSuggestMethod('e2', 'E', null);
-    assertSuggestMethod('f2', 'F', null);
-    assertSuggestMethod('i2', 'I', null);
-    assertSuggestMethod('m2', 'M', 'int');
-  }
-
-  Future<void> test_flutter_setState_hasPrefix() async {
-    var spaces_4 = ' ' * 4;
-    var spaces_6 = ' ' * 6;
-    await _check_flutter_setState(
-        '    setSt',
-        '''
-setState(() {
-$spaces_6
-$spaces_4});''',
-        20);
-  }
-
-  Future<void> test_flutter_setState_longPrefix() async {
-    var spaces_6 = ' ' * 6;
-    var spaces_8 = ' ' * 8;
-    await _check_flutter_setState(
-        '      setSt',
-        '''
-setState(() {
-$spaces_8
-$spaces_6});''',
-        22);
-  }
-
-  Future<void> test_flutter_setState_noPrefix() async {
-    var spaces_4 = ' ' * 4;
-    var spaces_6 = ' ' * 6;
-    await _check_flutter_setState(
-        '    ',
-        '''
-setState(() {
-$spaces_6
-$spaces_4});''',
-        20);
-  }
-
-  Future<void> test_inherited() async {
-    resolveSource('/home/test/lib/b.dart', '''
-lib libB;
-class A2 {
-  int x;
-  int y() {return 0;}
-  int x2;
-  int y2() {return 0;}
-}''');
-    addTestSource('''
-import "b.dart";
-class A1 {
-  int x;
-  int y() {return 0;}
-  int x1;
-  int y1() {return 0;}
-}
-class B extends A1 with A2 {
-  int a;
-  int b() {return 0;}
-  foo() {^}
-}
-''');
-
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('Object');
-    assertNotSuggested('B');
-    assertNotSuggested('a');
-    assertNotSuggested('b');
-    assertNotSuggested('foo');
-    assertNotSuggested('A');
-    assertSuggestField('x', 'int');
-    assertSuggestMethod('y', 'A1', 'int');
-    assertSuggestField('x1', 'int');
-    assertSuggestMethod('y1', 'A1', 'int');
-    assertSuggestField('x2', 'int');
-    assertSuggestMethod('y2', 'A2', 'int');
-  }
-
-  Future<void> test_method_inClass() async {
-    addTestSource('''
-class A {
-  void m(x, int y) {}
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    assertNotSuggested('m');
-  }
-
-  Future<void> test_method_inMixin() async {
-    addTestSource('''
-mixin A {
-  void m(x, int y) {}
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    assertNotSuggested('m');
-  }
-
-  Future<void> test_method_inMixin_fromSuperclassConstraint() async {
-    addTestSource('''
-class C {
-  void c(x, int y) {}
-}
-mixin M on C {
-  m() {^}
-}
-''');
-    await computeSuggestions();
-    assertSuggestMethod('c', 'C', 'void');
-  }
-
-  Future<void> test_method_parameters_mixed_required_and_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m(x, {int y}) {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  Future<void> test_method_parameters_mixed_required_and_named_local() async {
-    addTestSource('''
-class A {
-  void m(x, {int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  Future<void> test_method_parameters_mixed_required_and_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m(x, [int y]) {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void>
-      test_method_parameters_mixed_required_and_positional_local() async {
-    addTestSource('''
-class A {
-  void m(x, [int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 1);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_method_parameters_named() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m({x, int y}) {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  Future<void> test_method_parameters_named_local() async {
-    addTestSource('''
-class A {
-  void m({x, int y}) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, true);
-  }
-
-  Future<void> test_method_parameters_none() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m() {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_method_parameters_none_local() async {
-    addTestSource('''
-class A {
-  void m() {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, isEmpty);
-    expect(suggestion.parameterTypes, isEmpty);
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_method_parameters_positional() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m([x, int y]) {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_method_parameters_positional_local() async {
-    addTestSource('''
-class A {
-  void m([x, int y]) {}
-}
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 0);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_method_parameters_required() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  void m(x, int y) {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestMethod('m', 'A', 'void');
-    expect(suggestion.parameterNames, hasLength(2));
-    expect(suggestion.parameterNames[0], 'x');
-    expect(suggestion.parameterTypes[0], 'dynamic');
-    expect(suggestion.parameterNames[1], 'y');
-    expect(suggestion.parameterTypes[1], 'int');
-    expect(suggestion.requiredParameterCount, 2);
-    expect(suggestion.hasNamedParameters, false);
-  }
-
-  Future<void> test_mixin_ordering() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class B {}
-class M1 {
-  void m() {}
-}
-class M2 {
-  void m() {}
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class C extends B with M1, M2 {
-  void f() {
-    ^
-  }
-}
-''');
-    await computeSuggestions();
-    assertSuggestMethod('m', 'M1', 'void');
-  }
-
-  Future<void> test_no_parameters_field() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  int x;
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestField('x', 'int');
-    assertHasNoParameterInfo(suggestion);
-  }
-
-  Future<void> test_no_parameters_getter() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  int get x => null;
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestGetter('x', 'int');
-    assertHasNoParameterInfo(suggestion);
-  }
-
-  Future<void> test_no_parameters_setter() async {
-    resolveSource('/home/test/lib/a.dart', '''
-class A {
-  set x(int value) {};
-}
-''');
-    addTestSource('''
-import 'a.dart';
-class B extends A {
-  main() {^}
-}
-''');
-    await computeSuggestions();
-    var suggestion = assertSuggestSetter('x');
-    assertHasNoParameterInfo(suggestion);
-  }
-
-  Future<void> test_outside_class() async {
-    resolveSource('/home/test/lib/b.dart', '''
-lib libB;
-class A2 {
-  int x;
-  int y() {return 0;}
-  int x2;
-  int y2() {return 0;}
-}''');
-    addTestSource('''
-import "b.dart";
-class A1 {
-  int x;
-  int y() {return 0;}
-  int x1;
-  int y1() {return 0;}
-}
-class B extends A1 with A2 {
-  int a;
-  int b() {return 0;}
-}
-foo() {^}
-''');
-
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('Object');
-    assertNotSuggested('B');
-    assertNotSuggested('a');
-    assertNotSuggested('b');
-    assertNotSuggested('foo');
-    assertNotSuggested('A');
-    assertNotSuggested('x');
-    assertNotSuggested('y');
-    assertNotSuggested('x1');
-    assertNotSuggested('y1');
-    assertNotSuggested('x2');
-    assertNotSuggested('y2');
-  }
-
-  Future<void> test_static_field() async {
-    resolveSource('/home/test/lib/b.dart', '''
-lib libB;
-class A2 {
-  int x;
-  int y() {return 0;}
-  int x2;
-  int y2() {return 0;}
-}''');
-    addTestSource('''
-import "b.dart";
-class A1 {
-  int x;
-  int y() {return 0;}
-  int x1;
-  int y1() {return 0;}
-}
-class B extends A1 with A2 {
-  int a;
-  int b() {return 0;}
-  static foo = ^
-}
-''');
-
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('Object');
-    assertNotSuggested('B');
-    assertNotSuggested('a');
-    assertNotSuggested('b');
-    assertNotSuggested('foo');
-    assertNotSuggested('A');
-    assertNotSuggested('x');
-    assertNotSuggested('y');
-    assertNotSuggested('x1');
-    assertNotSuggested('y1');
-    assertNotSuggested('x2');
-    assertNotSuggested('y2');
-  }
-
-  Future<void> test_static_method() async {
-    resolveSource('/home/test/lib/b.dart', '''
-lib libB;
-class A2 {
-  int x;
-  int y() {return 0;}
-  int x2;
-  int y2() {return 0;}
-}''');
-    addTestSource('''
-import "b.dart";
-class A1 {
-  int x;
-  int y() {return 0;}
-  int x1;
-  int y1() {return 0;}
-}
-class B extends A1 with A2 {
-  int a;
-  int b() {return 0;}
-  static foo() {^}
-}
-''');
-
-    await computeSuggestions();
-    expect(replacementOffset, completionOffset);
-    expect(replacementLength, 0);
-    assertNotSuggested('Object');
-    assertNotSuggested('B');
-    assertNotSuggested('a');
-    assertNotSuggested('b');
-    assertNotSuggested('foo');
-    assertNotSuggested('A');
-    assertNotSuggested('x');
-    assertNotSuggested('y');
-    assertNotSuggested('x1');
-    assertNotSuggested('y1');
-    assertNotSuggested('x2');
-    assertNotSuggested('y2');
-  }
-
-  Future<void> _check_flutter_setState(
-      String line, String completion, int selectionOffset) async {
-    addFlutterPackage();
-    addTestSource('''
-import 'package:flutter/widgets.dart';
-
-class TestWidget extends StatefulWidget {
-  @override
-  TestWidgetState createState() {
-    return new TestWidgetState();
-  }
-}
-
-class TestWidgetState extends State<TestWidget> {
-  @override
-  Widget build(BuildContext context) {
-$line^
-  }
-}
-''');
-    await computeSuggestions();
-    var cs = assertSuggest(completion, selectionOffset: selectionOffset);
-    expect(cs.selectionLength, 0);
-
-    // It is an invocation, but we don't need any additional info for it.
-    // So, all parameter information is absent.
-    expect(cs.parameterNames, isNull);
-    expect(cs.parameterTypes, isNull);
-    expect(cs.requiredParameterCount, isNull);
-    expect(cs.hasNamedParameters, isNull);
-  }
-}
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 b6e17f7..b56c10c 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
@@ -19,6 +19,9 @@
 @reflectiveTest
 class LocalReferenceContributorTest extends DartCompletionContributorTest {
   @override
+  bool get isNullExpectedReturnTypeConsideredDynamic => false;
+
+  @override
   DartCompletionContributor createContributor() {
     return LocalReferenceContributor();
   }
@@ -77,6 +80,27 @@
         defaultArgumentListTextRanges: [0, 3, 10, 4]);
   }
 
+  Future<void> test_ArgDefaults_inherited_method_with_required_named() async {
+    addMetaPackage();
+    resolveSource('/home/test/lib/b.dart', '''
+import 'package:meta/meta.dart';
+
+lib libB;
+class A {
+   bool foo(int bar, {bool boo, @required int baz}) => false;
+}''');
+    addTestSource('''
+import "b.dart";
+class B extends A {
+  b() => f^
+}
+''');
+    await computeSuggestions();
+
+    assertSuggestMethod('foo', 'A', 'bool',
+        defaultArgListString: 'bar, baz: null');
+  }
+
   Future<void> test_ArgDefaults_method_with_required_named() async {
     addMetaPackage();
     addTestSource('''
@@ -742,6 +766,32 @@
     assertNotSuggested('Object');
   }
 
+  Future<void> test_AwaitExpression_inherited() async {
+    // SimpleIdentifier  AwaitExpression  ExpressionStatement
+    resolveSource('/home/test/lib/b.dart', '''
+lib libB;
+class A {
+  Future y() async {return 0;}
+}''');
+    addTestSource('''
+import "b.dart";
+class B extends A {
+  Future a() async {return 0;}
+  foo() async {await ^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggest('a', elemKind: ElementKind.METHOD);
+    assertSuggest('foo', elemKind: ElementKind.METHOD);
+    assertSuggest('B', elemKind: ElementKind.CLASS);
+    assertNotSuggested('A');
+    assertNotSuggested('Object');
+    assertSuggestMethod('y', 'A', 'Future<dynamic>');
+  }
+
   Future<void> test_BinaryExpression_LHS() async {
     // SimpleIdentifier  BinaryExpression  VariableDeclaration
     // VariableDeclarationList  VariableDeclarationStatement
@@ -1276,19 +1326,70 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    // TODO (danrubel) prefer fields over getters
-    // If add `get e1;` to interface I
-    // then suggestions include getter e1 rather than field e1
-    assertNotSuggested('e1');
-    assertNotSuggested('f1');
-    assertNotSuggested('i1');
-    assertNotSuggested('m1');
-    assertNotSuggested('f3');
-    assertNotSuggested('f4');
-    assertNotSuggested('e2');
-    assertNotSuggested('f2');
-    assertNotSuggested('i2');
-    //assertNotSuggested('m2');
+    assertSuggest('e1', elemKind: ElementKind.FIELD);
+    assertSuggest('f1', elemKind: ElementKind.FIELD);
+    assertSuggest('i1', elemKind: ElementKind.FIELD);
+    assertSuggest('m1', elemKind: ElementKind.FIELD);
+    assertSuggest('f3', elemKind: ElementKind.GETTER);
+    assertSuggest('f4', elemKind: ElementKind.SETTER);
+    assertSuggest('e2', elemKind: ElementKind.METHOD);
+    assertSuggest('f2', elemKind: ElementKind.METHOD);
+    assertSuggest('i2', elemKind: ElementKind.METHOD);
+    assertSuggest('m2', elemKind: ElementKind.METHOD);
+    assertSuggest('toString', elemKind: ElementKind.METHOD);
+  }
+
+  Future<void> test_Block_inherited_imported_from_constructor() async {
+    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
+    resolveSource('/home/test/lib/b.dart', '''
+      lib B;
+      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }''');
+    addTestSource('''
+      import "b.dart";
+      class A extends E implements I with M {const A() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+    assertNotSuggested('==');
+  }
+
+  Future<void> test_Block_inherited_imported_from_method() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    resolveSource('/home/test/lib/b.dart', '''
+      lib B;
+      class F { var f1; f2() { } get f3 => 0; set f4(fx) { } var _pf; }
+      class E extends F { var e1; e2() { } }
+      class I { int i1; i2() { } }
+      class M { var m1; int m2() { } }''');
+    addTestSource('''
+      import "b.dart";
+      class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
     assertNotSuggested('==');
   }
 
@@ -1304,16 +1405,65 @@
 
     expect(replacementOffset, completionOffset);
     expect(replacementLength, 0);
-    assertNotSuggested('e1');
-    assertNotSuggested('f1');
-    assertNotSuggested('i1');
-    assertNotSuggested('m1');
-    assertNotSuggested('f3');
-    assertNotSuggested('f4');
-    assertNotSuggested('e2');
-    assertNotSuggested('f2');
-    assertNotSuggested('i2');
-    assertNotSuggested('m2');
+    assertSuggest('e1', elemKind: ElementKind.FIELD);
+    assertSuggest('f1', elemKind: ElementKind.FIELD);
+    assertSuggest('i1', elemKind: ElementKind.FIELD);
+    assertSuggest('m1', elemKind: ElementKind.FIELD);
+    assertSuggest('f3', elemKind: ElementKind.GETTER);
+    assertSuggest('f4', elemKind: ElementKind.SETTER);
+    assertSuggest('e2', elemKind: ElementKind.METHOD);
+    assertSuggest('f2', elemKind: ElementKind.METHOD);
+    assertSuggest('i2', elemKind: ElementKind.METHOD);
+    assertSuggest('m2', elemKind: ElementKind.METHOD);
+    assertSuggest('toString', elemKind: ElementKind.METHOD);
+  }
+
+  Future<void> test_Block_inherited_local_from_constructor() async {
+    // Block  BlockFunctionBody  ConstructorDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {const A() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
+  }
+
+  Future<void> test_Block_inherited_local_from_method() async {
+    // Block  BlockFunctionBody  MethodDeclaration  ClassDeclaration
+    addTestSource('''
+class F { var f1; f2() { } get f3 => 0; set f4(fx) { } }
+class E extends F { var e1; e2() { } }
+class I { int i1; i2() { } }
+class M { var m1; int m2() { } }
+class A extends E implements I with M {a() {^}}''');
+    await computeSuggestions();
+
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertSuggestField('e1', null);
+    assertSuggestField('f1', null);
+    assertSuggestField('i1', 'int');
+    assertSuggestField('m1', null);
+    assertSuggestGetter('f3', null);
+    assertSuggestSetter('f4');
+    assertSuggestMethod('e2', 'E', null);
+    assertSuggestMethod('f2', 'F', null);
+    assertSuggestMethod('i2', 'I', null);
+    assertSuggestMethod('m2', 'M', 'int');
   }
 
   Future<void> test_Block_local_function() async {
@@ -2661,6 +2811,42 @@
     assertNoSuggestions();
   }
 
+  Future<void> test_flutter_setState_hasPrefix() async {
+    var spaces_4 = ' ' * 4;
+    var spaces_6 = ' ' * 6;
+    await _check_flutter_setState(
+        '    setSt',
+        '''
+setState(() {
+$spaces_6
+$spaces_4});''',
+        20);
+  }
+
+  Future<void> test_flutter_setState_longPrefix() async {
+    var spaces_6 = ' ' * 6;
+    var spaces_8 = ' ' * 8;
+    await _check_flutter_setState(
+        '      setSt',
+        '''
+setState(() {
+$spaces_8
+$spaces_6});''',
+        22);
+  }
+
+  Future<void> test_flutter_setState_noPrefix() async {
+    var spaces_4 = ' ' * 4;
+    var spaces_6 = ' ' * 6;
+    await _check_flutter_setState(
+        '    ',
+        '''
+setState(() {
+$spaces_6
+$spaces_4});''',
+        20);
+  }
+
   Future<void> test_forEachPartsWithIdentifier_class() async {
     addTestSource('''
 class C {}
@@ -3021,7 +3207,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -3051,7 +3237,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -3082,7 +3268,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -3363,6 +3549,47 @@
     assertSuggestLocalVariable('v', 'int');
   }
 
+  Future<void> test_inherited() async {
+    resolveSource('/home/test/lib/b.dart', '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "b.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggest('B', elemKind: ElementKind.CLASS);
+    assertSuggestField('a', 'int');
+    assertSuggestMethod('b', 'B', 'int');
+    assertSuggestMethod('foo', 'B', 'dynamic');
+    assertNotSuggested('A2');
+    assertSuggestField('x', 'int');
+    assertSuggestMethod('y', 'A1', 'int');
+    assertSuggestField('x1', 'int');
+    assertSuggestMethod('y1', 'A1', 'int');
+    assertSuggestField('x2', 'int');
+    assertSuggestMethod('y2', 'A2', 'int');
+  }
+
   Future<void> test_InstanceCreationExpression() async {
     addTestSource('''
 class A {foo(){var f; {var x;}}}
@@ -3629,7 +3856,7 @@
     assertSuggestTopLevelVar('T2', 'int',
         relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
     assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertSuggestLocalVariable('name', 'String');
   }
@@ -3972,7 +4199,7 @@
     assertSuggestTopLevelVar('T2', 'int',
         relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
     assertSuggestFunction('F2', null, relevance: DART_RELEVANCE_LOCAL_FUNCTION);
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
   }
 
@@ -4022,7 +4249,65 @@
         relevance: DART_RELEVANCE_LOCAL_TOP_LEVEL_VARIABLE);
   }
 
+  Future<void> test_method_inClass() async {
+    addTestSource('''
+class A {
+  void m(x, int y) {}
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'A', 'void');
+  }
+
+  Future<void> test_method_inMixin() async {
+    addTestSource('''
+mixin A {
+  void m(x, int y) {}
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'A', 'void');
+  }
+
+  Future<void> test_method_inMixin_fromSuperclassConstraint() async {
+    addTestSource('''
+class C {
+  void c(x, int y) {}
+}
+mixin M on C {
+  m() {^}
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('c', 'C', 'void');
+  }
+
   Future<void> test_method_parameters_mixed_required_and_named() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  void m(x, {int y}) {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  Future<void> test_method_parameters_mixed_required_and_named_local() async {
     addTestSource('''
 class A {
   void m(x, {int y}) {}
@@ -4032,10 +4317,41 @@
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, true);
   }
 
   Future<void> test_method_parameters_mixed_required_and_positional() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  void m(x, [int y]) {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  Future<void>
+      test_method_parameters_mixed_required_and_positional_local() async {
     addTestSource('''
 class A {
   void m(x, [int y]) {}
@@ -4045,10 +4361,40 @@
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 1);
+    expect(suggestion.hasNamedParameters, false);
   }
 
   Future<void> test_method_parameters_named() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  void m({x, int y}) {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
+  }
+
+  Future<void> test_method_parameters_named_local() async {
     addTestSource('''
 class A {
   void m({x, int y}) {}
@@ -4058,10 +4404,37 @@
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, true);
   }
 
   Future<void> test_method_parameters_none() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  void m() {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  Future<void> test_method_parameters_none_local() async {
     addTestSource('''
 class A {
   void m() {}
@@ -4071,10 +4444,37 @@
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, isEmpty);
+    expect(suggestion.parameterTypes, isEmpty);
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
   }
 
   Future<void> test_method_parameters_positional() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  void m([x, int y]) {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
+  }
+
+  Future<void> test_method_parameters_positional_local() async {
     addTestSource('''
 class A {
   void m([x, int y]) {}
@@ -4084,20 +4484,37 @@
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 0);
+    expect(suggestion.hasNamedParameters, false);
   }
 
   Future<void> test_method_parameters_required() async {
-    addTestSource('''
+    resolveSource('/home/test/lib/a.dart', '''
 class A {
   void m(x, int y) {}
 }
+''');
+    addTestSource('''
+import 'a.dart';
 class B extends A {
   main() {^}
 }
 ''');
     await computeSuggestions();
-    assertNotSuggested('m');
+    var suggestion = assertSuggestMethod('m', 'A', 'void');
+    expect(suggestion.parameterNames, hasLength(2));
+    expect(suggestion.parameterNames[0], 'x');
+    expect(suggestion.parameterTypes[0], 'dynamic');
+    expect(suggestion.parameterNames[1], 'y');
+    expect(suggestion.parameterTypes[1], 'int');
+    expect(suggestion.requiredParameterCount, 2);
+    expect(suggestion.hasNamedParameters, false);
   }
 
   Future<void> test_MethodDeclaration_body_getters() async {
@@ -4330,7 +4747,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -4359,7 +4776,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -4388,7 +4805,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -4419,7 +4836,7 @@
     assertNotSuggested('C1');
     assertNotSuggested('T2');
     assertNotSuggested('F2');
-    assertSuggestFunctionTypeAlias('D2', null);
+    assertSuggestFunctionTypeAlias('D2', 'dynamic');
     assertSuggestClass('C2');
     assertNotSuggested('name');
   }
@@ -4442,6 +4859,27 @@
     assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
   }
 
+  Future<void> test_MethodDeclaration_shadowed2() async {
+    // MethodDeclaration  ClassDeclaration  CompilationUnit
+    addTestSource('''
+class A {
+  void foo() {}
+}
+class B extends A{
+  void foo() {}
+  void bar(List list) {
+    for (var foo in list) {
+      ^
+    }
+  }
+}
+''');
+    await computeSuggestions();
+
+    assertNotSuggested('foo', elemKind: ElementKind.METHOD);
+    assertSuggest('foo', elemKind: ElementKind.LOCAL_VARIABLE);
+  }
+
   Future<void> test_MethodInvocation_no_semicolon() async {
     // MethodInvocation  ExpressionStatement  Block
     addTestSource('''
@@ -4490,6 +4928,28 @@
     await computeSuggestions();
   }
 
+  Future<void> test_mixin_ordering() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class B {}
+class M1 {
+  void m() {}
+}
+class M2 {
+  void m() {}
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class C extends B with M1, M2 {
+  void f() {
+    ^
+  }
+}
+''');
+    await computeSuggestions();
+    assertSuggestMethod('m', 'M1', 'void');
+  }
+
   Future<void> test_MixinDeclaration_body() async {
     // MixinDeclaration  CompilationUnit
     addSource('/home/test/lib/b.dart', '''
@@ -4575,6 +5035,99 @@
     assertNotSuggested('A');
   }
 
+  Future<void> test_no_parameters_field() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  int x;
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestField('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  Future<void> test_no_parameters_getter() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  int get x => null;
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestGetter('x', 'int');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  Future<void> test_no_parameters_setter() async {
+    resolveSource('/home/test/lib/a.dart', '''
+class A {
+  set x(int value) {};
+}
+''');
+    addTestSource('''
+import 'a.dart';
+class B extends A {
+  main() {^}
+}
+''');
+    await computeSuggestions();
+    var suggestion = assertSuggestSetter('x');
+    assertHasNoParameterInfo(suggestion);
+  }
+
+  Future<void> test_outside_class() async {
+    resolveSource('/home/test/lib/b.dart', '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "b.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+}
+foo() {^}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggestClass('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertSuggestFunction('foo', 'dynamic');
+    assertSuggestClass('A1');
+    assertSuggestConstructor('A1');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
   Future<void> test_overrides() async {
     addTestSource('''
 class A {m() {}}
@@ -5034,6 +5587,90 @@
     assertSuggestField('a', null, relevance: DART_RELEVANCE_LOCAL_FIELD);
   }
 
+  Future<void> test_static_field() async {
+    resolveSource('/home/test/lib/b.dart', '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "b.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo = ^
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggestClass('B');
+    assertSuggestField('a', 'int');
+    assertSuggestMethod('b', 'B', 'int');
+    assertSuggestField('foo', 'dynamic');
+    assertSuggestClass('A1');
+    assertSuggestConstructor('A1');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
+  Future<void> test_static_method() async {
+    resolveSource('/home/test/lib/b.dart', '''
+lib libB;
+class A2 {
+  int x;
+  int y() {return 0;}
+  int x2;
+  int y2() {return 0;}
+}''');
+    addTestSource('''
+import "b.dart";
+class A1 {
+  int x;
+  int y() {return 0;}
+  int x1;
+  int y1() {return 0;}
+}
+class B extends A1 with A2 {
+  int a;
+  int b() {return 0;}
+  static foo() {^}
+}
+''');
+
+    await computeSuggestions();
+    expect(replacementOffset, completionOffset);
+    expect(replacementLength, 0);
+    assertNotSuggested('Object');
+    assertSuggestClass('B');
+    assertNotSuggested('a');
+    assertNotSuggested('b');
+    assertSuggestMethod('foo', 'B', 'dynamic');
+    assertSuggestClass('A1');
+    assertSuggestConstructor('A1');
+    assertNotSuggested('x');
+    assertNotSuggested('y');
+    assertNotSuggested('x1');
+    assertNotSuggested('y1');
+    assertNotSuggested('x2');
+    assertNotSuggested('y2');
+  }
+
   Future<void> test_SwitchStatement_c() async {
     // SwitchStatement  Block  BlockFunctionBody  MethodDeclaration
     addTestSource('class A {String g(int x) {switch(x) {c^}}}');
@@ -5507,4 +6144,36 @@
 
     assertSuggestLocalVariable('value', null);
   }
+
+  Future<void> _check_flutter_setState(
+      String line, String completion, int selectionOffset) async {
+    addFlutterPackage();
+    addTestSource('''
+import 'package:flutter/widgets.dart';
+
+class TestWidget extends StatefulWidget {
+  @override
+  TestWidgetState createState() {
+    return new TestWidgetState();
+  }
+}
+
+class TestWidgetState extends State<TestWidget> {
+  @override
+  Widget build(BuildContext context) {
+$line^
+  }
+}
+''');
+    await computeSuggestions();
+    var cs = assertSuggest(completion, selectionOffset: selectionOffset);
+    expect(cs.selectionLength, 0);
+
+    // It is an invocation, but we don't need any additional info for it.
+    // So, all parameter information is absent.
+    expect(cs.parameterNames, isNull);
+    expect(cs.parameterTypes, isNull);
+    expect(cs.requiredParameterCount, isNull);
+    expect(cs.hasNamedParameters, isNull);
+  }
 }
diff --git a/pkg/analysis_server/test/services/completion/dart/test_all.dart b/pkg/analysis_server/test/services/completion/dart/test_all.dart
index 63e74ff..9b71160 100644
--- a/pkg/analysis_server/test/services/completion/dart/test_all.dart
+++ b/pkg/analysis_server/test/services/completion/dart/test_all.dart
@@ -15,7 +15,6 @@
 import 'extension_member_contributor_test.dart' as extension_member_contributor;
 import 'field_formal_contributor_test.dart' as field_formal_contributor_test;
 import 'imported_reference_contributor_test.dart' as imported_ref_test;
-import 'inherited_reference_contributor_test.dart' as inherited_ref_test;
 import 'keyword_contributor_test.dart' as keyword_test;
 import 'label_contributor_test.dart' as label_contributor_test;
 // ignore: unused_import
@@ -45,7 +44,6 @@
     extension_member_contributor.main();
     field_formal_contributor_test.main();
     imported_ref_test.main();
-    inherited_ref_test.main();
     keyword_test.main();
     label_contributor_test.main();
     // TODO(brianwilkerson) Run this test when it's been updated to not rely on
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
index 3ca5251..2aecfe5 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_to_test.dart
@@ -54,6 +54,19 @@
 ''');
   }
 
+  Future<void> test_class_extends() async {
+    await resolveTestUnit('''
+class MyClass extends BaseClssa {}
+
+class BaseClass {}
+''');
+    await assertHasFix('''
+class MyClass extends BaseClass {}
+
+class BaseClass {}
+''');
+  }
+
   Future<void> test_class_fromImport() async {
     await resolveTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
index b40284a..b9f2735 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_type_annotation_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
@@ -69,4 +70,16 @@
 }
 ''');
   }
+
+  Future<void> test_synthetic_implicitCast() async {
+    createAnalysisOptionsFile(implicitCasts: false);
+    await resolveTestUnit('''
+int foo =
+''');
+    await assertNoFix(
+      errorFilter: (e) {
+        return e.errorCode == StaticTypeWarningCode.INVALID_ASSIGNMENT;
+      },
+    );
+  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
index eedea5b..f930fe9 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/create_class_test.dart
@@ -38,6 +38,18 @@
         change.linkedEditGroups[0], ["Test('", 'Test {', 'Test(S']);
   }
 
+  Future<void> test_extends() async {
+    await resolveTestUnit('''
+class MyClass extends BaseClass {}
+''');
+    await assertHasFix('''
+class MyClass extends BaseClass {}
+
+class BaseClass {
+}
+''');
+  }
+
   Future<void> test_hasUnresolvedPrefix() async {
     await resolveTestUnit('''
 main() {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
index 1f5ad4c..dd87b99 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_sdk_test.dart
@@ -47,6 +47,17 @@
 ''');
   }
 
+  Future<void> test_withClass_extends() async {
+    await resolveTestUnit('''
+class MyCompleter extends Completer<String> {}
+''');
+    await assertHasFix('''
+import 'dart:async';
+
+class MyCompleter extends Completer<String> {}
+''');
+  }
+
   Future<void> test_withClass_instanceCreation_explicitNew() async {
     await resolveTestUnit('''
 class C {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.dart
new file mode 100644
index 0000000..5003102
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_filled_test.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 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+void main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithFilledTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithFilledTest extends FixProcessorTest {
+  @override
+  List<String> get experiments => [EnableString.non_nullable];
+
+  @override
+  FixKind get kind => DartFixKind.REPLACE_WITH_FILLED;
+
+  Future<void> test_nonNullableElements() async {
+    await resolveTestUnit('''
+var l = new List<int>(3);
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nonNullableElements_inferred() async {
+    await resolveTestUnit('''
+List<int> l = List(3);
+''');
+    await assertNoFix();
+  }
+
+  Future<void> test_nullableElements() async {
+    await resolveTestUnit('''
+var l = new List<int?>(3);
+''');
+    await assertHasFix('''
+var l = new List<int?>.filled(3, null, growable: false);
+''');
+  }
+
+  Future<void> test_nullableElements_inferred() async {
+    await resolveTestUnit('''
+List<int?> l = List(5);
+''');
+    await assertHasFix('''
+List<int?> l = List.filled(5, null, growable: false);
+''');
+  }
+
+  Future<void> test_trailingComma() async {
+    await resolveTestUnit('''
+var l = List<int?>(3,);
+''');
+    await assertHasFix('''
+var l = List<int?>.filled(3, null, growable: false,);
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
index 736738d..00a1f08 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/test_all.dart
@@ -140,6 +140,7 @@
     as replace_with_conditional_assignment;
 import 'replace_with_eight_digit_hex_test.dart' as replace_with_eight_digit_hex;
 import 'replace_with_extension_name_test.dart' as replace_with_extension_name;
+import 'replace_with_filled_test.dart' as replace_with_filled;
 import 'replace_with_identifier_test.dart' as replace_with_identifier;
 import 'replace_with_interpolation_test.dart' as replace_with_interpolation;
 import 'replace_with_is_empty_test.dart' as replace_with_is_empty;
@@ -283,6 +284,7 @@
     replace_with_conditional_assignment.main();
     replace_with_eight_digit_hex.main();
     replace_with_extension_name.main();
+    replace_with_filled.main();
     replace_with_identifier.main();
     replace_with_interpolation.main();
     replace_with_is_empty.main();
diff --git a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
index 41158e2..01d9d48 100644
--- a/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/completion_metrics.dart
@@ -935,7 +935,7 @@
         print('  $i Suggestion: ${topSuggestion.description}');
         if (result.listener != null) {
           var feature = result.listener.featureMap[topSuggestion];
-          if (feature.isEmpty) {
+          if (feature == null || feature.isEmpty) {
             print('    Features: <none>');
           } else {
             print('    Features: $feature');
diff --git a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
index c2d60c6..5b185dc 100644
--- a/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
+++ b/pkg/analysis_server/tool/completion_metrics/relevance_metrics.dart
@@ -275,6 +275,10 @@
   /// The library containing the compilation unit being visited.
   LibraryElement enclosingLibrary;
 
+  /// A flag indicating whether we are currently in a context in which type
+  /// parameters are visible.
+  bool inGenericContext = false;
+
   /// The type provider associated with the current compilation unit.
   TypeProvider typeProvider;
 
@@ -433,6 +437,8 @@
 
   @override
   void visitClassDeclaration(ClassDeclaration node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     data.recordPercentage(
         'Classes with type parameters', node.typeParameters != null);
     var context = 'name';
@@ -453,10 +459,13 @@
           allowedKeywords: memberKeywords);
     }
     super.visitClassDeclaration(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
   void visitClassTypeAlias(ClassTypeAlias node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     _recordDataForNode('ClassTypeAlias (superclass)', node.superclass);
     var context = 'superclass';
     if (node.withClause != null) {
@@ -465,6 +474,7 @@
     }
     _recordTokenType('ClassDeclaration ($context)', node.implementsClause);
     super.visitClassTypeAlias(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -660,6 +670,8 @@
 
   @override
   void visitExtensionDeclaration(ExtensionDeclaration node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     data.recordPercentage(
         'Extensions with type parameters', node.typeParameters != null);
     _recordDataForNode('ExtensionDeclaration (type)', node.extendedType);
@@ -668,6 +680,7 @@
           allowedKeywords: memberKeywords);
     }
     super.visitExtensionDeclaration(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -787,8 +800,11 @@
 
   @override
   void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     // There are no completions.
     super.visitFunctionTypeAlias(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -799,15 +815,21 @@
 
   @override
   void visitGenericFunctionType(GenericFunctionType node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     // There are no completions.
     super.visitGenericFunctionType(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
   void visitGenericTypeAlias(GenericTypeAlias node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     _recordDataForNode('GenericTypeAlias (functionType)', node.functionType,
         allowedKeywords: [Keyword.FUNCTION]);
     super.visitGenericTypeAlias(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -957,6 +979,8 @@
 
   @override
   void visitMethodDeclaration(MethodDeclaration node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     // There are no completions.
     data.recordPercentage(
         'Methods with type parameters', node.typeParameters != null);
@@ -976,6 +1000,7 @@
       }
     }
     super.visitMethodDeclaration(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -1007,6 +1032,8 @@
 
   @override
   void visitMixinDeclaration(MixinDeclaration node) {
+    var wasInGenericContext = inGenericContext;
+    inGenericContext = inGenericContext || node.typeParameters != null;
     data.recordPercentage(
         'Mixins with type parameters', node.typeParameters != null);
     var context = 'name';
@@ -1023,6 +1050,7 @@
           allowedKeywords: memberKeywords);
     }
     super.visitMixinDeclaration(node);
+    inGenericContext = wasInGenericContext;
   }
 
   @override
@@ -1573,6 +1601,11 @@
   void _recordDataForNode(String context, AstNode node,
       {List<Keyword> allowedKeywords = noKeywords}) {
     _recordElementKind(context, node);
+    if (inGenericContext) {
+      _recordElementKind(context + ' - generic', node);
+    } else {
+      _recordElementKind(context + ' - non-generic', node);
+    }
     _recordReferenceDepth(node);
     _recordTokenDistance(node);
     _recordTokenType(context, node, allowedKeywords: allowedKeywords);
diff --git a/pkg/analyzer/lib/analyzer.dart b/pkg/analyzer/lib/analyzer.dart
index ddb8fae..3c53fd0 100644
--- a/pkg/analyzer/lib/analyzer.dart
+++ b/pkg/analyzer/lib/analyzer.dart
@@ -2,7 +2,10 @@
 // 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.
 
-@deprecated
+/// This library is no longer supported, but most of the functionality it
+/// provides is available through supported analyzer APIs.  See specific methods
+/// below for more information about their supported replacements.
+@Deprecated('See package:analyzer/analyzer.dart file for details')
 library analyzer;
 
 import 'dart:io';
@@ -67,12 +70,12 @@
 /// If [parseFunctionBodies] is [false] then only function signatures will be
 /// parsed.  (Currently broken; function bodies are always parsed).
 ///
-/// Deprecated - please use the `parseFile2` function
+/// Deprecated - please use the `parseFile` function
 /// (from package:analyzer/dart/analysis/utilities.dart) instead.
 ///
-/// Note that `parseFile2` does not support the `parseFunctionBodies` option;
+/// Note that `parseFile` does not support the `parseFunctionBodies` option;
 /// callers that don't require function bodies should simply ignore them.
-@Deprecated('Please use parseFile2 instead')
+@Deprecated('Please use parseFile instead')
 CompilationUnit parseDartFile(String path,
     {bool suppressErrors = false,
     bool parseFunctionBodies = true,
diff --git a/pkg/analyzer/lib/dart/ast/ast.dart b/pkg/analyzer/lib/dart/ast/ast.dart
index 7fe19b3..33ef4c3 100644
--- a/pkg/analyzer/lib/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/dart/ast/ast.dart
@@ -2689,7 +2689,8 @@
 ///        [Expression] [TypeArgumentList]? [ArgumentList]
 ///
 /// Clients may not extend, implement or mix-in this class.
-abstract class FunctionExpressionInvocation implements InvocationExpression {
+abstract class FunctionExpressionInvocation
+    implements NullShortableExpression, InvocationExpression {
   /// Set the list of arguments to the method to the given [argumentList].
   set argumentList(ArgumentList argumentList);
 
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 90a78b3..de961aa 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -100,6 +100,7 @@
   CompileTimeErrorCode.CONST_CONSTRUCTOR_THROWS_EXCEPTION,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_FIELD_INITIALIZED_BY_NON_CONST,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
+  CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER,
   CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD,
   CompileTimeErrorCode.CONST_DEFERRED_CLASS,
@@ -234,7 +235,6 @@
   CompileTimeErrorCode.MIXIN_INSTANTIATE,
   CompileTimeErrorCode.MIXIN_OF_DISALLOWED_CLASS,
   CompileTimeErrorCode.MIXIN_OF_NON_CLASS,
-  CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_DISALLOWED_CLASS,
   CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 67b1448..283c6c6 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -5015,6 +5015,7 @@
 ///    functionExpressionInvocation ::=
 ///        [Expression] [TypeArgumentList]? [ArgumentList]
 class FunctionExpressionInvocationImpl extends InvocationExpressionImpl
+    with NullShortableExpressionImpl
     implements FunctionExpressionInvocation {
   /// The expression producing the function being invoked.
   ExpressionImpl _function;
@@ -5054,6 +5055,9 @@
   Precedence get precedence => Precedence.postfix;
 
   @override
+  AstNode get _nullShortingExtensionCandidate => parent;
+
+  @override
   E accept<E>(AstVisitor<E> visitor) =>
       visitor.visitFunctionExpressionInvocation(this);
 
@@ -5063,6 +5067,9 @@
     _typeArguments?.accept(visitor);
     _argumentList?.accept(visitor);
   }
+
+  @override
+  bool _extendsNullShorting(Expression child) => identical(child, _function);
 }
 
 /// A function type alias.
diff --git a/pkg/analyzer/lib/src/dart/constant/compute.dart b/pkg/analyzer/lib/src/dart/constant/compute.dart
index 5496e4d..072014a 100644
--- a/pkg/analyzer/lib/src/dart/constant/compute.dart
+++ b/pkg/analyzer/lib/src/dart/constant/compute.dart
@@ -18,60 +18,43 @@
     DeclaredVariables declaredVariables,
     List<ConstantEvaluationTarget> constants,
     ExperimentStatus experimentStatus) {
-  var evaluationEngine = ConstantEvaluationEngine(
-      typeProvider, declaredVariables,
-      typeSystem: typeSystem, experimentStatus: experimentStatus);
+  var walker = _ConstantWalker(declaredVariables, experimentStatus);
 
-  var nodes = <_ConstantNode>[];
-  var nodeMap = <ConstantEvaluationTarget, _ConstantNode>{};
   for (var constant in constants) {
-    var node = _ConstantNode(evaluationEngine, nodeMap, constant);
-    nodes.add(node);
-    nodeMap[constant] = node;
-  }
-
-  for (var node in nodes) {
+    var node = walker._getNode(constant);
     if (!node.isEvaluated) {
-      _ConstantWalker(evaluationEngine).walk(node);
+      walker.walk(node);
     }
   }
 }
 
 /// [graph.Node] that is used to compute constants in dependency order.
 class _ConstantNode extends graph.Node<_ConstantNode> {
-  final ConstantEvaluationEngine evaluationEngine;
-  final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap;
+  final _ConstantWalker walker;
   final ConstantEvaluationTarget constant;
 
-  _ConstantNode(this.evaluationEngine, this.nodeMap, this.constant);
+  _ConstantNode(this.walker, this.constant);
 
   @override
   bool get isEvaluated => constant.isConstantEvaluated;
 
   @override
   List<_ConstantNode> computeDependencies() {
-    var targets = <ConstantEvaluationTarget>[];
-    evaluationEngine.computeDependencies(constant, targets.add);
-    return targets.map(_getNode).toList();
-  }
-
-  _ConstantNode _getNode(ConstantEvaluationTarget constant) {
-    return nodeMap.putIfAbsent(
-      constant,
-      () => _ConstantNode(evaluationEngine, nodeMap, constant),
-    );
+    return walker._computeDependencies(this);
   }
 }
 
 /// [graph.DependencyWalker] for computing constants and detecting cycles.
 class _ConstantWalker extends graph.DependencyWalker<_ConstantNode> {
-  final ConstantEvaluationEngine evaluationEngine;
+  final DeclaredVariables declaredVariables;
+  final ExperimentStatus experimentStatus;
+  final Map<ConstantEvaluationTarget, _ConstantNode> nodeMap = {};
 
-  _ConstantWalker(this.evaluationEngine);
+  _ConstantWalker(this.declaredVariables, this.experimentStatus);
 
   @override
   void evaluate(_ConstantNode node) {
-    evaluationEngine.computeConstantValue(node.constant);
+    _getEvaluationEngine(node).computeConstantValue(node.constant);
   }
 
   @override
@@ -82,7 +65,31 @@
       if (constant is ConstructorElementImpl) {
         constant.isCycleFree = false;
       }
-      evaluationEngine.generateCycleError(constantsInCycle, constant);
+      _getEvaluationEngine(node).generateCycleError(constantsInCycle, constant);
     }
   }
+
+  List<_ConstantNode> _computeDependencies(_ConstantNode node) {
+    var evaluationEngine = _getEvaluationEngine(node);
+    var targets = <ConstantEvaluationTarget>[];
+    evaluationEngine.computeDependencies(node.constant, targets.add);
+    return targets.map(_getNode).toList();
+  }
+
+  ConstantEvaluationEngine _getEvaluationEngine(_ConstantNode node) {
+    var library = node.constant.library;
+    return ConstantEvaluationEngine(
+      library.typeProvider,
+      declaredVariables,
+      typeSystem: library.typeSystem,
+      experimentStatus: experimentStatus,
+    );
+  }
+
+  _ConstantNode _getNode(ConstantEvaluationTarget constant) {
+    return nodeMap.putIfAbsent(
+      constant,
+      () => _ConstantNode(this, constant),
+    );
+  }
 }
diff --git a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
index 6e670ce..7641697 100644
--- a/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
+++ b/pkg/analyzer/lib/src/dart/constant/constant_verifier.dart
@@ -298,9 +298,11 @@
   ///         not <i>int</i> or <i>String</i>.
   bool _implementsEqualsWhenNotAllowed(DartType type) {
     // ignore int or String
-    if (type == null || type == _intType || type == _typeProvider.stringType) {
+    if (type == null ||
+        type.element == _intType.element ||
+        type.element == _typeProvider.stringType.element) {
       return false;
-    } else if (type == _typeProvider.doubleType) {
+    } else if (type.element == _typeProvider.doubleType.element) {
       return true;
     }
     // prepare ClassElement
@@ -557,10 +559,13 @@
               .NON_CONSTANT_CASE_EXPRESSION_FROM_DEFERRED_LIBRARY,
         );
 
+        var expressionValueType = _typeSystem.toLegacyType(
+          expressionValue.type,
+        );
+
         if (firstType == null) {
-          firstType = expressionValue.type;
+          firstType = expressionValueType;
         } else {
-          var expressionValueType = expressionValue.type;
           if (firstType != expressionValueType) {
             _errorReporter.reportErrorForNode(
               CompileTimeErrorCode.INCONSISTENT_CASE_EXPRESSION_TYPES,
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 569a568..9cd7292 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -25,6 +25,7 @@
 import 'package:analyzer/src/dart/constant/value.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/constant.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -655,8 +656,11 @@
       }
     }
     ConstantVisitor initializerVisitor = ConstantVisitor(
-        this, externalErrorReporter,
-        lexicalEnvironment: parameterMap);
+      this,
+      externalErrorReporter,
+      lexicalEnvironment: parameterMap,
+      substitution: Substitution.fromInterfaceType(definingClass),
+    );
     String superName;
     NodeList<Expression> superArguments;
     for (var i = 0; i < initializers.length; i++) {
@@ -889,6 +893,9 @@
 
   /// Return whether this constant is evaluated.
   bool get isConstantEvaluated;
+
+  /// The library with this constant.
+  LibraryElement get library;
 }
 
 /// Interface used by unit tests to verify correct dependency analysis during
@@ -948,6 +955,7 @@
   final ConstantEvaluationEngine evaluationEngine;
 
   final Map<String, DartObjectImpl> _lexicalEnvironment;
+  final Substitution _substitution;
 
   /// Error reporter that we use to report errors accumulated while computing
   /// the constant.
@@ -962,9 +970,15 @@
   /// no overriding is necessary. The [_errorReporter] is used to report errors
   /// found during evaluation.  The [validator] is used by unit tests to verify
   /// correct dependency analysis.
-  ConstantVisitor(this.evaluationEngine, this._errorReporter,
-      {Map<String, DartObjectImpl> lexicalEnvironment})
-      : _lexicalEnvironment = lexicalEnvironment {
+  ///
+  /// The [substitution] is specified for instance creations.
+  ConstantVisitor(
+    this.evaluationEngine,
+    this._errorReporter, {
+    Map<String, DartObjectImpl> lexicalEnvironment,
+    Substitution substitution,
+  })  : _lexicalEnvironment = lexicalEnvironment,
+        _substitution = substitution {
     this._dartObjectComputer =
         DartObjectComputer(_errorReporter, evaluationEngine);
   }
@@ -1467,6 +1481,11 @@
     if (!_isNonNullableByDefault && hasTypeParameterReference(type)) {
       return super.visitTypeName(node);
     }
+
+    if (_substitution != null) {
+      type = _substitution.substituteType(type);
+    }
+
     return DartObjectImpl(
       typeSystem,
       _typeProvider.typeType,
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index 82bbe07..95fb86e 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -28,72 +28,12 @@
 
 /// Return `true` if the [node] is a constant type expression.
 bool isConstantTypeExpression(TypeAnnotation node) {
-  if (node is TypeName) {
-    if (_isConstantTypeName(node.name)) {
-      var arguments = node.typeArguments?.arguments;
-      if (arguments != null) {
-        for (var argument in arguments) {
-          if (!isConstantTypeExpression(argument)) {
-            return false;
-          }
-        }
-      }
-      return true;
-    }
-    if (node.type is DynamicTypeImpl) {
-      return true;
-    }
-    if (node.type is VoidType) {
-      return true;
-    }
-    return false;
-  }
-
-  if (node is GenericFunctionType) {
-    var returnType = node.returnType;
-    if (returnType != null) {
-      if (!isConstantTypeExpression(returnType)) {
-        return false;
-      }
-    }
-
-    var typeParameters = node.typeParameters?.typeParameters;
-    if (typeParameters != null) {
-      for (var parameter in typeParameters) {
-        var bound = parameter.bound;
-        if (bound != null && !isConstantTypeExpression(bound)) {
-          return false;
-        }
-      }
-    }
-
-    var formalParameters = node.parameters?.parameters;
-    if (formalParameters != null) {
-      for (var parameter in formalParameters) {
-        if (parameter is SimpleFormalParameter) {
-          if (!isConstantTypeExpression(parameter.type)) {
-            return false;
-          }
-        }
-      }
-    }
-
-    return true;
-  }
-
-  return false;
+  return _ConstantTypeChecker(potentially: false).check(node);
 }
 
 /// Return `true` if the [node] is a potentially constant type expression.
 bool isPotentiallyConstantTypeExpression(TypeAnnotation node) {
-  if (node is TypeName) {
-    var element = node.name.staticElement;
-    if (element is TypeParameterElement) {
-      return true;
-    }
-  }
-
-  return isConstantTypeExpression(node);
+  return _ConstantTypeChecker(potentially: true).check(node);
 }
 
 bool _isConstantTypeName(Identifier name) {
@@ -397,3 +337,76 @@
     return temporaryConstConstructorElements[element] ?? false;
   }
 }
+
+class _ConstantTypeChecker {
+  final bool potentially;
+
+  _ConstantTypeChecker({@required this.potentially});
+
+  /// Return `true` if the [node] is a constant type expression.
+  bool check(TypeAnnotation node) {
+    if (potentially) {
+      if (node is TypeName) {
+        var element = node.name.staticElement;
+        if (element is TypeParameterElement) {
+          return true;
+        }
+      }
+    }
+
+    if (node is TypeName) {
+      if (_isConstantTypeName(node.name)) {
+        var arguments = node.typeArguments?.arguments;
+        if (arguments != null) {
+          for (var argument in arguments) {
+            if (!check(argument)) {
+              return false;
+            }
+          }
+        }
+        return true;
+      }
+      if (node.type is DynamicTypeImpl) {
+        return true;
+      }
+      if (node.type is VoidType) {
+        return true;
+      }
+      return false;
+    }
+
+    if (node is GenericFunctionType) {
+      var returnType = node.returnType;
+      if (returnType != null) {
+        if (!check(returnType)) {
+          return false;
+        }
+      }
+
+      var typeParameters = node.typeParameters?.typeParameters;
+      if (typeParameters != null) {
+        for (var parameter in typeParameters) {
+          var bound = parameter.bound;
+          if (bound != null && !check(bound)) {
+            return false;
+          }
+        }
+      }
+
+      var formalParameters = node.parameters?.parameters;
+      if (formalParameters != null) {
+        for (var parameter in formalParameters) {
+          if (parameter is SimpleFormalParameter) {
+            if (!check(parameter.type)) {
+              return false;
+            }
+          }
+        }
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index 2e000e5..44e894c 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -260,10 +260,6 @@
   DartObjectImpl castToType(
       TypeSystemImpl typeSystem, DartObjectImpl castType) {
     _assertType(castType);
-    if (isNull) {
-      return this;
-    }
-
     var resultType = (castType._state as TypeState)._type;
 
     // We don't know the actual value of a type parameter.
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index a3288c9..4c42716 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -993,7 +993,7 @@
   /// Compute a list of constructors for this class, which is a mixin
   /// application.  If specified, [visitedClasses] is a list of the other mixin
   /// application classes which have been visited on the way to reaching this
-  /// one (this is used to detect circularities).
+  /// one (this is used to detect cycles).
   List<ConstructorElement> _computeMixinAppConstructors(
       [List<ClassElementImpl> visitedClasses]) {
     if (supertype == null) {
@@ -1012,7 +1012,8 @@
     if (!superElement.isMixinApplication) {
       var library = this.library;
       constructorsToForward = superElement.constructors
-          .where((constructor) => constructor.isAccessibleIn(library));
+          .where((constructor) => constructor.isAccessibleIn(library))
+          .where((constructor) => !constructor.isFactory);
     } else {
       if (visitedClasses == null) {
         visitedClasses = <ClassElementImpl>[this];
@@ -1048,6 +1049,9 @@
     var substitution =
         Substitution.fromPairs(superClassParameters, argumentTypes);
 
+    bool typeHasInstanceVariables(InterfaceType type) =>
+        type.element.fields.any((e) => !e.isSynthetic);
+
     // Now create an implicit constructor for every constructor found above,
     // substituting type parameters as appropriate.
     return constructorsToForward
@@ -1056,6 +1060,9 @@
           ConstructorElementImpl(superclassConstructor.name, -1);
       implicitConstructor.isSynthetic = true;
       implicitConstructor.redirectedConstructor = superclassConstructor;
+      var hasMixinWithInstanceVariables = mixins.any(typeHasInstanceVariables);
+      implicitConstructor.isConst =
+          superclassConstructor.isConst && !hasMixinWithInstanceVariables;
       List<ParameterElement> superParameters = superclassConstructor.parameters;
       int count = superParameters.length;
       if (count > 0) {
@@ -2558,6 +2565,9 @@
       element.name == _VISIBLE_FOR_TESTING_VARIABLE_NAME &&
       element.library?.name == _META_LIB_NAME;
 
+  @override
+  LibraryElement get library => compilationUnit.library;
+
   /// Get the library containing this annotation.
   @override
   Source get librarySource => compilationUnit.librarySource;
diff --git a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
index c99951f..1964682 100644
--- a/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
+++ b/pkg/analyzer/lib/src/dart/element/generic_inferrer.dart
@@ -14,6 +14,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_algebra.dart';
 import 'package:analyzer/src/dart/element/type_constraint_gatherer.dart';
+import 'package:analyzer/src/dart/element/type_demotion.dart';
 import 'package:analyzer/src/dart/element/type_schema.dart';
 import 'package:analyzer/src/error/codes.dart' show HintCode, StrongModeCode;
 import 'package:analyzer/src/generated/type_system.dart';
@@ -257,6 +258,7 @@
       }
     }
 
+    _nonNullifyTypes(result);
     return result;
   }
 
@@ -461,6 +463,14 @@
     return t;
   }
 
+  void _nonNullifyTypes(List<DartType> types) {
+    if (_typeSystem.isNonNullableByDefault) {
+      for (var i = 0; i < types.length; i++) {
+        types[i] = nonNullifyType(_typeSystem, types[i]);
+      }
+    }
+  }
+
   /// If in a legacy library, return the legacy version of the [type].
   /// Otherwise, return the original type.
   DartType _toLegacyType(DartType type) {
diff --git a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
index 825a272..071fa1b 100644
--- a/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
+++ b/pkg/analyzer/lib/src/dart/element/inheritance_manager3.dart
@@ -54,6 +54,66 @@
   /// self-referencing cycles.
   final Set<ClassElement> _processingClasses = <ClassElement>{};
 
+  /// Combine [candidates] into a single signature in the [targetClass].
+  ///
+  /// If such signature does not exist, return `null`, and if [conflicts] is
+  /// not `null`, add a new [Conflict] to it.
+  ExecutableElement combineSignatures({
+    @required ClassElement targetClass,
+    @required List<ExecutableElement> candidates,
+    @required bool doTopMerge,
+    @required Name name,
+    List<Conflict> conflicts,
+  }) {
+    // If just one candidate, it is always valid.
+    if (candidates.length == 1) {
+      return candidates[0];
+    }
+
+    // Check for a getter/method conflict.
+    var conflict = _checkForGetterMethodConflict(name, candidates);
+    if (conflict != null) {
+      conflicts?.add(conflict);
+      return null;
+    }
+
+    var validOverrides = <ExecutableElement>[];
+    for (var i = 0; i < candidates.length; i++) {
+      var validOverride = candidates[i];
+      var overrideHelper = CorrectOverrideHelper(
+        library: targetClass.library,
+        thisMember: validOverride,
+      );
+      for (var j = 0; j < candidates.length; j++) {
+        var candidate = candidates[j];
+        if (!overrideHelper.isCorrectOverrideOf(superMember: candidate)) {
+          validOverride = null;
+          break;
+        }
+      }
+      if (validOverride != null) {
+        validOverrides.add(validOverride);
+      }
+    }
+
+    if (validOverrides.isEmpty) {
+      conflicts?.add(
+        CandidatesConflict(
+          name: name,
+          candidates: candidates,
+        ),
+      );
+      return null;
+    }
+
+    if (doTopMerge) {
+      var typeSystem = targetClass.library.typeSystem;
+      return _topMerge(typeSystem, targetClass, validOverrides);
+    } else {
+      return validOverrides.first;
+    }
+  }
+
   /// Return the result of [getInherited2] with [type] substitution.
   ExecutableElement getInherited(InterfaceType type, Name name) {
     var rawElement = getInherited2(type.element, name);
@@ -369,9 +429,7 @@
     Map<Name, List<ExecutableElement>> namedCandidates, {
     @required bool doTopMerge,
   }) {
-    TypeSystemImpl typeSystem = targetClass.library.typeSystem;
-
-    List<Conflict> conflicts;
+    var conflicts = <Conflict>[];
 
     for (var name in namedCandidates.keys) {
       if (map.containsKey(name)) {
@@ -380,54 +438,18 @@
 
       var candidates = namedCandidates[name];
 
-      // If just one candidate, it is always valid.
-      if (candidates.length == 1) {
-        map[name] = candidates[0];
+      var combinedSignature = combineSignatures(
+        targetClass: targetClass,
+        candidates: candidates,
+        doTopMerge: doTopMerge,
+        name: name,
+        conflicts: conflicts,
+      );
+
+      if (combinedSignature != null) {
+        map[name] = combinedSignature;
         continue;
       }
-
-      // Check for a getter/method conflict.
-      var conflict = _checkForGetterMethodConflict(name, candidates);
-      if (conflict != null) {
-        conflicts ??= <Conflict>[];
-        conflicts.add(conflict);
-      }
-
-      var validOverrides = <ExecutableElement>[];
-      for (var i = 0; i < candidates.length; i++) {
-        var validOverride = candidates[i];
-        var overrideHelper = CorrectOverrideHelper(
-          library: targetClass.library,
-          thisMember: validOverride,
-        );
-        for (var j = 0; j < candidates.length; j++) {
-          var candidate = candidates[j];
-          if (!overrideHelper.isCorrectOverrideOf(superMember: candidate)) {
-            validOverride = null;
-            break;
-          }
-        }
-        if (validOverride != null) {
-          validOverrides.add(validOverride);
-        }
-      }
-
-      if (validOverrides.isEmpty) {
-        conflicts ??= <Conflict>[];
-        conflicts.add(
-          CandidatesConflict(
-            name: name,
-            candidates: candidates,
-          ),
-        );
-        continue;
-      }
-
-      if (doTopMerge) {
-        map[name] = _topMerge(typeSystem, targetClass, validOverrides);
-      } else {
-        map[name] = validOverrides.first;
-      }
     }
 
     return conflicts;
diff --git a/pkg/analyzer/lib/src/dart/element/type_demotion.dart b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
index cd2ad8b..3ec8097 100644
--- a/pkg/analyzer/lib/src/dart/element/type_demotion.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_demotion.dart
@@ -8,6 +8,7 @@
 import 'package:analyzer/src/dart/element/replacement_visitor.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/type_visitor.dart';
+import 'package:analyzer/src/generated/type_system.dart';
 
 /// Returns [type] in which all promoted type variables have been replace with
 /// their unpromoted equivalents, and, if [library] is non-nullable by default,
@@ -29,8 +30,8 @@
 
 /// Returns [type] in which all legacy types have been replaced with
 /// non-nullable types.
-DartType nonNullifyType(LibraryElement library, DartType type) {
-  if (library.isNonNullableByDefault && type != null) {
+DartType nonNullifyType(TypeSystemImpl typeSystem, DartType type) {
+  if (typeSystem.isNonNullableByDefault && type != null) {
     var visitor = const _DemotionNonNullification(demoteTypeVariables: false);
     return visitor.visit(type) ?? type;
   }
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index 226aa1d..6020ed5 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -61,7 +61,7 @@
       message:
           "The method 'Pointer.fromFunction' must not have an exceptional return "
           "value (the second argument) when the return type of the function is "
-          "either 'void' or 'Pointer'.",
+          "either 'void', 'Handle' or 'Pointer'.",
       correction: "Try removing the exceptional return value.");
 
   /**
@@ -102,7 +102,7 @@
       message:
           "The method 'Pointer.fromFunction' must have an exceptional return "
           "value (the second argument) when the return type of the function is "
-          "neither 'void' or 'Pointer'.",
+          "neither 'void', 'Handle' or 'Pointer'.",
       correction: "Try adding an exceptional return value.");
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
new file mode 100644
index 0000000..af6b3af
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/micro/cider_byte_store.dart
@@ -0,0 +1,55 @@
+// 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:collection/collection.dart';
+
+/**
+ * Store of bytes associated with string keys and a hash.
+ *
+ * Each key must be not longer than 100 characters and consist of only `[a-z]`,
+ * `[0-9]`, `.` and `_` characters. The key cannot be an empty string, the
+ * literal `.`, or contain the sequence `..`.
+ *
+ * Note that associations are not guaranteed to be persistent. The value
+ * associated with a key can change or become `null` at any point in time.
+ */
+abstract class CiderByteStore {
+  /**
+   * Return the bytes associated with the errors for given [key] and [signature].
+   * Return `null` if the association does not exist.
+   */
+  List<int> get(String key, List<int> signature);
+
+  /**
+   * Associate the given [bytes] with the [key] and [digest].
+   */
+  void put(String key, List<int> signature, List<int> bytes);
+}
+
+class CiderMemoryByteStore implements CiderByteStore {
+  final Map<String, _CiderCacheEntry> _map = {};
+
+  @override
+  List<int> get(String key, List<int> signature) {
+    var entry = _map[key];
+
+    if (entry != null &&
+        const ListEquality().equals(entry.signature, signature)) {
+      return entry.bytes;
+    }
+    return null;
+  }
+
+  @override
+  void put(String key, List<int> signature, List<int> bytes) {
+    _map[key] = _CiderCacheEntry(signature, bytes);
+  }
+}
+
+class _CiderCacheEntry {
+  final List<int> signature;
+  final List<int> bytes;
+
+  _CiderCacheEntry(this.signature, this.bytes);
+}
diff --git a/pkg/analyzer/lib/src/dart/micro/library_graph.dart b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
index 7133ec0..566ffa9 100644
--- a/pkg/analyzer/lib/src/dart/micro/library_graph.dart
+++ b/pkg/analyzer/lib/src/dart/micro/library_graph.dart
@@ -11,10 +11,10 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 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/unlinked_api_signature.dart';
+import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/scanner/reader.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart';
 import 'package:analyzer/src/generated/engine.dart';
@@ -27,7 +27,6 @@
 import 'package:analyzer/src/summary/link.dart' as graph
     show DependencyWalker, Node;
 import 'package:analyzer/src/summary2/informative_data.dart';
-import 'package:collection/collection.dart';
 import 'package:convert/convert.dart';
 
 /// Ensure that the [FileState.libraryCycle] for the [file] and anything it
@@ -168,16 +167,7 @@
     // Prepare bytes of the unlinked bundle - existing or new.
     List<int> bytes;
     {
-      bytes = _fsState._byteStore.get(unlinkedKey);
-      // unlinked summary should be updated if contents have changed, can be
-      // seen if file digest has changed.
-      if (bytes != null) {
-        var ciderUnlinkedUnit = CiderUnlinkedUnit.fromBuffer(bytes);
-        if (!const ListEquality()
-            .equals(ciderUnlinkedUnit.contentDigest, _digest)) {
-          bytes = null;
-        }
-      }
+      bytes = _fsState._byteStore.get(unlinkedKey, _digest);
 
       if (bytes == null || bytes.isEmpty) {
         var content = _fsState.timers.read.run(() {
@@ -189,7 +179,7 @@
         _fsState.timers.unlinked.run(() {
           var unlinkedBuilder = serializeAstCiderUnlinked(_digest, unit);
           bytes = unlinkedBuilder.toBuffer();
-          _fsState._byteStore.put(unlinkedKey, bytes);
+          _fsState._byteStore.put(unlinkedKey, _digest, bytes);
         });
 
         _fsState.timers.prefetch.run(() {
@@ -377,7 +367,7 @@
 class FileSystemState {
   final PerformanceLog _logger;
   final ResourceProvider _resourceProvider;
-  final MemoryByteStore _byteStore;
+  final CiderByteStore _byteStore;
   final SourceFactory _sourceFactory;
   final AnalysisOptions _analysisOptions;
   final Uint32List _linkedSalt;
diff --git a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
index c835175..0d2bb29 100644
--- a/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
+++ b/pkg/analyzer/lib/src/dart/micro/resolve_file.dart
@@ -19,6 +19,7 @@
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
 import 'package:analyzer/src/dart/analysis/results.dart';
 import 'package:analyzer/src/dart/micro/analysis_context.dart';
+import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/micro/library_analyzer.dart';
 import 'package:analyzer/src/dart/micro/library_graph.dart';
 import 'package:analyzer/src/generated/engine.dart'
@@ -33,7 +34,6 @@
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer/src/workspace/workspace.dart';
-import 'package:collection/collection.dart';
 import 'package:meta/meta.dart';
 import 'package:yaml/yaml.dart';
 
@@ -47,7 +47,7 @@
 class FileResolver {
   final PerformanceLog logger;
   final ResourceProvider resourceProvider;
-  final MemoryByteStore byteStore;
+  CiderByteStore byteStore;
   final SourceFactory sourceFactory;
 
   /*
@@ -76,22 +76,48 @@
 
   _LibraryContext libraryContext;
 
-  FileResolver(
-    this.logger,
-    this.resourceProvider,
-    this.byteStore,
-    this.sourceFactory,
-    this.getFileDigest,
-    this.prefetchFiles, {
+  FileResolver.from({
+    @required PerformanceLog logger,
+    @required ResourceProvider resourceProvider,
+    @required SourceFactory sourceFactory,
+    @required String Function(String path) getFileDigest,
+    @required void Function(List<String> paths) prefetchFiles,
     @required Workspace workspace,
+    CiderByteStore byteStore,
     Duration libraryContextResetTimeout = const Duration(seconds: 60),
-  }) : this.workspace = workspace {
+  })  : this.logger = logger,
+        this.sourceFactory = sourceFactory,
+        this.resourceProvider = resourceProvider,
+        this.getFileDigest = getFileDigest,
+        this.prefetchFiles = prefetchFiles,
+        this.workspace = workspace {
+    byteStore ??= CiderMemoryByteStore();
+    this.byteStore = byteStore;
     _libraryContextReset = _LibraryContextReset(
       fileResolver: this,
       resetTimeout: libraryContextResetTimeout,
     );
   }
 
+  FileResolver(
+    PerformanceLog logger,
+    ResourceProvider resourceProvider,
+    @deprecated ByteStore byteStore,
+    SourceFactory sourceFactory,
+    String Function(String path) getFileDigest,
+    void Function(List<String> paths) prefetchFiles, {
+    @required Workspace workspace,
+    Duration libraryContextResetTimeout = const Duration(seconds: 60),
+  }) : this.from(
+          logger: logger,
+          resourceProvider: resourceProvider,
+          sourceFactory: sourceFactory,
+          getFileDigest: getFileDigest,
+          prefetchFiles: prefetchFiles,
+          workspace: workspace,
+          libraryContextResetTimeout: libraryContextResetTimeout,
+        );
+
   FeatureSet get defaultFeatureSet => FeatureSet.fromEnableFlags([]);
 
   /// Update the resolver to reflect the fact that the file with the given
@@ -134,16 +160,13 @@
         var errorsSignature = errorsSignatureBuilder.toByteList();
 
         var errorsKey = file.path + '.errors';
-        var bytes = byteStore.get(errorsKey);
-
+        var bytes = byteStore.get(errorsKey, errorsSignature);
         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();
-          }
+          errors = data.errors.map((error) {
+            return ErrorEncoding.decode(file.source, error);
+          }).toList();
         }
 
         if (errors == null) {
@@ -154,7 +177,7 @@
             signature: errorsSignature,
             errors: errors.map((ErrorEncoding.encode)).toList(),
           ).toBuffer();
-          byteStore.put(errorsKey, bytes);
+          byteStore.put(errorsKey, errorsSignature, bytes);
         }
 
         return ErrorsResultImpl(
@@ -412,7 +435,7 @@
 class _LibraryContext {
   final PerformanceLog logger;
   final ResourceProvider resourceProvider;
-  final MemoryByteStore byteStore;
+  final CiderByteStore byteStore;
   final MicroContextObjects contextObjects;
 
   LinkedElementFactory elementFactory;
@@ -451,15 +474,7 @@
       cycle.directDependencies.forEach(loadBundle);
 
       var key = cycle.cyclePathsHash;
-      var bytes = byteStore.get(key);
-
-      // check to see if any of the sources have changed
-      if (bytes != null) {
-        var hash = CiderLinkedLibraryCycle.fromBuffer(bytes).signature;
-        if (!const ListEquality().equals(hash, cycle.signature)) {
-          bytes = null;
-        }
-      }
+      var bytes = byteStore.get(key, cycle.signature);
 
       if (bytes == null) {
         librariesLinkedTimer.start();
@@ -510,7 +525,7 @@
 
         bytes = serializeBundle(cycle.signature, linkResult).toBuffer();
 
-        byteStore.put(key, bytes);
+        byteStore.put(key, cycle.signature, bytes);
         bytesPut += bytes.length;
 
         librariesLinkedTimer.stop();
diff --git a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
index db924a3..3af9e12 100644
--- a/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/body_inference_context.dart
@@ -7,6 +7,7 @@
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/dart/element/type_provider.dart';
 import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_demotion.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:meta/meta.dart';
@@ -97,7 +98,7 @@
         _typeSystem.isSubtypeOf2(actualReturnedType, contextType)) {
       clampedReturnedType = actualReturnedType;
     } else {
-      clampedReturnedType = contextType;
+      clampedReturnedType = nonNullifyType(_typeSystem, contextType);
     }
 
     if (_isGenerator) {
diff --git a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
index 236219d..9dc3e92 100644
--- a/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
+++ b/pkg/analyzer/lib/src/dart/resolver/function_expression_resolver.dart
@@ -51,8 +51,6 @@
     }
 
     var contextType = InferenceContext.getContext(node);
-    contextType = nonNullifyType(_resolver.definingLibrary, contextType);
-
     if (contextType is FunctionType) {
       contextType = _matchFunctionTypeParameters(
         node.typeParameters,
@@ -94,8 +92,15 @@
         // Check that there is no declared type, and that we have not already
         // inferred a type in some fashion.
         if (p.hasImplicitType && (p.type == null || p.type.isDynamic)) {
+          // If no type is declared for a parameter and there is a
+          // corresponding parameter in the context type schema with type
+          // schema `K`, the parameter is given an inferred type `T` where `T`
+          // is derived from `K` as follows.
           inferredType = _typeSystem.greatestClosure(inferredType);
-          if (inferredType.isDartCoreNull || inferredType is NeverTypeImpl) {
+
+          // If the greatest closure of `K` is `S` and `S` is a subtype of
+          // `Null`, then `T` is `Object?`. Otherwise, `T` is `S`.
+          if (_typeSystem.isSubtypeOf2(inferredType, _typeSystem.nullNone)) {
             inferredType = _isNonNullableByDefault
                 ? _typeSystem.objectQuestion
                 : _typeSystem.objectStar;
@@ -103,6 +108,8 @@
           if (_migrationResolutionHooks != null) {
             inferredType = _migrationResolutionHooks
                 .modifyInferredParameterType(p, inferredType);
+          } else {
+            inferredType = nonNullifyType(_typeSystem, inferredType);
           }
           if (!inferredType.isDynamic) {
             p.type = inferredType;
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 4fefde5..21f7582 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -960,15 +960,43 @@
    * implicitly declared constructor named ... is declared. If Sq is a
    * generative const constructor, and M does not declare any fields, Cq is
    * also a const constructor.
+   *
+   * Parameters:
+   * 0: the name of the instance field.
    */
   static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD =
-      CompileTimeErrorCode(
+      CompileTimeErrorCodeWithUniqueName(
           'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
-          "Const constructor can't be declared for a class with a mixin "
-              "that declares an instance field.",
-          correction: "Try removing the 'const' keyword or "
-              "removing the 'with' clause from the class declaration, "
-              "or removing fields from the mixin class.");
+          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+          "This constructor can't be declared 'const' because a mixin adds the "
+              "instance field: {0}.",
+          correction: "Try removing the 'const' keyword or removing the 'with' "
+              "clause from the class declaration, or removing the field from "
+              "the mixin class.");
+
+  /**
+   * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
+   * or implicitly, in the initializer list of a constant constructor must
+   * specify a constant constructor of the superclass of the immediately
+   * enclosing class or a compile-time error occurs.
+   *
+   * 12.1 Mixin Application: For each generative constructor named ... an
+   * implicitly declared constructor named ... is declared. If Sq is a
+   * generative const constructor, and M does not declare any fields, Cq is
+   * also a const constructor.
+   *
+   * Parameters:
+   * 0: the names of the instance fields.
+   */
+  static const CompileTimeErrorCode CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS =
+      CompileTimeErrorCodeWithUniqueName(
+          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD',
+          'CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS',
+          "This constructor can't be declared 'const' because the mixins add "
+              "the instance fields: {0}.",
+          correction: "Try removing the 'const' keyword or removing the 'with' "
+              "clause from the class declaration, or removing the fields from "
+              "the mixin classes.");
 
   /**
    * 7.6.3 Constant Constructors: The superinitializer that appears, explicitly
@@ -1547,8 +1575,10 @@
   // var l = List.generate(3, (i) => i);
   // ```
   static const CompileTimeErrorCode DEFAULT_LIST_CONSTRUCTOR =
-      CompileTimeErrorCode('DEFAULT_LIST_CONSTRUCTOR',
-          "Calling the default 'List' constructor causes an error.",
+      CompileTimeErrorCode(
+          'DEFAULT_LIST_CONSTRUCTOR',
+          "The default 'List' constructor is not available when null safety is "
+              "enabled.",
           correction: "Try using a list literal, 'List.filled' or "
               "'List.generate'.");
 
@@ -4105,16 +4135,6 @@
       'MIXIN_OF_NON_CLASS', "Classes can only mix in mixins and classes.",
       hasPublishedDocs: true);
 
-  /**
-   * 9 Mixins: It is a compile-time error if a declared or derived mixin refers
-   * to super.
-   */
-  static const CompileTimeErrorCode MIXIN_REFERENCES_SUPER =
-      CompileTimeErrorCode(
-          'MIXIN_REFERENCES_SUPER',
-          "The class '{0}' can't be used as a mixin because it references "
-              "'super'.");
-
   static const CompileTimeErrorCode
       MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS = CompileTimeErrorCode(
           'MIXIN_SUPER_CLASS_CONSTRAINT_DEFERRED_CLASS',
diff --git a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
index dea3b72..9cabeb7 100644
--- a/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
+++ b/pkg/analyzer/lib/src/error/duplicate_definition_verifier.dart
@@ -11,6 +11,14 @@
 import 'package:analyzer/src/error/codes.dart';
 
 class DuplicateDefinitionVerifier {
+  static final Set<String> _enumInstanceMembers = {
+    'hashCode',
+    'index',
+    'noSuchMethod',
+    'runtimeType',
+    'toString',
+  };
+
   final LibraryElement _currentLibrary;
   final ErrorReporter _errorReporter;
 
@@ -39,12 +47,9 @@
   void checkEnum(EnumDeclaration node) {
     ClassElement element = node.declaredElement;
 
-    Map<String, Element> instanceGetters = HashMap<String, Element>();
-    Map<String, Element> staticGetters = HashMap<String, Element>();
-
-    instanceGetters['index'] = element.getGetter('index');
-    instanceGetters['toString'] = element.getMethod('toString');
-    staticGetters['values'] = element.getGetter('values');
+    Map<String, Element> staticGetters = {
+      'values': element.getGetter('values')
+    };
 
     for (EnumConstantDeclaration constant in node.constants) {
       _checkDuplicateIdentifier(staticGetters, constant.name);
@@ -59,7 +64,7 @@
           CompileTimeErrorCode.ENUM_CONSTANT_SAME_NAME_AS_ENCLOSING,
           identifier,
         );
-      } else if (instanceGetters.containsKey(name)) {
+      } else if (_enumInstanceMembers.contains(name)) {
         _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE,
           identifier,
diff --git a/pkg/analyzer/lib/src/generated/element_resolver.dart b/pkg/analyzer/lib/src/generated/element_resolver.dart
index 2811c3a..9fda12a 100644
--- a/pkg/analyzer/lib/src/generated/element_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/element_resolver.dart
@@ -476,7 +476,6 @@
   @override
   void visitMethodInvocation(MethodInvocation node) {
     _methodInvocationResolver.resolve(node);
-    _resolver.nullShortingTermination(node);
   }
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index b4ecb6a..cdc3a4c 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -444,6 +444,7 @@
         _checkClassInheritance(node, superclass, withClause, implementsClause);
       }
 
+      _checkForConflictingClassMembers();
       _constructorFieldsVerifier.enterClass(node);
       _checkForFinalNotInitializedInClass(members);
       _checkForBadFunctionUse(node);
@@ -951,6 +952,7 @@
         _checkMixinInheritance(node, onClause, implementsClause);
       }
 
+      _checkForConflictingClassMembers();
       _checkForFinalNotInitializedInClass(members);
       _checkForWrongTypeParameterVarianceInSuperinterfaces();
       //      _checkForBadFunctionUse(node);
@@ -1267,7 +1269,6 @@
         !_checkForAllMixinErrorCodes(withClause)) {
       _checkForImplicitDynamicType(superclass);
       _checkForExtendsDeferredClass(superclass);
-      _checkForConflictingClassMembers();
       _checkForRepeatedType(implementsClause?.interfaces,
           CompileTimeErrorCode.IMPLEMENTS_REPEATED);
       _checkImplementsSuperClass(implementsClause);
@@ -1300,8 +1301,7 @@
    * Verify that all classes of the given [withClause] are valid.
    *
    * See [CompileTimeErrorCode.MIXIN_CLASS_DECLARES_CONSTRUCTOR],
-   * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT], and
-   * [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
+   * [CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT].
    */
   bool _checkForAllMixinErrorCodes(WithClause withClause) {
     if (withClause == null) {
@@ -1341,9 +1341,6 @@
             if (_checkForMixinInheritsNotFromObject(mixinName, mixinElement)) {
               problemReported = true;
             }
-            if (_checkForMixinReferencesSuper(mixinName, mixinElement)) {
-              problemReported = true;
-            }
           }
         }
       }
@@ -1756,7 +1753,7 @@
 
   /**
    * Verify that the [_enclosingClass] does not have a method and getter pair
-   * with the same name on, via inheritance.
+   * with the same name, via inheritance.
    *
    * See [CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE],
    * [CompileTimeErrorCode.CONFLICTING_METHOD_AND_FIELD], and
@@ -1902,12 +1899,12 @@
     }
   }
 
-  /**
-   * Verify that if the given [constructor] declaration is 'const' then there
-   * are no invocations of non-'const' super constructors.
-   *
-   * See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER].
-   */
+  /// Verify that if the given [constructor] declaration is 'const' then there
+  /// are no invocations of non-'const' super constructors, and that there are
+  /// no instance variables mixed in.
+  ///
+  /// See [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_CONST_SUPER], and
+  /// [CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD].
   void _checkForConstConstructorWithNonConstSuper(
       ConstructorDeclaration constructor) {
     if (!_enclosingExecutable.isConstConstructor) {
@@ -1919,21 +1916,26 @@
     }
 
     // check for mixins
-    var hasInstanceField = false;
+    var instanceFields = <FieldElement>[];
     for (var mixin in _enclosingClass.mixins) {
-      var fields = mixin.element.fields;
-      for (var i = 0; i < fields.length; ++i) {
-        if (!fields[i].isStatic) {
-          hasInstanceField = true;
-          break;
-        }
-      }
+      instanceFields.addAll(mixin.element.fields
+          .where((field) => !field.isStatic && !field.isSynthetic));
     }
-    if (hasInstanceField) {
-      // TODO(scheglov) Provide the list of fields.
+    if (instanceFields.length == 1) {
+      var field = instanceFields.single;
       _errorReporter.reportErrorForNode(
           CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD,
-          constructor.returnType);
+          constructor.returnType,
+          ["'${field.enclosingElement.name}.${field.name}'"]);
+      return;
+    } else if (instanceFields.length > 1) {
+      var fieldNames = instanceFields
+          .map((field) => "'${field.enclosingElement.name}.${field.name}'")
+          .join(', ');
+      _errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS,
+          constructor.returnType,
+          [fieldNames]);
       return;
     }
 
@@ -3291,24 +3293,6 @@
     return false;
   }
 
-  /**
-   * Verify that the given mixin does not reference 'super'. The [mixinName] is
-   * the node to report problem on. The [mixinElement] is the mixing to
-   * evaluate.
-   *
-   * See [CompileTimeErrorCode.MIXIN_REFERENCES_SUPER].
-   */
-  bool _checkForMixinReferencesSuper(
-      TypeName mixinName, ClassElement mixinElement) {
-    if (mixinElement.hasReferenceToSuper) {
-      _errorReporter.reportErrorForNode(
-          CompileTimeErrorCode.MIXIN_REFERENCES_SUPER,
-          mixinName,
-          [mixinElement.name]);
-    }
-    return false;
-  }
-
   /// Check that superclass constrains for the mixin type of [mixinName] at
   /// the [mixinIndex] position in the mixins list are satisfied by the
   /// [_enclosingClass], or a previous mixin.
@@ -4915,7 +4899,6 @@
     if (!_checkForOnClauseErrorCodes(onClause) &&
         !_checkForImplementsClauseErrorCodes(implementsClause)) {
 //      _checkForImplicitDynamicType(superclass);
-      _checkForConflictingClassMembers();
       _checkForRepeatedType(
         onClause?.superclassConstraints,
         CompileTimeErrorCode.ON_REPEATED,
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 5217e36..a0d763d 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -190,6 +190,9 @@
   bool _isPointer(Element element) =>
       element.name == 'Pointer' && element.library.name == 'dart.ffi';
 
+  bool _isHandle(Element element) =>
+      element.name == 'Handle' && element.library.name == 'dart.ffi';
+
   bool _isNativeFunctionPointerExtension(Element element) =>
       element.name == 'NativeFunctionPointer' &&
       element.library.name == 'dart.ffi';
@@ -295,6 +298,9 @@
         if (name == 'Void') {
           return _PrimitiveDartType.void_;
         }
+        if (name == 'Handle') {
+          return _PrimitiveDartType.handle;
+        }
       }
     }
     return _PrimitiveDartType.none;
@@ -449,6 +455,11 @@
       return dartType.isDartCoreDouble;
     } else if (nativeReturnType == _PrimitiveDartType.void_) {
       return dartType.isVoid;
+    } else if (nativeReturnType == _PrimitiveDartType.handle) {
+      InterfaceType objectType = typeSystem.objectStar;
+      return checkCovariance
+          ? /* everything is subtype of objectStar */ true
+          : typeSystem.isSubtypeOf2(objectType, dartType);
     } else if (dartType is InterfaceType && nativeType is InterfaceType) {
       return checkCovariance
           ? typeSystem.isSubtypeOf2(dartType, nativeType)
@@ -520,7 +531,9 @@
 
     // TODO(brianwilkerson) Validate that `f` is a top-level function.
     final DartType R = (T as FunctionType).returnType;
-    if ((FT as FunctionType).returnType.isVoid || _isPointer(R.element)) {
+    if ((FT as FunctionType).returnType.isVoid ||
+        _isPointer(R.element) ||
+        _isHandle(R.element)) {
       if (argCount != 1) {
         _errorReporter.reportErrorForNode(
             FfiCode.INVALID_EXCEPTION_VALUE, node.argumentList.arguments[1]);
@@ -591,5 +604,6 @@
   double,
   int,
   void_,
+  handle,
   none,
 }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index f158bd0..0b52455 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -449,7 +449,7 @@
 
   /// If we reached a null-shorting termination, and the [node] has null
   /// shorting, make the type of the [node] nullable.
-  void nullShortingTermination(Expression node) {
+  void nullShortingTermination(Expression node, {bool discardType = false}) {
     if (!_isNonNullableByDefault) return;
 
     if (identical(_unfinishedNullShorts.last, node)) {
@@ -457,7 +457,7 @@
         _unfinishedNullShorts.removeLast();
         _flowAnalysis.flow.nullAwareAccess_end();
       } while (identical(_unfinishedNullShorts.last, node));
-      if (node is! CascadeExpression) {
+      if (node is! CascadeExpression && !discardType) {
         node.staticType = typeSystem.makeNullable(node.staticType);
       }
     }
@@ -1327,7 +1327,10 @@
 
     var functionRewrite = MethodInvocationResolver.getRewriteResult(node);
     if (functionRewrite != null) {
-      _functionExpressionInvocationResolver.resolve(functionRewrite);
+      nullShortingTermination(node, discardType: true);
+      _resolveRewrittenFunctionExpressionInvocation(functionRewrite);
+    } else {
+      nullShortingTermination(node);
     }
   }
 
@@ -1804,6 +1807,30 @@
     }
   }
 
+  /// Continues resolution of a [FunctionExpressionInvocation] that was created
+  /// from a rewritten [MethodInvocation]. The target function is already
+  /// resolved.
+  ///
+  /// The specification says that `target.getter()` should be treated as an
+  /// ordinary method invocation. So, we need to perform the same null shorting
+  /// as for method invocations.
+  void _resolveRewrittenFunctionExpressionInvocation(
+    FunctionExpressionInvocation node,
+  ) {
+    var function = node.function;
+
+    if (function is PropertyAccess &&
+        _migratableAstInfoProvider.isPropertyAccessNullAware(function) &&
+        _isNonNullableByDefault) {
+      _flowAnalysis.flow.nullAwareAccess_rightBegin(function);
+      _unfinishedNullShorts.add(node.nullShortingTermination);
+    }
+
+    _functionExpressionInvocationResolver.resolve(node);
+
+    nullShortingTermination(node);
+  }
+
   /// Given an [argumentList] and the [parameters] related to the element that
   /// will be invoked using those arguments, compute the list of parameters that
   /// correspond to the list of arguments.
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index 2b0e133..f224920 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -834,7 +834,7 @@
     if (initializer != null) {
       if (parent is VariableDeclarationList && parent.type == null) {
         DartType type = initializer.staticType;
-        if (type != null && !type.isBottom && !type.isDartCoreNull) {
+        if (type != null && !type.isDartCoreNull) {
           VariableElement element = node.declaredElement;
           if (element is LocalVariableElementImpl) {
             var initializerType = initializer.staticType;
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 87254cc..3a6484c 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -1333,6 +1333,9 @@
       if (Identifier.isPrivateName(name.name)) {
         return null;
       }
+      if (isConst) {
+        relevanceTags = [...?relevanceTags, 'isConst'];
+      }
 
       var locationOffset = name.offset;
       var lineLocation = lineInfo.getLocation(locationOffset);
diff --git a/pkg/analyzer/lib/src/source/package_map_resolver.dart b/pkg/analyzer/lib/src/source/package_map_resolver.dart
index a9f1f88..c618a29 100644
--- a/pkg/analyzer/lib/src/source/package_map_resolver.dart
+++ b/pkg/analyzer/lib/src/source/package_map_resolver.dart
@@ -53,20 +53,20 @@
     if (!isPackageUri(uri)) {
       return null;
     }
-    // Prepare path.
-    String path = uri.path;
-    // Prepare path components.
-    int index = path.indexOf('/');
-    if (index == -1 || index == 0) {
+
+    var pathSegments = uri.pathSegments;
+    if (pathSegments.length < 2) {
       return null;
     }
+
     // <pkgName>/<relPath>
-    String pkgName = path.substring(0, index);
-    String relPath = path.substring(index + 1);
+    String pkgName = pathSegments[0];
+
     // If the package is known, return the corresponding file.
     List<Folder> packageDirs = packageMap[pkgName];
     if (packageDirs != null) {
       Folder packageDir = packageDirs.single;
+      String relPath = pathSegments.skip(1).join('/');
       File file = packageDir.getChildAssumingFile(relPath);
       return file.createSource(uri);
     }
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 06cc17d..0082065 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -99,6 +99,7 @@
             InferenceContext.setType(variable.initializer, typeNode.type);
             return variable.initializer;
           },
+          isTopLevelVariableInitializer: true,
         );
       }
     }
diff --git a/pkg/analyzer/lib/src/task/strong_mode.dart b/pkg/analyzer/lib/src/task/strong_mode.dart
index 2f4ae36..3371051 100644
--- a/pkg/analyzer/lib/src/task/strong_mode.dart
+++ b/pkg/analyzer/lib/src/task/strong_mode.dart
@@ -61,134 +61,6 @@
   }
 
   /**
-   * Compute the inferred type for the given property [accessor]. The returned
-   * value is never `null`, but might be an error, and/or have the `null` type.
-   */
-  _FieldOverrideInferenceResult _computeFieldOverrideType(
-      PropertyAccessorElement accessor) {
-    String name = accessor.displayName;
-
-    var overriddenGetters = inheritance.getOverridden2(
-      currentClassElement,
-      Name(accessor.library.source.uri, name),
-    );
-
-    List<ExecutableElement> overriddenSetters;
-    if (overriddenGetters == null || !accessor.variable.isFinal) {
-      overriddenSetters = inheritance.getOverridden2(
-        currentClassElement,
-        Name(accessor.library.source.uri, '$name='),
-      );
-    }
-
-    // Choose overridden members from getters or/and setters.
-    List<ExecutableElement> overriddenElements = <ExecutableElement>[];
-    if (overriddenGetters == null && overriddenSetters == null) {
-      overriddenElements = const <ExecutableElement>[];
-    } else if (overriddenGetters == null && overriddenSetters != null) {
-      overriddenElements = overriddenSetters;
-    } else if (overriddenGetters != null && overriddenSetters == null) {
-      overriddenElements = overriddenGetters;
-    } else {
-      overriddenElements = <ExecutableElement>[
-        ...overriddenGetters,
-        ...overriddenSetters,
-      ];
-    }
-
-    bool isCovariant = false;
-    DartType impliedType;
-    for (ExecutableElement overriddenElement in overriddenElements) {
-      var overriddenElementKind = overriddenElement.kind;
-      if (overriddenElement == null) {
-        return _FieldOverrideInferenceResult(false, null, true);
-      }
-
-      DartType type;
-      if (overriddenElementKind == ElementKind.GETTER) {
-        type = overriddenElement.returnType;
-      } else if (overriddenElementKind == ElementKind.SETTER) {
-        if (overriddenElement.parameters.length == 1) {
-          ParameterElement parameter = overriddenElement.parameters[0];
-          type = parameter.type;
-          isCovariant = isCovariant || parameter.isCovariant;
-        }
-      } else {
-        return _FieldOverrideInferenceResult(false, null, true);
-      }
-
-      if (impliedType == null) {
-        impliedType = type;
-      } else if (type != impliedType) {
-        return _FieldOverrideInferenceResult(false, null, true);
-      }
-    }
-
-    return _FieldOverrideInferenceResult(isCovariant, impliedType, false);
-  }
-
-  /**
-   * Compute the best type for the [parameter] at the given [index] that must be
-   * compatible with the types of the corresponding parameters of the given
-   * [overriddenTypes].
-   *
-   * At the moment, this method will only return a type other than 'dynamic' if
-   * the types of all of the parameters are the same. In the future we might
-   * want to be smarter about it, such as by returning the least upper bound of
-   * the parameter types.
-   */
-  DartType _computeParameterType(ParameterElement parameter, int index,
-      List<FunctionType> overriddenTypes) {
-    var typesMerger = _OverriddenTypesMerger(typeSystem);
-
-    for (var overriddenType in overriddenTypes) {
-      ParameterElement matchingParameter = _getCorrespondingParameter(
-        parameter,
-        index,
-        overriddenType.parameters,
-      );
-      DartType type = matchingParameter?.type ?? _dynamicType;
-      typesMerger.update(type);
-
-      if (typesMerger.hasError) {
-        if (parameter is ParameterElementImpl && parameter.linkedNode != null) {
-          LazyAst.setTypeInferenceError(
-            parameter.linkedNode,
-            TopLevelInferenceErrorBuilder(
-              kind: TopLevelInferenceErrorKind.overrideConflictParameterType,
-            ),
-          );
-        }
-        return _dynamicType;
-      }
-    }
-
-    return typesMerger.result ?? _dynamicType;
-  }
-
-  /**
-   * Compute the best return type for a method that must be compatible with the
-   * return types of each of the given [overriddenReturnTypes].
-   *
-   * At the moment, this method will only return a type other than 'dynamic' if
-   * the return types of all of the methods are the same. In the future we might
-   * want to be smarter about it.
-   */
-  DartType _computeReturnType(Iterable<DartType> overriddenReturnTypes) {
-    var typesMerger = _OverriddenTypesMerger(typeSystem);
-
-    for (DartType type in overriddenReturnTypes) {
-      type ??= _dynamicType;
-      typesMerger.update(type);
-      if (typesMerger.hasError) {
-        return _dynamicType;
-      }
-    }
-
-    return typesMerger.result ?? _dynamicType;
-  }
-
-  /**
    * Given a method, return the parameter in the method that corresponds to the
    * given [parameter]. If the parameter is positional, then
    * it appears at the given [index] in its enclosing element's list of
@@ -223,37 +95,267 @@
   }
 
   /**
-   * If the given [element] represents a non-synthetic instance property
+   * If the given [accessor] represents a non-synthetic instance property
    * accessor for which no type was provided, infer its types.
+   *
+   * If the given [field] represents a non-synthetic instance field for
+   * which no type was provided, infer the type of the field.
    */
-  void _inferAccessor(PropertyAccessorElement element) {
-    if (element.isSynthetic || element.isStatic) {
-      return;
-    }
+  void _inferAccessorOrField({
+    PropertyAccessorElementImpl accessor,
+    FieldElementImpl field,
+  }) {
+    Uri elementLibraryUri;
+    String elementName;
 
-    if (element.kind == ElementKind.GETTER && !element.hasImplicitReturnType) {
-      return;
-    }
-
-    _FieldOverrideInferenceResult typeResult =
-        _computeFieldOverrideType(element);
-    if (typeResult.isError == null || typeResult.type == null) {
-      return;
-    }
-
-    if (element.kind == ElementKind.GETTER) {
-      (element as ExecutableElementImpl).returnType = typeResult.type;
-    } else if (element.kind == ElementKind.SETTER) {
-      List<ParameterElement> parameters = element.parameters;
-      if (parameters.isNotEmpty) {
-        var parameter = parameters[0] as ParameterElementImpl;
-        if (parameter.hasImplicitType) {
-          parameter.type = typeResult.type;
-        }
-        parameter.inheritsCovariant = typeResult.isCovariant;
+    if (accessor != null) {
+      if (accessor.isSynthetic || accessor.isStatic) {
+        return;
       }
+      elementLibraryUri = accessor.library.source.uri;
+      elementName = accessor.displayName;
     }
-    (element.variable as FieldElementImpl).type = typeResult.type;
+
+    if (field != null) {
+      if (field.isSynthetic || field.isStatic) {
+        return;
+      }
+      elementLibraryUri = field.library.source.uri;
+      elementName = field.name;
+    }
+
+    var getterName = Name(elementLibraryUri, elementName);
+    var overriddenGetters = inheritance.getOverridden2(
+      currentClassElement,
+      getterName,
+    );
+    overriddenGetters ??= const [];
+
+    var setterName = Name(elementLibraryUri, '$elementName=');
+    var overriddenSetters = inheritance.getOverridden2(
+      currentClassElement,
+      setterName,
+    );
+    overriddenSetters ??= const [];
+
+    if (accessor != null && accessor.isGetter) {
+      if (!accessor.hasImplicitReturnType) {
+        return;
+      }
+
+      // The return type of a getter, parameter type of a setter or type of a
+      // field which overrides/implements only one or more getters is inferred
+      // to be the return type of the combined member signature of said getter
+      // in the direct superinterfaces.
+      //
+      // The return type of a getter which overrides/implements both a setter
+      // and a getter is inferred to be the return type of the combined member
+      // signature of said getter in the direct superinterfaces.
+      if (overriddenGetters.isNotEmpty) {
+        var combinedGetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenGetters,
+          doTopMerge: true,
+          name: getterName,
+        );
+        if (combinedGetter != null) {
+          accessor.returnType = combinedGetter.returnType;
+        }
+      }
+
+      // The return type of a getter, parameter type of a setter or type of
+      // field which overrides/implements only one or more setters is inferred
+      // to be the parameter type of the combined member signature of said
+      // setter in the direct superinterfaces.
+      if (overriddenGetters.isEmpty && overriddenSetters.isNotEmpty) {
+        var combinedSetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenSetters,
+          doTopMerge: true,
+          name: setterName,
+        );
+        if (combinedSetter != null) {
+          accessor.returnType = combinedSetter.parameters[0].type;
+        }
+      }
+
+      return;
+    }
+
+    if (accessor != null && accessor.isSetter) {
+      var parameters = accessor.parameters;
+      if (parameters.isEmpty) {
+        return;
+      }
+      var parameter = parameters[0] as ParameterElementImpl;
+
+      if (overriddenSetters.any(_isCovariantSetter)) {
+        parameter.inheritsCovariant = true;
+      }
+
+      if (!parameter.hasImplicitType) {
+        return;
+      }
+
+      // The return type of a getter, parameter type of a setter or type of a
+      // field which overrides/implements only one or more getters is inferred
+      // to be the return type of the combined member signature of said getter
+      // in the direct superinterfaces.
+      if (overriddenGetters.isNotEmpty && overriddenSetters.isEmpty) {
+        var combinedGetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenGetters,
+          doTopMerge: true,
+          name: getterName,
+        );
+        if (combinedGetter != null) {
+          parameter.type = combinedGetter.returnType;
+        }
+        return;
+      }
+
+      // The return type of a getter, parameter type of a setter or type of
+      // field which overrides/implements only one or more setters is inferred
+      // to be the parameter type of the combined member signature of said
+      // setter in the direct superinterfaces.
+      //
+      // The parameter type of a setter which overrides/implements both a
+      // setter and a getter is inferred to be the parameter type of the
+      // combined member signature of said setter in the direct superinterfaces.
+      if (overriddenSetters.isNotEmpty) {
+        var combinedSetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenSetters,
+          doTopMerge: true,
+          name: setterName,
+        );
+        if (combinedSetter != null) {
+          parameter.type = combinedSetter.parameters[0].type;
+        }
+        return;
+      }
+
+      return;
+    }
+
+    if (field != null) {
+      if (field.setter != null) {
+        if (overriddenSetters.any(_isCovariantSetter)) {
+          var parameter = field.setter.parameters[0] as ParameterElementImpl;
+          parameter.inheritsCovariant = true;
+        }
+      }
+
+      if (!field.hasImplicitType) {
+        return;
+      }
+
+      // The return type of a getter, parameter type of a setter or type of a
+      // field which overrides/implements only one or more getters is inferred
+      // to be the return type of the combined member signature of said getter
+      // in the direct superinterfaces.
+      if (overriddenGetters.isNotEmpty && overriddenSetters.isEmpty) {
+        var combinedGetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenGetters,
+          doTopMerge: true,
+          name: getterName,
+        );
+        if (combinedGetter != null) {
+          field.type = combinedGetter.returnType;
+        }
+        return;
+      }
+
+      // The return type of a getter, parameter type of a setter or type of
+      // field which overrides/implements only one or more setters is inferred
+      // to be the parameter type of the combined member signature of said
+      // setter in the direct superinterfaces.
+      if (overriddenGetters.isEmpty && overriddenSetters.isNotEmpty) {
+        var combinedSetter = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenSetters,
+          doTopMerge: true,
+          name: setterName,
+        );
+        if (combinedSetter != null) {
+          field.type = combinedSetter.parameters[0].type;
+        }
+        return;
+      }
+
+      if (overriddenGetters.isNotEmpty && overriddenSetters.isNotEmpty) {
+        // The type of a final field which overrides/implements both a setter
+        // and a getter is inferred to be the return type of the combined
+        // member signature of said getter in the direct superinterfaces.
+        if (field.isFinal) {
+          var combinedGetter = inheritance.combineSignatures(
+            targetClass: currentClassElement,
+            candidates: overriddenGetters,
+            doTopMerge: true,
+            name: getterName,
+          );
+          if (combinedGetter != null) {
+            field.type = combinedGetter.returnType;
+          }
+          return;
+        }
+
+        // The type of a non-final field which overrides/implements both a
+        // setter and a getter is inferred to be the parameter type of the
+        // combined member signature of said setter in the direct
+        // superinterfaces, if this type is the same as the return type of the
+        // combined member signature of said getter in the direct
+        // superinterfaces. If the types are not the same then inference
+        // fails with an error.
+        if (!field.isFinal) {
+          var combinedGetter = inheritance.combineSignatures(
+            targetClass: currentClassElement,
+            candidates: overriddenGetters,
+            doTopMerge: true,
+            name: getterName,
+          );
+          var getterType = combinedGetter?.returnType;
+
+          var combinedSetter = inheritance.combineSignatures(
+            targetClass: currentClassElement,
+            candidates: overriddenSetters,
+            doTopMerge: true,
+            name: setterName,
+          );
+          DartType setterType;
+          if (combinedSetter != null) {
+            setterType = combinedSetter.parameters[0].type;
+          }
+
+          if (getterType == setterType) {
+            field.type = getterType ?? _dynamicType;
+          } else {
+            LazyAst.setTypeInferenceError(
+              field.linkedNode,
+              TopLevelInferenceErrorBuilder(
+                kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
+              ),
+            );
+          }
+          return;
+        }
+      }
+
+      // Otherwise, declarations of static variables and fields that omit a
+      // type will be inferred from their initializer if present.
+      var initializer = field.initializer;
+      if (initializer != null) {
+        var initializerType = initializer.returnType;
+        if (initializerType == null || initializerType.isDartCoreNull) {
+          initializerType = _dynamicType;
+        }
+        field.type = initializerType;
+        return;
+      }
+
+      return;
+    }
   }
 
   /**
@@ -287,10 +389,10 @@
         //
         currentClassElement = classElement;
         for (FieldElement field in classElement.fields) {
-          _inferField(field);
+          _inferAccessorOrField(field: field);
         }
         for (PropertyAccessorElement accessor in classElement.accessors) {
-          _inferAccessor(accessor);
+          _inferAccessorOrField(accessor: accessor);
         }
         for (MethodElement method in classElement.methods) {
           _inferExecutable(method);
@@ -340,42 +442,57 @@
       return;
     }
 
-    // TODO(scheglov) If no implicit types, don't ask inherited.
-
-    List<ExecutableElement> overriddenElements = inheritance.getOverridden2(
-      currentClassElement,
-      Name(element.library.source.uri, element.name),
-    );
+    var name = Name(element.library.source.uri, element.name);
+    List<ExecutableElement> overriddenElements =
+        inheritance.getOverridden2(currentClassElement, name);
     if (overriddenElements == null ||
         !_allSameElementKind(element, overriddenElements)) {
       return;
     }
 
-    List<FunctionType> overriddenTypes =
-        _toOverriddenFunctionTypes(element, overriddenElements);
-    if (overriddenTypes.isEmpty) {
-      return;
+    FunctionType combinedSignatureType;
+    FunctionType getCombinedSignatureType() {
+      if (combinedSignatureType == null) {
+        var combinedSignature = inheritance.combineSignatures(
+          targetClass: currentClassElement,
+          candidates: overriddenElements,
+          doTopMerge: true,
+          name: name,
+        );
+        if (combinedSignature != null) {
+          combinedSignatureType = _toOverriddenFunctionType(
+            element,
+            combinedSignature,
+          );
+        }
+      }
+      return combinedSignatureType;
     }
 
     //
     // Infer the return type.
     //
     if (element.hasImplicitReturnType && element.displayName != '[]=') {
-      element.returnType =
-          _computeReturnType(overriddenTypes.map((t) => t.returnType));
+      var combinedSignatureType = getCombinedSignatureType();
+      if (combinedSignatureType != null) {
+        element.returnType = combinedSignatureType.returnType;
+      } else {
+        element.returnType = DynamicTypeImpl.instance;
+      }
     }
+
     //
     // Infer the parameter types.
     //
     List<ParameterElement> parameters = element.parameters;
-    int length = parameters.length;
-    for (int i = 0; i < length; ++i) {
-      ParameterElement parameter = parameters[i];
+    for (var index = 0; index < parameters.length; index++) {
+      ParameterElement parameter = parameters[index];
       if (parameter is ParameterElementImpl) {
-        _inferParameterCovariance(parameter, i, overriddenTypes);
+        _inferParameterCovariance(parameter, index, overriddenElements);
 
         if (parameter.hasImplicitType) {
-          parameter.type = _computeParameterType(parameter, i, overriddenTypes);
+          var combinedSignatureType = getCombinedSignatureType();
+          _inferParameterType(parameter, index, combinedSignatureType);
         }
       }
     }
@@ -384,63 +501,46 @@
   }
 
   /**
-   * If the given [field] represents a non-synthetic instance field for
-   * which no type was provided, infer the type of the field.
-   */
-  void _inferField(FieldElementImpl field) {
-    if (field.isSynthetic || field.isStatic) {
-      return;
-    }
-
-    _FieldOverrideInferenceResult typeResult =
-        _computeFieldOverrideType(field.getter);
-    if (typeResult.isError) {
-      if (field.linkedNode != null) {
-        LazyAst.setTypeInferenceError(
-          field.linkedNode,
-          TopLevelInferenceErrorBuilder(
-            kind: TopLevelInferenceErrorKind.overrideConflictFieldType,
-          ),
-        );
-      }
-      return;
-    }
-
-    if (field.hasImplicitType) {
-      DartType newType = typeResult.type;
-
-      if (newType == null) {
-        var initializer = field.initializer;
-        if (initializer != null) {
-          newType = initializer.returnType;
-        }
-      }
-
-      if (newType == null || newType.isBottom || newType.isDartCoreNull) {
-        newType = _dynamicType;
-      }
-
-      field.type = newType;
-    }
-
-    if (field.setter != null) {
-      var parameter = field.setter.parameters[0] as ParameterElementImpl;
-      parameter.inheritsCovariant = typeResult.isCovariant;
-    }
-  }
-
-  /**
    * If a parameter is covariant, any parameters that override it are too.
    */
   void _inferParameterCovariance(ParameterElementImpl parameter, int index,
-      Iterable<FunctionType> overriddenTypes) {
-    parameter.inheritsCovariant = overriddenTypes.any((f) {
+      Iterable<ExecutableElement> overridden) {
+    parameter.inheritsCovariant = overridden.any((f) {
       var param = _getCorrespondingParameter(parameter, index, f.parameters);
       return param != null && param.isCovariant;
     });
   }
 
   /**
+   * Set the type for the [parameter] at the given [index] from the given
+   * [combinedSignatureType], which might be `null` if there is no valid
+   * combined signature for signatures from direct superinterfaces.
+   */
+  void _inferParameterType(ParameterElementImpl parameter, int index,
+      FunctionType combinedSignatureType) {
+    if (combinedSignatureType != null) {
+      var matchingParameter = _getCorrespondingParameter(
+        parameter,
+        index,
+        combinedSignatureType.parameters,
+      );
+      if (matchingParameter != null) {
+        parameter.type = matchingParameter.type;
+      } else {
+        parameter.type = DynamicTypeImpl.instance;
+      }
+    } else {
+      parameter.type = DynamicTypeImpl.instance;
+      LazyAst.setTypeInferenceError(
+        parameter.linkedNode,
+        TopLevelInferenceErrorBuilder(
+          kind: TopLevelInferenceErrorKind.overrideConflictParameterType,
+        ),
+      );
+    }
+  }
+
+  /**
    * Infer type information for all of the instance members in the given
    * interface [type].
    */
@@ -532,22 +632,12 @@
     return replaceTypeParameters(overriddenType, elementTypeParameters);
   }
 
-  /**
-   * Return [FunctionType]s of [overriddenElements] that override [element].
-   * Return the empty list, in case of type parameters inconsistency.
-   */
-  List<FunctionType> _toOverriddenFunctionTypes(
-      ExecutableElement element, List<ExecutableElement> overriddenElements) {
-    var overriddenTypes = <FunctionType>[];
-    for (ExecutableElement overriddenElement in overriddenElements) {
-      FunctionType overriddenType =
-          _toOverriddenFunctionType(element, overriddenElement);
-      if (overriddenType == null) {
-        return const <FunctionType>[];
-      }
-      overriddenTypes.add(overriddenType);
+  static bool _isCovariantSetter(ExecutableElement element) {
+    if (element is PropertyAccessorElement) {
+      var parameters = element.parameters;
+      return parameters.isNotEmpty && parameters[0].isCovariant;
     }
-    return overriddenTypes;
+    return false;
   }
 }
 
@@ -555,64 +645,3 @@
  * A class of exception that is not used anywhere else.
  */
 class _CycleException implements Exception {}
-
-/**
- * The result of field type inference.
- */
-class _FieldOverrideInferenceResult {
-  final bool isCovariant;
-  final DartType type;
-  final bool isError;
-
-  _FieldOverrideInferenceResult(this.isCovariant, this.type, this.isError);
-}
-
-/// Helper for merging types from several overridden executables, according
-/// to legacy or NNBD rules.
-class _OverriddenTypesMerger {
-  final TypeSystemImpl _typeSystem;
-
-  bool hasError = false;
-
-  DartType _legacyResult;
-
-  DartType _notNormalized;
-  DartType _currentMerge;
-
-  _OverriddenTypesMerger(this._typeSystem);
-
-  DartType get result {
-    if (_typeSystem.isNonNullableByDefault) {
-      return _currentMerge ?? _notNormalized;
-    } else {
-      return _legacyResult;
-    }
-  }
-
-  void update(DartType type) {
-    if (hasError) {
-      // Stop updating it.
-    } else if (_typeSystem.isNonNullableByDefault) {
-      if (_currentMerge == null) {
-        if (_notNormalized == null) {
-          _notNormalized = type;
-          return;
-        } else {
-          _currentMerge = _typeSystem.normalize(_notNormalized);
-        }
-      }
-      var normType = _typeSystem.normalize(type);
-      try {
-        _currentMerge = _typeSystem.topMerge(_currentMerge, normType);
-      } catch (_) {
-        hasError = true;
-      }
-    } else {
-      if (_legacyResult == null) {
-        _legacyResult = type;
-      } else if (_legacyResult != type) {
-        hasError = true;
-      }
-    }
-  }
-}
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 712e057..490e703 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -540,6 +540,7 @@
   int indexOf(Pattern pattern, [int start = 0]);
   int lastIndexOf(Pattern pattern, [int? start]);
   bool startsWith(Pattern pattern, [int index = 0]);
+  List<String> split(Pattern pattern);
   String splitMapJoin(Pattern pattern,
       {String Function(Match)? onMatch, String Function(String)? onNonMatch});
   String substring(int startIndex, [int? endIndex]);
@@ -904,6 +905,8 @@
 
 import 'dart:convert';
 
+Never exit(int code) => throw code;
+
 abstract class Directory implements FileSystemEntity {
   factory Directory(String path) {
     throw 0;
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 2522f3f..33dda57 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -618,6 +618,58 @@
     ]);
   }
 
+  test_constWithNonConst_mixinApplication_constSuperConstructor() async {
+    await assertNoErrorsInCode(r'''
+mixin M {}
+class A {
+  const A();
+}
+class B = A with M;
+const b = const B();
+''');
+  }
+
+  test_constWithNonConst_mixinApplication_constSuperConstructor_field() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  int i = 0;
+}
+class A {
+  const A();
+}
+class B = A with M;
+var b = const B();
+''', [
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONST, 78, 5),
+    ]);
+  }
+
+  test_constWithNonConst_mixinApplication_constSuperConstructor_getter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  int get i => 0;
+}
+class A {
+  const A();
+}
+class B = A with M;
+var b = const B();
+''');
+  }
+
+  test_constWithNonConst_mixinApplication_constSuperConstructor_setter() async {
+    await assertNoErrorsInCode(r'''
+mixin M {
+  set(int i) {}
+}
+class A {
+  const A();
+}
+class B = A with M;
+var b = const B();
+''');
+  }
+
   test_constWithNonConstantArgument_annotation() async {
     await assertErrorsInCode(r'''
 class A {
@@ -792,121 +844,6 @@
     ]);
   }
 
-  test_fieldInitializerFactoryConstructor() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  factory A(this.x) => throw 0;
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, 31, 6),
-    ]);
-  }
-
-  test_fieldInitializerOutsideConstructor() async {
-    // TODO(brianwilkerson) Fix the duplicate error messages.
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  m(this.x) {}
-}
-''', [
-      error(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 23, 4),
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 23, 6),
-    ]);
-  }
-
-  test_fieldInitializerOutsideConstructor_closure() async {
-    await assertErrorsInCode(r'''
-class A {
-  dynamic field = ({this.field}) {};
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 30, 10),
-    ]);
-  }
-
-  test_fieldInitializerOutsideConstructor_defaultParameter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  m([this.x]) {}
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 24, 6),
-    ]);
-  }
-
-  test_fieldInitializerOutsideConstructor_inFunctionTypeParameter() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  A(int p(this.x));
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 29, 6),
-    ]);
-  }
-
-  test_fieldInitializerOutsideConstructor_topLevelFunction() async {
-    await assertErrorsInCode(r'''
-f(this.x(y)) {}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 2, 9),
-    ]);
-  }
-
-  test_fieldInitializerRedirectingConstructor_afterRedirection() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  A.named() {}
-  A() : this.named(), x = 42;
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 56,
-          6),
-    ]);
-  }
-
-  test_fieldInitializerRedirectingConstructor_beforeRedirection() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  A.named() {}
-  A() : x = 42, this.named();
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 42,
-          6),
-    ]);
-  }
-
-  test_fieldInitializingFormalRedirectingConstructor() async {
-    await assertErrorsInCode(r'''
-class A {
-  int x;
-  A.named() {}
-  A(this.x) : this.named();
-}
-''', [
-      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 38,
-          6),
-    ]);
-  }
-
-  test_forInWithConstVariable_forEach_identifier() async {
-    await assertErrorsInCode(r'''
-f() {
-  const x = 0;
-  for (x in [0, 1, 2]) {}
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 14, 1),
-      error(StaticWarningCode.ASSIGNMENT_TO_CONST, 28, 1),
-    ]);
-  }
-
   test_fromEnvironment_bool_badArgs() async {
     await assertErrorsInCode(r'''
 var b1 = const bool.fromEnvironment(1);
@@ -1006,36 +943,6 @@
     await assertNoErrorsInCode(code);
   }
 
-  test_implementsDeferredClass() async {
-    newFile('/test/lib/lib1.dart', content: '''
-library lib1;
-class A {}
-''');
-    await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class B implements a.A {}
-''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS, 67, 3),
-    ]);
-  }
-
-  test_implementsDeferredClass_classTypeAlias() async {
-    newFile('/test/lib/lib1.dart', content: '''
-library lib1;
-class A {}
-''');
-    await assertErrorsInCode('''
-library root;
-import 'lib1.dart' deferred as a;
-class B {}
-class M {}
-class C = B with M implements a.A;
-''', [
-      error(CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS, 100, 3),
-    ]);
-  }
-
   test_importInternalLibrary() async {
     // Note, in these error cases we may generate an UNUSED_IMPORT hint, while
     // we could prevent the hint from being generated by testing the import
diff --git a/pkg/analyzer/test/generated/simple_resolver_test.dart b/pkg/analyzer/test/generated/simple_resolver_test.dart
index 80e6e1d..f957a1d 100644
--- a/pkg/analyzer/test/generated/simple_resolver_test.dart
+++ b/pkg/analyzer/test/generated/simple_resolver_test.dart
@@ -753,9 +753,7 @@
     ]);
   }
 
-  @failingTest
   test_import_spaceInUri() async {
-    // TODO(scheglov) Fix this. The problem is in `package` URI resolver.
     newFile('/test/lib/sub folder/a.dart', content: r'''
 foo() {}''');
 
@@ -863,15 +861,13 @@
   }
 
   test_isValidMixin_super() async {
-    await assertErrorsInCode(r'''
+    await assertNoErrorsInCode(r'''
 class A {
   toString() {
     return super.toString();
   }
 }
-class C = Object with A;''', [
-      error(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, 82, 1),
-    ]);
+class C = Object with A;''');
     verifyTestResolved();
 
     var a = findElement.class_('A');
diff --git a/pkg/analyzer/test/source/package_map_resolver_test.dart b/pkg/analyzer/test/source/package_map_resolver_test.dart
index 4f66d50..db9a3d1 100644
--- a/pkg/analyzer/test/source/package_map_resolver_test.dart
+++ b/pkg/analyzer/test/source/package_map_resolver_test.dart
@@ -96,6 +96,40 @@
     }
   }
 
+  void test_resolve_OK_withNonAscii() {
+    var resolver = PackageMapUriResolver(provider, {
+      'aaa': <Folder>[
+        provider.getFolder(
+          provider.convertPath('/packages/aaa/lib'),
+        ),
+      ],
+    });
+
+    var uri = Uri.parse('package:aaa/проба/a.dart');
+    var result = resolver.resolveAbsolute(uri);
+    expect(
+      result.fullName,
+      provider.convertPath('/packages/aaa/lib/проба/a.dart'),
+    );
+  }
+
+  void test_resolve_OK_withSpace() {
+    var resolver = PackageMapUriResolver(provider, {
+      'aaa': <Folder>[
+        provider.getFolder(
+          provider.convertPath('/packages/aaa/lib'),
+        ),
+      ],
+    });
+
+    var uri = Uri.parse('package:aaa/with space/a.dart');
+    var result = resolver.resolveAbsolute(uri);
+    expect(
+      result.fullName,
+      provider.convertPath('/packages/aaa/lib/with space/a.dart'),
+    );
+  }
+
   void test_resolve_package_invalid_leadingSlash() {
     UriResolver resolver = PackageMapUriResolver(provider, EMPTY_MAP);
     Uri uri = Uri.parse('package:/foo');
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index 44d4dd4..91e2cc5 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -43,7 +43,7 @@
     newFile('/test/lib/a.dart', content: r'''
 class A {}
 ''');
-    await _assertNotConst(r'''
+    await _assertNeverConst(r'''
 import 'a.dart' deferred as p;
 p.A x;
 ''');
@@ -56,7 +56,7 @@
   }
 
   test_class_typeArguments_notConst() async {
-    await _assertNotConst(r'''
+    await _assertPotentiallyConst(r'''
 class A<T> {
   m() {
     List<T> x;
@@ -78,7 +78,7 @@
   }
 
   test_genericFunctionType_formalParameterType() async {
-    await _assertNotConst(r'''
+    await _assertPotentiallyConst(r'''
 class A<T> {
   m() {
     Function(T) x;
@@ -88,7 +88,7 @@
   }
 
   test_genericFunctionType_returnType() async {
-    await _assertNotConst(r'''
+    await _assertPotentiallyConst(r'''
 class A<T> {
   m() {
     T Function() x;
@@ -98,7 +98,7 @@
   }
 
   test_genericFunctionType_typeParameterBound() async {
-    await _assertNotConst(r'''
+    await _assertPotentiallyConst(r'''
 class A<T> {
   m() {
     Function<U extends T>() x;
@@ -108,7 +108,7 @@
   }
 
   test_typeParameter() async {
-    await _assertNotConst(r'''
+    await _assertPotentiallyConst(r'''
 class A<T> {
   m() {
     T x;
@@ -129,7 +129,13 @@
     expect(isConstantTypeExpression(type), isTrue);
   }
 
-  Future<void> _assertNotConst(String code) async {
+  Future<void> _assertNeverConst(String code) async {
+    await resolveTestCode(code);
+    var type = findNode.variableDeclarationList('x;').type;
+    expect(isConstantTypeExpression(type), isFalse);
+  }
+
+  Future<void> _assertPotentiallyConst(String code) async {
     await resolveTestCode(code);
     var type = findNode.variableDeclarationList('x;').type;
     expect(isConstantTypeExpression(type), isFalse);
@@ -150,6 +156,16 @@
 ''');
   }
 
+  test_typeParameter_nested() async {
+    await _assertConst(r'''
+class A<T> {
+  m() {
+    List<T> x;
+  }
+}
+''');
+  }
+
   @override
   Future<void> _assertConst(String code) async {
     await resolveTestCode(code);
@@ -158,10 +174,10 @@
   }
 
   @override
-  Future<void> _assertNotConst(String code) async {
+  Future<void> _assertPotentiallyConst(String code) async {
     await resolveTestCode(code);
     var type = findNode.variableDeclarationList('x;').type;
-    expect(isPotentiallyConstantTypeExpression(type), isFalse);
+    expect(isPotentiallyConstantTypeExpression(type), isTrue);
   }
 }
 
@@ -919,6 +935,17 @@
 ''', () => _xInitializer());
   }
 
+  test_asExpression_typeParameter_nested() async {
+    await _assertConst(r'''
+const a = 0;
+class A<T> {
+  m() {
+    var x = a as List<T>;
+  }
+}
+''', () => _xInitializer());
+  }
+
   @override
   test_isExpression_typeParameter() async {
     await _assertConst(r'''
@@ -930,6 +957,17 @@
 }
 ''', () => _xInitializer());
   }
+
+  test_isExpression_typeParameter_nested() async {
+    await _assertConst(r'''
+const a = 0;
+class A<T> {
+  m() {
+    var x = a is List<T>;
+  }
+}
+''', () => _xInitializer());
+  }
 }
 
 mixin WithNullSafetyMixin on DriverResolutionTest {
diff --git a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
index c0e9cc7..8427087 100644
--- a/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
+++ b/pkg/analyzer/test/src/dart/element/generic_inferrer_test.dart
@@ -39,8 +39,10 @@
       ],
       returnType: typeParameterTypeNone(tTo),
     );
-    expect(_inferCall(cast, [stringNone]),
-        [stringNone, (iterableNone(stringNone))]);
+    _assertTypes(
+      _inferCall(cast, [stringNone]),
+      [stringNone, (iterableNone(stringNone))],
+    );
   }
 
   void test_boundedByOuterClass() {
@@ -181,10 +183,10 @@
       ],
       returnType: typeS,
     );
-    expect(_inferCall(clone, [typeB, typeB]), [typeB]);
+    _assertTypes(_inferCall(clone, [typeB, typeB]), [typeB]);
 
     // Something invalid...
-    expect(
+    _assertTypes(
       _inferCall(clone, [stringNone, numNone], expectError: true),
       [objectNone],
     );
@@ -203,7 +205,7 @@
       ],
       returnType: typeParameterTypeNone(tTo),
     );
-    expect(_inferCall(cast, [intNone]), [intNone, dynamicNone]);
+    _assertTypes(_inferCall(cast, [intNone]), [intNone, dynamicNone]);
   }
 
   void test_genericCastFunctionWithUpperBound() {
@@ -222,7 +224,7 @@
       ],
       returnType: typeParameterTypeNone(tTo),
     );
-    expect(_inferCall(cast, [intNone]), [intNone, intNone]);
+    _assertTypes(_inferCall(cast, [intNone]), [intNone, intNone]);
   }
 
   void test_parameter_contravariantUseUpperBound() {
@@ -244,7 +246,7 @@
       returnType: typeParameterTypeNone(T),
     );
 
-    expect(_inferCall(function, [intNone, numFunction]), [numNone]);
+    _assertTypes(_inferCall(function, [intNone, numFunction]), [numNone]);
   }
 
   void test_parameter_covariantUseLowerBound() {
@@ -266,7 +268,7 @@
       returnType: typeParameterTypeNone(T),
     );
 
-    expect(_inferCall(function, [intNone, numFunction]), [intNone]);
+    _assertTypes(_inferCall(function, [intNone, numFunction]), [intNone]);
   }
 
   void test_parametersToFunctionParam() {
@@ -288,7 +290,7 @@
       ],
       returnType: typeParameterTypeNone(T),
     );
-    expect(
+    _assertTypes(
       _inferCall(cast, [
         functionTypeNone(
           parameters: [
@@ -312,7 +314,7 @@
       ],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(cast, [intNone, doubleNone]), [numNone]);
+    _assertTypes(_inferCall(cast, [intNone, doubleNone]), [numNone]);
   }
 
   void test_parameterTypeUsesUpperBound() {
@@ -325,7 +327,7 @@
       ],
       returnType: dynamicNone,
     );
-    expect(_inferCall(f, [intNone]), [intNone]);
+    _assertTypes(_inferCall(f, [intNone]), [intNone]);
   }
 
   void test_returnFunctionWithGenericParameter() {
@@ -350,7 +352,7 @@
         returnType: voidNone,
       ),
     );
-    expect(
+    _assertTypes(
       _inferCall(f, [
         functionTypeNone(
           parameters: [
@@ -385,7 +387,7 @@
         returnType: nullNone,
       ),
     );
-    expect(
+    _assertTypes(
       _inferCall(
         f,
         [],
@@ -422,7 +424,7 @@
         returnType: typeParameterTypeNone(T),
       ),
     );
-    expect(
+    _assertTypes(
       _inferCall(f, [
         functionTypeNone(
           parameters: [
@@ -454,7 +456,7 @@
         returnType: typeParameterTypeNone(T),
       ),
     );
-    expect(
+    _assertTypes(
       _inferCall(f, [
         functionTypeNone(
           parameters: [
@@ -474,7 +476,17 @@
       typeFormals: [T],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(f, [], returnType: stringNone), [stringNone]);
+    _assertTypes(_inferCall(f, [], returnType: stringNone), [stringNone]);
+  }
+
+  void test_returnTypeFromContext_nonNullify() {
+    // <T>() -> T
+    var T = typeParameter('T');
+    var f = functionTypeNone(
+      typeFormals: [T],
+      returnType: typeParameterTypeNone(T),
+    );
+    _assertTypes(_inferCall(f, [], returnType: intStar), [intNone]);
   }
 
   void test_returnTypeWithBoundFromContext() {
@@ -484,7 +496,7 @@
       typeFormals: [T],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(f, [], returnType: doubleNone), [doubleNone]);
+    _assertTypes(_inferCall(f, [], returnType: doubleNone), [doubleNone]);
   }
 
   void test_returnTypeWithBoundFromInvalidContext() {
@@ -494,7 +506,7 @@
       typeFormals: [T],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(f, [], returnType: stringNone), [neverNone]);
+    _assertTypes(_inferCall(f, [], returnType: stringNone), [neverNone]);
   }
 
   void test_unifyParametersToFunctionParam() {
@@ -526,7 +538,7 @@
       ],
       returnType: typeParameterTypeNone(T),
     );
-    expect(
+    _assertTypes(
       _inferCall(cast, [
         functionTypeNone(
           parameters: [
@@ -552,7 +564,7 @@
       typeFormals: [T],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(f, []), [dynamicNone]);
+    _assertTypes(_inferCall(f, []), [dynamicNone]);
   }
 
   void test_unusedReturnTypeWithUpperBound() {
@@ -562,7 +574,7 @@
       typeFormals: [T],
       returnType: typeParameterTypeNone(T),
     );
-    expect(_inferCall(f, []), [numNone]);
+    _assertTypes(_inferCall(f, []), [numNone]);
   }
 
   void _assertType(DartType type, String expected) {
@@ -570,6 +582,18 @@
     expect(typeStr, expected);
   }
 
+  void _assertTypes(List<DartType> actual, List<DartType> expected) {
+    var actualStr = actual.map((e) {
+      return e.getDisplayString(withNullability: true);
+    }).toList();
+
+    var expectedStr = expected.map((e) {
+      return e.getDisplayString(withNullability: true);
+    }).toList();
+
+    expect(actualStr, expectedStr);
+  }
+
   List<DartType> _inferCall(FunctionTypeImpl ft, List<DartType> arguments,
       {DartType returnType, bool expectError = false}) {
     var listener = RecordingErrorListener();
diff --git a/pkg/analyzer/test/src/dart/micro/file_resolution.dart b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
index ef3df6c..395f676 100644
--- a/pkg/analyzer/test/src/dart/micro/file_resolution.dart
+++ b/pkg/analyzer/test/src/dart/micro/file_resolution.dart
@@ -5,8 +5,8 @@
 import 'dart:convert';
 
 import 'package:analyzer/dart/analysis/results.dart';
-import 'package:analyzer/src/dart/analysis/byte_store.dart';
 import 'package:analyzer/src/dart/analysis/performance_logger.dart';
+import 'package:analyzer/src/dart/micro/cider_byte_store.dart';
 import 'package:analyzer/src/dart/micro/resolve_file.dart';
 import 'package:analyzer/src/test_utilities/find_element.dart';
 import 'package:analyzer/src/test_utilities/find_node.dart';
@@ -22,7 +22,7 @@
 class FileResolutionTest with ResourceProviderMixin, ResolutionTest {
   static final String _testFile = '/workspace/dart/test/lib/test.dart';
 
-  final ByteStore byteStore = MemoryByteStore();
+  final CiderByteStore byteStore = CiderMemoryByteStore();
 
   final StringBuffer logBuffer = StringBuffer();
   PerformanceLog logger;
@@ -44,15 +44,14 @@
       convertPath(_testFile),
     );
 
-    fileResolver = FileResolver(
-      logger,
-      resourceProvider,
-      byteStore,
-      workspace.createSourceFactory(sdk, null),
-      (String path) => _getDigest(path),
-      null,
+    fileResolver = FileResolver.from(
+      logger: logger,
+      resourceProvider: resourceProvider,
+      byteStore: byteStore,
+      sourceFactory: workspace.createSourceFactory(sdk, null),
+      getFileDigest: (String path) => _getDigest(path),
       workspace: workspace,
-      libraryContextResetTimeout: null,
+      prefetchFiles: null,
     );
     fileResolver.testView = FileResolverTestView();
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
index da98f88..07570ba 100644
--- a/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/class_alias_test.dart
@@ -2,6 +2,7 @@
 // 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:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../../../generated/elements_types_mixin.dart';
@@ -90,7 +91,6 @@
     );
   }
 
-  @failingTest
   test_implicitConstructors_const() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -103,7 +103,58 @@
 
 const x = const C();
 ''');
-    // TODO(scheglov) add also negative test with fields
+  }
+
+  test_implicitConstructors_const_field() async {
+    await assertErrorsInCode(r'''
+class A {
+  const A();
+}
+
+class M {
+  int i = 0;
+}
+
+class C = A with M;
+
+const x = const C();
+''', [
+      error(CompileTimeErrorCode.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE, 83,
+          5),
+      error(CompileTimeErrorCode.CONST_WITH_NON_CONST, 83, 5),
+    ]);
+  }
+
+  test_implicitConstructors_const_getter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  const A();
+}
+
+class M {
+  int get i => 0;
+}
+
+class C = A with M;
+
+const x = const C();
+''');
+  }
+
+  test_implicitConstructors_const_setter() async {
+    await assertNoErrorsInCode(r'''
+class A {
+  const A();
+}
+
+class M {
+  set(int i) {}
+}
+
+class C = A with M;
+
+const x = const C();
+''');
   }
 
   test_implicitConstructors_dependencies() async {
diff --git a/pkg/analyzer/test/src/dart/resolution/constant_test.dart b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
index 9d51f53..a535f95 100644
--- a/pkg/analyzer/test/src/dart/resolution/constant_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/constant_test.dart
@@ -288,6 +288,32 @@
     _assertIntValue(bar, 42);
   }
 
+  test_fromEnvironment_optOut_fromOptIn() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.5
+
+const cBool = const bool.fromEnvironment('foo', defaultValue: false);
+const cInt = const int.fromEnvironment('foo', defaultValue: 1);
+const cString = const String.fromEnvironment('foo', defaultValue: 'bar');
+''');
+
+    await assertNoErrorsInCode(r'''
+import 'a.dart';
+
+const vBool = cBool;
+const vInt = cInt;
+const vString = cString;
+''');
+
+    DartObjectImpl evaluate(String name) {
+      return findElement.topVar(name).computeConstantValue();
+    }
+
+    expect(evaluate('vBool').toBoolValue(), false);
+    expect(evaluate('vInt').toIntValue(), 1);
+    expect(evaluate('vString').toStringValue(), 'bar');
+  }
+
   test_topLevelVariable_optIn_fromOptOut() async {
     newFile('/test/lib/a.dart', content: r'''
 const foo = 42;
diff --git a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
index f142343..03d250f 100644
--- a/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/function_expression_invocation_test.dart
@@ -189,4 +189,54 @@
 
     assertType(findNode.binary('1 + 2'), 'int');
   }
+
+  test_nullShorting() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  int Function() get foo;
+}
+
+class B {
+  void bar(A? a) {
+    a?.foo();
+  }
+}
+''');
+
+    assertFunctionExpressionInvocation(
+      findNode.functionExpressionInvocation('a?.foo()'),
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'int Function()',
+      type: 'int?',
+    );
+  }
+
+  test_nullShorting_extends() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  int Function() get foo;
+}
+
+class B {
+  void bar(A? a) {
+    a?.foo().isEven;
+  }
+}
+''');
+
+    assertFunctionExpressionInvocation(
+      findNode.functionExpressionInvocation('a?.foo()'),
+      element: null,
+      typeArgumentTypes: [],
+      invokeType: 'int Function()',
+      type: 'int',
+    );
+
+    assertPropertyAccess2(
+      findNode.propertyAccess('isEven'),
+      element: intElement.getGetter('isEven'),
+      type: 'bool?',
+    );
+  }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
index f11aa35..ba751e4 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_class_test.dart
@@ -3,7 +3,9 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'driver_resolution.dart';
@@ -17,6 +19,375 @@
 
 @reflectiveTest
 class InstanceMemberInferenceClassTest extends DriverResolutionTest {
+  test_field_covariant_fromField() async {
+    await resolveTestCode('''
+class A {
+  covariant num foo = 0;
+}
+
+class B implements A {
+  int foo = 0;
+}
+''');
+    var foo = findElement.field('foo', of: 'B');
+    _assertFieldType(foo, 'int', isCovariant: true);
+  }
+
+  test_field_covariant_fromSetter() async {
+    await resolveTestCode('''
+class A {
+  set foo(covariant num _) {}
+}
+
+class B implements A {
+  int foo = 0;
+}
+''');
+    var foo = findElement.field('foo', of: 'B');
+    _assertFieldType(foo, 'int', isCovariant: true);
+  }
+
+  test_field_fromInitializer_inherited() async {
+    await resolveTestCode('''
+class A {
+  var foo = 0;
+}
+
+class B implements A {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'B');
+    _assertFieldType(foo, 'int');
+  }
+
+  test_field_fromInitializer_preferSuper() async {
+    await resolveTestCode('''
+class A {
+  num foo;
+}
+
+class B implements A {
+  var foo = 0;
+}
+''');
+    var foo = findElement.field('foo', of: 'B');
+    _assertFieldType(foo, 'num');
+  }
+
+  test_field_multiple_fields_incompatible() async {
+    await resolveTestCode('''
+class A {
+  int foo = throw 0;
+}
+class B {
+  String foo = throw 0;
+}
+class C implements A, B {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'C');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_field_multiple_getters_combined() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'C');
+    _assertFieldType(foo, 'int');
+  }
+
+  test_field_multiple_getters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'C');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_field_multiple_gettersSetters_final_combined() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(String _) {}
+}
+class X implements A, B, C {
+  final foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldType(foo, 'int');
+  }
+
+  test_field_multiple_gettersSetters_final_incompatible() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(String _) {}
+}
+class X implements A, B, C {
+  final foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_field_multiple_gettersSetters_notFinal_combined_notSame() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(String _) {}
+}
+class X implements A, B, C {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldTypeDynamic(foo);
+    // TODO(scheglov) error?
+  }
+
+  test_field_multiple_gettersSetters_notFinal_combined_same() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(int _) {}
+}
+class X implements A, B, C {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldType(foo, 'int');
+  }
+
+  test_field_multiple_gettersSetters_notFinal_incompatible_getters() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(int _) {}
+}
+class X implements A, B, C {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_field_multiple_gettersSetters_notFinal_incompatible_setters() async {
+    await resolveTestCode('''
+class A {
+  int get foo => throw 0;
+}
+class B {
+  set foo(String _) {}
+}
+class C {
+  set foo(int _) {}
+}
+class X implements A, B, C {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'X');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_field_multiple_setters_combined() async {
+    await resolveTestCode('''
+class A {
+  set foo(num _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'C');
+    _assertFieldType(foo, 'num');
+  }
+
+  test_field_multiple_setters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  set foo(String _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  var foo;
+}
+''');
+    var foo = findElement.field('foo', of: 'C');
+    _assertFieldTypeDynamic(foo);
+  }
+
+  test_getter_multiple_getters_combined() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'C');
+    _assertGetterType(foo, 'int');
+  }
+
+  test_getter_multiple_getters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'C');
+    _assertGetterTypeDynamic(foo);
+  }
+
+  test_getter_multiple_getters_same() async {
+    await resolveTestCode('''
+class A {
+  int get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'C');
+    _assertGetterType(foo, 'int');
+  }
+
+  test_getter_multiple_gettersSetters_combined() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(String _) {}
+}
+class X implements A, B, C {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'X');
+    _assertGetterType(foo, 'int');
+  }
+
+  test_getter_multiple_gettersSetters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C {
+  set foo(String _) {}
+}
+class X implements A, B, C {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'X');
+    _assertGetterTypeDynamic(foo);
+  }
+
+  test_getter_multiple_setters_combined() async {
+    await resolveTestCode('''
+class A {
+  set foo(num _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'C');
+    _assertGetterType(foo, 'num');
+  }
+
+  test_getter_multiple_setters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  set foo(String _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  get foo => throw 0;
+}
+''');
+    var foo = findElement.getter('foo', of: 'C');
+    _assertGetterTypeDynamic(foo);
+  }
+
   test_invalid_inheritanceCycle() async {
     await resolveTestCode('''
 class A extends C {}
@@ -25,100 +396,244 @@
 ''');
   }
 
-  test_method_parameter_multiple_different() async {
+  test_method_parameter_covariant_named() async {
     await resolveTestCode('''
 class A {
-  foo(int p) => 0;
+  void foo({num p}) {}
 }
 class B {
-  foo(double p) => 0;
+  void foo({covariant num p}) {}
 }
 class C implements A, B {
-  foo(p) => 0;
+  void foo({int p}) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    _assertParameter(p, type: 'int', isCovariant: true);
+  }
+
+  test_method_parameter_covariant_positional() async {
+    await resolveTestCode('''
+class A {
+  void foo([num p]) {}
+}
+class B {
+  void foo([covariant num p]) {}
+}
+class C implements A, B {
+  void foo([int p]) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    _assertParameter(p, type: 'int', isCovariant: true);
+  }
+
+  test_method_parameter_covariant_required() async {
+    await resolveTestCode('''
+class A {
+  void foo(num p) {}
+}
+class B {
+  void foo(covariant num p) {}
+}
+class C implements A, B {
+  void foo(int p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    _assertParameter(p, type: 'int', isCovariant: true);
+  }
+
+  test_method_parameter_named_multiple_combined() async {
+    await resolveTestCode('''
+class A {
+  void foo({int p}) {}
+}
+class B {
+  void foo({num p}) {}
+}
+class C implements A, B {
+  void foo({p}) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertType(p.type, 'num');
+  }
+
+  test_method_parameter_named_multiple_incompatible() async {
+    await resolveTestCode('''
+class A {
+  void foo({int p}) {}
+}
+class B {
+  void foo({int q}) {}
+}
+class C implements A, B {
+  void foo({p}) {}
 }
 ''');
     var p = findElement.method('foo', of: 'C').parameters[0];
     assertTypeDynamic(p.type);
   }
 
-  test_method_parameter_multiple_named_different() async {
+  test_method_parameter_named_multiple_same() async {
     await resolveTestCode('''
 class A {
-  foo({int p}) => 0;
+  void foo({int p}) {}
 }
 class B {
-  foo({int q}) => 0;
+  void foo({int p}) {}
 }
 class C implements A, B {
-  foo({p}) => 0;
-}
-''');
-    var p = findElement.method('foo', of: 'C').parameters[0];
-    assertTypeDynamic(p.type);
-  }
-
-  test_method_parameter_multiple_named_same() async {
-    await resolveTestCode('''
-class A {
-  foo({int p}) => 0;
-}
-class B {
-  foo({int p}) => 0;
-}
-class C implements A, B {
-  foo({p}) => 0;
+  void foo({p}) {}
 }
 ''');
     var p = findElement.method('foo', of: 'C').parameters[0];
     assertType(p.type, 'int');
   }
 
-  test_method_parameter_multiple_namedAndRequired() async {
+  test_method_parameter_namedAndRequired() async {
     await resolveTestCode('''
 class A {
-  foo({int p}) => 0;
+  void foo({int p}) {}
 }
 class B {
-  foo(int p) => 0;
+  void foo(int p) {}
 }
 class C implements A, B {
-  foo(p) => 0;
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'C').parameters[0];
     assertTypeDynamic(p.type);
   }
 
-  test_method_parameter_multiple_optionalAndRequired() async {
+  test_method_parameter_required_multiple_combined() async {
     await resolveTestCode('''
 class A {
-  foo(int p) => 0;
+  void foo(int p) {}
 }
 class B {
-  foo([int p]) => 0;
+  void foo(num p) {}
 }
 class C implements A, B {
-  foo(p) => 0;
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertType(p.type, 'num');
+  }
+
+  test_method_parameter_required_multiple_incompatible() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo(double p) {}
+}
+class C implements A, B {
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertTypeDynamic(p.type);
+  }
+
+  test_method_parameter_required_multiple_same() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo(int p) {}
+}
+class C implements A, B {
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'C').parameters[0];
     assertType(p.type, 'int');
   }
 
-  test_method_parameter_single_generic() async {
+  test_method_parameter_required_single_generic() async {
     await resolveTestCode('''
 class A<E> {
-  foo(E p) => 0;
+  void foo(E p) {}
 }
 class C<T> implements A<T> {
-  foo(p) => 0;
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'C').parameters[0];
     assertType(p.type, 'T');
   }
 
-  test_method_return_multiple_different() async {
+  test_method_parameter_requiredAndPositional() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo([int p]) {}
+}
+class C implements A, B {
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'C').parameters[0];
+    assertType(p.type, 'int');
+  }
+
+  test_method_return_multiple_different_combined() async {
+    await resolveTestCode('''
+class A {
+  int foo() => 0;
+}
+class B {
+  num foo() => 0.0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'C');
+    assertType(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_different_dynamic() async {
+    await resolveTestCode('''
+class A {
+  int foo() => 0;
+}
+class B {
+  foo() => 0;
+}
+class C implements A, B {
+  foo() => 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'C');
+    assertType(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_different_generic() async {
+    await resolveTestCode('''
+class A<E> {
+  E foo() => throw 0;
+}
+class B<E> {
+  E foo() => throw 0;
+}
+class C implements A<int>, B<double> {
+  foo() => throw 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'C');
+    assertTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_incompatible() async {
     await resolveTestCode('''
 class A {
   int foo() => 0;
@@ -134,22 +649,6 @@
     assertTypeDynamic(foo.returnType);
   }
 
-  test_method_return_multiple_different_generic() async {
-    await resolveTestCode('''
-class A<E> {
-  E foo() => null;
-}
-class B<E> {
-  E foo() => null;
-}
-class C implements A<int>, B<double> {
-  foo() => null;
-}
-''');
-    var foo = findElement.method('foo', of: 'C');
-    assertTypeDynamic(foo.returnType);
-  }
-
   test_method_return_multiple_different_void() async {
     await resolveTestCode('''
 class A {
@@ -163,23 +662,7 @@
 }
 ''');
     var foo = findElement.method('foo', of: 'C');
-    assertTypeDynamic(foo.returnType);
-  }
-
-  test_method_return_multiple_dynamic() async {
-    await resolveTestCode('''
-class A {
-  int foo() => 0;
-}
-class B {
-  foo() => 0;
-}
-class C implements A, B {
-  foo() => 0;
-}
-''');
-    var foo = findElement.method('foo', of: 'C');
-    assertTypeDynamic(foo.returnType);
+    assertType(foo.returnType, 'int');
   }
 
   test_method_return_multiple_same_generic() async {
@@ -246,15 +729,189 @@
   test_method_return_single_generic() async {
     await resolveTestCode('''
 class A<E> {
-  E foo() => 0;
+  E foo() => throw 0;
 }
 class B<T> extends A<T> {
-  foo() => 0;
+  foo() => throw 0;
 }
 ''');
     var foo = findElement.method('foo', of: 'B');
     assertType(foo.returnType, 'T');
   }
+
+  test_setter_covariant_fromSetter() async {
+    await resolveTestCode('''
+class A {
+  set foo(num _) {}
+}
+class B {
+  set foo(covariant num _) {}
+}
+class C implements A, B {
+  set foo(int x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'C');
+    _assertSetterType(foo, 'int', isCovariant: true);
+  }
+
+  test_setter_multiple_getters_combined() async {
+    await resolveTestCode('''
+class A {
+  num get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'C');
+    _assertSetterType(foo, 'int');
+  }
+
+  test_setter_multiple_getters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  String get foo => throw 0;
+}
+class B {
+  int get foo => throw 0;
+}
+class C implements A, B {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'C');
+    _assertSetterTypeDynamic(foo);
+  }
+
+  test_setter_multiple_gettersSetters_combined() async {
+    await resolveTestCode('''
+class A {
+  set foo(num _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C {
+  String get foo => throw 0;
+}
+class X implements A, B, C {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'X');
+    _assertSetterType(foo, 'num');
+  }
+
+  test_setter_multiple_gettersSetters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  set foo(String _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C {
+  int get foo => throw 0;
+}
+class X implements A, B, C {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'X');
+    _assertSetterTypeDynamic(foo);
+  }
+
+  test_setter_multiple_setters_combined() async {
+    await resolveTestCode('''
+class A {
+  set foo(num _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'C');
+    _assertSetterType(foo, 'num');
+  }
+
+  test_setter_multiple_setters_incompatible() async {
+    await resolveTestCode('''
+class A {
+  set foo(String _) {}
+}
+class B {
+  set foo(int _) {}
+}
+class C implements A, B {
+  set foo(x) {}
+}
+''');
+    var foo = findElement.setter('foo', of: 'C');
+    _assertSetterTypeDynamic(foo);
+  }
+
+  void _assertFieldType(
+    FieldElement field,
+    String type, {
+    bool isCovariant = false,
+  }) {
+    expect(field.isSynthetic, isFalse);
+
+    _assertGetterType(field.getter, type);
+
+    var setter = field.setter;
+    if (setter != null) {
+      _assertSetterType(setter, type, isCovariant: isCovariant);
+    }
+  }
+
+  void _assertFieldTypeDynamic(FieldElement field) {
+    expect(field.isSynthetic, isFalse);
+
+    _assertGetterTypeDynamic(field.getter);
+
+    if (!field.isFinal) {
+      _assertSetterTypeDynamic(field.setter);
+    }
+  }
+
+  void _assertGetterType(PropertyAccessorElement accessor, String expected) {
+    assertType(accessor.returnType, expected);
+  }
+
+  void _assertGetterTypeDynamic(PropertyAccessorElement accessor) {
+    assertTypeDynamic(accessor.returnType);
+  }
+
+  void _assertParameter(
+    ParameterElement element, {
+    String type,
+    bool isCovariant = false,
+  }) {
+    assertType(element.type, type);
+    expect(element.isCovariant, isCovariant);
+  }
+
+  void _assertSetterType(
+    PropertyAccessorElement accessor,
+    String expected, {
+    bool isCovariant = false,
+  }) {
+    var parameter = accessor.parameters.single;
+    assertType(parameter.type, expected);
+    expect(parameter.isCovariant, isCovariant);
+  }
+
+  void _assertSetterTypeDynamic(PropertyAccessorElement accessor) {
+    assertTypeDynamic(accessor.parameters.single.type);
+  }
 }
 
 @reflectiveTest
@@ -268,7 +925,7 @@
   @override
   bool get typeToStringWithNullability => true;
 
-  test_method_parameter_multiple_different_merge() async {
+  test_method_parameter_required_multiple_different_merge() async {
     await resolveTestCode('''
 class A {
   void foo(Object? p) {}
diff --git a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
index 7795b3c..0f6a4a8 100644
--- a/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/instance_member_inference_mixin_test.dart
@@ -2,121 +2,219 @@
 // 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:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
-    defineReflectiveTests(InstanceMemberInferenceMixinDriverResolutionTest);
+    defineReflectiveTests(InstanceMemberInferenceClassTest);
+    defineReflectiveTests(InstanceMemberInferenceClassWithNullSafetyTest);
   });
 }
 
 @reflectiveTest
-class InstanceMemberInferenceMixinDriverResolutionTest
-    extends DriverResolutionTest {
+class InstanceMemberInferenceClassTest extends DriverResolutionTest {
   test_invalid_inheritanceCycle() async {
     await resolveTestCode('''
-mixin A on C {}
-mixin B on A {}
-mixin C on B {}
+class A extends C {}
+class B extends A {}
+class C extends B {}
 ''');
   }
 
-  test_method_parameter_multiple_different() async {
+  test_method_parameter_named_multiple_combined() async {
     await resolveTestCode('''
 class A {
-  foo(int p) => 0;
+  void foo({int p}) {}
 }
 class B {
-  foo(double p) => 0;
+  void foo({num p}) {}
 }
 mixin M on A, B {
-  foo(p) => 0;
+  void foo({p}) {}
+}
+''');
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertType(p.type, 'num');
+  }
+
+  test_method_parameter_named_multiple_incompatible() async {
+    await resolveTestCode('''
+class A {
+  void foo({int p}) {}
+}
+class B {
+  void foo({int q}) {}
+}
+mixin M on A, B {
+  void foo({p}) {}
 }
 ''');
     var p = findElement.method('foo', of: 'M').parameters[0];
     assertTypeDynamic(p.type);
   }
 
-  test_method_parameter_multiple_named_different() async {
+  test_method_parameter_named_multiple_same() async {
     await resolveTestCode('''
 class A {
-  foo({int p}) => 0;
+  void foo({int p}) {}
 }
 class B {
-  foo({int q}) => 0;
+  void foo({int p}) {}
 }
 mixin M on A, B {
-  foo({p}) => 0;
-}
-''');
-    var p = findElement.method('foo', of: 'M').parameters[0];
-    assertTypeDynamic(p.type);
-  }
-
-  test_method_parameter_multiple_named_same() async {
-    await resolveTestCode('''
-class A {
-  foo({int p}) => 0;
-}
-class B {
-  foo({int p}) => 0;
-}
-mixin M on A, B {
-  foo({p}) => 0;
+  void foo({p}) {}
 }
 ''');
     var p = findElement.method('foo', of: 'M').parameters[0];
     assertType(p.type, 'int');
   }
 
-  test_method_parameter_multiple_namedAndRequired() async {
+  test_method_parameter_namedAndRequired() async {
     await resolveTestCode('''
 class A {
-  foo({int p}) => 0;
+  void foo({int p}) {}
 }
 class B {
-  foo(int p) => 0;
+  void foo(int p) {}
 }
 mixin M on A, B {
-  foo(p) => 0;
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'M').parameters[0];
     assertTypeDynamic(p.type);
   }
 
-  test_method_parameter_multiple_optionalAndRequired() async {
+  test_method_parameter_required_multiple_combined() async {
     await resolveTestCode('''
 class A {
-  foo(int p) => 0;
+  void foo(int p) {}
 }
 class B {
-  foo([int p]) => 0;
+  void foo(num p) {}
 }
 mixin M on A, B {
-  foo(p) => 0;
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertType(p.type, 'num');
+  }
+
+  test_method_parameter_required_multiple_incompatible() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo(double p) {}
+}
+mixin M on A, B {
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertTypeDynamic(p.type);
+  }
+
+  test_method_parameter_required_multiple_same() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo(int p) {}
+}
+mixin M on A, B {
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'M').parameters[0];
     assertType(p.type, 'int');
   }
 
-  test_method_parameter_single_generic() async {
+  test_method_parameter_required_single_generic() async {
     await resolveTestCode('''
 class A<E> {
-  foo(E p) => 0;
+  void foo(E p) {}
 }
 mixin M<T> on A<T> {
-  foo(p) => 0;
+  void foo(p) {}
 }
 ''');
     var p = findElement.method('foo', of: 'M').parameters[0];
     assertType(p.type, 'T');
   }
 
-  test_method_return_multiple_different() async {
+  test_method_parameter_requiredAndPositional() async {
+    await resolveTestCode('''
+class A {
+  void foo(int p) {}
+}
+class B {
+  void foo([int p]) {}
+}
+mixin M on A, B {
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertType(p.type, 'int');
+  }
+
+  test_method_return_multiple_different_combined() async {
+    await resolveTestCode('''
+class A {
+  int foo() => 0;
+}
+class B {
+  num foo() => 0.0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'M');
+    assertType(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_different_dynamic() async {
+    await resolveTestCode('''
+class A {
+  int foo() => 0;
+}
+class B {
+  foo() => 0;
+}
+mixin M on A, B {
+  foo() => 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'M');
+    assertType(foo.returnType, 'int');
+  }
+
+  test_method_return_multiple_different_generic() async {
+    await resolveTestCode('''
+class A<E> {
+  E foo() => throw 0;
+}
+class B<E> {
+  E foo() => throw 0;
+}
+mixin M on A<int>, B<double> {
+  foo() => throw 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'M');
+    assertTypeDynamic(foo.returnType);
+  }
+
+  test_method_return_multiple_different_incompatible() async {
     await resolveTestCode('''
 class A {
   int foo() => 0;
@@ -132,22 +230,6 @@
     assertTypeDynamic(foo.returnType);
   }
 
-  test_method_return_multiple_different_generic() async {
-    await resolveTestCode('''
-class A<E> {
-  E foo() => null;
-}
-class B<E> {
-  E foo() => null;
-}
-mixin M on A<int>, B<double> {
-  foo() => null;
-}
-''');
-    var foo = findElement.method('foo', of: 'M');
-    assertTypeDynamic(foo.returnType);
-  }
-
   test_method_return_multiple_different_void() async {
     await resolveTestCode('''
 class A {
@@ -161,23 +243,7 @@
 }
 ''');
     var foo = findElement.method('foo', of: 'M');
-    assertTypeDynamic(foo.returnType);
-  }
-
-  test_method_return_multiple_dynamic() async {
-    await resolveTestCode('''
-class A {
-  int foo() => 0;
-}
-class B {
-  foo() => 0;
-}
-mixin M on A, B {
-  foo() => 0;
-}
-''');
-    var foo = findElement.method('foo', of: 'M');
-    assertTypeDynamic(foo.returnType);
+    assertType(foo.returnType, 'int');
   }
 
   test_method_return_multiple_same_generic() async {
@@ -233,24 +299,72 @@
 class A {
   int foo() => 0;
 }
-mixin M on A {
+class B extends A {
   foo() => 0;
 }
 ''');
-    var foo = findElement.method('foo', of: 'M');
+    var foo = findElement.method('foo', of: 'B');
     assertType(foo.returnType, 'int');
   }
 
   test_method_return_single_generic() async {
     await resolveTestCode('''
 class A<E> {
-  E foo() => 0;
+  E foo() => throw 0;
 }
-mixin M<T> on A<T> {
-  foo() => 0;
+class B<T> extends A<T> {
+  foo() => throw 0;
+}
+''');
+    var foo = findElement.method('foo', of: 'B');
+    assertType(foo.returnType, 'T');
+  }
+}
+
+@reflectiveTest
+class InstanceMemberInferenceClassWithNullSafetyTest
+    extends InstanceMemberInferenceClassTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..contextFeatures = FeatureSet.forTesting(
+        sdkVersion: '2.3.0', additionalFeatures: [Feature.non_nullable]);
+
+  @override
+  bool get typeToStringWithNullability => true;
+
+  test_method_parameter_required_multiple_different_merge() async {
+    await resolveTestCode('''
+class A {
+  void foo(Object? p) {}
+}
+
+class B {
+  void foo(dynamic p) {}
+}
+
+mixin M on A, B {
+  void foo(p) {}
+}
+''');
+    var p = findElement.method('foo', of: 'M').parameters[0];
+    assertType(p.type, 'Object?');
+  }
+
+  test_method_return_multiple_different_merge() async {
+    await resolveTestCode('''
+class A {
+  Object? foo() => throw 0;
+}
+
+class B {
+  dynamic foo() => throw 0;
+}
+
+mixin M on A, B {
+  foo() => throw 0;
 }
 ''');
     var foo = findElement.method('foo', of: 'M');
-    assertType(foo.returnType, 'T');
+    assertType(foo.returnType, 'Object?');
   }
 }
diff --git a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
index 487f00f..e1ba156 100644
--- a/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/metadata_test.dart
@@ -470,7 +470,7 @@
   void _assertIntValue(ElementAnnotation annotation, int intValue) {
     _assertConstantValue(
       annotation.computeConstantValue(),
-      type: 'int*',
+      type: 'int',
       intValue: intValue,
     );
   }
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
index 5fbd485..2c08363 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/function_expression_test.dart
@@ -429,6 +429,38 @@
     _assertReturnType('(a) {', 'int');
   }
 
+  test_contextFunctionType_nonNullify_returnType_takeActual() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+
+void foo(int Function() x) {}
+''');
+    await assertNoErrorsInCode('''
+import 'a.dart';
+
+void test(int? a) {
+  foo(() => a);
+}
+''');
+    _assertReturnType('() => a', 'int?');
+  }
+
+  test_contextFunctionType_nonNullify_returnType_takeContext() async {
+    newFile('/test/lib/a.dart', content: r'''
+// @dart = 2.7
+
+void foo(int Function() x) {}
+''');
+    await assertNoErrorsInCode('''
+import 'a.dart';
+
+void test(dynamic a) {
+  foo(() => a);
+}
+''');
+    _assertReturnType('() => a', 'int');
+  }
+
   test_contextFunctionType_returnType_async_blockBody_objectQ() async {
     await assertNoErrorsInCode('''
 T foo<T>() => throw 0;
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/local_variable_test.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/local_variable_test.dart
new file mode 100644
index 0000000..48ebf3e
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/local_variable_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 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../constant/potentially_constant_test.dart';
+import '../driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(LocalVariableTest);
+    defineReflectiveTests(LocalVariableWithNullSafetyTest);
+  });
+}
+
+@reflectiveTest
+class LocalVariableTest extends DriverResolutionTest {
+  test_int() async {
+    await resolveTestCode('''
+void f() {
+  var v = 0;
+  v;
+}
+''');
+    _assertTypeOfV('int');
+  }
+
+  test_null() async {
+    await resolveTestCode('''
+void f() {
+  var v = null;
+  v;
+}
+''');
+    _assertTypeOfV('dynamic');
+  }
+
+  void _assertTypeOfV(String expected) {
+    assertType(findElement.localVar('v').type, expected);
+    assertType(findNode.simple('v;'), expected);
+  }
+}
+
+@reflectiveTest
+class LocalVariableWithNullSafetyTest extends LocalVariableTest
+    with WithNullSafetyMixin {
+  test_Never() async {
+    await resolveTestCode('''
+void f(Never a) {
+  var v = a;
+  v;
+}
+''');
+    _assertTypeOfV('Never');
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
index 8262958..a998d76 100644
--- a/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
+++ b/pkg/analyzer/test/src/dart/resolution/type_inference/test_all.dart
@@ -10,6 +10,7 @@
 import 'extension_methods_test.dart' as extension_methods;
 import 'function_expression_test.dart' as function_expression;
 import 'list_literal_test.dart' as list_literal;
+import 'local_variable_test.dart' as local_variable;
 import 'logical_boolean_expressions_test.dart' as logical_boolean_expressions;
 import 'map_literal_test.dart' as map_literal;
 import 'set_literal_test.dart' as set_literal;
@@ -26,6 +27,7 @@
     extension_methods.main();
     function_expression.main();
     list_literal.main();
+    local_variable.main();
     logical_boolean_expressions.main();
     map_literal.main();
     set_literal.main();
diff --git a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
index bde5cd0..08d604b 100644
--- a/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/conflicting_static_and_instance_test.dart
@@ -363,6 +363,26 @@
     ]);
   }
 
+  test_inSuper_implicitObject_method_getter() async {
+    await assertErrorsInCode(r'''
+class A {
+  static String runtimeType() => 'x';
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 26, 11),
+    ]);
+  }
+
+  test_inSuper_implicitObject_method_method() async {
+    await assertErrorsInCode(r'''
+class A {
+  static String toString() => 'x';
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 26, 8),
+    ]);
+  }
+
   test_inSuper_method_getter() async {
     await assertErrorsInCode(r'''
 class A {
@@ -431,6 +451,16 @@
 
 @reflectiveTest
 class ConflictingStaticAndInstanceEnumTest extends DriverResolutionTest {
+  test_hashCode() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, hashCode, b
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 8),
+    ]);
+  }
+
   test_index() async {
     await assertErrorsInCode(r'''
 enum E {
@@ -441,6 +471,26 @@
     ]);
   }
 
+  test_noSuchMethod() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, noSuchMethod, b
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 12),
+    ]);
+  }
+
+  test_runtimeType() async {
+    await assertErrorsInCode(r'''
+enum E {
+  a, runtimeType, b
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 14, 11),
+    ]);
+  }
+
   test_toString() async {
     await assertErrorsInCode(r'''
 enum E {
@@ -493,6 +543,26 @@
     ]);
   }
 
+  test_inConstraint_implicitObject_method_getter() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static String runtimeType() => 'x';
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 26, 11),
+    ]);
+  }
+
+  test_inConstraint_implicitObject_method_method() async {
+    await assertErrorsInCode(r'''
+mixin M {
+  static String toString() => 'x';
+}
+''', [
+      error(CompileTimeErrorCode.CONFLICTING_STATIC_AND_INSTANCE, 26, 8),
+    ]);
+  }
+
   test_inConstraint_method_getter() async {
     await assertErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
index 1d72da3..c138d36 100644
--- a/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_constructor_with_mixin_with_field_test.dart
@@ -15,7 +15,46 @@
 
 @reflectiveTest
 class ConstConstructorWithMixinWithFieldTest extends DriverResolutionTest {
-  test_class_instance() async {
+  test_class_instance_final() async {
+    await assertErrorsInCode('''
+class A {
+  final a = 0;
+}
+
+class B extends Object with A {
+  const B();
+}
+''', [
+      error(
+          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD, 68, 1),
+    ]);
+  }
+
+  test_class_instance_getter() async {
+    await assertNoErrorsInCode('''
+class A {
+  int get a => 7;
+}
+
+class B extends Object with A {
+  const B();
+}
+''');
+  }
+
+  test_class_instance_setter() async {
+    await assertNoErrorsInCode('''
+class A {
+  set a(int x) {}
+}
+
+class B extends Object with A {
+  const B();
+}
+''');
+  }
+
+  test_class_instanceField() async {
     await assertErrorsInCode('''
 class A {
   var a;
@@ -31,18 +70,20 @@
     ]);
   }
 
-  test_class_instance_final() async {
+  test_class_multipleInstanceFields() async {
     await assertErrorsInCode('''
 class A {
-  final a = 0;
+  var a;
+  var b;
 }
 
 class B extends Object with A {
   const B();
 }
 ''', [
+      error(CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_NON_FINAL_FIELD, 71, 1),
       error(
-          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELD, 68, 1),
+          CompileTimeErrorCode.CONST_CONSTRUCTOR_WITH_MIXIN_WITH_FIELDS, 71, 1),
     ]);
   }
 
diff --git a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
index 60527d0..c688c88 100644
--- a/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/const_eval_throws_exception_test.dart
@@ -9,11 +9,13 @@
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConstEvalThrowsExceptionTest);
+    defineReflectiveTests(ConstEvalThrowsExceptionWithNullSafetyTest);
     defineReflectiveTests(ConstEvalThrowsExceptionWithConstantUpdateTest);
   });
 }
@@ -82,7 +84,7 @@
     expect(otherFileResult.errors, isEmpty);
   }
 
-  test_default_constructor_arg_empty_map_importAnalyzedAfter() async {
+  test_default_constructor_arg_empty_map_import() async {
     newFile('/test/lib/other.dart', content: '''
 class C {
   final Map<String, int> m;
@@ -101,29 +103,15 @@
     ]);
     var otherFileResult =
         await resolveFile(convertPath('/test/lib/other.dart'));
-    expect(otherFileResult.errors, isEmpty);
-  }
-
-  test_default_constructor_arg_empty_map_importAnalyzedBefore() async {
-    newFile('/test/lib/other.dart', content: '''
-class C {
-  final Map<String, int> m;
-  const C({this.m = const <String, int>{}})
-    : assert(m != null);
-}
-''');
-    await assertErrorsInCode('''
-import 'other.dart';
-
-main() {
-  var c = const C();
-}
-''', [
-      error(HintCode.UNUSED_LOCAL_VARIABLE, 37, 1),
-    ]);
-    var otherFileResult =
-        await resolveFile(convertPath('/test/lib/other.dart'));
-    expect(otherFileResult.errors, isEmpty);
+    assertErrorsInList(
+      otherFileResult.errors,
+      expectedErrorsByNullability(
+        nullable: [
+          error(HintCode.UNNECESSARY_NULL_COMPARISON_TRUE, 97, 7),
+        ],
+        legacy: [],
+      ),
+    );
   }
 
   test_finalAlreadySet_initializer() async {
@@ -356,3 +344,43 @@
 ''');
   }
 }
+
+@reflectiveTest
+class ConstEvalThrowsExceptionWithNullSafetyTest
+    extends ConstEvalThrowsExceptionTest with WithNullSafetyMixin {
+  test_asExpression_typeParameter() async {
+    await assertErrorsInCode('''
+class C<T> {
+  final t;
+  const C(dynamic x) : t = x as T;
+}
+
+main() {
+  const C<int>(0);
+  const C<int>('foo');
+  const C<int>(null);
+}
+''', [
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 92, 19),
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 115, 18),
+    ]);
+  }
+
+  test_asExpression_typeParameter_nested() async {
+    await assertErrorsInCode('''
+class C<T> {
+  final t;
+  const C(dynamic x) : t = x as List<T>;
+}
+
+main() {
+  const C<int>(<int>[]);
+  const C<int>(<num>[]);
+  const C<int>(null);
+}
+''', [
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 104, 21),
+      error(CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION, 129, 18),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart
new file mode 100644
index 0000000..6368edb
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/field_initializer_factory_constructor_test.dart
@@ -0,0 +1,43 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FieldInitializerFactoryConstructorTest);
+  });
+}
+
+@reflectiveTest
+class FieldInitializerFactoryConstructorTest extends DriverResolutionTest {
+  test_fieldFormalParameter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  factory A(this.x) => throw 0;
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, 31, 6),
+    ]);
+  }
+
+  test_functionTypedParameter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int Function() x;
+  factory A(int this.x());
+}
+''', [
+      // TODO(srawlins): Only report one error. Theoretically change Fasta to
+      // report "Field initiailizer in factory constructor" as a parse error.
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR, 42, 12),
+      error(ParserErrorCode.MISSING_FUNCTION_BODY, 55, 1),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_outside_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_outside_constructor_test.dart
new file mode 100644
index 0000000..8c5a955
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/field_initializer_outside_constructor_test.dart
@@ -0,0 +1,84 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FieldInitializerOutsideConstructorTest);
+  });
+}
+
+@reflectiveTest
+class FieldInitializerOutsideConstructorTest extends DriverResolutionTest {
+  test_closure() async {
+    await assertErrorsInCode(r'''
+class A {
+  dynamic field = ({this.field}) {};
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 30, 10),
+    ]);
+  }
+
+  test_defaultParameter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  m([this.x]) {}
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 24, 6),
+    ]);
+  }
+
+  test_functionTypedFieldFormalParameter() async {
+    // TODO(srawlins) Fix the duplicate error messages.
+    await assertErrorsInCode(r'''
+class A {
+  int Function() x;
+  m(int this.x()) {}
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 34, 12),
+      error(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 38, 4),
+    ]);
+  }
+
+  test_inFunctionTypedParameter() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  A(int p(this.x));
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 29, 6),
+    ]);
+  }
+
+  test_method() async {
+    // TODO(brianwilkerson) Fix the duplicate error messages.
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  m(this.x) {}
+}
+''', [
+      error(ParserErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 23, 4),
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 23, 6),
+    ]);
+  }
+
+  test_topLevelFunction() async {
+    await assertErrorsInCode(r'''
+f(this.x(y)) {}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR, 2, 9),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/field_initializer_redirecting_constructor_test.dart b/pkg/analyzer/test/src/diagnostics/field_initializer_redirecting_constructor_test.dart
new file mode 100644
index 0000000..9a11dde
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/field_initializer_redirecting_constructor_test.dart
@@ -0,0 +1,56 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(FieldInitializerRedirectingConstructorTest);
+  });
+}
+
+@reflectiveTest
+class FieldInitializerRedirectingConstructorTest extends DriverResolutionTest {
+  test_afterRedirection() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  A.named() {}
+  A() : this.named(), x = 42;
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 56,
+          6),
+    ]);
+  }
+
+  test_beforeRedirection() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  A.named() {}
+  A() : x = 42, this.named();
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 42,
+          6),
+    ]);
+  }
+
+  test_redirectionOnly() async {
+    await assertErrorsInCode(r'''
+class A {
+  int x;
+  A.named() {}
+  A(this.x) : this.named();
+}
+''', [
+      error(CompileTimeErrorCode.FIELD_INITIALIZER_REDIRECTING_CONSTRUCTOR, 38,
+          6),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/implements_deferred_class_test.dart b/pkg/analyzer/test/src/diagnostics/implements_deferred_class_test.dart
new file mode 100644
index 0000000..771fd00
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/implements_deferred_class_test.dart
@@ -0,0 +1,47 @@
+// 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:analyzer/src/error/codes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ImplementsDeferredClassTest);
+  });
+}
+
+@reflectiveTest
+class ImplementsDeferredClassTest extends DriverResolutionTest {
+  test_implements() async {
+    newFile('/test/lib/lib1.dart', content: '''
+library lib1;
+class A {}
+''');
+    await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class B implements a.A {}
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS, 67, 3),
+    ]);
+  }
+
+  test_mixinApplication() async {
+    newFile('/test/lib/lib1.dart', content: '''
+library lib1;
+class A {}
+''');
+    await assertErrorsInCode('''
+library root;
+import 'lib1.dart' deferred as a;
+class B {}
+class M {}
+class C = B with M implements a.A;
+''', [
+      error(CompileTimeErrorCode.IMPLEMENTS_DEFERRED_CLASS, 100, 3),
+    ]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart b/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart
index b092ae2..9dee843 100644
--- a/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/inconsistent_case_expression_types_test.dart
@@ -5,11 +5,13 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InconsistentCaseExpressionTypesTest);
+    defineReflectiveTests(InconsistentCaseExpressionTypesWithNullSafetyTest);
   });
 }
 
@@ -87,3 +89,27 @@
     ]);
   }
 }
+
+@reflectiveTest
+class InconsistentCaseExpressionTypesWithNullSafetyTest
+    extends DriverResolutionTest with WithNullSafetyMixin {
+  test_int_none_legacy() async {
+    newFile('/test/lib/a.dart', content: r'''
+const a = 0;
+''');
+
+    await assertNoErrorsInCode(r'''
+// @dart = 2.8
+import 'a.dart';
+
+void f(int e) {
+  switch (e) {
+    case a:
+      break;
+    case 1:
+      break;
+  }
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart
index 59567a3..ef14538a 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_constant_test.dart
@@ -5,11 +5,13 @@
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
+import '../dart/constant/potentially_constant_test.dart';
 import '../dart/resolution/driver_resolution.dart';
 
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(InvalidConstantTest);
+    defineReflectiveTests(InvalidConstantWithNullSafetyTest);
   });
 }
 
@@ -38,12 +40,12 @@
   test_in_initializer_field() async {
     await assertErrorsInCode(r'''
 class A {
-  static int C;
+  static int C = 0;
   final int a;
   const A() : a = C;
 }
 ''', [
-      error(CompileTimeErrorCode.INVALID_CONSTANT, 59, 1),
+      error(CompileTimeErrorCode.INVALID_CONSTANT, 63, 1),
     ]);
   }
 
@@ -160,3 +162,16 @@
     ]);
   }
 }
+
+@reflectiveTest
+class InvalidConstantWithNullSafetyTest extends InvalidConstantTest
+    with WithNullSafetyMixin {
+  test_in_initializer_field_as() async {
+    await assertNoErrorsInCode('''
+class C<T> {
+  final l;
+  const C.test(dynamic x) : l = x as List<T>;
+}
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/mixin_references_super_test.dart b/pkg/analyzer/test/src/diagnostics/mixin_references_super_test.dart
deleted file mode 100644
index 5e6558e..0000000
--- a/pkg/analyzer/test/src/diagnostics/mixin_references_super_test.dart
+++ /dev/null
@@ -1,37 +0,0 @@
-// 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:analyzer/src/error/codes.dart';
-import 'package:test_reflective_loader/test_reflective_loader.dart';
-
-import '../dart/resolution/driver_resolution.dart';
-
-main() {
-  defineReflectiveSuite(() {
-    defineReflectiveTests(MixinReferencesSuperTest);
-  });
-}
-
-@reflectiveTest
-class MixinReferencesSuperTest extends DriverResolutionTest {
-  test_mixin_references_super() async {
-    await assertErrorsInCode(r'''
-class A {
-  toString() => super.toString();
-}
-class B extends Object with A {}
-''', [
-      error(CompileTimeErrorCode.MIXIN_REFERENCES_SUPER, 74, 1),
-    ]);
-  }
-
-  test_mixin_unconstrained_references_super() async {
-    await assertNoErrorsInCode(r'''
-mixin A {
-  toString() => super.toString();
-}
-class B extends Object with A {}
-''');
-  }
-}
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 615827a..2b75e35 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -139,19 +139,25 @@
     as field_in_struct_with_initializer;
 import 'field_initialized_by_multiple_initializers_test.dart'
     as field_initialized_by_multiple_initializers;
+import 'final_initialized_in_delcaration_and_constructor_test.dart'
+    as final_initialized_in_declaration_and_constructor;
 import 'field_initialized_in_initializer_and_declaration_test.dart'
     as field_initialized_in_initializer_and_declaration;
 import 'field_initialized_in_parameter_and_initializer_test.dart'
     as field_initialized_in_parameter_and_initializer;
+import 'final_initialized_multiple_times_test.dart'
+    as final_initialized_multiple_times;
+import 'field_initializer_factory_constructor_test.dart'
+    as field_initializer_factory_constructor;
 import 'field_initializer_in_struct_test.dart' as field_initializer_in_struct;
 import 'field_initializer_not_assignable_test.dart'
     as field_initializer_not_assignable;
+import 'field_initializer_outside_constructor_test.dart'
+    as field_initializer_outside_constructor;
+import 'field_initializer_redirecting_constructor_test.dart'
+    as field_initializer_redirecting_constructor;
 import 'field_initializing_formal_not_assignable_test.dart'
     as field_initializing_formal_not_assignable;
-import 'final_initialized_in_delcaration_and_constructor_test.dart'
-    as final_initialized_in_declaration_and_constructor;
-import 'final_initialized_multiple_times_test.dart'
-    as final_initialized_multiple_times;
 import 'final_not_initialized_constructor_test.dart'
     as final_not_initialized_constructor;
 import 'final_not_initialized_test.dart' as final_not_initialized;
@@ -167,6 +173,7 @@
 import 'if_element_condition_from_deferred_library_test.dart'
     as if_element_condition_from_deferred_library;
 import 'illegal_async_return_type_test.dart' as illegal_async_return_type;
+import 'implements_deferred_class_test.dart' as implements_deferred_class;
 import 'implements_disallowed_class_test.dart' as implements_disallowed_class;
 import 'implements_non_class_test.dart' as implements_non_class;
 import 'implements_super_class_test.dart' as implements_super_class;
@@ -293,7 +300,6 @@
 import 'mixin_of_disallowed_class_test.dart' as mixin_of_disallowed_class;
 import 'mixin_of_non_class_test.dart' as mixin_of_non_class;
 import 'mixin_on_sealed_class_test.dart' as mixin_on_sealed_class;
-import 'mixin_references_super_test.dart' as mixin_references_super;
 import 'mixin_super_class_constraint_non_interface_test.dart'
     as mixin_super_class_constraint_non_interface;
 import 'mixin_with_non_class_superclass_test.dart'
@@ -619,13 +625,16 @@
     extra_positional_arguments.main();
     field_in_struct_with_initializer.main();
     field_initialized_by_multiple_initializers.main();
+    final_initialized_in_declaration_and_constructor.main();
     field_initialized_in_initializer_and_declaration.main();
     field_initialized_in_parameter_and_initializer.main();
+    final_initialized_multiple_times.main();
+    field_initializer_factory_constructor.main();
     field_initializer_in_struct.main();
     field_initializer_not_assignable.main();
+    field_initializer_outside_constructor.main();
+    field_initializer_redirecting_constructor.main();
     field_initializing_formal_not_assignable.main();
-    final_initialized_in_declaration_and_constructor.main();
-    final_initialized_multiple_times.main();
     final_not_initialized_constructor.main();
     final_not_initialized.main();
     for_in_of_invalid_element_type.main();
@@ -636,16 +645,17 @@
     getter_not_subtype_setter_types.main();
     if_element_condition_from_deferred_library.main();
     illegal_async_return_type.main();
+    implements_deferred_class.main();
     implements_disallowed_class.main();
     implements_non_class.main();
     implements_super_class.main();
     implicit_this_reference_in_initializer.main();
     import_deferred_library_with_load_function.main();
     import_duplicated_library_named.main();
+    import_of_non_library.main();
     inconsistent_case_expression_types.main();
     inconsistent_inheritance_getter_and_method.main();
     inconsistent_inheritance.main();
-    import_of_non_library.main();
     inference_failure_on_collection_literal.main();
     inference_failure_on_function_return_type.main();
     inference_failure_on_uninitialized_variable.main();
@@ -721,7 +731,6 @@
     mixin_of_disallowed_class.main();
     mixin_of_non_class.main();
     mixin_on_sealed_class.main();
-    mixin_references_super.main();
     mixin_super_class_constraint_non_interface.main();
     mixin_with_non_class_superclass.main();
     must_be_a_native_function_type.main();
diff --git a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
index 6e9bc88..20615c6 100644
--- a/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/undefined_method_test.dart
@@ -179,6 +179,25 @@
 ''');
   }
 
+  test_static_mixinApplication_superConstructorIsFactory() async {
+    await assertErrorsInCode(r'''
+mixin M {}
+
+class A {
+  A();
+  factory A.named() = A;
+}
+
+class B = A with M;
+
+void main() {
+  B.named();
+}
+''', [
+      error(StaticTypeWarningCode.UNDEFINED_METHOD, 96, 5),
+    ]);
+  }
+
   test_withExtension() async {
     await assertErrorsInCode(r'''
 class C {}
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index 6cd8490..f179e21 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -1210,7 +1210,7 @@
       DeclarationKind.FIELD,
       isConst: true,
       isStatic: true,
-      relevanceTags: ['dart:core::int'],
+      relevanceTags: ['dart:core::int', 'isConst'],
       returnType: 'int',
     );
     _assertDeclaration(
@@ -2419,7 +2419,7 @@
       'd',
       DeclarationKind.VARIABLE,
       isConst: true,
-      relevanceTags: ['dart:core::int'],
+      relevanceTags: ['dart:core::int', 'isConst'],
       returnType: '',
     );
     _assertDeclaration(
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index 74c3543..6513033 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -280,6 +280,30 @@
 ''');
   }
 
+  test_class_alias_with_const_constructors() async {
+    addLibrarySource('/a.dart', '''
+class Base {
+  const Base._priv();
+  const Base();
+  const Base.named();
+}
+''');
+    var library = await checkLibrary('''
+import "a.dart";
+class M {}
+class MixinApp = Base with M;
+''');
+    checkElementText(library, r'''
+import 'a.dart';
+class M {
+}
+class alias MixinApp extends Base with M {
+  synthetic const MixinApp() = Base;
+  synthetic const MixinApp.named() = Base.named;
+}
+''');
+  }
+
   test_class_alias_with_forwarding_constructors() async {
     addLibrarySource('/a.dart', '''
 class Base {
@@ -308,8 +332,6 @@
   synthetic MixinApp.requiredArg(dynamic x) = Base.requiredArg;
   synthetic MixinApp.positionalArg([bool x = true]) = Base.positionalArg;
   synthetic MixinApp.namedArg({int x: 42}) = Base.namedArg;
-  synthetic MixinApp.fact() = Base.fact;
-  synthetic MixinApp.fact2() = Base.fact2;
 }
 ''');
   }
@@ -1856,33 +1878,33 @@
 class B/*codeOffset=12, codeLength=10*/ {
 }
 class alias Raw/*codeOffset=28, codeLength=29*/ extends Object with A, B {
-  synthetic Raw() = Object;
+  synthetic const Raw() = Object;
 }
 /// Comment 1.
 /// Comment 2.
 class alias HasDocComment/*codeOffset=59, codeLength=69*/ extends Object with A, B {
-  synthetic HasDocComment() = Object;
+  synthetic const HasDocComment() = Object;
 }
 @Object()
 class alias HasAnnotation/*codeOffset=130, codeLength=49*/ extends Object with A, B {
-  synthetic HasAnnotation() = Object;
+  synthetic const HasAnnotation() = Object;
 }
 /// Comment 1.
 /// Comment 2.
 @Object()
 class alias AnnotationThenComment/*codeOffset=181, codeLength=87*/ extends Object with A, B {
-  synthetic AnnotationThenComment() = Object;
+  synthetic const AnnotationThenComment() = Object;
 }
 /// Comment 1.
 /// Comment 2.
 @Object()
 class alias CommentThenAnnotation/*codeOffset=270, codeLength=87*/ extends Object with A, B {
-  synthetic CommentThenAnnotation() = Object;
+  synthetic const CommentThenAnnotation() = Object;
 }
 /// Comment 2.
 @Object()
 class alias CommentAroundAnnotation/*codeOffset=374, codeLength=74*/ extends Object with A, B {
-  synthetic CommentAroundAnnotation() = Object;
+  synthetic const CommentAroundAnnotation() = Object;
 }
 ''',
         withCodeRanges: true,
@@ -3974,6 +3996,24 @@
 ''');
   }
 
+  test_const_topLevel_nullSafe_nullAware_propertyAccess() async {
+    featureSet = enableNnbd;
+    var library = await checkLibrary(r'''
+const String? a = '';
+
+const List<int?> b = [
+  a?.length,
+];
+''');
+    // TODO(scheglov) include fully resolved AST, when types with suffixes
+    checkElementText(library, r'''
+const String a = '';
+const List<int> b = [
+        a/*location: test.dart;a?*/.
+        length/*location: dart:core;String;length?*/];
+''');
+  }
+
   test_const_topLevel_parenthesis() async {
     var library = await checkLibrary(r'''
 const int v1 = (1 + 2) * 3;
@@ -5560,7 +5600,7 @@
   dynamic foo() {}
 }
 class alias D extends Object with M {
-  synthetic D() = Object;
+  synthetic const D() = Object;
 }
 ''');
   }
diff --git a/pkg/analyzer/test/src/summary/top_level_inference_test.dart b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
index 3daa825..954c0ac 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -1707,7 +1707,7 @@
   dynamic get x;
 }
 class C implements A, B {
-  dynamic get x {}
+  int get x {}
 }
 ''');
   }
@@ -1850,8 +1850,8 @@
   void set x(String _);
 }
 class C implements A, B {
-  synthetic dynamic x;
-  void set x(dynamic _);
+  synthetic String x;
+  void set x(String _);
 }
 ''',
         withSyntheticFields: true);
@@ -2121,7 +2121,7 @@
   void m(E a) {}
 }
 class C extends A<int> implements B<double> {
-  m(a) {}
+  void m(a) {}
 }
 ''');
     checkElementText(library, r'''
@@ -2146,7 +2146,7 @@
   void m(String a) {}
 }
 class C extends A implements B {
-  m(a) {}
+  void m(a) {}
 }
 ''');
     checkElementText(library, r'''
@@ -2174,7 +2174,6 @@
   m(a) {}
 }
 ''');
-    // TODO(scheglov) test for inference failure error
     checkElementText(library, r'''
 class A<K, V> {
   V m(K a) {}
@@ -2183,7 +2182,7 @@
   T m(int a) {}
 }
 class C extends A<int, String> implements B<double> {
-  dynamic m(int a) {}
+  dynamic m(dynamic a/*error: overrideConflictParameterType*/) {}
 }
 ''');
   }
@@ -2220,7 +2219,7 @@
   void m(int a) {}
 }
 class B extends A {
-  m(a, b) {}
+  void m(a, b) {}
 }
 ''');
     // It's an error to add a new required parameter, but it is not a
diff --git a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
index 2da885b..fde389d 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -352,34 +352,6 @@
     _assertTypeStr(y.initializer.returnType, 'dynamic Function()');
   }
 
-  test_conflictsCanHappen() async {
-    await checkFileElement('''
-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 /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/a => null;
-}
-
-// Still ambiguous
-class C2 implements B, A {
-  get /*error:INVALID_OVERRIDE,error:INVALID_OVERRIDE*/a => null;
-}
-''');
-  }
-
   test_conflictsCanHappen2() async {
     await checkFileElement('''
 class I1 {
diff --git a/pkg/analyzer/tool/diagnostics/diagnostics.md b/pkg/analyzer/tool/diagnostics/diagnostics.md
index e4481c9..2d947ba 100644
--- a/pkg/analyzer/tool/diagnostics/diagnostics.md
+++ b/pkg/analyzer/tool/diagnostics/diagnostics.md
@@ -1379,7 +1379,7 @@
 
 ### default_list_constructor
 
-_Calling the default 'List' constructor causes an error._
+_The default 'List' constructor is not available when null safety is enabled._
 
 #### Description
 
diff --git a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
index 08c094e..db06369 100644
--- a/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
+++ b/pkg/analyzer_plugin/lib/utilities/completion/relevance.dart
@@ -102,4 +102,8 @@
   /// The relevance boost used when suggesting an enum constant from an
   /// available declaration set.
   static const int availableEnumConstant = 100;
+
+  /// The relevance boost used when suggesting a constant value / constructor
+  /// from an available declaration set in a constant context.
+  static const int constInConstantContext = 200;
 }
diff --git a/pkg/compiler/lib/src/common/names.dart b/pkg/compiler/lib/src/common/names.dart
index 21975bf..6d9b83a 100644
--- a/pkg/compiler/lib/src/common/names.dart
+++ b/pkg/compiler/lib/src/common/names.dart
@@ -256,6 +256,10 @@
   /// The URI for 'package:js'.
   static final Uri package_js = new Uri(scheme: 'package', path: 'js/js.dart');
 
+  /// The URI for 'dart:_js_annotations'.
+  static final Uri dart__js_annotations =
+      Uri(scheme: 'dart', path: '_js_annotations');
+
   /// The URI for 'package:meta/dart2js.dart'.
   static final Uri package_meta_dart2js =
       new Uri(scheme: 'package', path: 'meta/dart2js.dart');
diff --git a/pkg/compiler/lib/src/common_elements.dart b/pkg/compiler/lib/src/common_elements.dart
index 9bbfd02..9090b5d 100644
--- a/pkg/compiler/lib/src/common_elements.dart
+++ b/pkg/compiler/lib/src/common_elements.dart
@@ -15,7 +15,6 @@
 import 'js_backend/native_data.dart' show NativeBasicData;
 import 'js_model/locals.dart';
 import 'kernel/dart2js_target.dart';
-import 'options.dart';
 import 'universe/selector.dart' show Selector;
 
 /// The common elements and types in Dart.
@@ -112,6 +111,9 @@
   /// The package:js library.
   LibraryEntity get packageJsLibrary;
 
+  /// The dart:_js_annotations library.
+  LibraryEntity get dartJsAnnotationsLibrary;
+
   /// The `NativeTypedData` class from dart:typed_data.
   ClassEntity get typedDataClass;
 
@@ -450,24 +452,6 @@
 
   FunctionEntity get getRuntimeTypeArgumentIntercepted;
 
-  FunctionEntity get assertIsSubtype;
-
-  FunctionEntity get checkSubtype;
-
-  FunctionEntity get assertSubtype;
-
-  FunctionEntity get subtypeCast;
-
-  FunctionEntity get functionTypeTest;
-
-  FunctionEntity get futureOrTest;
-
-  FunctionEntity get checkSubtypeOfRuntimeType;
-
-  FunctionEntity get assertSubtypeOfRuntimeType;
-
-  FunctionEntity get subtypeOfRuntimeTypeCast;
-
   FunctionEntity get checkDeferredIsLoaded;
 
   FunctionEntity get throwNoSuchMethod;
@@ -572,13 +556,35 @@
       ClassEntity cls, NativeBasicData nativeBasicData);
 
   // From package:js
-  FunctionEntity get jsAllowInterop;
+  FunctionEntity get jsAllowInterop1;
+
+  // From dart:_js_annotations;
+  FunctionEntity get jsAllowInterop2;
+
+  /// Returns `true` if [function] is `allowInterop`.
+  ///
+  /// This function can come from either `package:js` or `dart:_js_annotations`.
+  bool isJsAllowInterop(FunctionEntity function);
 }
 
 abstract class KCommonElements implements CommonElements {
   // From package:js
-  ClassEntity get jsAnnotationClass;
-  ClassEntity get jsAnonymousClass;
+  ClassEntity get jsAnnotationClass1;
+  ClassEntity get jsAnonymousClass1;
+
+  // From dart:_js_annotations
+  ClassEntity get jsAnnotationClass2;
+  ClassEntity get jsAnonymousClass2;
+
+  /// Returns `true` if [cls] is a @JS() annotation.
+  ///
+  /// The class can come from either `package:js` or `dart:_js_annotations`.
+  bool isJsAnnotationClass(ClassEntity cls);
+
+  /// Returns `true` if [cls] is an @anonymous annotation.
+  ///
+  /// The class can come from either `package:js` or `dart:_js_annotations`.
+  bool isJsAnonymousClass(ClassEntity cls);
 
   ClassEntity get pragmaClass;
   FieldEntity get pragmaClassNameField;
@@ -676,9 +682,8 @@
   @override
   final DartTypes dartTypes;
   final ElementEnvironment _env;
-  final CompilerOptions _options;
 
-  CommonElementsImpl(this.dartTypes, this._env, this._options);
+  CommonElementsImpl(this.dartTypes, this._env);
 
   ClassEntity _objectClass;
   @override
@@ -826,6 +831,11 @@
   LibraryEntity get packageJsLibrary =>
       _packageJsLibrary ??= _env.lookupLibrary(Uris.package_js);
 
+  LibraryEntity _dartJsAnnotationsLibrary;
+  @override
+  LibraryEntity get dartJsAnnotationsLibrary => _dartJsAnnotationsLibrary ??=
+      _env.lookupLibrary(Uris.dart__js_annotations);
+
   ClassEntity _typedDataClass;
   @override
   ClassEntity get typedDataClass =>
@@ -1483,22 +1493,57 @@
       _jsConstClass ??= _findClass(foreignLibrary, 'JS_CONST');
 
   // From dart:js
-  FunctionEntity _jsAllowInterop;
+  FunctionEntity _jsAllowInterop1;
   @override
-  FunctionEntity get jsAllowInterop => _jsAllowInterop ??=
+  FunctionEntity get jsAllowInterop1 => _jsAllowInterop1 ??=
       _findLibraryMember(dartJsLibrary, 'allowInterop', required: false);
 
-  // From package:js
-  ClassEntity _jsAnnotationClass;
+  // From dart:_js_annotations
+  FunctionEntity _jsAllowInterop2;
   @override
-  ClassEntity get jsAnnotationClass => _jsAnnotationClass ??=
+  FunctionEntity get jsAllowInterop2 => _jsAllowInterop2 ??= _findLibraryMember(
+      dartJsAnnotationsLibrary, 'allowInterop',
+      required: false);
+
+  @override
+  bool isJsAllowInterop(FunctionEntity function) {
+    return function == jsAllowInterop1 || function == jsAllowInterop2;
+  }
+
+  // From package:js
+  ClassEntity _jsAnnotationClass1;
+  @override
+  ClassEntity get jsAnnotationClass1 => _jsAnnotationClass1 ??=
       _findClass(packageJsLibrary, 'JS', required: false);
 
-  ClassEntity _jsAnonymousClass;
+  // From dart:_js_annotations
+  ClassEntity _jsAnnotationClass2;
   @override
-  ClassEntity get jsAnonymousClass => _jsAnonymousClass ??=
+  ClassEntity get jsAnnotationClass2 => _jsAnnotationClass2 ??=
+      _findClass(dartJsAnnotationsLibrary, 'JS', required: false);
+
+  @override
+  bool isJsAnnotationClass(ClassEntity cls) {
+    return cls == jsAnnotationClass1 || cls == jsAnnotationClass2;
+  }
+
+  // From dart:js
+  ClassEntity _jsAnonymousClass1;
+  @override
+  ClassEntity get jsAnonymousClass1 => _jsAnonymousClass1 ??=
       _findClass(packageJsLibrary, '_Anonymous', required: false);
 
+  // From dart:_js_annotations
+  ClassEntity _jsAnonymousClass2;
+  @override
+  ClassEntity get jsAnonymousClass2 => _jsAnonymousClass2 ??=
+      _findClass(dartJsAnnotationsLibrary, '_Anonymous', required: false);
+
+  @override
+  bool isJsAnonymousClass(ClassEntity cls) {
+    return cls == jsAnonymousClass1 || cls == jsAnonymousClass2;
+  }
+
   @override
   FunctionEntity findHelperFunction(String name) => _findHelperFunction(name);
 
@@ -1519,9 +1564,8 @@
 
   ClassEntity _typeLiteralClass;
   @override
-  ClassEntity get typeLiteralClass => _typeLiteralClass ??= _options.useNewRti
-      ? _findRtiClass('_Type')
-      : _findHelperClass('TypeImpl');
+  ClassEntity get typeLiteralClass =>
+      _typeLiteralClass ??= _findRtiClass('_Type');
 
   ClassEntity _constMapLiteralClass;
   @override
@@ -1776,37 +1820,6 @@
       _findHelperFunction('getRuntimeTypeArgumentIntercepted');
 
   @override
-  FunctionEntity get assertIsSubtype => _findHelperFunction('assertIsSubtype');
-
-  @override
-  FunctionEntity get checkSubtype => _findHelperFunction('checkSubtype');
-
-  @override
-  FunctionEntity get assertSubtype => _findHelperFunction('assertSubtype');
-
-  @override
-  FunctionEntity get subtypeCast => _findHelperFunction('subtypeCast');
-
-  @override
-  FunctionEntity get functionTypeTest =>
-      _findHelperFunction('functionTypeTest');
-
-  @override
-  FunctionEntity get futureOrTest => _findHelperFunction('futureOrTest');
-
-  @override
-  FunctionEntity get checkSubtypeOfRuntimeType =>
-      _findHelperFunction('checkSubtypeOfRuntimeType');
-
-  @override
-  FunctionEntity get assertSubtypeOfRuntimeType =>
-      _findHelperFunction('assertSubtypeOfRuntimeType');
-
-  @override
-  FunctionEntity get subtypeOfRuntimeTypeCast =>
-      _findHelperFunction('subtypeOfRuntimeTypeCast');
-
-  @override
   FunctionEntity get checkDeferredIsLoaded =>
       _findHelperFunction('checkDeferredIsLoaded');
 
@@ -1815,9 +1828,7 @@
       _findHelperFunction('throwNoSuchMethod');
 
   @override
-  FunctionEntity get createRuntimeType => _options.useNewRti
-      ? _findRtiFunction('createRuntimeType')
-      : _findHelperFunction('createRuntimeType');
+  FunctionEntity get createRuntimeType => _findRtiFunction('createRuntimeType');
 
   @override
   FunctionEntity get fallThroughError =>
diff --git a/pkg/compiler/lib/src/ir/annotations.dart b/pkg/compiler/lib/src/ir/annotations.dart
index 899b8d0..637bd63 100644
--- a/pkg/compiler/lib/src/ir/annotations.dart
+++ b/pkg/compiler/lib/src/ir/annotations.dart
@@ -295,7 +295,9 @@
 String _getJsInteropName(ir.Constant constant) {
   if (constant is ir.InstanceConstant &&
       constant.classNode.name == 'JS' &&
-      constant.classNode.enclosingLibrary.importUri == Uris.package_js) {
+      (constant.classNode.enclosingLibrary.importUri == Uris.package_js ||
+          constant.classNode.enclosingLibrary.importUri ==
+              Uris.dart__js_annotations)) {
     assert(constant.fieldValues.length == 1);
     ir.Constant fieldValue = constant.fieldValues.values.single;
     if (fieldValue is ir.NullConstant) {
@@ -310,7 +312,9 @@
 bool _isAnonymousJsInterop(ir.Constant constant) {
   return constant is ir.InstanceConstant &&
       constant.classNode.name == '_Anonymous' &&
-      constant.classNode.enclosingLibrary.importUri == Uris.package_js;
+      (constant.classNode.enclosingLibrary.importUri == Uris.package_js ||
+          constant.classNode.enclosingLibrary.importUri ==
+              Uris.dart__js_annotations);
 }
 
 class PragmaAnnotationData {
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 5f7ce38..7e6ebbf 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -1940,7 +1940,13 @@
             newTypesOfInterest.add(typeOfInterest);
           }
         }
-        if (newTypesOfInterest.isNotEmpty) {
+        if (newTypesOfInterest.length > 1 ||
+            (newTypesOfInterest.length == 1 &&
+                newTypesOfInterest.single != info.declaredType)) {
+          // If [newTypesOfInterest] only contains the declared type we have no
+          // information about the variable (it is either an instance of its
+          // declared type or null) and the canonical way to represent this is
+          // to have _no_ target info.
           TypeHolder typeHolderIfNonNull =
               new TypeHolder(info.declaredType, newTypesOfInterest, null);
           TypeHolder typeHolderIfNull = new TypeHolder(info.declaredType, null,
diff --git a/pkg/compiler/lib/src/js_backend/backend_impact.dart b/pkg/compiler/lib/src/js_backend/backend_impact.dart
index d22ce35..f5d5d1d 100644
--- a/pkg/compiler/lib/src/js_backend/backend_impact.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_impact.dart
@@ -168,10 +168,7 @@
   BackendImpact get typeVariableBoundCheck {
     return _typeVariableBoundCheck ??= new BackendImpact(staticUses: [
       _commonElements.throwTypeError,
-      if (_options.useNewRti)
-        _commonElements.checkTypeBound
-      else
-        _commonElements.assertIsSubtype,
+      _commonElements.checkTypeBound,
     ]);
   }
 
@@ -435,7 +432,7 @@
       _commonElements.typeLiteralClass
     ], staticUses: [
       _commonElements.createRuntimeType,
-      if (_options.useNewRti) _commonElements.typeLiteralMaker,
+      _commonElements.typeLiteralMaker,
     ]);
   }
 
@@ -481,7 +478,6 @@
 
   BackendImpact get genericTypeCheck {
     return _genericTypeCheck ??= new BackendImpact(staticUses: [
-      _commonElements.checkSubtype,
       // TODO(johnniwinther): Investigate why this is needed.
       _commonElements.setRuntimeTypeInfo,
       _commonElements.getRuntimeTypeInfo
@@ -502,9 +498,8 @@
   BackendImpact _typeVariableTypeCheck;
 
   BackendImpact get typeVariableTypeCheck {
-    return _typeVariableTypeCheck ??= new BackendImpact(
-        staticUses: [_commonElements.checkSubtypeOfRuntimeType],
-        otherImpacts: [newRtiImpact]);
+    return _typeVariableTypeCheck ??=
+        new BackendImpact(staticUses: [], otherImpacts: [newRtiImpact]);
   }
 
   BackendImpact _functionTypeCheck;
@@ -518,9 +513,8 @@
   BackendImpact _futureOrTypeCheck;
 
   BackendImpact get futureOrTypeCheck {
-    return _futureOrTypeCheck ??= new BackendImpact(
-        staticUses: [_commonElements.futureOrTest],
-        otherImpacts: [newRtiImpact]);
+    return _futureOrTypeCheck ??=
+        new BackendImpact(staticUses: [], otherImpacts: [newRtiImpact]);
   }
 
   BackendImpact _nativeTypeCheck;
@@ -565,7 +559,8 @@
 
   BackendImpact get allowInterop => _allowInterop ??= BackendImpact(
           staticUses: [
-            _commonElements.jsAllowInterop,
+            _commonElements.jsAllowInterop1,
+            _commonElements.jsAllowInterop2,
           ],
           features: EnumSet<BackendFeature>.fromValues([
             BackendFeature.needToInitializeIsolateAffinityTag,
@@ -785,15 +780,8 @@
       _genericInstantiation[typeArgumentCount] ??=
           new BackendImpact(staticUses: [
         _commonElements.getInstantiateFunction(typeArgumentCount),
-        ..._options.useNewRti
-            ? [
-                _commonElements.instantiatedGenericFunctionTypeNewRti,
-                _commonElements.closureFunctionType
-              ]
-            : [
-                _commonElements.instantiatedGenericFunctionType,
-                _commonElements.extractFunctionTypeObjectFromInternal
-              ],
+        _commonElements.instantiatedGenericFunctionTypeNewRti,
+        _commonElements.closureFunctionType,
       ], instantiatedClasses: [
         _commonElements.getInstantiationClass(typeArgumentCount),
       ]);
@@ -802,51 +790,50 @@
   BackendImpact _newRtiImpact;
 
   // TODO(sra): Split into refined impacts.
-  BackendImpact get newRtiImpact => _newRtiImpact ??= _options.useNewRti
-      ? BackendImpact(staticUses: [
-          _commonElements.findType,
-          _commonElements.instanceType,
-          _commonElements.arrayInstanceType,
-          _commonElements.simpleInstanceType,
-          _commonElements.rtiEvalMethod,
-          _commonElements.rtiBindMethod,
-          _commonElements.installSpecializedIsTest,
-          _commonElements.generalIsTestImplementation,
-          _commonElements.generalAsCheckImplementation,
-          if (_options.useNullSafety) ...[
-            _commonElements.installSpecializedAsCheck,
-            _commonElements.generalNullableIsTestImplementation,
-            _commonElements.generalNullableAsCheckImplementation,
-          ],
-          // Specialized checks.
-          _commonElements.specializedIsBool,
-          _commonElements.specializedAsBool,
-          _commonElements.specializedAsBoolLegacy,
-          _commonElements.specializedAsBoolNullable,
-          // no specializedIsDouble.
-          _commonElements.specializedAsDouble,
-          _commonElements.specializedAsDoubleLegacy,
-          _commonElements.specializedAsDoubleNullable,
-          _commonElements.specializedIsInt,
-          _commonElements.specializedAsInt,
-          _commonElements.specializedAsIntLegacy,
-          _commonElements.specializedAsIntNullable,
-          _commonElements.specializedIsNum,
-          _commonElements.specializedAsNum,
-          _commonElements.specializedAsNumLegacy,
-          _commonElements.specializedAsNumNullable,
-          _commonElements.specializedIsString,
-          _commonElements.specializedAsString,
-          _commonElements.specializedAsStringLegacy,
-          _commonElements.specializedAsStringNullable,
-          _commonElements.specializedIsTop,
-          _commonElements.specializedAsTop,
-          _commonElements.specializedIsObject,
-          _commonElements.specializedAsObject,
-        ], globalClasses: [
-          _commonElements.closureClass, // instanceOrFunctionType uses this.
-        ])
-      : BackendImpact();
+  BackendImpact get newRtiImpact =>
+      _newRtiImpact ??= BackendImpact(staticUses: [
+        _commonElements.findType,
+        _commonElements.instanceType,
+        _commonElements.arrayInstanceType,
+        _commonElements.simpleInstanceType,
+        _commonElements.rtiEvalMethod,
+        _commonElements.rtiBindMethod,
+        _commonElements.installSpecializedIsTest,
+        _commonElements.generalIsTestImplementation,
+        _commonElements.generalAsCheckImplementation,
+        if (_options.useNullSafety) ...[
+          _commonElements.installSpecializedAsCheck,
+          _commonElements.generalNullableIsTestImplementation,
+          _commonElements.generalNullableAsCheckImplementation,
+        ],
+        // Specialized checks.
+        _commonElements.specializedIsBool,
+        _commonElements.specializedAsBool,
+        _commonElements.specializedAsBoolLegacy,
+        _commonElements.specializedAsBoolNullable,
+        // no specializedIsDouble.
+        _commonElements.specializedAsDouble,
+        _commonElements.specializedAsDoubleLegacy,
+        _commonElements.specializedAsDoubleNullable,
+        _commonElements.specializedIsInt,
+        _commonElements.specializedAsInt,
+        _commonElements.specializedAsIntLegacy,
+        _commonElements.specializedAsIntNullable,
+        _commonElements.specializedIsNum,
+        _commonElements.specializedAsNum,
+        _commonElements.specializedAsNumLegacy,
+        _commonElements.specializedAsNumNullable,
+        _commonElements.specializedIsString,
+        _commonElements.specializedAsString,
+        _commonElements.specializedAsStringLegacy,
+        _commonElements.specializedAsStringNullable,
+        _commonElements.specializedIsTop,
+        _commonElements.specializedAsTop,
+        _commonElements.specializedIsObject,
+        _commonElements.specializedAsObject,
+      ], globalClasses: [
+        _commonElements.closureClass, // instanceOrFunctionType uses this.
+      ]);
 
   BackendImpact _rtiAddRules;
 
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 5790e10..c0e2d78 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -2,17 +2,12 @@
 // 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 '../common.dart';
+// TODO(39733): This file exists now just to register the use of
+// 'boolConversionCheck'. Fix the registration and remove this file.
+
 import '../common_elements.dart';
-import '../elements/entities.dart';
-import '../elements/types.dart';
-import '../js/js.dart' as jsAst;
-import '../js/js.dart' show js;
-import '../ssa/codegen.dart' show SsaCodeGenerator;
-import '../ssa/nodes.dart' show HTypeConversion;
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/use.dart' show StaticUse;
-import 'namer.dart' show ModularNamer;
 
 class CheckedModeHelper {
   final String name;
@@ -27,93 +22,6 @@
   }
 
   CallStructure get callStructure => CallStructure.ONE_ARG;
-
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    // No additional arguments needed.
-  }
-}
-
-class PropertyCheckedModeHelper extends CheckedModeHelper {
-  const PropertyCheckedModeHelper(String name) : super(name);
-
-  @override
-  CallStructure get callStructure => CallStructure.TWO_ARGS;
-
-  @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    DartType type = node.typeExpression;
-    jsAst.Name additionalArgument = namer.operatorIsType(type);
-    arguments.add(js.quoteName(additionalArgument));
-  }
-}
-
-class TypeVariableCheckedModeHelper extends CheckedModeHelper {
-  const TypeVariableCheckedModeHelper(String name) : super(name);
-
-  @override
-  CallStructure get callStructure => CallStructure.TWO_ARGS;
-
-  @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    assert(node.typeExpression is TypeVariableType);
-    codegen.use(node.typeRepresentation);
-    arguments.add(codegen.pop());
-  }
-}
-
-class FunctionTypeRepresentationCheckedModeHelper extends CheckedModeHelper {
-  const FunctionTypeRepresentationCheckedModeHelper(String name) : super(name);
-
-  @override
-  CallStructure get callStructure => CallStructure.TWO_ARGS;
-
-  @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    assert(node.typeExpression is FunctionType);
-    codegen.use(node.typeRepresentation);
-    arguments.add(codegen.pop());
-  }
-}
-
-class FutureOrRepresentationCheckedModeHelper extends CheckedModeHelper {
-  const FutureOrRepresentationCheckedModeHelper(String name) : super(name);
-
-  @override
-  CallStructure get callStructure => CallStructure.TWO_ARGS;
-
-  @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    assert(node.typeExpression is FutureOrType);
-    codegen.use(node.typeRepresentation);
-    arguments.add(codegen.pop());
-  }
-}
-
-class SubtypeCheckedModeHelper extends CheckedModeHelper {
-  const SubtypeCheckedModeHelper(String name) : super(name);
-
-  @override
-  CallStructure get callStructure => const CallStructure.unnamed(4);
-
-  @override
-  void generateAdditionalArguments(SsaCodeGenerator codegen, ModularNamer namer,
-      HTypeConversion node, List<jsAst.Expression> arguments) {
-    // TODO(sra): Move these calls into the SSA graph so that the arguments can
-    // be optimized, e,g, GVNed.
-    InterfaceType type = node.typeExpression;
-    ClassEntity element = type.element;
-    jsAst.Name isField = namer.operatorIs(element);
-    arguments.add(js.quoteName(isField));
-    codegen.use(node.typeRepresentation);
-    arguments.add(codegen.pop());
-    jsAst.Name asField = namer.substitutionName(element);
-    arguments.add(js.quoteName(asField));
-  }
 }
 
 class CheckedModeHelpers {
@@ -121,180 +29,6 @@
 
   /// All the checked mode helpers.
   static const List<CheckedModeHelper> helpers = const <CheckedModeHelper>[
-    const CheckedModeHelper('stringTypeCast'),
-    const CheckedModeHelper('stringTypeCheck'),
-    const CheckedModeHelper('doubleTypeCast'),
-    const CheckedModeHelper('doubleTypeCheck'),
-    const CheckedModeHelper('numTypeCast'),
-    const CheckedModeHelper('numTypeCheck'),
     const CheckedModeHelper('boolConversionCheck'),
-    const CheckedModeHelper('boolTypeCast'),
-    const CheckedModeHelper('boolTypeCheck'),
-    const CheckedModeHelper('intTypeCast'),
-    const CheckedModeHelper('intTypeCheck'),
-    const PropertyCheckedModeHelper('numberOrStringSuperNativeTypeCast'),
-    const PropertyCheckedModeHelper('numberOrStringSuperNativeTypeCheck'),
-    const PropertyCheckedModeHelper('numberOrStringSuperTypeCast'),
-    const PropertyCheckedModeHelper('numberOrStringSuperTypeCheck'),
-    const PropertyCheckedModeHelper('stringSuperNativeTypeCast'),
-    const PropertyCheckedModeHelper('stringSuperNativeTypeCheck'),
-    const PropertyCheckedModeHelper('stringSuperTypeCast'),
-    const PropertyCheckedModeHelper('stringSuperTypeCheck'),
-    const CheckedModeHelper('listTypeCast'),
-    const CheckedModeHelper('listTypeCheck'),
-    const PropertyCheckedModeHelper('listSuperNativeTypeCast'),
-    const PropertyCheckedModeHelper('listSuperNativeTypeCheck'),
-    const PropertyCheckedModeHelper('listSuperTypeCast'),
-    const PropertyCheckedModeHelper('listSuperTypeCheck'),
-    const PropertyCheckedModeHelper('interceptedTypeCast'),
-    const PropertyCheckedModeHelper('interceptedTypeCheck'),
-    const SubtypeCheckedModeHelper('subtypeCast'),
-    const SubtypeCheckedModeHelper('assertSubtype'),
-    const TypeVariableCheckedModeHelper('subtypeOfRuntimeTypeCast'),
-    const TypeVariableCheckedModeHelper('assertSubtypeOfRuntimeType'),
-    const PropertyCheckedModeHelper('propertyTypeCast'),
-    const PropertyCheckedModeHelper('propertyTypeCheck'),
-    const FunctionTypeRepresentationCheckedModeHelper('functionTypeCast'),
-    const FunctionTypeRepresentationCheckedModeHelper('functionTypeCheck'),
-    const FutureOrRepresentationCheckedModeHelper('futureOrCast'),
-    const FutureOrRepresentationCheckedModeHelper('futureOrCheck'),
   ];
-
-  // Checked mode helpers indexed by name.
-  static final Map<String, CheckedModeHelper> checkedModeHelperByName =
-      new Map<String, CheckedModeHelper>.fromIterable(helpers,
-          key: (helper) => helper.name);
-
-  /// Returns the checked mode helper that will be needed to do a type
-  /// check/type cast on [type] at runtime. Note that this method is being
-  /// called both by the resolver with interface types (int, String, ...), and
-  /// by the SSA backend with implementation types (JSInt, JSString, ...).
-  CheckedModeHelper getCheckedModeHelper(
-      DartType type, CommonElements commonElements,
-      {bool typeCast}) {
-    return getCheckedModeHelperInternal(type, commonElements,
-        typeCast: typeCast, nativeCheckOnly: false);
-  }
-
-  /// Returns the native checked mode helper that will be needed to do a type
-  /// check/type cast on [type] at runtime. If no native helper exists for
-  /// [type], [:null:] is returned.
-  CheckedModeHelper getNativeCheckedModeHelper(
-      DartType type, CommonElements commonElements,
-      {bool typeCast}) {
-    return getCheckedModeHelperInternal(type, commonElements,
-        typeCast: typeCast, nativeCheckOnly: true);
-  }
-
-  /// Returns the checked mode helper for the type check/type cast for
-  /// [type]. If [nativeCheckOnly] is [:true:], only names for native helpers
-  /// are returned.
-  CheckedModeHelper getCheckedModeHelperInternal(
-      DartType type, CommonElements commonElements,
-      {bool typeCast, bool nativeCheckOnly}) {
-    String name = getCheckedModeHelperNameInternal(type, commonElements,
-        typeCast: typeCast, nativeCheckOnly: nativeCheckOnly);
-    if (name == null) return null;
-    CheckedModeHelper helper = checkedModeHelperByName[name];
-    assert(helper != null);
-    return helper;
-  }
-
-  String getCheckedModeHelperNameInternal(
-      DartType type, CommonElements commonElements,
-      {bool typeCast, bool nativeCheckOnly}) {
-    DartTypes dartTypes = commonElements.dartTypes;
-
-    if (type is TypeVariableType) {
-      return typeCast
-          ? 'subtypeOfRuntimeTypeCast'
-          : 'assertSubtypeOfRuntimeType';
-    }
-
-    if (type is FunctionType) {
-      return typeCast ? 'functionTypeCast' : 'functionTypeCheck';
-    }
-
-    if (type is FutureOrType) {
-      return typeCast ? 'futureOrCast' : 'futureOrCheck';
-    }
-
-    assert(type is InterfaceType,
-        failedAt(NO_LOCATION_SPANNABLE, "Unexpected type: $type"));
-    InterfaceType interfaceType = type;
-    ClassEntity element = interfaceType.element;
-    bool nativeCheck = true;
-    // TODO(13955), TODO(9731).  The test for non-primitive types should use an
-    // interceptor.  The interceptor should be an argument to HTypeConversion so
-    // that it can be optimized by standard interceptor optimizations.
-    //  nativeCheckOnly || emitter.nativeEmitter.requiresNativeIsCheck(element);
-
-    var suffix = typeCast ? 'TypeCast' : 'TypeCheck';
-    if (element == commonElements.jsStringClass ||
-        element == commonElements.stringClass) {
-      if (nativeCheckOnly) return null;
-      return 'string$suffix';
-    }
-
-    if (element == commonElements.jsDoubleClass ||
-        element == commonElements.doubleClass) {
-      if (nativeCheckOnly) return null;
-      return 'double$suffix';
-    }
-
-    if (element == commonElements.jsNumberClass ||
-        element == commonElements.numClass) {
-      if (nativeCheckOnly) return null;
-      return 'num$suffix';
-    }
-
-    if (element == commonElements.jsBoolClass ||
-        element == commonElements.boolClass) {
-      if (nativeCheckOnly) return null;
-      return 'bool$suffix';
-    }
-
-    if (element == commonElements.jsIntClass ||
-        element == commonElements.intClass ||
-        element == commonElements.jsUInt32Class ||
-        element == commonElements.jsUInt31Class ||
-        element == commonElements.jsPositiveIntClass) {
-      if (nativeCheckOnly) return null;
-      return 'int$suffix';
-    }
-
-    if (commonElements.isNumberOrStringSupertype(element)) {
-      return nativeCheck
-          ? 'numberOrStringSuperNative$suffix'
-          : 'numberOrStringSuper$suffix';
-    }
-
-    if (commonElements.isStringOnlySupertype(element)) {
-      return nativeCheck ? 'stringSuperNative$suffix' : 'stringSuper$suffix';
-    }
-
-    if ((element == commonElements.listClass ||
-            element == commonElements.jsArrayClass) &&
-        dartTypes.treatAsRawType(type)) {
-      if (nativeCheckOnly) return null;
-      return 'list$suffix';
-    }
-
-    if (commonElements.isListSupertype(element) &&
-        dartTypes.treatAsRawType(type)) {
-      return nativeCheck ? 'listSuperNative$suffix' : 'listSuper$suffix';
-    }
-
-    if (type is InterfaceType && !dartTypes.treatAsRawType(type)) {
-      return typeCast ? 'subtypeCast' : 'assertSubtype';
-    }
-
-    if (nativeCheck) {
-      // TODO(karlklose): can we get rid of this branch when we use
-      // interceptors?
-      return 'intercepted$suffix';
-    } else {
-      return 'property$suffix';
-    }
-  }
 }
diff --git a/pkg/compiler/lib/src/js_backend/codegen_listener.dart b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
index 0049501..46aa940 100644
--- a/pkg/compiler/lib/src/js_backend/codegen_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/codegen_listener.dart
@@ -122,7 +122,7 @@
     }
 
     // TODO(fishythefish): Avoid registering unnecessary impacts.
-    if (_options.useNewRti && !_isNewRtiUsed) {
+    if (!_isNewRtiUsed) {
       WorldImpactBuilderImpl newRtiImpact = new WorldImpactBuilderImpl();
       newRtiImpact.registerStaticUse(StaticUse.staticInvoke(
           _commonElements.rtiAddRulesMethod, CallStructure.TWO_ARGS));
@@ -189,20 +189,11 @@
           _elementEnvironment.getThisType(_commonElements
               .getInstantiationClass(constant.typeArguments.length))));
 
-      if (_options.useNewRti) {
-        impactBuilder.registerStaticUse(StaticUse.staticInvoke(
-            _commonElements.instantiatedGenericFunctionTypeNewRti,
-            CallStructure.TWO_ARGS));
-        impactBuilder.registerStaticUse(StaticUse.staticInvoke(
-            _commonElements.closureFunctionType, CallStructure.ONE_ARG));
-      } else {
-        impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            _commonElements.instantiatedGenericFunctionType,
-            CallStructure.TWO_ARGS));
-        impactBuilder.registerStaticUse(new StaticUse.staticInvoke(
-            _commonElements.extractFunctionTypeObjectFromInternal,
-            CallStructure.ONE_ARG));
-      }
+      impactBuilder.registerStaticUse(StaticUse.staticInvoke(
+          _commonElements.instantiatedGenericFunctionTypeNewRti,
+          CallStructure.TWO_ARGS));
+      impactBuilder.registerStaticUse(StaticUse.staticInvoke(
+          _commonElements.closureFunctionType, CallStructure.ONE_ARG));
     }
   }
 
diff --git a/pkg/compiler/lib/src/js_backend/constant_emitter.dart b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
index 4cd0619..c5c0da1 100644
--- a/pkg/compiler/lib/src/js_backend/constant_emitter.dart
+++ b/pkg/compiler/lib/src/js_backend/constant_emitter.dart
@@ -240,11 +240,7 @@
         .toList(growable: false);
     jsAst.ArrayInitializer array = new jsAst.ArrayInitializer(elements);
     jsAst.Expression value = _makeConstantList(array);
-    if (_options.useNewRti) {
-      return maybeAddListTypeArgumentsNewRti(constant, constant.type, value);
-    } else {
-      return maybeAddTypeArguments(constant, constant.type, value);
-    }
+    return maybeAddListTypeArgumentsNewRti(constant, constant.type, value);
   }
 
   @override
@@ -263,12 +259,7 @@
     ];
 
     if (_rtiNeed.classNeedsTypeArguments(classElement)) {
-      if (_options.useNewRti) {
-        arguments.add(_reifiedTypeNewRti(sourceType));
-      } else {
-        arguments
-            .add(_reifiedTypeArguments(constant, sourceType.typeArguments));
-      }
+      arguments.add(_reifiedTypeNewRti(sourceType));
     }
 
     jsAst.Expression constructor = _emitter.constructorAccess(classElement);
@@ -354,12 +345,7 @@
     }
 
     if (_rtiNeed.classNeedsTypeArguments(classElement)) {
-      if (_options.useNewRti) {
-        arguments.add(_reifiedTypeNewRti(constant.type));
-      } else {
-        arguments
-            .add(_reifiedTypeArguments(constant, constant.type.typeArguments));
-      }
+      arguments.add(_reifiedTypeNewRti(constant.type));
     }
 
     jsAst.Expression constructor = _emitter.constructorAccess(classElement);
@@ -375,34 +361,18 @@
   jsAst.Expression visitType(TypeConstantValue constant, [_]) {
     DartType type = constant.representedType;
 
-    if (_options.useNewRti) {
-      assert(!type.containsTypeVariables);
+    assert(!type.containsTypeVariables);
 
-      jsAst.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
-          _emitter, TypeExpressionRecipe(type));
+    jsAst.Expression recipe = _rtiRecipeEncoder.encodeGroundRecipe(
+        _emitter, TypeExpressionRecipe(type));
 
-      // Generate  `typeLiteral(recipe)`.
+    // Generate  `typeLiteral(recipe)`.
 
-      // TODO(sra): `typeLiteral(r)` calls `createRuntimeType(findType(r))`.
-      // Find a way to share the `findType` call with methods that also use the
-      // type.
-      return js('#(#)',
-          [getHelperProperty(_commonElements.typeLiteralMaker), recipe]);
-    } else {
-      jsAst.Expression unexpected(TypeVariableType _variable) {
-        TypeVariableType variable = _variable;
-        throw failedAt(
-            NO_LOCATION_SPANNABLE,
-            "Unexpected type variable '${variable}'"
-            " in constant '${constant.toDartText(_commonElements.dartTypes)}'");
-      }
-
-      jsAst.Expression rti =
-          _rtiEncoder.getTypeRepresentation(_emitter, type, unexpected);
-
-      return new jsAst.Call(
-          getHelperProperty(_commonElements.createRuntimeType), [rti]);
-    }
+    // TODO(sra): `typeLiteral(r)` calls `createRuntimeType(findType(r))`.
+    // Find a way to share the `findType` call with methods that also use the
+    // type.
+    return js(
+        '#(#)', [getHelperProperty(_commonElements.typeLiteralMaker), recipe]);
   }
 
   @override
@@ -430,12 +400,7 @@
       }
     });
     if (_rtiNeed.classNeedsTypeArguments(constant.type.element)) {
-      if (_options.useNewRti) {
-        fields.add(_reifiedTypeNewRti(constant.type));
-      } else {
-        fields
-            .add(_reifiedTypeArguments(constant, constant.type.typeArguments));
-      }
+      fields.add(_reifiedTypeNewRti(constant.type));
     }
     return new jsAst.New(constructor, fields);
   }
@@ -448,12 +413,8 @@
     List<jsAst.Expression> fields = <jsAst.Expression>[
       _constantReferenceGenerator(constant.function)
     ];
-    if (_options.useNewRti) {
-      fields.add(_reifiedTypeNewRti(_commonElements.dartTypes
-          .interfaceType(cls, constant.typeArguments)));
-    } else {
-      fields.add(_reifiedTypeArguments(constant, constant.typeArguments));
-    }
+    fields.add(_reifiedTypeNewRti(
+        _commonElements.dartTypes.interfaceType(cls, constant.typeArguments)));
     jsAst.Expression constructor = _emitter.constructorAccess(cls);
     return new jsAst.New(constructor, fields);
   }
@@ -504,7 +465,6 @@
   }
 
   jsAst.Expression _reifiedTypeNewRti(DartType type) {
-    assert(_options.useNewRti);
     assert(!type.containsTypeVariables);
     return TypeReference(TypeExpressionRecipe(type))..forConstant = true;
   }
diff --git a/pkg/compiler/lib/src/js_backend/resolution_listener.dart b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
index 9c2eed4..9bd730b 100644
--- a/pkg/compiler/lib/src/js_backend/resolution_listener.dart
+++ b/pkg/compiler/lib/src/js_backend/resolution_listener.dart
@@ -443,15 +443,14 @@
       _registerBackendImpact(impactBuilder, _impacts.traceHelper);
     }
 
-    if (_options.useNewRti) {
-      _registerBackendImpact(impactBuilder, _impacts.rtiAddRules);
-    }
+    _registerBackendImpact(impactBuilder, _impacts.rtiAddRules);
 
     _registerBackendImpact(impactBuilder, _impacts.assertUnreachable);
     _registerCheckedModeHelpers(impactBuilder);
     return impactBuilder;
   }
 
+  // TODO(39733): Move registration of boolConversionCheck.
   void _registerCheckedModeHelpers(WorldImpactBuilder impactBuilder) {
     // We register all the _commonElements in the resolution queue.
     // TODO(13155): Find a way to register fewer _commonElements.
diff --git a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
index 0dcffa2..d872941 100644
--- a/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
+++ b/pkg/compiler/lib/src/js_emitter/code_emitter_task.dart
@@ -102,7 +102,6 @@
           _compiler.options,
           _compiler.reporter,
           _emitter,
-          codegen.rtiEncoder,
           codegen.rtiRecipeEncoder,
           closedWorld.elementEnvironment);
       typeTestRegistry = new TypeTestRegistry(
diff --git a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
index bce1fbb..9ed1e17 100644
--- a/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/instantiation_stub_generator.dart
@@ -10,7 +10,6 @@
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
 import '../js_backend/namer.dart' show Namer;
-import '../options.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../universe/codegen_world_builder.dart';
 import '../universe/selector.dart' show Selector;
@@ -39,8 +38,6 @@
   JElementEnvironment get _elementEnvironment =>
       _closedWorld.elementEnvironment;
 
-  CompilerOptions get _options => _emitterTask.options;
-
   /// Generates a stub to forward a call selector with no type arguments to a
   /// call selector with stored types.
   ///
@@ -81,18 +78,12 @@
       parameters.add(new jsAst.Parameter(jsName));
     }
 
-    if (_options.useNewRti) {
-      for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
-        arguments.add(js('this.#.#[#]', [
-          _namer.rtiFieldJsName,
-          _namer.fieldPropertyName(_commonElements.rtiRestField),
-          js.number(i)
-        ]));
-      }
-    } else {
-      for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
-        arguments.add(js('this.#[#]', [_namer.rtiFieldJsName, js.number(i)]));
-      }
+    for (int i = 0; i < targetSelector.typeArgumentCount; i++) {
+      arguments.add(js('this.#.#[#]', [
+        _namer.rtiFieldJsName,
+        _namer.fieldPropertyName(_commonElements.rtiRestField),
+        js.number(i)
+      ]));
     }
 
     jsAst.Fun function = js('function(#) { return this.#.#(#); }', [
@@ -122,9 +113,7 @@
     jsAst.Name operatorSignature =
         _namer.asName(_namer.fixedNames.operatorSignature);
 
-    jsAst.Fun function = _options.useNewRti
-        ? _generateSignatureNewRti(functionField)
-        : _generateSignatureLegacy(functionField);
+    jsAst.Fun function = _generateSignatureNewRti(functionField);
 
     // TODO(sra): Generate source information for stub that has no member.
     // TODO(sra): .withSourceInformation(sourceInformation);
@@ -132,16 +121,6 @@
     return new ParameterStubMethod(operatorSignature, null, function);
   }
 
-  jsAst.Fun _generateSignatureLegacy(FieldEntity functionField) =>
-      js('function() { return #(#(this.#), this.#); }', [
-        _emitter.staticFunctionAccess(
-            _commonElements.instantiatedGenericFunctionType),
-        _emitter.staticFunctionAccess(
-            _commonElements.extractFunctionTypeObjectFromInternal),
-        _namer.fieldPropertyName(functionField),
-        _namer.rtiFieldJsName,
-      ]);
-
   jsAst.Fun _generateSignatureNewRti(FieldEntity functionField) =>
       js('function() { return #(#(this.#), this.#); }', [
         _emitter.staticFunctionAccess(
diff --git a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
index ed33fbe..8066ff1 100644
--- a/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
+++ b/pkg/compiler/lib/src/js_emitter/metadata_collector.dart
@@ -16,7 +16,6 @@
 import '../elements/types.dart';
 import '../js/js.dart' as jsAst;
 import '../js/js.dart' show js;
-import '../js_backend/runtime_types.dart' show RuntimeTypesEncoder;
 import '../js_backend/runtime_types_new.dart' show RecipeEncoder;
 import '../js_model/type_recipe.dart' show TypeExpressionRecipe;
 import '../options.dart';
@@ -102,7 +101,6 @@
   final CompilerOptions _options;
   final DiagnosticReporter reporter;
   final Emitter _emitter;
-  final RuntimeTypesEncoder _rtiEncoder;
   final RecipeEncoder _rtiRecipeEncoder;
   final JElementEnvironment _elementEnvironment;
 
@@ -134,7 +132,7 @@
       <OutputUnit, Map<DartType, _BoundMetadataEntry>>{};
 
   MetadataCollector(this._options, this.reporter, this._emitter,
-      this._rtiEncoder, this._rtiRecipeEncoder, this._elementEnvironment);
+      this._rtiRecipeEncoder, this._elementEnvironment);
 
   List<jsAst.DeferredNumber> reifyDefaultArguments(
       FunctionEntity function, OutputUnit outputUnit) {
@@ -173,26 +171,6 @@
     });
   }
 
-  jsAst.Expression _computeTypeRepresentation(DartType type) {
-    jsAst.Expression representation =
-        _rtiEncoder.getTypeRepresentation(_emitter, type, (variable) {
-      failedAt(
-          NO_LOCATION_SPANNABLE,
-          "Type representation for type variable $variable in "
-          "$type is not supported.");
-      return jsAst.LiteralNull();
-    });
-
-    if (representation is jsAst.LiteralString) {
-      // We don't want the representation to be a string, since we use
-      // strings as indicator for non-initialized types in the lazy emitter.
-      reporter.internalError(
-          NO_LOCATION_SPANNABLE, 'reified types should not be strings.');
-    }
-
-    return representation;
-  }
-
   jsAst.Expression _computeTypeRepresentationNewRti(DartType type) {
     return _rtiRecipeEncoder.encodeGroundRecipe(
         _emitter, TypeExpressionRecipe(type));
@@ -201,11 +179,7 @@
   jsAst.Expression addTypeInOutputUnit(DartType type, OutputUnit outputUnit) {
     _typesMap[outputUnit] ??= new Map<DartType, _BoundMetadataEntry>();
     return _typesMap[outputUnit].putIfAbsent(type, () {
-      if (_options.useNewRti) {
-        return new _BoundMetadataEntry(_computeTypeRepresentationNewRti(type));
-      } else {
-        return new _BoundMetadataEntry(_computeTypeRepresentation(type));
-      }
+      return new _BoundMetadataEntry(_computeTypeRepresentationNewRti(type));
     });
   }
 
diff --git a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
index 75d6ce4..a536bca 100644
--- a/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/parameter_stub_generator.dart
@@ -36,7 +36,7 @@
   final NativeEmitter _nativeEmitter;
   final Namer _namer;
   final RuntimeTypesEncoder _rtiEncoder;
-  final RecipeEncoder _rtiRecipeEncoder; // `null` if not useNewRti.
+  final RecipeEncoder _rtiRecipeEncoder;
   final NativeData _nativeData;
   final InterceptorData _interceptorData;
   final CodegenWorld _codegenWorld;
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 3287c1a..f1dde90 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
@@ -247,9 +247,7 @@
 
     _markEagerClasses();
 
-    if (_options.useNewRti) {
-      associateNamedTypeVariablesNewRti();
-    }
+    associateNamedTypeVariablesNewRti();
 
     List<Holder> holders = _registry.holders.toList(growable: false);
 
@@ -279,10 +277,10 @@
   void _initializeSoftDeferredMap() {
     var allocatedClassesPath = _options.experimentalAllocationsPath;
     if (allocatedClassesPath != null) {
-      // TODO(29574): the following blacklist is ad-hoc and potentially
+      // TODO(29574): the following denylist is ad-hoc and potentially
       // incomplete. We need to mark all classes as black listed, that are
       // used without code going through the class' constructor.
-      var blackList = [
+      var denylist = [
         'dart:_interceptors',
         'dart:html',
         'dart:typed_data_implementation',
@@ -331,7 +329,7 @@
           var key = "${element.library.canonicalUri}:${element.name}";
           if (allocatedClassesKeys.contains(key) ||
               _nativeData.isJsInteropClass(element) ||
-              blackList.contains(element.library.canonicalUri.toString())) {
+              denylist.contains(element.library.canonicalUri.toString())) {
             collect(element);
           }
         }
@@ -982,20 +980,7 @@
 
   js.Expression _generateFunctionType(ClassEntity /*?*/ enclosingClass,
           FunctionType type, OutputUnit outputUnit) =>
-      _options.useNewRti
-          ? _generateFunctionTypeNewRti(enclosingClass, type, outputUnit)
-          : _generateFunctionTypeLegacy(enclosingClass, type, outputUnit);
-
-  js.Expression _generateFunctionTypeLegacy(ClassEntity /*?*/ enclosingClass,
-      FunctionType type, OutputUnit outputUnit) {
-    if (type.containsTypeVariables) {
-      js.Expression thisAccess = js.js(r'this.$receiver');
-      return _rtiEncoder.getSignatureEncoding(
-          _namer, _task.emitter, type, thisAccess);
-    } else {
-      return _task.metadataCollector.reifyType(type, outputUnit);
-    }
-  }
+      _generateFunctionTypeNewRti(enclosingClass, type, outputUnit);
 
   js.Expression _generateFunctionTypeNewRti(ClassEntity /*?*/ enclosingClass,
       FunctionType type, OutputUnit outputUnit) {
@@ -1034,7 +1019,7 @@
         _task.nativeEmitter,
         _namer,
         _rtiEncoder,
-        _options.useNewRti ? _rtiRecipeEncoder : null,
+        _rtiRecipeEncoder,
         _nativeData,
         _interceptorData,
         _codegenWorld,
diff --git a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
index c1e165f..5af0868 100644
--- a/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
+++ b/pkg/compiler/lib/src/js_emitter/runtime_type_generator.dart
@@ -13,14 +13,13 @@
 import '../js_backend/js_interop_analysis.dart' as jsInteropAnalysis;
 import '../js_backend/namer.dart' show Namer;
 import '../js_backend/runtime_types.dart'
-    show RuntimeTypesChecks, RuntimeTypesEncoder, OnVariableCallback;
+    show RuntimeTypesChecks, RuntimeTypesEncoder;
 import '../js_backend/runtime_types_codegen.dart'
-    show ClassChecks, ClassFunctionType, Substitution, TypeCheck;
+    show ClassChecks, ClassFunctionType, TypeCheck;
 import '../js_emitter/sorter.dart';
-import '../options.dart';
 import '../util/util.dart' show Setlet;
 
-import 'code_emitter_task.dart' show CodeEmitterTask, Emitter;
+import 'code_emitter_task.dart' show CodeEmitterTask;
 
 // Function signatures used in the generation of runtime type information.
 typedef void FunctionTypeSignatureEmitter(ClassFunctionType classFunctionType);
@@ -94,8 +93,6 @@
   final RuntimeTypesEncoder _rtiEncoder;
   final _TypeContainedInOutputUnitVisitor _outputUnitVisitor;
 
-  CompilerOptions get _options => emitterTask.options;
-
   RuntimeTypeGenerator(this._commonElements, this._outputUnitData,
       this.emitterTask, this._namer, this._rtiChecks, this._rtiEncoder)
       : _outputUnitVisitor = new _TypeContainedInOutputUnitVisitor(
@@ -183,13 +180,6 @@
         result.addIsTest(
             checkedClass, _namer.operatorIs(checkedClass), js('1'));
       }
-      Substitution substitution = check.substitution;
-      if (substitution != null && !_options.useNewRti) {
-        jsAst.Expression body =
-            _getSubstitutionCode(emitterTask.emitter, substitution);
-        result.addSubstitution(
-            checkedClass, _namer.substitutionName(checkedClass), body);
-      }
     }
 
     _generateIsTestsOn(
@@ -210,71 +200,6 @@
     return result;
   }
 
-  /// Compute a JavaScript expression that describes the necessary substitution
-  /// for type arguments in a subtype test.
-  ///
-  /// The result can be:
-  ///  1) `null`, if no substituted check is necessary, because the type
-  ///     variables are the same or there are no type variables in the class
-  ///     that is checked for.
-  ///  2) A list expression describing the type arguments to be used in the
-  ///     subtype check, if the type arguments to be used in the check do not
-  ///     depend on the type arguments of the object.
-  ///  3) A function mapping the type variables of the object to be checked to
-  ///     a list expression.
-  jsAst.Expression _getSubstitutionCode(
-      Emitter emitter, Substitution substitution) {
-    if (substitution.isTrivial) {
-      return new jsAst.LiteralNull();
-    }
-
-    if (substitution.isJsInterop) {
-      return js('function() { return # }',
-          _rtiEncoder.getJsInteropTypeArguments(substitution.length));
-    }
-
-    jsAst.Expression declaration(TypeVariableType variable) {
-      return new jsAst.Parameter(_getVariableName(variable.element.name));
-    }
-
-    jsAst.Expression use(TypeVariableType variable) {
-      return new jsAst.VariableUse(_getVariableName(variable.element.name));
-    }
-
-    if (substitution.arguments.every((DartType type) => type is DynamicType)) {
-      return emitter.generateFunctionThatReturnsNull();
-    } else {
-      jsAst.Expression value =
-          _getSubstitutionRepresentation(emitter, substitution.arguments, use);
-      if (substitution.isFunction) {
-        Iterable<jsAst.Expression> formals =
-            // TODO(johnniwinther): Pass [declaration] directly to `map` when
-            // `substitution.parameters` can no longer be a
-            // `List<ResolutionDartType>`.
-            substitution.parameters.map((type) => declaration(type));
-        return js('function(#) { return # }', [formals, value]);
-      } else {
-        return js('function() { return # }', value);
-      }
-    }
-  }
-
-  jsAst.Expression _getSubstitutionRepresentation(
-      Emitter emitter, List<DartType> types, OnVariableCallback onVariable) {
-    List<jsAst.Expression> elements = types
-        .map((DartType type) =>
-            _rtiEncoder.getTypeRepresentation(emitter, type, onVariable))
-        .toList(growable: false);
-    return new jsAst.ArrayInitializer(elements);
-  }
-
-  String _getVariableName(String name) {
-    // Kernel type variable names for anonymous mixin applications have names
-    // canonicalized to a non-identified, e.g. '#U0'.
-    name = name.replaceAll('#', '_');
-    return _namer.safeVariableName(name);
-  }
-
   void _generateIsTestsOn(
       ClassEntity cls,
       FunctionTypeSignatureEmitter generateFunctionTypeSignature,
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
index fff5a8f..5de338a 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/fragment_emitter.dart
@@ -615,19 +615,17 @@
       this._nativeEmitter,
       this._closedWorld,
       this._codegenWorld) {
-    if (_options.useNewRti) {
-      _recipeEncoder = RecipeEncoderImpl(
-          _closedWorld,
-          _options.disableRtiOptimization
-              ? TrivialRuntimeTypesSubstitutions(_closedWorld)
-              : RuntimeTypesImpl(_closedWorld),
-          _closedWorld.nativeData,
-          _closedWorld.elementEnvironment,
-          _closedWorld.commonElements,
-          _closedWorld.rtiNeed);
-      _rulesetEncoder =
-          RulesetEncoder(_closedWorld.dartTypes, _emitter, _recipeEncoder);
-    }
+    _recipeEncoder = RecipeEncoderImpl(
+        _closedWorld,
+        _options.disableRtiOptimization
+            ? TrivialRuntimeTypesSubstitutions(_closedWorld)
+            : RuntimeTypesImpl(_closedWorld),
+        _closedWorld.nativeData,
+        _closedWorld.elementEnvironment,
+        _closedWorld.commonElements,
+        _closedWorld.rtiNeed);
+    _rulesetEncoder =
+        RulesetEncoder(_closedWorld.dartTypes, _emitter, _recipeEncoder);
   }
 
   js.Expression generateEmbeddedGlobalAccess(String global) =>
@@ -700,7 +698,7 @@
           emitEmbeddedGlobalsPart2(program, deferredLoadingState),
       'typeRules': emitTypeRules(fragment),
       'variances': emitVariances(fragment),
-      'sharedTypeRtis': _options.useNewRti ? TypeReferenceResource() : [],
+      'sharedTypeRtis': TypeReferenceResource(),
       'nativeSupport': emitNativeSupport(fragment),
       'jsInteropSupport': jsInteropAnalysis.buildJsInteropBootstrap(
               _codegenWorld, _closedWorld.nativeData, _namer) ??
@@ -831,7 +829,7 @@
       'types': deferredTypes,
       'nativeSupport': nativeSupport,
       'typesOffset': _namer.typesOffsetName,
-      'sharedTypeRtis': _options.useNewRti ? TypeReferenceResource() : [],
+      'sharedTypeRtis': TypeReferenceResource(),
     });
 
     if (_options.experimentStartupFunctions) {
@@ -842,8 +840,6 @@
   }
 
   void finalizeTypeReferences(js.Node code) {
-    if (!_options.useNewRti) return;
-
     TypeReferenceFinalizer finalizer = TypeReferenceFinalizerImpl(
         _emitter, _commonElements, _recipeEncoder, _options.enableMinification);
     finalizer.addCode(code);
@@ -1918,9 +1914,7 @@
           js.Property(js.string(TYPE_TO_INTERCEPTOR_MAP), js.LiteralNull()));
     }
 
-    if (_options.useNewRti) {
-      globals.add(js.Property(js.string(RTI_UNIVERSE), createRtiUniverse()));
-    }
+    globals.add(js.Property(js.string(RTI_UNIVERSE), createRtiUniverse()));
 
     globals.add(emitMangledGlobalNames());
 
@@ -1969,8 +1963,6 @@
   }
 
   js.Block emitTypeRules(Fragment fragment) {
-    if (!_options.useNewRti) return js.Block.empty();
-
     List<js.Statement> statements = [];
 
     bool addJsObjectRedirections = false;
@@ -2061,7 +2053,7 @@
   }
 
   js.Statement emitVariances(Fragment fragment) {
-    if (!_options.enableVariance || !_options.useNewRti) {
+    if (!_options.enableVariance) {
       return js.EmptyStatement();
     }
 
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 fe06ca1..e92f9f1 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -138,8 +138,7 @@
     _elementEnvironment = new JsElementEnvironment(this);
     _typeConverter = new DartTypeConverter(options, this);
     _types = new KernelDartTypes(this, options);
-    _commonElements = new CommonElementsImpl(
-        _types, _elementEnvironment, _elementMap.options);
+    _commonElements = new CommonElementsImpl(_types, _elementEnvironment);
     _constantValuefier = new ConstantValuefier(this);
 
     programEnv = _elementMap.env.convert();
@@ -299,8 +298,7 @@
     _elementEnvironment = new JsElementEnvironment(this);
     _typeConverter = new DartTypeConverter(options, this);
     _types = new KernelDartTypes(this, options);
-    _commonElements =
-        new CommonElementsImpl(_types, _elementEnvironment, options);
+    _commonElements = new CommonElementsImpl(_types, _elementEnvironment);
     _constantValuefier = new ConstantValuefier(this);
 
     source.registerComponentLookup(new ComponentLookup(component));
@@ -1186,9 +1184,9 @@
         environment: _environment.toMap(),
         enableTripleShift:
             options.languageExperiments[ir.ExperimentalFlag.tripleShift],
-        evaluationMode: options.nullSafetyMode == NullSafetyMode.sound
-            ? ir.EvaluationMode.strong
-            : ir.EvaluationMode.weak);
+        evaluationMode: options.useLegacySubtyping
+            ? ir.EvaluationMode.weak
+            : ir.EvaluationMode.strong);
   }
 
   @override
@@ -1332,6 +1330,10 @@
       var mainUri = elementEnvironment.mainLibrary.canonicalUri;
       // Tests permit lookup outside of dart: libraries.
       return mainUri.path
+              .contains(RegExp(r'(?<!generated_)tests/dart2js/internal')) ||
+          mainUri.path
+              .contains(RegExp(r'(?<!generated_)tests/dart2js/native')) ||
+          mainUri.path
               .contains(RegExp(r'(?<!generated_)tests/dart2js_2/internal')) ||
           mainUri.path
               .contains(RegExp(r'(?<!generated_)tests/dart2js_2/native'));
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index 58716eb..aedff40 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -648,13 +648,17 @@
       String name = parameter.name;
       ConstantValue defaultValue;
       if (parameter.isRequired) {
-        defaultValue = elementMap.getRequiredSentinelConstantValue();
+        if (elementMap.types.useLegacySubtyping) {
+          defaultValue = NullConstantValue();
+        } else {
+          defaultValue = elementMap.getRequiredSentinelConstantValue();
+        }
       } else if (isOptional) {
         if (parameter.initializer != null) {
           defaultValue =
               elementMap.getConstantValue(memberContext, parameter.initializer);
         } else {
-          defaultValue = new NullConstantValue();
+          defaultValue = NullConstantValue();
         }
       }
       f(type, name, defaultValue);
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 06fc442..ecd134b 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -218,15 +218,13 @@
       rtiSubstitutions = runtimeTypesImpl;
     }
 
-    RecipeEncoder rtiRecipeEncoder = _compiler.options.useNewRti
-        ? new RecipeEncoderImpl(
-            closedWorld,
-            rtiSubstitutions,
-            closedWorld.nativeData,
-            closedWorld.elementEnvironment,
-            closedWorld.commonElements,
-            closedWorld.rtiNeed)
-        : null;
+    RecipeEncoder rtiRecipeEncoder = new RecipeEncoderImpl(
+        closedWorld,
+        rtiSubstitutions,
+        closedWorld.nativeData,
+        closedWorld.elementEnvironment,
+        closedWorld.commonElements,
+        closedWorld.rtiNeed);
 
     CodegenInputs codegen = new CodegenInputsImpl(rtiSubstitutions, rtiEncoder,
         rtiRecipeEncoder, tracer, rtiTags, fixedNames);
diff --git a/pkg/compiler/lib/src/kernel/dart2js_target.dart b/pkg/compiler/lib/src/kernel/dart2js_target.dart
index b0748af..7bb0b27 100644
--- a/pkg/compiler/lib/src/kernel/dart2js_target.dart
+++ b/pkg/compiler/lib/src/kernel/dart2js_target.dart
@@ -36,7 +36,10 @@
   bool allowedTestLibrary() {
     String scriptName = uri.path;
     return scriptName
-            .contains(RegExp(r'(?<!generated_)tests/dart2js_2/native')) ||
+            .contains(RegExp(r'(?<!generated_)tests/dart2js/native')) ||
+        scriptName.contains(RegExp(r'(?<!generated_)tests/dart2js/internal')) ||
+        scriptName.contains('generated_tests/dart2js/native/native_test') ||
+        scriptName.contains(RegExp(r'(?<!generated_)tests/dart2js_2/native')) ||
         scriptName
             .contains(RegExp(r'(?<!generated_)tests/dart2js_2/internal')) ||
         scriptName.contains('generated_tests/dart2js_2/native/native_test');
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 7031f2e..386f119 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -119,8 +119,7 @@
     _elementEnvironment = new KernelElementEnvironment(this);
     _typeConverter = new DartTypeConverter(options, this);
     _types = new KernelDartTypes(this, options);
-    _commonElements =
-        new CommonElementsImpl(_types, _elementEnvironment, options);
+    _commonElements = new CommonElementsImpl(_types, _elementEnvironment);
     _constantValuefier = new ConstantValuefier(this);
   }
 
@@ -819,9 +818,9 @@
         environment: _environment.toMap(),
         enableTripleShift:
             options.languageExperiments[ir.ExperimentalFlag.tripleShift],
-        evaluationMode: options.nullSafetyMode == NullSafetyMode.sound
-            ? ir.EvaluationMode.strong
-            : ir.EvaluationMode.weak);
+        evaluationMode: options.useLegacySubtyping
+            ? ir.EvaluationMode.weak
+            : ir.EvaluationMode.strong);
   }
 
   @override
@@ -916,6 +915,10 @@
       var mainUri = elementEnvironment.mainLibrary.canonicalUri;
       // Tests permit lookup outside of dart: libraries.
       return mainUri.path
+              .contains(RegExp(r'(?<!generated_)tests/dart2js/internal')) ||
+          mainUri.path
+              .contains(RegExp(r'(?<!generated_)tests/dart2js/native')) ||
+          mainUri.path
               .contains(RegExp(r'(?<!generated_)tests/dart2js_2/internal')) ||
           mainUri.path
               .contains(RegExp(r'(?<!generated_)tests/dart2js_2/native'));
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index 6b4bde7..fee3632 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -64,7 +64,7 @@
       // We defer selecting the platform until we've resolved the NNBD mode.
       String getPlatformFilename() {
         String platform = targetName;
-        if ((_options.nullSafetyMode == NullSafetyMode.sound)) {
+        if (!_options.useLegacySubtyping) {
           platform += "_nnbd_strong";
         }
         platform += "_platform.dill";
diff --git a/pkg/compiler/lib/src/kernel/native_basic_data.dart b/pkg/compiler/lib/src/kernel/native_basic_data.dart
index 81256fb..f4e35a2 100644
--- a/pkg/compiler/lib/src/kernel/native_basic_data.dart
+++ b/pkg/compiler/lib/src/kernel/native_basic_data.dart
@@ -33,8 +33,10 @@
     String annotationName;
     for (ConstantValue value in metadata) {
       String name = readAnnotationName(commonElements.dartTypes, spannable,
-          value, commonElements.jsAnnotationClass,
-          defaultValue: '');
+              value, commonElements.jsAnnotationClass1, defaultValue: '') ??
+          readAnnotationName(commonElements.dartTypes, spannable, value,
+              commonElements.jsAnnotationClass2,
+              defaultValue: '');
       if (annotationName == null) {
         annotationName = name;
       } else if (name != null) {
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 5b84ff7..2f719b0 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -339,9 +339,6 @@
   /// called.
   bool experimentCallInstrumentation = false;
 
-  /// Whether to use the new RTI representation (default).
-  final bool useNewRti = true;
-
   /// Whether null-safety (non-nullable types) are enabled in the sdk.
   ///
   /// This may be true either when `--enable-experiment=non-nullable` is
@@ -353,6 +350,9 @@
   /// unsound or sound semantics.
   ///
   /// If unspecified, the mode must be inferred from the entrypoint.
+  ///
+  /// This option should rarely need to be accessed directly. Consider using
+  /// [useLegacySubtyping] instead.
   NullSafetyMode nullSafetyMode = NullSafetyMode.unspecified;
   bool _soundNullSafety = false;
   bool _noSoundNullSafety = false;
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index b3fac71..d5b39b7 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -340,24 +340,6 @@
     return new HLiteralList(inputs, _abstractValueDomain.growableListType);
   }
 
-  HInstruction _callSetRuntimeTypeInfoWithTypeArguments(
-      InterfaceType type,
-      List<HInstruction> rtiInputs,
-      HInstruction newObject,
-      SourceInformation sourceInformation) {
-    if (!_rtiNeed.classNeedsTypeArguments(type.element)) {
-      return newObject;
-    }
-
-    HInstruction typeInfo = new HTypeInfoExpression(
-        TypeInfoExpressionKind.INSTANCE,
-        closedWorld.elementEnvironment.getThisType(type.element),
-        rtiInputs,
-        _abstractValueDomain.dynamicType);
-    add(typeInfo);
-    return _callSetRuntimeTypeInfo(typeInfo, newObject, sourceInformation);
-  }
-
   /// Called when control flow is about to change, in which case we need to
   /// specify special successors if we are already in a try/catch/finally block.
   void _handleInTryStatement() {
@@ -384,7 +366,7 @@
       case 'USE_CONTENT_SECURITY_POLICY':
         return options.useContentSecurityPolicy;
       case 'USE_NEW_RTI':
-        return options.useNewRti;
+        return true;
       case 'VARIANCE':
         return options.enableVariance;
       case 'NNBD':
@@ -529,11 +511,7 @@
                 "Unexpected function signature: "
                 "$targetElement inside a non-closure: $target");
           }
-          if (options.useNewRti) {
-            _buildMethodSignatureNewRti(originalClosureNode);
-          } else {
-            _buildMethodSignature(originalClosureNode);
-          }
+          _buildMethodSignatureNewRti(originalClosureNode);
           break;
         case MemberKind.generatorBody:
           _buildGeneratorBody(
@@ -826,31 +804,11 @@
       bool needsTypeArguments =
           closedWorld.rtiNeed.classNeedsTypeArguments(cls);
       if (needsTypeArguments) {
-        if (options.useNewRti) {
-          InterfaceType thisType = _elementEnvironment.getThisType(cls);
-          HInstruction typeArgument = _typeBuilder.analyzeTypeArgumentNewRti(
-              thisType, sourceElement,
-              sourceInformation: sourceInformation);
-          constructorArguments.add(typeArgument);
-        } else {
-          // Read the values of the type arguments and create a
-          // HTypeInfoExpression to set on the newly created object.
-          List<HInstruction> typeArguments = <HInstruction>[];
-          InterfaceType thisType = _elementEnvironment.getThisType(cls);
-          for (DartType typeVariable in thisType.typeArguments) {
-            HInstruction argument = localsHandler
-                .readLocal(localsHandler.getTypeVariableAsLocal(typeVariable));
-            typeArguments.add(argument);
-          }
-
-          HInstruction typeInfo = new HTypeInfoExpression(
-              TypeInfoExpressionKind.INSTANCE,
-              thisType,
-              typeArguments,
-              _abstractValueDomain.dynamicType);
-          add(typeInfo);
-          constructorArguments.add(typeInfo);
-        }
+        InterfaceType thisType = _elementEnvironment.getThisType(cls);
+        HInstruction typeArgument = _typeBuilder.analyzeTypeArgumentNewRti(
+            thisType, sourceElement,
+            sourceInformation: sourceInformation);
+        constructorArguments.add(typeArgument);
       }
       newObject = new HCreate(cls, constructorArguments,
           _abstractValueDomain.createNonNullExact(cls), sourceInformation,
@@ -1243,35 +1201,6 @@
     localsHandler.scopeInfo = oldScopeInfo;
   }
 
-  /// Constructs a special signature function for a closure. It is unique in
-  /// that no corresponding ir.Node actually exists for it. We just use the
-  /// targetElement.
-  void _buildMethodSignature(ir.FunctionNode originalClosureNode) {
-    _openFunction(targetElement, checks: TargetChecks.none);
-    List<HInstruction> typeArguments = <HInstruction>[];
-
-    // Add function type variables.
-    FunctionType functionType =
-        _elementMap.getFunctionType(originalClosureNode);
-    functionType.forEachTypeVariable((TypeVariableType typeVariableType) {
-      DartType result = localsHandler.substInContext(typeVariableType);
-      HInstruction argument =
-          _typeBuilder.analyzeTypeArgument(result, sourceElement);
-      typeArguments.add(argument);
-    });
-    push(new HTypeInfoExpression(
-        TypeInfoExpressionKind.COMPLETE,
-        _elementMap.getFunctionType(originalClosureNode),
-        typeArguments,
-        _abstractValueDomain.functionType));
-    HInstruction value = pop();
-    close(new HReturn(_abstractValueDomain, value,
-            _sourceInformationBuilder.buildReturn(originalClosureNode)))
-        .addSuccessor(graph.exit);
-
-    _closeFunction();
-  }
-
   /// Constructs a special signature function for a closure.
   void _buildMethodSignatureNewRti(ir.FunctionNode originalClosureNode) {
     // The signature function has no corresponding ir.Node, so we just use the
@@ -1405,12 +1334,7 @@
     if (elementType.containsFreeTypeVariables) {
       // Type must be computed in the entry function, where the type variables
       // are in scope, and passed to the body function.
-      if (options.useNewRti) {
-        inputs
-            .add(_typeBuilder.analyzeTypeArgumentNewRti(elementType, function));
-      } else {
-        inputs.add(_typeBuilder.analyzeTypeArgument(elementType, function));
-      }
+      inputs.add(_typeBuilder.analyzeTypeArgumentNewRti(elementType, function));
     } else {
       // Types with no type variables can be emitted as part of the generator,
       // avoiding an extra argument.
@@ -1533,17 +1457,8 @@
         DartType bound = _getDartTypeIfValid(typeParameter.bound);
         if (!dartTypes.isTopType(bound)) {
           registry.registerTypeUse(TypeUse.typeVariableBoundCheck(bound));
-          if (options.useNewRti) {
-            // TODO(sigmund): method name here is not minified, should it be?
-            _checkTypeBound(newParameter, bound, local.name, method.name);
-          } else {
-            _assertIsType(
-                newParameter,
-                bound,
-                "The type argument '",
-                "' is not a subtype of the type variable bound '",
-                "' of type variable '${local.name}' in '${method.name}'.");
-          }
+          // TODO(sigmund): method name here is not minified, should it be?
+          _checkTypeBound(newParameter, bound, local.name, method.name);
         }
       }
     }
@@ -2474,13 +2389,9 @@
     }
 
     if (policy.isEmitted) {
-      HInstruction converted = _typeBuilder.buildTypeConversion(
-          expressionInstruction,
-          localsHandler.substInContext(type),
-          node.isTypeError
-              ? HTypeConversion.TYPE_CHECK
-              : HTypeConversion.CAST_CHECK,
-          sourceInformation: sourceInformation);
+      HInstruction converted = _typeBuilder.buildAsCheck(
+          expressionInstruction, localsHandler.substInContext(type),
+          isTypeError: node.isTypeError, sourceInformation: sourceInformation);
       if (converted != expressionInstruction) {
         add(converted);
       }
@@ -3133,22 +3044,12 @@
         _equivalentToMissingRti(arrayType)) {
       return object;
     }
-    if (options.useNewRti) {
-      HInstruction rti =
-          _typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
+    HInstruction rti =
+        _typeBuilder.analyzeTypeArgumentNewRti(arrayType, sourceElement);
 
-      // TODO(15489): Register at codegen.
-      registry?.registerInstantiation(type);
-      return _callSetRuntimeTypeInfo(rti, object, sourceInformation);
-    }
-    List<HInstruction> arguments = <HInstruction>[];
-    for (DartType argument in type.typeArguments) {
-      arguments.add(_typeBuilder.analyzeTypeArgument(argument, sourceElement));
-    }
     // TODO(15489): Register at codegen.
     registry?.registerInstantiation(type);
-    return _callSetRuntimeTypeInfoWithTypeArguments(
-        type, arguments, object, sourceInformation);
+    return _callSetRuntimeTypeInfo(rti, object, sourceInformation);
   }
 
   @override
@@ -4080,38 +3981,26 @@
 
     HInstruction object = arguments[0];
     HInstruction closure = arguments[1];
-    HInstruction interceptor = _interceptorFor(object, sourceInformation);
 
     List<HInstruction> inputs = <HInstruction>[closure];
     List<DartType> typeArguments = <DartType>[];
 
-    if (options.useNewRti) {
-      closedWorld.registerExtractTypeArguments(cls);
-      HInstruction instanceType =
-          HInstanceEnvironment(object, _abstractValueDomain.dynamicType);
-      add(instanceType);
-      TypeEnvironmentStructure envStructure =
-          FullTypeEnvironmentStructure(classType: thisType);
+    closedWorld.registerExtractTypeArguments(cls);
+    HInstruction instanceType =
+        HInstanceEnvironment(object, _abstractValueDomain.dynamicType);
+    add(instanceType);
+    TypeEnvironmentStructure envStructure =
+        FullTypeEnvironmentStructure(classType: thisType);
 
-      thisType.typeArguments.forEach((_typeVariable) {
-        TypeVariableType variable = _typeVariable;
-        typeArguments.add(variable);
-        TypeRecipe recipe = TypeExpressionRecipe(variable);
-        HInstruction typeEval = new HTypeEval(instanceType, envStructure,
-            recipe, _abstractValueDomain.dynamicType);
-        add(typeEval);
-        inputs.add(typeEval);
-      });
-    } else {
-      thisType.typeArguments.forEach((_typeVariable) {
-        TypeVariableType variable = _typeVariable;
-        typeArguments.add(variable);
-        HInstruction readType = new HTypeInfoReadVariable.intercepted(
-            variable, interceptor, object, _abstractValueDomain.dynamicType);
-        add(readType);
-        inputs.add(readType);
-      });
-    }
+    thisType.typeArguments.forEach((_typeVariable) {
+      TypeVariableType variable = _typeVariable;
+      typeArguments.add(variable);
+      TypeRecipe recipe = TypeExpressionRecipe(variable);
+      HInstruction typeEval = new HTypeEval(
+          instanceType, envStructure, recipe, _abstractValueDomain.dynamicType);
+      add(typeEval);
+      inputs.add(typeEval);
+    });
 
     // TODO(sra): In compliance mode, insert a check that [closure] is a
     // function of N type arguments.
@@ -4734,8 +4623,7 @@
 
   void _handleForeignGetJSArrayInteropRti(ir.StaticInvocation invocation) {
     if (_unexpectedForeignArguments(invocation,
-            minPositional: 0, maxPositional: 0) ||
-        !options.useNewRti) {
+        minPositional: 0, maxPositional: 0)) {
       // Result expected on stack.
       stack.add(graph.addConstantNull(closedWorld));
       return;
@@ -5366,28 +5254,6 @@
         sourceInformation);
   }
 
-  void _assertIsType(HInstruction subtypeInstruction, DartType supertype,
-      String prefix, String infix, String suffix) {
-    HInstruction supertypeInstruction = _typeBuilder.analyzeTypeArgument(
-        localsHandler.substInContext(supertype), sourceElement);
-    HInstruction prefixInstruction =
-        graph.addConstantString(prefix, closedWorld);
-    HInstruction infixInstruction = graph.addConstantString(infix, closedWorld);
-    HInstruction suffixInstruction =
-        graph.addConstantString(suffix, closedWorld);
-    FunctionEntity element = _commonElements.assertIsSubtype;
-    var inputs = <HInstruction>[
-      subtypeInstruction,
-      supertypeInstruction,
-      prefixInstruction,
-      infixInstruction,
-      suffixInstruction
-    ];
-    HInstruction assertIsSubtype = new HInvokeStatic(element, inputs,
-        subtypeInstruction.instructionType, const <DartType>[]);
-    add(assertIsSubtype);
-  }
-
   void _checkTypeBound(HInstruction typeInstruction, DartType bound,
       String variableName, String methodName) {
     HInstruction boundInstruction = _typeBuilder.analyzeTypeArgumentNewRti(
@@ -5484,146 +5350,14 @@
     DartType typeValue =
         localsHandler.substInContext(_elementMap.getDartType(type));
 
-    if (options.useNewRti) {
-      HInstruction rti =
-          _typeBuilder.analyzeTypeArgumentNewRti(typeValue, sourceElement);
-      AbstractValueWithPrecision checkedType =
-          _abstractValueDomain.createFromStaticType(typeValue, nullable: false);
+    HInstruction rti =
+        _typeBuilder.analyzeTypeArgumentNewRti(typeValue, sourceElement);
+    AbstractValueWithPrecision checkedType =
+        _abstractValueDomain.createFromStaticType(typeValue, nullable: false);
 
-      push(HIsTest(typeValue, checkedType, expression, rti,
-          _abstractValueDomain.boolType)
-        ..sourceInformation = sourceInformation);
-      return;
-    }
-
-    if (dartTypes.isTopType(typeValue)) {
-      stack.add(graph.addConstantBool(true, closedWorld));
-      return;
-    }
-
-    if (typeValue is FunctionType) {
-      HInstruction representation =
-          _typeBuilder.analyzeTypeArgument(typeValue, sourceElement);
-      List<HInstruction> inputs = <HInstruction>[
-        expression,
-        representation,
-      ];
-      _pushStaticInvocation(_commonElements.functionTypeTest, inputs,
-          _abstractValueDomain.boolType, const <DartType>[],
-          sourceInformation: sourceInformation);
-      HInstruction call = pop();
-      push(new HIs.compound(typeValue, expression, call,
-          _abstractValueDomain.boolType, sourceInformation));
-      return;
-    }
-
-    if (typeValue is FutureOrType) {
-      HInstruction representation =
-          _typeBuilder.analyzeTypeArgument(typeValue, sourceElement);
-      List<HInstruction> inputs = <HInstruction>[
-        expression,
-        representation,
-      ];
-      _pushStaticInvocation(_commonElements.futureOrTest, inputs,
-          _abstractValueDomain.boolType, const <DartType>[],
-          sourceInformation: sourceInformation);
-      HInstruction call = pop();
-      push(new HIs.compound(typeValue, expression, call,
-          _abstractValueDomain.boolType, sourceInformation));
-      return;
-    }
-
-    if (typeValue is TypeVariableType) {
-      HInstruction runtimeType =
-          _typeBuilder.addTypeVariableReference(typeValue, sourceElement);
-      _pushStaticInvocation(
-          _commonElements.checkSubtypeOfRuntimeType,
-          <HInstruction>[expression, runtimeType],
-          _abstractValueDomain.boolType,
-          const <DartType>[],
-          sourceInformation: sourceInformation);
-      push(new HIs.variable(typeValue, expression, pop(),
-          _abstractValueDomain.boolType, sourceInformation));
-      return;
-    }
-
-    if (typeValue is InterfaceType && !_canIgnoreTypeArguments(typeValue)) {
-      HInstruction representations = _typeBuilder
-          .buildTypeArgumentRepresentations(typeValue, sourceElement);
-      add(representations);
-      ClassEntity element = typeValue.element;
-      js.Name operator = _namer.operatorIs(element);
-      HInstruction isFieldName =
-          graph.addConstantStringFromName(operator, closedWorld);
-      HInstruction asFieldName =
-          closedWorld.classHierarchy.hasAnyStrictSubtype(element) ||
-                  closedWorld.nativeData.isJsInteropClass(element)
-              ? graph.addConstantStringFromName(
-                  _namer.substitutionName(element), closedWorld)
-              : graph.addConstantNull(closedWorld);
-      List<HInstruction> inputs = <HInstruction>[
-        expression,
-        isFieldName,
-        representations,
-        asFieldName
-      ];
-      _pushStaticInvocation(_commonElements.checkSubtype, inputs,
-          _abstractValueDomain.boolType, const <DartType>[],
-          sourceInformation: sourceInformation);
-      push(new HIs.compound(typeValue, expression, pop(),
-          _abstractValueDomain.boolType, sourceInformation));
-      return;
-    }
-
-    if (_hasDirectCheckFor(typeValue)) {
-      push(new HIs.direct(typeValue, expression, _abstractValueDomain.boolType,
-          sourceInformation));
-      return;
-    }
-    // The interceptor is not always needed.  It is removed by optimization
-    // when the receiver type or tested type permit.
-    push(new HIs.raw(
-        typeValue,
-        expression,
-        _interceptorFor(expression, sourceInformation),
-        _abstractValueDomain.boolType,
-        sourceInformation));
-    return;
-  }
-
-  /// Returns `true` if the checking of [type] is performed directly on the
-  /// object and not on an interceptor.
-  bool _hasDirectCheckFor(DartType type) {
-    if (type is! InterfaceType) return false;
-    InterfaceType interfaceType = type;
-    ClassEntity element = interfaceType.element;
-    return element == _commonElements.stringClass ||
-        element == _commonElements.boolClass ||
-        element == _commonElements.numClass ||
-        element == _commonElements.intClass ||
-        element == _commonElements.doubleClass ||
-        element == _commonElements.jsArrayClass ||
-        element == _commonElements.jsMutableArrayClass ||
-        element == _commonElements.jsExtendableArrayClass ||
-        element == _commonElements.jsFixedArrayClass ||
-        element == _commonElements.jsUnmodifiableArrayClass;
-  }
-
-  /// Whether an is-check for [type] can be done ignoring type-arguments.
-  /// This will be true if [type] is raw, or all its type-arguments match the
-  /// type-parameter bounds.
-  bool _canIgnoreTypeArguments(InterfaceType type) {
-    InterfaceType thisType = _elementEnvironment.getThisType(type.element);
-    List<DartType> bounds = thisType.typeArguments;
-    for (int i = 0; i < bounds.length; i++) {
-      DartType arg = type.typeArguments[i];
-      if (dartTypes.isTopType(arg)) continue;
-      TypeVariableType typeVariable = bounds[i];
-      DartType bound =
-          _elementEnvironment.getTypeVariableBound(typeVariable.element);
-      if (bound != arg) return false;
-    }
-    return true;
+    push(HIsTest(
+        typeValue, checkedType, expression, rti, _abstractValueDomain.boolType)
+      ..sourceInformation = sourceInformation);
   }
 
   @override
@@ -6116,14 +5850,7 @@
       FunctionEntity function, TypeVariableType typeVariable) {
     DartType bound =
         _elementEnvironment.getTypeVariableDefaultType(typeVariable.element);
-    if (bound.containsTypeVariables && !options.useNewRti) {
-      // TODO(33422): Support type variables in default
-      // types. Temporarily using the "any" type (encoded as -2) to
-      // avoid failing on bounds checks.
-      return graph.addConstantInt(-2, closedWorld);
-    } else {
-      return _typeBuilder.analyzeTypeArgument(bound, function);
-    }
+    return _typeBuilder.analyzeTypeArgument(bound, function);
   }
 
   /// This method is invoked before inlining the body of [function] into this
diff --git a/pkg/compiler/lib/src/ssa/codegen.dart b/pkg/compiler/lib/src/ssa/codegen.dart
index cbb4bc0..73ab2b7 100644
--- a/pkg/compiler/lib/src/ssa/codegen.dart
+++ b/pkg/compiler/lib/src/ssa/codegen.dart
@@ -25,7 +25,6 @@
 import '../js_backend/checked_mode_helpers.dart';
 import '../js_backend/native_data.dart';
 import '../js_backend/namer.dart' show ModularNamer;
-import '../js_backend/runtime_types.dart';
 import '../js_backend/runtime_types_codegen.dart';
 import '../js_backend/runtime_types_new.dart'
     show RecipeEncoder, RecipeEncoding, indexTypeVariable;
@@ -117,9 +116,7 @@
           this,
           _options,
           emitter,
-          codegen.checkedModeHelpers,
           codegen.rtiSubstitutions,
-          codegen.rtiEncoder,
           codegen.rtiRecipeEncoder,
           namer,
           codegen.tracer,
@@ -147,9 +144,7 @@
           this,
           _options,
           emitter,
-          codegen.checkedModeHelpers,
           codegen.rtiSubstitutions,
-          codegen.rtiEncoder,
           codegen.rtiRecipeEncoder,
           namer,
           codegen.tracer,
@@ -185,9 +180,7 @@
   final CompilerTask _codegenTask;
   final CompilerOptions _options;
   final ModularEmitter _emitter;
-  final CheckedModeHelpers _checkedModeHelpers;
   final RuntimeTypesSubstitutions _rtiSubstitutions;
-  final RuntimeTypesEncoder _rtiEncoder;
   final RecipeEncoder _rtiRecipeEncoder;
   final ModularNamer _namer;
   final Tracer _tracer;
@@ -240,9 +233,7 @@
       this._codegenTask,
       this._options,
       this._emitter,
-      this._checkedModeHelpers,
       this._rtiSubstitutions,
-      this._rtiEncoder,
       this._rtiRecipeEncoder,
       this._namer,
       this._tracer,
@@ -704,8 +695,7 @@
     // argument.
     bool needsAssignment = true;
     if (instruction is HCheck) {
-      if (instruction is HTypeConversion ||
-          instruction is HPrimitiveCheck ||
+      if (instruction is HPrimitiveCheck ||
           instruction is HAsCheck ||
           instruction is HAsCheckSimple ||
           instruction is HBoolConversion ||
@@ -2094,7 +2084,8 @@
 
     List<js.Expression> arguments = visitArguments(node.inputs, start: 0);
 
-    if (element == _commonElements.jsAllowInterop) {
+    if (element == _commonElements.jsAllowInterop1 ||
+        element == _commonElements.jsAllowInterop2) {
       _nativeData.registerAllowInterop();
     }
 
@@ -3215,35 +3206,6 @@
   }
 
   @override
-  void visitTypeConversion(HTypeConversion node) {
-    assert(node.isTypeCheck || node.isCastCheck);
-    DartType type = node.typeExpression;
-    assert(type is! DynamicType);
-    assert(type is! VoidType);
-    if (type is FunctionType) {
-      // TODO(5022): We currently generate $isFunction checks for
-      // function types.
-      _registry
-          .registerTypeUse(new TypeUse.isCheck(_commonElements.functionType));
-    }
-    _registry.registerTypeUse(new TypeUse.isCheck(type));
-
-    CheckedModeHelper helper = _checkedModeHelpers.getCheckedModeHelper(
-        type, _closedWorld.commonElements,
-        typeCast: node.isCastCheck);
-
-    StaticUse staticUse = helper.getStaticUse(_closedWorld.commonElements);
-    _registry.registerStaticUse(staticUse);
-    List<js.Expression> arguments = <js.Expression>[];
-    use(node.checkedInput);
-    arguments.add(pop());
-    helper.generateAdditionalArguments(this, _namer, node, arguments);
-    push(
-        new js.Call(_emitter.staticFunctionAccess(staticUse.element), arguments)
-            .withSourceInformation(node.sourceInformation));
-  }
-
-  @override
   void visitPrimitiveCheck(HPrimitiveCheck node) {
     js.Expression test = _generateReceiverOrArgumentTypeTest(node);
     js.Block oldContainer = currentContainer;
@@ -3325,129 +3287,6 @@
   }
 
   @override
-  void visitTypeInfoReadRaw(HTypeInfoReadRaw node) {
-    use(node.inputs[0]);
-    js.Expression receiver = pop();
-    push(js.js(r'#.#', [receiver, _namer.rtiFieldJsName]));
-  }
-
-  @override
-  void visitTypeInfoReadVariable(HTypeInfoReadVariable node) {
-    TypeVariableEntity element = node.variable.element;
-    int index = element.index;
-
-    js.Expression interceptor;
-    if (node.isIntercepted) {
-      use(node.interceptor);
-      interceptor = pop();
-    }
-    HInstruction object = node.object;
-    use(object);
-    js.Expression receiver = pop();
-
-    if (typeVariableAccessNeedsSubstitution(element, object.instructionType)) {
-      js.Expression typeName =
-          js.quoteName(_namer.runtimeTypeName(element.typeDeclaration));
-      if (node.isIntercepted) {
-        FunctionEntity helperElement =
-            _commonElements.getRuntimeTypeArgumentIntercepted;
-        _registry.registerStaticUse(
-            new StaticUse.staticInvoke(helperElement, CallStructure.FOUR_ARGS));
-        js.Expression helper = _emitter.staticFunctionAccess(helperElement);
-        push(js.js(r'#(#, #, #, #)', [
-          helper,
-          interceptor,
-          receiver,
-          typeName,
-          js.js.number(index)
-        ]).withSourceInformation(node.sourceInformation));
-      } else {
-        FunctionEntity helperElement = _commonElements.getRuntimeTypeArgument;
-        _registry.registerStaticUse(new StaticUse.staticInvoke(
-            helperElement, CallStructure.THREE_ARGS));
-        js.Expression helper = _emitter.staticFunctionAccess(helperElement);
-        push(js.js(r'#(#, #, #)', [
-          helper,
-          receiver,
-          typeName,
-          js.js.number(index)
-        ]).withSourceInformation(node.sourceInformation));
-      }
-    } else {
-      FunctionEntity helperElement = _commonElements.getTypeArgumentByIndex;
-      _registry.registerStaticUse(
-          new StaticUse.staticInvoke(helperElement, CallStructure.TWO_ARGS));
-      js.Expression helper = _emitter.staticFunctionAccess(helperElement);
-      push(js.js(r'#(#, #)', [
-        helper,
-        receiver,
-        js.js.number(index)
-      ]).withSourceInformation(node.sourceInformation));
-    }
-  }
-
-  @override
-  void visitTypeInfoExpression(HTypeInfoExpression node) {
-    DartType type = node.dartType;
-    if (node.isTypeVariableReplacement) {
-      _registry.registerTypeUse(new TypeUse.typeArgument(type));
-    }
-
-    List<js.Expression> arguments = <js.Expression>[];
-    for (HInstruction input in node.inputs) {
-      use(input);
-      arguments.add(pop());
-    }
-
-    switch (node.kind) {
-      case TypeInfoExpressionKind.COMPLETE:
-        int index = 0;
-        js.Expression result = _rtiEncoder.getTypeRepresentation(
-            _emitter, type, (TypeVariableType variable) => arguments[index++]);
-        assert(
-            index == node.inputs.length,
-            "Not all input is read for type ${type}: "
-            "$index of ${node.inputs}.");
-        push(result);
-        return;
-
-      case TypeInfoExpressionKind.INSTANCE:
-        // We expect only flat types for the INSTANCE representation.
-        assert(
-            (type as InterfaceType).typeArguments.length == arguments.length);
-        _registry
-            // ignore:deprecated_member_use_from_same_package
-            .registerInstantiatedClass(_commonElements.listClass);
-        push(new js.ArrayInitializer(arguments)
-            .withSourceInformation(node.sourceInformation));
-    }
-  }
-
-  bool typeVariableAccessNeedsSubstitution(
-      TypeVariableEntity element, AbstractValue receiverMask) {
-    ClassEntity cls = element.typeDeclaration;
-
-    // See if the receiver type narrows the set of classes to ones that can be
-    // indexed.
-    // TODO(sra): Currently the only convenient query is [singleClass]. We
-    // should iterate over all the concrete classes in [receiverMask].
-    ClassEntity receiverClass =
-        _abstractValueDomain.getExactClass(receiverMask);
-    if (receiverClass != null) {
-      if (_rtiSubstitutions.isTrivialSubstitution(receiverClass, cls)) {
-        return false;
-      }
-    }
-
-    if (_closedWorld.isUsedAsMixin(cls)) return true;
-
-    return _closedWorld.classHierarchy.anyStrictSubclassOf(cls,
-        (ClassEntity subclass) {
-      return !_rtiSubstitutions.isTrivialSubstitution(subclass, cls);
-    });
-  }
-
-  @override
   void visitRef(HRef node) {
     visit(node.value);
   }
diff --git a/pkg/compiler/lib/src/ssa/codegen_helpers.dart b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
index 071c7fb..05f415f 100644
--- a/pkg/compiler/lib/src/ssa/codegen_helpers.dart
+++ b/pkg/compiler/lib/src/ssa/codegen_helpers.dart
@@ -846,13 +846,6 @@
   }
 
   @override
-  void visitTypeConversion(HTypeConversion instruction) {
-    // Type checks and cast checks compile to code that only use their input
-    // once, so we can safely visit them and try to merge the input.
-    visitInstruction(instruction);
-  }
-
-  @override
   void visitAsCheck(HAsCheck instruction) {
     // Type checks and cast checks compile to code that only use their input
     // once, so we can safely visit them and try to merge the input.
diff --git a/pkg/compiler/lib/src/ssa/nodes.dart b/pkg/compiler/lib/src/ssa/nodes.dart
index f844949..e654310 100644
--- a/pkg/compiler/lib/src/ssa/nodes.dart
+++ b/pkg/compiler/lib/src/ssa/nodes.dart
@@ -100,17 +100,12 @@
   R visitThrowExpression(HThrowExpression node);
   R visitTruncatingDivide(HTruncatingDivide node);
   R visitTry(HTry node);
-  R visitTypeConversion(HTypeConversion node);
   R visitPrimitiveCheck(HPrimitiveCheck node);
   R visitBoolConversion(HBoolConversion node);
   R visitNullCheck(HNullCheck node);
   R visitTypeKnown(HTypeKnown node);
   R visitYield(HYield node);
 
-  R visitTypeInfoReadRaw(HTypeInfoReadRaw node);
-  R visitTypeInfoReadVariable(HTypeInfoReadVariable node);
-  R visitTypeInfoExpression(HTypeInfoExpression node);
-
   // Instructions for 'dart:_rti'.
   R visitIsTest(HIsTest node);
   R visitIsTestSimple(HIsTestSimple node);
@@ -589,8 +584,6 @@
   @override
   visitIsViaInterceptor(HIsViaInterceptor node) => visitInstruction(node);
   @override
-  visitTypeConversion(HTypeConversion node) => visitCheck(node);
-  @override
   visitBoolConversion(HBoolConversion node) => visitCheck(node);
   @override
   visitNullCheck(HNullCheck node) => visitCheck(node);
@@ -604,15 +597,6 @@
   visitYield(HYield node) => visitInstruction(node);
 
   @override
-  visitTypeInfoReadRaw(HTypeInfoReadRaw node) => visitInstruction(node);
-  @override
-  visitTypeInfoReadVariable(HTypeInfoReadVariable node) =>
-      visitInstruction(node);
-
-  @override
-  visitTypeInfoExpression(HTypeInfoExpression node) => visitInstruction(node);
-
-  @override
   visitIsTest(HIsTest node) => visitInstruction(node);
   @override
   visitIsTestSimple(HIsTestSimple node) => visitInstruction(node);
@@ -1087,7 +1071,6 @@
   static const int STATIC_STORE_TYPECODE = 22;
   static const int FIELD_GET_TYPECODE = 23;
   static const int FUNCTION_REFERENCE_TYPECODE = 24;
-  static const int TYPE_CONVERSION_TYPECODE = 25;
   static const int TYPE_KNOWN_TYPECODE = 26;
   static const int INVOKE_STATIC_TYPECODE = 27;
   static const int INDEX_TYPECODE = 28;
@@ -1098,10 +1081,6 @@
   static const int TRUNCATING_DIVIDE_TYPECODE = 36;
   static const int IS_VIA_INTERCEPTOR_TYPECODE = 37;
 
-  static const int TYPE_INFO_READ_RAW_TYPECODE = 38;
-  static const int TYPE_INFO_READ_VARIABLE_TYPECODE = 39;
-  static const int TYPE_INFO_EXPRESSION_TYPECODE = 40;
-
   static const int INVOKE_EXTERNAL_TYPECODE = 41;
   static const int FOREIGN_CODE_TYPECODE = 42;
   static const int REMAINDER_TYPECODE = 43;
@@ -1407,30 +1386,6 @@
     return false;
   }
 
-  HInstruction convertType(JClosedWorld closedWorld, DartType type, int kind) {
-    if (type == null) return this;
-    // Only the builder knows how to create [HTypeConversion]
-    // instructions with generics. It has the generic type context
-    // available.
-    assert(type is! TypeVariableType);
-    assert(closedWorld.dartTypes.treatAsRawType(type) || type is FunctionType);
-    if (closedWorld.dartTypes.isTopType(type)) return this;
-    if (type is FunctionType || type is FutureOrType) {
-      return new HTypeConversion(type, kind,
-          closedWorld.abstractValueDomain.dynamicType, this, sourceInformation);
-    }
-    assert(type is InterfaceType);
-    if (kind == HTypeConversion.TYPE_CHECK &&
-        !closedWorld.dartTypes.treatAsRawType(type)) {
-      throw 'creating compound check to $type (this = ${this})';
-    } else {
-      InterfaceType interfaceType = type;
-      AbstractValue subtype = closedWorld.abstractValueDomain
-          .createNullableSubtype(interfaceType.element);
-      return new HTypeConversion(type, kind, subtype, this, sourceInformation);
-    }
-  }
-
   /// Return whether the instructions do not belong to a loop or
   /// belong to the same loop.
   bool hasSameLoopHeaderAs(HInstruction other) {
@@ -1588,15 +1543,6 @@
   HInstruction get value => inputs[0];
 
   @override
-  HInstruction convertType(JClosedWorld closedWorld, DartType type, int kind) {
-    HInstruction converted = value.convertType(closedWorld, type, kind);
-    if (converted == value) return this;
-    HTypeConversion conversion = converted;
-    conversion.inputs[0] = this;
-    return conversion;
-  }
-
-  @override
   accept(HVisitor visitor) => visitor.visitRef(this);
 
   @override
@@ -3678,121 +3624,6 @@
   toString() => 'HLateValue($target)';
 }
 
-/// Type check or cast using legacy constructor-based type representation.
-class HTypeConversion extends HCheck {
-  // Values for [kind].
-  static const int TYPE_CHECK = 0;
-  static const int CAST_CHECK = 1;
-
-  final DartType typeExpression;
-  final int kind;
-
-  AbstractValue checkedType; // Not final because we refine it.
-
-  HTypeConversion(this.typeExpression, this.kind, AbstractValue type,
-      HInstruction input, SourceInformation sourceInformation)
-      : checkedType = type,
-        super(<HInstruction>[input], type) {
-    this.sourceElement = input.sourceElement;
-    this.sourceInformation = sourceInformation;
-  }
-
-  HTypeConversion.withTypeRepresentation(this.typeExpression, this.kind,
-      AbstractValue type, HInstruction input, HInstruction typeRepresentation)
-      : checkedType = type,
-        super(<HInstruction>[input, typeRepresentation], type) {
-    sourceElement = input.sourceElement;
-  }
-
-  bool get hasTypeRepresentation {
-    return typeExpression != null &&
-        typeExpression is InterfaceType &&
-        inputs.length > 1;
-  }
-
-  HInstruction get typeRepresentation => inputs[1];
-
-  @override
-  HInstruction get checkedInput => super.checkedInput;
-
-  @override
-  HInstruction convertType(JClosedWorld closedWorld, DartType type, int kind) {
-    if (typeExpression == type) {
-      return this;
-    }
-    return super.convertType(closedWorld, type, kind);
-  }
-
-  bool get isTypeCheck => kind == TYPE_CHECK;
-  bool get isCastCheck => kind == CAST_CHECK;
-
-  @override
-  accept(HVisitor visitor) => visitor.visitTypeConversion(this);
-
-  @override
-  bool isJsStatement() => isControlFlow();
-  @override
-  bool isControlFlow() => false;
-
-  @override
-  int typeCode() => HInstruction.TYPE_CONVERSION_TYPECODE;
-  @override
-  bool typeEquals(HInstruction other) => other is HTypeConversion;
-  @override
-  bool isCodeMotionInvariant() => false;
-
-  @override
-  bool dataEquals(HTypeConversion other) {
-    return kind == other.kind &&
-        typeExpression == other.typeExpression &&
-        checkedType == other.checkedType;
-  }
-
-  bool isRedundant(JClosedWorld closedWorld) {
-    AbstractValueDomain abstractValueDomain = closedWorld.abstractValueDomain;
-    DartType type = typeExpression;
-    if (type != null) {
-      if (type is TypeVariableType) {
-        return false;
-      }
-      if (type is FutureOrType) {
-        // `null` always passes type conversion.
-        if (checkedInput.isNull(abstractValueDomain).isDefinitelyTrue) {
-          return true;
-        }
-        // TODO(johnniwinther): Optimize FutureOr type conversions.
-        return false;
-      }
-      if (!closedWorld.dartTypes.treatAsRawType(type)) {
-        // `null` always passes type conversion.
-        if (checkedInput.isNull(abstractValueDomain).isDefinitelyTrue) {
-          return true;
-        }
-        return false;
-      }
-      if (type is FunctionType) {
-        // `null` always passes type conversion.
-        if (checkedInput.isNull(abstractValueDomain).isDefinitelyTrue) {
-          return true;
-        }
-        // TODO(johnniwinther): Optimize function type conversions.
-        return false;
-      }
-    }
-    // Type is refined from `dynamic`, so it might become non-redundant.
-    if (abstractValueDomain.containsAll(checkedType).isPotentiallyTrue) {
-      return false;
-    }
-    AbstractValue inputType = checkedInput.instructionType;
-    return abstractValueDomain.isIn(inputType, checkedType).isDefinitelyTrue;
-  }
-
-  @override
-  String toString() => 'HTypeConversion(type=$typeExpression, kind=$kind, '
-      '${hasTypeRepresentation ? 'representation=$typeRepresentation, ' : ''}'
-      'checkedInput=$checkedInput)';
-}
-
 /// Check for receiver or argument type when lowering operation to a primitive,
 /// e.g. lowering `+` to [HAdd].
 ///
@@ -3828,14 +3659,6 @@
     this.sourceInformation = sourceInformation;
   }
 
-  @override
-  HInstruction convertType(JClosedWorld closedWorld, DartType type, int kind) {
-    if (typeExpression == type) {
-      return this;
-    }
-    return super.convertType(closedWorld, type, kind);
-  }
-
   bool get isArgumentTypeCheck => kind == ARGUMENT_TYPE_CHECK;
   bool get isReceiverTypeCheck => kind == RECEIVER_TYPE_CHECK;
 
@@ -4360,175 +4183,6 @@
       visitor.visitSwitchInfo(this);
 }
 
-/// Reads raw reified type info from an object.
-class HTypeInfoReadRaw extends HInstruction {
-  HTypeInfoReadRaw(HInstruction receiver, AbstractValue instructionType)
-      : super(<HInstruction>[receiver], instructionType) {
-    setUseGvn();
-  }
-
-  @override
-  accept(HVisitor visitor) => visitor.visitTypeInfoReadRaw(this);
-
-  @override
-  bool canThrow(AbstractValueDomain domain) => false;
-
-  @override
-  int typeCode() => HInstruction.TYPE_INFO_READ_RAW_TYPECODE;
-  @override
-  bool typeEquals(HInstruction other) => other is HTypeInfoReadRaw;
-
-  @override
-  bool dataEquals(HTypeInfoReadRaw other) {
-    return true;
-  }
-}
-
-/// Reads a type variable from an object. The read may be a simple indexing of
-/// the type parameters or it may require 'substitution'. There may be an
-/// interceptor argument to access the substitution of native classes.
-class HTypeInfoReadVariable extends HInstruction {
-  /// The type variable being read.
-  final TypeVariableType variable;
-  final bool isIntercepted;
-
-  HTypeInfoReadVariable.intercepted(this.variable, HInstruction interceptor,
-      HInstruction receiver, AbstractValue instructionType)
-      : isIntercepted = true,
-        super(<HInstruction>[interceptor, receiver], instructionType) {
-    setUseGvn();
-  }
-
-  HTypeInfoReadVariable.noInterceptor(
-      this.variable, HInstruction receiver, AbstractValue instructionType)
-      : isIntercepted = false,
-        super(<HInstruction>[receiver], instructionType) {
-    setUseGvn();
-  }
-
-  HInstruction get interceptor {
-    assert(isIntercepted);
-    return inputs.first;
-  }
-
-  HInstruction get object => inputs.last;
-
-  @override
-  accept(HVisitor visitor) => visitor.visitTypeInfoReadVariable(this);
-
-  @override
-  bool canThrow(AbstractValueDomain domain) => false;
-
-  @override
-  int typeCode() => HInstruction.TYPE_INFO_READ_VARIABLE_TYPECODE;
-  @override
-  bool typeEquals(HInstruction other) => other is HTypeInfoReadVariable;
-
-  @override
-  bool dataEquals(HTypeInfoReadVariable other) {
-    return variable == other.variable;
-  }
-
-  @override
-  String toString() => 'HTypeInfoReadVariable($variable)';
-}
-
-enum TypeInfoExpressionKind { COMPLETE, INSTANCE }
-
-/// Constructs a representation of a closed or ground-term type (that is, a type
-/// without type variables).
-///
-/// There are two forms:
-///
-/// - COMPLETE: A complete form that is self contained, used for the values of
-///   type parameters and non-raw is-checks.
-///
-/// - INSTANCE: A headless flat form for representing the sequence of values of
-///   the type parameters of an instance of a generic type.
-///
-/// The COMPLETE form value is constructed from [dartType] by replacing the type
-/// variables with consecutive values from [inputs], in the order generated by
-/// [DartType.forEachTypeVariable].  The type variables in [dartType] are
-/// treated as 'holes' in the term, which means that it must be ensured at
-/// construction, that duplicate occurences of a type variable in [dartType] are
-/// assigned the same value.
-///
-/// The INSTANCE form is constructed as a list of [inputs]. This is the same as
-/// the COMPLETE form for the 'thisType', except the root term's type is
-/// missing; this is implicit as the raw type of instance.  The [dartType] of
-/// the INSTANCE form must be the thisType of some class.
-///
-/// We want to remove the constrains on the INSTANCE form. In the meantime we
-/// get by with a tree of TypeExpressions.  Consider:
-///
-///     class Foo<T> {
-///       ... new Set<List<T>>()
-///     }
-///     class Set<E1> {
-///       factory Set() => new _LinkedHashSet<E1>();
-///     }
-///     class List<E2> { ... }
-///     class _LinkedHashSet<E3> { ... }
-///
-/// After inlining the factory constructor for `Set<E1>`, the HCreate should
-/// have type `_LinkedHashSet<List<T>>` and the TypeExpression should be a tree:
-///
-///    HCreate(dartType: _LinkedHashSet<List<T>>,
-///        [], // No arguments
-///        HTypeInfoExpression(INSTANCE,
-///            dartType: _LinkedHashSet<E3>, // _LinkedHashSet's thisType
-///            HTypeInfoExpression(COMPLETE,  // E3 = List<T>
-///                dartType: List<E2>,
-///                HTypeInfoReadVariable(this, T)))) // E2 = T
-
-// TODO(sra): The INSTANCE form requires the actual instance for full
-// interpretation. If the COMPLETE form was used on instances, then we could
-// simplify HTypeInfoReadVariable without an object.
-
-class HTypeInfoExpression extends HInstruction {
-  final TypeInfoExpressionKind kind;
-  final DartType dartType;
-
-  /// `true` if this
-  final bool isTypeVariableReplacement;
-
-  HTypeInfoExpression(this.kind, this.dartType, List<HInstruction> inputs,
-      AbstractValue instructionType,
-      {this.isTypeVariableReplacement: false})
-      : super(inputs, instructionType) {
-    setUseGvn();
-  }
-
-  @override
-  accept(HVisitor visitor) => visitor.visitTypeInfoExpression(this);
-
-  @override
-  bool canThrow(AbstractValueDomain domain) => false;
-
-  @override
-  int typeCode() => HInstruction.TYPE_INFO_EXPRESSION_TYPECODE;
-  @override
-  bool typeEquals(HInstruction other) => other is HTypeInfoExpression;
-
-  @override
-  bool dataEquals(HTypeInfoExpression other) {
-    return kind == other.kind && dartType == other.dartType;
-  }
-
-  @override
-  String toString() => 'HTypeInfoExpression($kindAsString, $dartType)';
-
-  // ignore: MISSING_RETURN
-  String get kindAsString {
-    switch (kind) {
-      case TypeInfoExpressionKind.COMPLETE:
-        return 'COMPLETE';
-      case TypeInfoExpressionKind.INSTANCE:
-        return 'INSTANCE';
-    }
-  }
-}
-
 // -----------------------------------------------------------------------------
 
 /// Is-test using Rti form of type expression.
diff --git a/pkg/compiler/lib/src/ssa/optimize.dart b/pkg/compiler/lib/src/ssa/optimize.dart
index 539a383..3dbabb7 100644
--- a/pkg/compiler/lib/src/ssa/optimize.dart
+++ b/pkg/compiler/lib/src/ssa/optimize.dart
@@ -769,30 +769,11 @@
 
     node.block.addBefore(node, splitInstruction);
 
-    HInstruction typeInfo;
-    if (_options.useNewRti) {
-      typeInfo = HLoadType.type(
-          _closedWorld.elementEnvironment.createInterfaceType(
-              commonElements.jsArrayClass, [commonElements.stringType]),
-          _abstractValueDomain.dynamicType);
-      node.block.addBefore(node, typeInfo);
-    } else {
-      HInstruction stringTypeInfo = new HTypeInfoExpression(
-          TypeInfoExpressionKind.COMPLETE,
-          _closedWorld.elementEnvironment
-              .getThisType(commonElements.stringClass),
-          <HInstruction>[],
-          _abstractValueDomain.dynamicType);
-      node.block.addBefore(node, stringTypeInfo);
-
-      typeInfo = new HTypeInfoExpression(
-          TypeInfoExpressionKind.INSTANCE,
-          _closedWorld.elementEnvironment
-              .getThisType(commonElements.jsArrayClass),
-          <HInstruction>[stringTypeInfo],
-          _abstractValueDomain.dynamicType);
-      node.block.addBefore(node, typeInfo);
-    }
+    HInstruction typeInfo = HLoadType.type(
+        _closedWorld.elementEnvironment.createInterfaceType(
+            commonElements.jsArrayClass, [commonElements.stringType]),
+        _abstractValueDomain.dynamicType);
+    node.block.addBefore(node, typeInfo);
 
     HInvokeStatic tagInstruction = new HInvokeStatic(
         commonElements.setRuntimeTypeInfo,
@@ -1316,29 +1297,6 @@
   }
 
   @override
-  HInstruction visitTypeConversion(HTypeConversion node) {
-    if (node.isRedundant(_closedWorld)) return node.checkedInput;
-
-    // Simplify 'as T' where T is a simple type.
-    DartType checkedType = node.typeExpression;
-    if (checkedType is TypeVariableType && node.inputs.length == 2) {
-      HInstruction rep = node.typeRepresentation;
-      if (rep is HTypeInfoExpression &&
-          rep.kind == TypeInfoExpressionKind.COMPLETE &&
-          rep.inputs.isEmpty) {
-        DartType type = rep.dartType;
-        if (type is InterfaceType &&
-            _closedWorld.dartTypes.treatAsRawType(type)) {
-          return node.checkedInput.convertType(_closedWorld, type, node.kind)
-            ..sourceInformation = node.sourceInformation;
-        }
-      }
-    }
-
-    return node;
-  }
-
-  @override
   HInstruction visitPrimitiveCheck(HPrimitiveCheck node) {
     if (node.isRedundant(_closedWorld)) return node.checkedInput;
     return node;
@@ -1582,42 +1540,20 @@
 
       DartType fieldType = _closedWorld.elementEnvironment.getFieldType(field);
 
-      if (_options.useNewRti) {
-        AbstractValueWithPrecision checkedType = _abstractValueDomain
-            .createFromStaticType(fieldType, nullable: true);
-        if (checkedType.isPrecise &&
-            _abstractValueDomain
-                .isIn(value.instructionType, checkedType.abstractValue)
-                .isDefinitelyTrue) {
-          return assignField();
-        }
-        // TODO(sra): Implement inlining of setters with checks for new rti. The
-        // check and field assignment for the setter should inlined if this is
-        // the only call to the setter, or the current function already computes
-        // the type of the field.
-        node.needsCheck = true;
-        return node;
+      AbstractValueWithPrecision checkedType =
+          _abstractValueDomain.createFromStaticType(fieldType, nullable: true);
+      if (checkedType.isPrecise &&
+          _abstractValueDomain
+              .isIn(value.instructionType, checkedType.abstractValue)
+              .isDefinitelyTrue) {
+        return assignField();
       }
-
-      if (!_closedWorld.dartTypes.treatAsRawType(fieldType) ||
-          fieldType is TypeVariableType ||
-          fieldType is FunctionType ||
-          fieldType is FutureOrType) {
-        // We cannot generate the correct type representation here, so don't
-        // inline this access.
-        // TODO(sra): If the input is such that we don't need a type check, we
-        // can skip the test an generate the HFieldSet.
-        node.needsCheck = true;
-        return node;
-      }
-      HInstruction other = value.convertType(
-          _closedWorld, fieldType, HTypeConversion.TYPE_CHECK);
-      if (other != value) {
-        node.block.addBefore(node, other);
-        value = other;
-      }
-
-      return assignField();
+      // TODO(sra): Implement inlining of setters with checks for new rti. The
+      // check and field assignment for the setter should inlined if this is
+      // the only call to the setter, or the current function already computes
+      // the type of the field.
+      node.needsCheck = true;
+      return node;
     }
 
     if (member is FunctionEntity) {
@@ -1903,228 +1839,6 @@
   }
 
   @override
-  HInstruction visitTypeInfoExpression(HTypeInfoExpression node) {
-    // Identify the case where the type info expression would be of the form:
-    //
-    //  [getTypeArgumentByIndex(this, 0), .., getTypeArgumentByIndex(this, k)]
-    //
-    // and k is the number of type arguments of 'this'.  We can simply copy the
-    // list from 'this'.
-    HInstruction tryCopyInfo() {
-      if (node.kind != TypeInfoExpressionKind.INSTANCE) return null;
-
-      HInstruction source;
-      int expectedIndex = 0;
-
-      for (HInstruction argument in node.inputs) {
-        if (argument is HTypeInfoReadVariable) {
-          ClassEntity context = DartTypes.getClassContext(argument.variable);
-          HInstruction nextSource = argument.object;
-          if (nextSource is HRef) {
-            HRef ref = nextSource;
-            nextSource = ref.value;
-          }
-          if (nextSource is HThis) {
-            if (source == null) {
-              source = nextSource;
-              ClassEntity thisClass = nextSource.sourceElement.enclosingClass;
-              InterfaceType thisType =
-                  _closedWorld.elementEnvironment.getThisType(thisClass);
-              if (node.inputs.length != thisType.typeArguments.length) {
-                return null;
-              }
-              if (needsSubstitutionForTypeVariableAccess(thisClass)) {
-                return null;
-              }
-              if (context != null &&
-                  !_rtiSubstitutions.isTrivialSubstitution(
-                      thisClass, context)) {
-                // If inlining, the [context] is not the same as [thisClass].
-                // If this is the case, then the substitution must be trivial.
-                // Consider this:
-                //
-                //    class A {
-                //      final Object value;
-                //      A(this.value);
-                //    }
-                //    class B<T> extends A {
-                //      B(T value) : super(value);
-                //      T get value => super.value as T;
-                //    }
-                //    class C<S> extends B<List<S>> {
-                //      C(List<S> value) : super(value);
-                //      S get first => value.first;
-                //    }
-                //
-                // If `B.value` is inlined into `C.first` the type info
-                // expression is the list `[B.T]` on a `this` of type `C<S>`.
-                // Since the substitution from C to B is not trivial
-                // (S -> List<S>) this type info expression cannot be replaced
-                // with the type arguments `C<S>` (it would yield [S] instead of
-                // [List<S>]).
-                return null;
-              }
-            }
-            if (nextSource != source) return null;
-            // Check that the index is the one we expect.
-            int index = argument.variable.element.index;
-            if (index != expectedIndex++) return null;
-          } else {
-            // TODO(sra): Handle non-this cases (i.e. inlined code). Some
-            // non-this cases will have a TypeMask that does not need
-            // substitution, even though the general case does, e.g. inlining a
-            // method on an exact class.
-            return null;
-          }
-        } else {
-          return null;
-        }
-      }
-
-      if (source == null) return null;
-      return new HTypeInfoReadRaw(source, _abstractValueDomain.dynamicType);
-    }
-
-    // TODO(sra): Consider fusing type expression trees with no type variables,
-    // as these could be represented like constants.
-
-    return tryCopyInfo() ?? node;
-  }
-
-  @override
-  HInstruction visitTypeInfoReadVariable(HTypeInfoReadVariable node) {
-    TypeVariableType variable = node.variable;
-    ClassEntity contextClass = variable.element.typeDeclaration;
-    HInstruction object = node.object;
-
-    HInstruction finishGroundType(InterfaceType groundType) {
-      InterfaceType typeAtVariable =
-          _closedWorld.dartTypes.asInstanceOf(groundType, contextClass);
-      if (typeAtVariable != null) {
-        int index = variable.element.index;
-        DartType typeArgument = typeAtVariable.typeArguments[index];
-        HInstruction replacement = new HTypeInfoExpression(
-            TypeInfoExpressionKind.COMPLETE,
-            typeArgument,
-            const <HInstruction>[],
-            _abstractValueDomain.dynamicType,
-            isTypeVariableReplacement: true);
-        return replacement;
-      }
-      return node;
-    }
-
-    /// Read the type variable from an allocation of type [createdClass], where
-    /// [selectTypeArgumentFromObjectCreation] extracts the type argument from
-    /// the allocation for factory constructor call.
-    HInstruction finishSubstituted(ClassEntity createdClass,
-        HInstruction selectTypeArgumentFromObjectCreation(int index)) {
-      InterfaceType thisType = _closedWorld.dartTypes.getThisType(createdClass);
-
-      HInstruction instructionForTypeVariable(TypeVariableType tv) {
-        return selectTypeArgumentFromObjectCreation(
-            thisType.typeArguments.indexOf(tv));
-      }
-
-      DartType type = _closedWorld.dartTypes
-          .asInstanceOf(thisType, contextClass)
-          .typeArguments[variable.element.index];
-      if (type is TypeVariableType) {
-        return instructionForTypeVariable(type);
-      }
-      List<HInstruction> arguments = <HInstruction>[];
-      type.forEachTypeVariable((v) {
-        arguments.add(instructionForTypeVariable(v));
-      });
-      HInstruction replacement = new HTypeInfoExpression(
-          TypeInfoExpressionKind.COMPLETE,
-          type,
-          arguments,
-          _abstractValueDomain.dynamicType,
-          isTypeVariableReplacement: true);
-      return replacement;
-    }
-
-    // Type variable evaluated in the context of a constant can be replaced with
-    // a ground term type.
-    if (object is HConstant) {
-      ConstantValue value = object.constant;
-      if (value is ConstructedConstantValue) {
-        return finishGroundType(value.type);
-      }
-      return node;
-    }
-
-    // Look for an allocation with type information and re-write type variable
-    // as a function of the type parameters of the allocation.  This effectively
-    // store-forwards a type variable read through an allocation.
-
-    // Match:
-    //
-    //     HCreate(ClassElement,
-    //       [arg_i,
-    //        ...,
-    //        HTypeInfoExpression(t_0, t_1, t_2, ...)]);
-    //
-    // The `t_i` are the values of the type parameters of ClassElement.
-
-    if (object is HCreate) {
-      void registerInstantiations() {
-        // Forwarding the type variable references might cause the HCreate to
-        // become dead. This breaks the algorithm for generating the per-type
-        // runtime type information, so we instantiate them here in case the
-        // HCreate becomes dead.
-        object.instantiatedTypes?.forEach(_registry.registerInstantiation);
-      }
-
-      if (object.hasRtiInput) {
-        HInstruction typeInfo = object.rtiInput;
-        if (typeInfo is HTypeInfoExpression) {
-          registerInstantiations();
-          return finishSubstituted(
-              object.element, (int index) => typeInfo.inputs[index]);
-        }
-      } else {
-        // Non-generic type (which extends or mixes in a generic type, for
-        // example CodeUnits extends UnmodifiableListBase<int>).  Also used for
-        // raw-type when the type parameters are elided.
-        registerInstantiations();
-        return finishSubstituted(
-            object.element,
-            // If there are type arguments, all type arguments are 'dynamic'.
-            (int i) => _graph.addConstantNull(_closedWorld));
-      }
-    }
-
-    // TODO(sra): Factory constructors pass type arguments after the value
-    // arguments. The [selectTypeArgumentFromObjectCreation] argument of
-    // [finishSubstituted] indexes into these type arguments.
-
-    // Try to remove the interceptor. The interceptor is used for accessing the
-    // substitution methods.
-    if (node.isIntercepted) {
-      // If we don't need the substitution methods then we don't need the
-      // interceptor to access them.
-      if (!needsSubstitutionForTypeVariableAccess(contextClass)) {
-        return new HTypeInfoReadVariable.noInterceptor(
-            variable, object, node.instructionType);
-      }
-      // All intercepted classes extend `Interceptor`, so if the receiver can't
-      // be a class extending `Interceptor` then the substitution methods can be
-      // called directly. (We don't care about Null since contexts reading class
-      // type variables originate from instance methods.)
-      if (_abstractValueDomain
-          .isInterceptor(object.instructionType)
-          .isDefinitelyFalse) {
-        return new HTypeInfoReadVariable.noInterceptor(
-            variable, object, node.instructionType);
-      }
-    }
-
-    return node;
-  }
-
-  @override
   HInstruction visitTypeEval(HTypeEval node) {
     HInstruction environment = node.inputs.single;
     if (_typeRecipeDomain.isIdentity(node.typeExpression, node.envStructure)) {
@@ -3765,12 +3479,6 @@
   void visitStringConcat(HStringConcat instruction) {}
   @override
   void visitTypeKnown(HTypeKnown instruction) {}
-  @override
-  void visitTypeInfoReadRaw(HTypeInfoReadRaw instruction) {}
-  @override
-  void visitTypeInfoReadVariable(HTypeInfoReadVariable instruction) {}
-  @override
-  void visitTypeInfoExpression(HTypeInfoExpression instruction) {}
 }
 
 /// A non-field based feature of an object.
@@ -4067,7 +3775,6 @@
           if (use is HFieldSet) {
             return use.value.nonCheck() != instruction;
           }
-          if (use is HTypeInfoReadVariable) return true;
           if (use is HGetLength) return true;
           if (use is HBoundsCheck) return true;
           if (use is HIndex) return true;
diff --git a/pkg/compiler/lib/src/ssa/ssa.dart b/pkg/compiler/lib/src/ssa/ssa.dart
index 111510b..9b643ec 100644
--- a/pkg/compiler/lib/src/ssa/ssa.dart
+++ b/pkg/compiler/lib/src/ssa/ssa.dart
@@ -177,13 +177,6 @@
   /// added as a function parameter to the rewritten code.
   // TODO(sra): We could also return an empty list if the generator takes no
   // type (e.g. due to rtiNeed optimization).
-  List<js.Expression> _fetchItemType(
-      CodegenInputs codegen, ModularEmitter emitter, DartType type) {
-    if (type == null) return null;
-    var ast = codegen.rtiEncoder.getTypeRepresentation(emitter, type, null);
-    return <js.Expression>[ast];
-  }
-
   List<js.Expression> _fetchItemTypeNewRti(
       CommonElements commonElements, CodegenRegistry registry, DartType type) {
     if (type == null) return null;
@@ -206,9 +199,8 @@
     FunctionEntity startFunction = commonElements.asyncHelperStartSync;
     FunctionEntity completerFactory = commonElements.asyncAwaitCompleterFactory;
 
-    List<js.Expression> itemTypeExpression = _options.useNewRti
-        ? _fetchItemTypeNewRti(commonElements, registry, elementType)
-        : _fetchItemType(codegen, emitter, elementType);
+    List<js.Expression> itemTypeExpression =
+        _fetchItemTypeNewRti(commonElements, registry, elementType);
 
     AsyncRewriter rewriter = new AsyncRewriter(_reporter, element,
         asyncStart: emitter.staticFunctionAccess(startFunction),
@@ -243,9 +235,8 @@
       js.Expression code,
       DartType asyncTypeParameter,
       js.Name name) {
-    List<js.Expression> itemTypeExpression = _options.useNewRti
-        ? _fetchItemTypeNewRti(commonElements, registry, asyncTypeParameter)
-        : _fetchItemType(codegen, emitter, asyncTypeParameter);
+    List<js.Expression> itemTypeExpression =
+        _fetchItemTypeNewRti(commonElements, registry, asyncTypeParameter);
 
     SyncStarRewriter rewriter = new SyncStarRewriter(_reporter, element,
         endOfIteration:
@@ -279,9 +270,8 @@
       js.Expression code,
       DartType asyncTypeParameter,
       js.Name name) {
-    List<js.Expression> itemTypeExpression = _options.useNewRti
-        ? _fetchItemTypeNewRti(commonElements, registry, asyncTypeParameter)
-        : _fetchItemType(codegen, emitter, asyncTypeParameter);
+    List<js.Expression> itemTypeExpression =
+        _fetchItemTypeNewRti(commonElements, registry, asyncTypeParameter);
 
     AsyncStarRewriter rewriter = new AsyncStarRewriter(_reporter, element,
         asyncStarHelper:
diff --git a/pkg/compiler/lib/src/ssa/ssa_tracer.dart b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
index ac9cfc9..053beb2f 100644
--- a/pkg/compiler/lib/src/ssa/ssa_tracer.dart
+++ b/pkg/compiler/lib/src/ssa/ssa_tracer.dart
@@ -609,26 +609,6 @@
   }
 
   @override
-  String visitTypeConversion(HTypeConversion node) {
-    String checkedInput = temporaryId(node.checkedInput);
-    String rest;
-    if (node.inputs.length == 2) {
-      rest = " ${temporaryId(node.inputs.last)}";
-    } else {
-      assert(node.inputs.length == 1);
-      rest = "";
-    }
-    String kind = _typeConversionKind(node);
-    return "TypeConversion: $kind $checkedInput to ${node.instructionType}$rest";
-  }
-
-  String _typeConversionKind(HTypeConversion node) {
-    if (node.isTypeCheck) return 'TYPE_CHECK';
-    if (node.isCastCheck) return 'CAST_CHECK';
-    return '?';
-  }
-
-  @override
   String visitPrimitiveCheck(HPrimitiveCheck node) {
     String checkedInput = temporaryId(node.checkedInput);
     assert(node.inputs.length == 1);
@@ -675,25 +655,6 @@
   }
 
   @override
-  String visitTypeInfoReadRaw(HTypeInfoReadRaw node) {
-    var inputs = node.inputs.map(temporaryId).join(', ');
-    return "TypeInfoReadRaw: $inputs";
-  }
-
-  @override
-  String visitTypeInfoReadVariable(HTypeInfoReadVariable node) {
-    var inputs = node.inputs.map(temporaryId).join(', ');
-    return "TypeInfoReadVariable: ${node.variable}  $inputs";
-  }
-
-  @override
-  String visitTypeInfoExpression(HTypeInfoExpression node) {
-    var inputs = node.inputs.map(temporaryId).join(', ');
-    return "TypeInfoExpression: ${node.kindAsString} ${node.dartType}"
-        " ($inputs)";
-  }
-
-  @override
   String visitAwait(HAwait node) {
     return "Await: ${temporaryId(node.inputs[0])}";
   }
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 36218f3..5e5d2b9 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -77,17 +77,12 @@
   HInstruction _checkType(HInstruction original, DartType type) {
     assert(type != null);
     type = builder.localsHandler.substInContext(type);
-    HInstruction other =
-        buildTypeConversion(original, type, HTypeConversion.TYPE_CHECK);
+    HInstruction other = buildAsCheck(original, type, isTypeError: true);
     // TODO(johnniwinther): This operation on `registry` may be inconsistent.
     // If it is needed then it seems likely that similar invocations of
-    // `buildTypeConversion` in `SsaBuilder.visitAs` should also be followed by
-    // a similar operation on `registry`; otherwise, this one might not be
-    // needed.
+    // `buildAsCheck` in `SsaBuilder.visitAs` should also be followed by a
+    // similar operation on `registry`; otherwise, this one might not be needed.
     builder.registry?.registerTypeUse(new TypeUse.isCheck(type));
-    if (other is HTypeConversion && other.isRedundant(builder.closedWorld)) {
-      return original;
-    }
     if (other is HAsCheck && other.isRedundant(builder.closedWorld)) {
       return original;
     }
@@ -181,124 +176,11 @@
 
   ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member);
 
-  /// Helper to create an instruction that gets the value of a type variable.
-  HInstruction addTypeVariableReference(
-      TypeVariableType type, MemberEntity member,
-      {SourceInformation sourceInformation}) {
-    Local typeVariableLocal =
-        builder.localsHandler.getTypeVariableAsLocal(type);
-
-    /// Read [typeVariable] as a property of on `this`.
-    HInstruction readAsProperty() {
-      return readTypeVariable(type, member,
-          sourceInformation: sourceInformation);
-    }
-
-    /// Read [typeVariable] as a parameter.
-    HInstruction readAsParameter() {
-      return builder.localsHandler
-          .readLocal(typeVariableLocal, sourceInformation: sourceInformation);
-    }
-
-    ClassTypeVariableAccess typeVariableAccess;
-    if (type.element.typeDeclaration is ClassEntity) {
-      typeVariableAccess = computeTypeVariableAccess(member);
-    } else {
-      typeVariableAccess = ClassTypeVariableAccess.parameter;
-    }
-    switch (typeVariableAccess) {
-      case ClassTypeVariableAccess.parameter:
-        return readAsParameter();
-      case ClassTypeVariableAccess.instanceField:
-        if (member != builder.targetElement) {
-          // When [member] is a field, we can either be generating a checked
-          // setter or inlining its initializer in a constructor. An initializer
-          // is never built standalone, so in that case [target] is not the
-          // [member] itself.
-          return readAsParameter();
-        }
-        return readAsProperty();
-      case ClassTypeVariableAccess.property:
-        return readAsProperty();
-      case ClassTypeVariableAccess.none:
-        builder.reporter.internalError(
-            type.element, 'Unexpected type variable in static context.');
-    }
-    builder.reporter.internalError(
-        type.element, 'Unexpected type variable access: $typeVariableAccess.');
-    return null;
-  }
-
-  /// Generate code to extract the type argument from the object.
-  HInstruction readTypeVariable(TypeVariableType variable, MemberEntity member,
-      {SourceInformation sourceInformation}) {
-    assert(member.isInstanceMember);
-    assert(variable.element.typeDeclaration is ClassEntity);
-    HInstruction target =
-        builder.localsHandler.readThis(sourceInformation: sourceInformation);
-    HInstruction interceptor =
-        new HInterceptor(target, _abstractValueDomain.nonNullType)
-          ..sourceInformation = sourceInformation;
-    builder.add(interceptor);
-    builder.push(new HTypeInfoReadVariable.intercepted(
-        variable, interceptor, target, _abstractValueDomain.dynamicType)
-      ..sourceInformation = sourceInformation);
-    return builder.pop();
-  }
-
-  HInstruction buildTypeArgumentRepresentations(
-      DartType type, MemberEntity sourceElement,
-      [SourceInformation sourceInformation]) {
-    assert(type is! TypeVariableType);
-    // Compute the representation of the type arguments, including access
-    // to the runtime type information for type variables as instructions.
-    assert(type is InterfaceType);
-    InterfaceType interface = type;
-    List<HInstruction> inputs = <HInstruction>[];
-    for (DartType argument in interface.typeArguments) {
-      inputs.add(analyzeTypeArgument(argument, sourceElement,
-          sourceInformation: sourceInformation));
-    }
-    HInstruction representation = new HTypeInfoExpression(
-        TypeInfoExpressionKind.INSTANCE,
-        _closedWorld.elementEnvironment.getThisType(interface.element),
-        inputs,
-        _abstractValueDomain.dynamicType)
-      ..sourceInformation = sourceInformation;
-    return representation;
-  }
-
   HInstruction analyzeTypeArgument(
       DartType argument, MemberEntity sourceElement,
       {SourceInformation sourceInformation}) {
-    if (builder.options.useNewRti) {
-      return analyzeTypeArgumentNewRti(argument, sourceElement,
-          sourceInformation: sourceInformation);
-    }
-    if (argument is DynamicType) {
-      // Represent [dynamic] as [null].
-      return builder.graph.addConstantNull(_closedWorld);
-    }
-
-    if (argument is TypeVariableType) {
-      return addTypeVariableReference(argument, sourceElement,
-          sourceInformation: sourceInformation);
-    }
-
-    List<HInstruction> inputs = <HInstruction>[];
-    argument.forEachTypeVariable((TypeVariableType variable) {
-      // TODO(johnniwinther): Also make this conditional on whether we have
-      // calculated we need that particular method signature.
-      inputs.add(analyzeTypeArgument(variable, sourceElement));
-    });
-    HInstruction result = new HTypeInfoExpression(
-        TypeInfoExpressionKind.COMPLETE,
-        argument,
-        inputs,
-        _abstractValueDomain.dynamicType)
-      ..sourceInformation = sourceInformation;
-    builder.add(result);
-    return result;
+    return analyzeTypeArgumentNewRti(argument, sourceElement,
+        sourceInformation: sourceInformation);
   }
 
   HInstruction analyzeTypeArgumentNewRti(
@@ -435,51 +317,6 @@
     return _EnvironmentExpressionAndStructure(environment, structure);
   }
 
-  /// Build a [HTypeConversion] for converting [original] to type [type].
-  ///
-  /// Invariant: [type] must be valid in the context.
-  /// See [LocalsHandler.substInContext].
-  HInstruction buildTypeConversion(
-      HInstruction original, DartType type, int kind,
-      {SourceInformation sourceInformation}) {
-    if (builder.options.useNewRti) {
-      return buildAsCheck(original, type,
-          isTypeError: kind == HTypeConversion.TYPE_CHECK,
-          sourceInformation: sourceInformation);
-    }
-
-    if (type == null) return original;
-    if (type is InterfaceType && !_closedWorld.dartTypes.treatAsRawType(type)) {
-      InterfaceType interfaceType = type;
-      AbstractValue subtype =
-          _abstractValueDomain.createNullableSubtype(interfaceType.element);
-      HInstruction representations = buildTypeArgumentRepresentations(
-          type, builder.sourceElement, sourceInformation);
-      builder.add(representations);
-      return new HTypeConversion.withTypeRepresentation(
-          type, kind, subtype, original, representations)
-        ..sourceInformation = sourceInformation;
-    } else if (type is TypeVariableType) {
-      AbstractValue subtype = original.instructionType;
-      HInstruction typeVariable =
-          addTypeVariableReference(type, builder.sourceElement);
-      return new HTypeConversion.withTypeRepresentation(
-          type, kind, subtype, original, typeVariable)
-        ..sourceInformation = sourceInformation;
-    } else if (type is FunctionType || type is FutureOrType) {
-      HInstruction reifiedType =
-          analyzeTypeArgument(type, builder.sourceElement);
-      // TypeMasks don't encode function types or FutureOr types.
-      AbstractValue refinedMask = original.instructionType;
-      return new HTypeConversion.withTypeRepresentation(
-          type, kind, refinedMask, original, reifiedType)
-        ..sourceInformation = sourceInformation;
-    } else {
-      return original.convertType(_closedWorld, type, kind)
-        ..sourceInformation = sourceInformation;
-    }
-  }
-
   /// Build a [HAsCheck] for converting [original] to type [type].
   ///
   /// Invariant: [type] must be valid in the context.
diff --git a/pkg/compiler/lib/src/ssa/types_propagation.dart b/pkg/compiler/lib/src/ssa/types_propagation.dart
index 5da0917..8e249f8 100644
--- a/pkg/compiler/lib/src/ssa/types_propagation.dart
+++ b/pkg/compiler/lib/src/ssa/types_propagation.dart
@@ -215,28 +215,6 @@
     return candidateType;
   }
 
-  @override
-  AbstractValue visitTypeConversion(HTypeConversion instruction) {
-    HInstruction input = instruction.checkedInput;
-    AbstractValue inputType = input.instructionType;
-    AbstractValue checkedType = instruction.checkedType;
-    AbstractValue outputType =
-        abstractValueDomain.intersection(checkedType, inputType);
-    outputType = _numericFixup(outputType, inputType, checkedType);
-    if (inputType != outputType) {
-      // Replace dominated uses of input with uses of this HTypeConversion so
-      // the uses benefit from the stronger type.
-      //
-      // The dependency on the checked value also improves the generated
-      // JavaScript. Many checks are compiled to a function call expression that
-      // returns the checked result, so the check can be generated as a
-      // subexpression rather than a separate statement.
-      assert(!(input is HParameterValue && input.usedAsVariable()));
-      input.replaceAllUsersDominatedBy(instruction.next, instruction);
-    }
-    return outputType;
-  }
-
   AbstractValue _numericFixup(AbstractValue outputType, AbstractValue inputType,
       AbstractValue checkedType) {
     if (abstractValueDomain.isEmpty(outputType).isDefinitelyTrue) {
diff --git a/pkg/compiler/test/analyses/dart2js_allowed.json b/pkg/compiler/test/analyses/dart2js_allowed.json
index 7f57a19..c916d07 100644
--- a/pkg/compiler/test/analyses/dart2js_allowed.json
+++ b/pkg/compiler/test/analyses/dart2js_allowed.json
@@ -180,9 +180,6 @@
   "third_party/pkg/dart2js_info/lib/binary_serialization.dart": {
     "Dynamic invocation of 'cast'.": 1
   },
-  "pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart": {
-    "Dynamic access of 'name'.": 1
-  },
   "pkg/compiler/lib/src/universe/side_effects.dart": {
     "Dynamic access of 'universe.side_effects::_flags'.": 1
   },
@@ -254,4 +251,4 @@
   "pkg/compiler/lib/src/ssa/value_set.dart": {
     "Dynamic invocation of 'add'.": 2
   }
-}
+}
\ No newline at end of file
diff --git a/pkg/compiler/test/codegen/new_rti_is_test.dart b/pkg/compiler/test/codegen/new_rti_is_test.dart
index b22f311..1ce65e9 100644
--- a/pkg/compiler/test/codegen/new_rti_is_test.dart
+++ b/pkg/compiler/test/codegen/new_rti_is_test.dart
@@ -108,8 +108,7 @@
 main() {
   runTests() async {
     Future check(String test) {
-      return compile(test,
-          entry: 'foo', check: checkerForAbsentPresent(test), newRti: true);
+      return compile(test, entry: 'foo', check: checkerForAbsentPresent(test));
     }
 
     await check(TEST1N);
diff --git a/pkg/compiler/test/codegen/variance_subtype_cast_test.dart b/pkg/compiler/test/codegen/variance_subtype_cast_test.dart
index be34b8e..ce555d4 100644
--- a/pkg/compiler/test/codegen/variance_subtype_cast_test.dart
+++ b/pkg/compiler/test/codegen/variance_subtype_cast_test.dart
@@ -117,7 +117,6 @@
       return compile(test,
           entry: 'foo',
           check: checkerForAbsentPresent(test),
-          newRti: true,
           enableVariance: true);
     }
 
diff --git a/pkg/compiler/test/helpers/compiler_helper.dart b/pkg/compiler/test/helpers/compiler_helper.dart
index 183ee1f..3dd4594 100644
--- a/pkg/compiler/test/helpers/compiler_helper.dart
+++ b/pkg/compiler/test/helpers/compiler_helper.dart
@@ -40,7 +40,6 @@
     bool trustJSInteropTypeAnnotations: false,
     bool disableTypeInference: true,
     bool omitImplicitChecks: true,
-    bool newRti: false,
     bool enableVariance: false,
     void check(String generatedEntry),
     bool returnAll: false}) async {
@@ -64,9 +63,6 @@
   if (disableInlining) {
     options.add(Flags.disableInlining);
   }
-  if (newRti) {
-    options.add(Flags.experimentNewRti);
-  }
   if (enableVariance) {
     options.add('${Flags.enableLanguageExperiments}=variance');
   }
diff --git a/pkg/compiler/test/impact/data/classes.dart b/pkg/compiler/test/impact/data/classes.dart
index 4e7ab2c..9261709 100644
--- a/pkg/compiler/test/impact/data/classes.dart
+++ b/pkg/compiler/test/impact/data/classes.dart
@@ -268,8 +268,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -323,8 +321,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -403,8 +399,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
-  checkSubtypeOfRuntimeType(2),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -459,8 +453,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
-  checkSubtypeOfRuntimeType(2),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -570,8 +562,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -627,8 +617,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/constants/lib.dart b/pkg/compiler/test/impact/data/constants/lib.dart
index 964ffcb..b3b226f 100644
--- a/pkg/compiler/test/impact/data/constants/lib.dart
+++ b/pkg/compiler/test/impact/data/constants/lib.dart
@@ -76,8 +76,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
-  checkSubtypeOfRuntimeType(2),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -131,8 +129,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
-  checkSubtypeOfRuntimeType(2),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/expressions.dart b/pkg/compiler/test/impact/data/expressions.dart
index 153a7bf..c5c9e6d 100644
--- a/pkg/compiler/test/impact/data/expressions.dart
+++ b/pkg/compiler/test/impact/data/expressions.dart
@@ -224,7 +224,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -278,7 +277,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -586,7 +584,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -640,7 +637,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -863,7 +859,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -917,7 +912,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -970,7 +964,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1024,7 +1017,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1077,7 +1069,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1131,7 +1122,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1184,7 +1174,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1238,7 +1227,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1291,7 +1279,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1345,7 +1332,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1484,7 +1470,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1538,7 +1523,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/extract_type_arguments.dart b/pkg/compiler/test/impact/data/extract_type_arguments.dart
index ac1d171..510414b 100644
--- a/pkg/compiler/test/impact/data/extract_type_arguments.dart
+++ b/pkg/compiler/test/impact/data/extract_type_arguments.dart
@@ -47,7 +47,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   extractTypeArguments<A<dynamic>>(2),
   findType(1),
   getRuntimeTypeArgument(3),
@@ -104,7 +103,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   extractTypeArguments<A<dynamic>*>(2),
   findType(1),
   getRuntimeTypeArgument(3),
@@ -160,7 +158,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   extractTypeArguments<B<dynamic,dynamic>>(2),
   findType(1),
   getRuntimeTypeArgument(3),
@@ -217,7 +214,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   extractTypeArguments<B<dynamic,dynamic>*>(2),
   findType(1),
   getRuntimeTypeArgument(3),
diff --git a/pkg/compiler/test/impact/data/initializers.dart b/pkg/compiler/test/impact/data/initializers.dart
index 36e9210..1fe3d3a 100644
--- a/pkg/compiler/test/impact/data/initializers.dart
+++ b/pkg/compiler/test/impact/data/initializers.dart
@@ -477,8 +477,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -532,8 +530,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/injected_cast.dart b/pkg/compiler/test/impact/data/injected_cast.dart
index 6c2a678..1a4863b 100644
--- a/pkg/compiler/test/impact/data/injected_cast.dart
+++ b/pkg/compiler/test/impact/data/injected_cast.dart
@@ -233,8 +233,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -300,7 +298,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -744,8 +741,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -820,7 +815,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -896,8 +890,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -972,7 +964,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1138,7 +1129,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -1195,8 +1185,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
-    checkSubtypeOfRuntimeType(2),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -1262,7 +1250,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/invokes.dart b/pkg/compiler/test/impact/data/invokes.dart
index 3e7d4b4..113213f 100644
--- a/pkg/compiler/test/impact/data/invokes.dart
+++ b/pkg/compiler/test/impact/data/invokes.dart
@@ -321,7 +321,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -377,7 +376,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -494,7 +492,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -547,7 +544,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -599,7 +595,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -652,7 +647,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -704,7 +698,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -757,7 +750,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -809,7 +801,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -862,7 +853,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1323,7 +1313,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1377,7 +1366,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/jsinterop.dart b/pkg/compiler/test/impact/data/jsinterop.dart
index c5581aa..260af92 100644
--- a/pkg/compiler/test/impact/data/jsinterop.dart
+++ b/pkg/compiler/test/impact/data/jsinterop.dart
@@ -93,7 +93,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
@@ -147,7 +146,6 @@
     _isObject(1),
     _isString(1),
     _isTop(1),
-    checkSubtype(4),
     findType(1),
     getRuntimeTypeArgument(3),
     getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/jsinterop_setter2.dart b/pkg/compiler/test/impact/data/jsinterop_setter2.dart
index b52a2ad..f5df446 100644
--- a/pkg/compiler/test/impact/data/jsinterop_setter2.dart
+++ b/pkg/compiler/test/impact/data/jsinterop_setter2.dart
@@ -43,7 +43,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -108,7 +107,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/impact/data/runtime_type.dart b/pkg/compiler/test/impact/data/runtime_type.dart
index e9cdb53..b61973e 100644
--- a/pkg/compiler/test/impact/data/runtime_type.dart
+++ b/pkg/compiler/test/impact/data/runtime_type.dart
@@ -142,7 +142,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -201,7 +200,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -260,7 +258,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -321,7 +318,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -379,7 +375,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -436,7 +431,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -493,7 +487,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -552,7 +545,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -611,7 +603,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -671,7 +662,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -729,7 +719,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -788,7 +777,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -843,7 +831,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -898,7 +885,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -957,7 +943,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
@@ -1019,7 +1004,6 @@
   _isObject(1),
   _isString(1),
   _isTop(1),
-  checkSubtype(4),
   findType(1),
   getRuntimeTypeArgument(3),
   getRuntimeTypeArgumentIntercepted(4),
diff --git a/pkg/compiler/test/jsinterop/internal_annotations_test.dart b/pkg/compiler/test/jsinterop/internal_annotations_test.dart
new file mode 100644
index 0000000..9e82c1e
--- /dev/null
+++ b/pkg/compiler/test/jsinterop/internal_annotations_test.dart
@@ -0,0 +1,218 @@
+// Copyright (c) 2016, 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.7
+
+library jsinterop.internal_annotations_test;
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/src/common_elements.dart';
+import 'package:compiler/src/compiler.dart';
+import 'package:compiler/src/elements/entities.dart' show ClassEntity;
+import 'package:compiler/src/elements/names.dart';
+import 'package:compiler/src/universe/class_hierarchy.dart';
+import 'package:compiler/src/universe/selector.dart';
+import 'package:compiler/src/world.dart';
+import '../helpers/element_lookup.dart';
+import '../helpers/memory_compiler.dart';
+
+void main() {
+  asyncTest(() async {
+    await testClasses('package:js/js.dart', 'dart:_js_annotations');
+    await testClasses('package:js/js.dart', 'package:js/js.dart');
+    await testClasses('dart:_js_annotations', 'dart:_js_annotations');
+  });
+}
+
+testClasses(String import1, String import2) async {
+  test(String mainSource,
+      {List<String> directlyInstantiated: const <String>[],
+      List<String> abstractlyInstantiated: const <String>[],
+      List<String> indirectlyInstantiated: const <String>[]}) async {
+    String mainFile = 'sdk/tests/dart2js_2/native/main.dart';
+    Uri entryPoint = Uri.parse('memory:$mainFile');
+    CompilationResult result =
+        await runCompiler(entryPoint: entryPoint, memorySourceFiles: {
+      mainFile: """
+import '$import1' as js1;
+import '$import2' as js2;
+
+@js1.JS()
+class A {
+  external get foo;
+
+  external A(var foo);
+}
+
+@js2.JS('BClass')
+class B {
+  external get foo;
+
+  external B(var foo);
+}
+
+@js1.JS()
+@js1.anonymous
+class C {
+  external get foo;
+
+  external factory C({foo});
+}
+
+@js2.JS()
+@js2.anonymous
+class D {
+  external get foo;
+
+  external factory D({foo});
+}
+
+class E {
+  final foo;
+
+  E(this.foo);
+}
+
+class F {
+  final foo;
+
+  F(this.foo);
+}
+
+newA() => new A(0);
+newB() => new B(1);
+newC() => new C(foo: 2);
+newD() => new D(foo: 3);
+newE() => new E(4);
+newF() => new F(5);
+
+$mainSource
+"""
+    });
+    Compiler compiler = result.compiler;
+    Map<String, ClassEntity> classEnvironment = <String, ClassEntity>{};
+
+    ClassEntity registerClass(ClassEntity cls) {
+      classEnvironment[cls.name] = cls;
+      return cls;
+    }
+
+    JClosedWorld world = compiler.backendClosedWorldForTesting;
+    ElementEnvironment elementEnvironment = world.elementEnvironment;
+    ClassEntity Object_ = registerClass(world.commonElements.objectClass);
+    ClassEntity Interceptor =
+        registerClass(world.commonElements.jsInterceptorClass);
+    ClassEntity JavaScriptObject =
+        registerClass(world.commonElements.jsJavaScriptObjectClass);
+    ClassEntity A = registerClass(findClass(world, 'A'));
+    ClassEntity B = registerClass(findClass(world, 'B'));
+    ClassEntity C = registerClass(findClass(world, 'C'));
+    ClassEntity D = registerClass(findClass(world, 'D'));
+    ClassEntity E = registerClass(findClass(world, 'E'));
+    ClassEntity F = registerClass(findClass(world, 'F'));
+
+    Selector nonExisting = new Selector.getter(const PublicName('nonExisting'));
+
+    Expect.equals(elementEnvironment.getSuperClass(Interceptor), Object_);
+    Expect.equals(
+        elementEnvironment.getSuperClass(JavaScriptObject), Interceptor);
+
+    Expect.equals(elementEnvironment.getSuperClass(A), JavaScriptObject);
+    Expect.equals(elementEnvironment.getSuperClass(B), JavaScriptObject);
+    Expect.equals(elementEnvironment.getSuperClass(C), JavaScriptObject);
+    Expect.equals(elementEnvironment.getSuperClass(D), JavaScriptObject);
+    Expect.equals(elementEnvironment.getSuperClass(E), Object_);
+    Expect.equals(elementEnvironment.getSuperClass(F), Object_);
+
+    Expect.isFalse(world.nativeData.isJsInteropClass(Object_));
+    Expect.isTrue(world.nativeData.isJsInteropClass(A));
+    Expect.isTrue(world.nativeData.isJsInteropClass(B));
+    Expect.isTrue(world.nativeData.isJsInteropClass(C));
+    Expect.isTrue(world.nativeData.isJsInteropClass(D));
+    Expect.isFalse(world.nativeData.isJsInteropClass(E));
+    Expect.isFalse(world.nativeData.isJsInteropClass(F));
+
+    Expect.isFalse(world.nativeData.isAnonymousJsInteropClass(Object_));
+    Expect.isFalse(world.nativeData.isAnonymousJsInteropClass(A));
+    Expect.isFalse(world.nativeData.isAnonymousJsInteropClass(B));
+    Expect.isTrue(world.nativeData.isAnonymousJsInteropClass(C));
+    Expect.isTrue(world.nativeData.isAnonymousJsInteropClass(D));
+    Expect.isFalse(world.nativeData.isAnonymousJsInteropClass(E));
+    Expect.isFalse(world.nativeData.isAnonymousJsInteropClass(F));
+
+    Expect.equals('', world.nativeData.getJsInteropClassName(A));
+    Expect.equals('BClass', world.nativeData.getJsInteropClassName(B));
+    Expect.equals('', world.nativeData.getJsInteropClassName(C));
+    Expect.equals('', world.nativeData.getJsInteropClassName(D));
+
+    for (String name in classEnvironment.keys) {
+      ClassEntity cls = classEnvironment[name];
+      bool isInstantiated = false;
+      if (directlyInstantiated.contains(name)) {
+        isInstantiated = true;
+        Expect.isTrue(
+            world.classHierarchy.isDirectlyInstantiated(cls),
+            "Expected $name to be directly instantiated in `${mainSource}`:"
+            "\n${world.classHierarchy.dump(cls)}");
+      }
+      if (abstractlyInstantiated.contains(name)) {
+        isInstantiated = true;
+        Expect.isTrue(
+            world.classHierarchy.isAbstractlyInstantiated(cls),
+            "Expected $name to be abstractly instantiated in `${mainSource}`:"
+            "\n${world.classHierarchy.dump(cls)}");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.EXACT),
+            "Expected $name to need noSuchMethod for $nonExisting.");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.SUBCLASS),
+            "Expected $name to need noSuchMethod for $nonExisting.");
+        Expect.isTrue(
+            world.needsNoSuchMethod(cls, nonExisting, ClassQuery.SUBTYPE),
+            "Expected $name to need noSuchMethod for $nonExisting.");
+      }
+      if (indirectlyInstantiated.contains(name)) {
+        isInstantiated = true;
+        Expect.isTrue(
+            world.classHierarchy.isIndirectlyInstantiated(cls),
+            "Expected $name to be indirectly instantiated in `${mainSource}`:"
+            "\n${world.classHierarchy.dump(cls)}");
+      }
+      if (!isInstantiated && (name != 'Object' && name != 'Interceptor')) {
+        Expect.isFalse(
+            world.classHierarchy.isInstantiated(cls),
+            "Expected $name to be uninstantiated in `${mainSource}`:"
+            "\n${world.classHierarchy.dump(cls)}");
+      }
+    }
+  }
+
+  await test('main() {}');
+
+  await test('main() => newA();',
+      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newB();',
+      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newC();',
+      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newD();',
+      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+
+  await test('main() => newE();', directlyInstantiated: ['E']);
+
+  await test('main() => newF();', directlyInstantiated: ['F']);
+
+  await test('main() => [newD(), newE()];',
+      directlyInstantiated: ['E'],
+      abstractlyInstantiated: ['A', 'B', 'C', 'D'],
+      indirectlyInstantiated: ['Object', 'Interceptor', 'JavaScriptObject']);
+}
diff --git a/pkg/compiler/test/model/cfe_constant_evaluation_test.dart b/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
index 803301d..1866938 100644
--- a/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
+++ b/pkg/compiler/test/model/cfe_constant_evaluation_test.dart
@@ -20,7 +20,6 @@
 import 'package:compiler/src/ir/visitors.dart';
 import 'package:compiler/src/kernel/kernel_strategy.dart';
 import 'package:compiler/src/kernel/element_map_impl.dart';
-import 'package:compiler/src/options.dart';
 import 'package:front_end/src/api_prototype/constant_evaluator.dart' as ir;
 import 'package:front_end/src/api_unstable/dart2js.dart' as ir;
 import 'package:kernel/ast.dart' as ir;
@@ -691,10 +690,9 @@
           },
                   environment: environment,
                   supportReevaluationForTesting: true,
-                  evaluationMode:
-                      compiler.options.nullSafetyMode == NullSafetyMode.sound
-                          ? ir.EvaluationMode.strong
-                          : ir.EvaluationMode.weak);
+                  evaluationMode: compiler.options.useLegacySubtyping
+                      ? ir.EvaluationMode.weak
+                      : ir.EvaluationMode.strong);
           ir.Constant evaluatedConstant = evaluator.evaluate(
               new ir.StaticTypeContext(node, typeEnvironment), initializer);
 
diff --git a/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart b/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
index 1b28a57..aca0ca8 100644
--- a/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
+++ b/pkg/compiler/test/sourcemaps/tools/source_mapping_tester.dart
@@ -134,7 +134,6 @@
 
 const Map<String, List<String>> TEST_CONFIGURATIONS = const {
   'kernel': const [],
-  'newRti': const ['--experiment-new-rti'],
 };
 
 final Map<String, Uri> TEST_FILES = _computeTestFiles();
diff --git a/pkg/compiler/test/static_type/data/issue42281.dart b/pkg/compiler/test/static_type/data/issue42281.dart
new file mode 100644
index 0000000..853da41
--- /dev/null
+++ b/pkg/compiler/test/static_type/data/issue42281.dart
@@ -0,0 +1,64 @@
+// 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 Class {
+  final Type componentType;
+
+  Class(this.componentType);
+}
+
+class SubClass extends Class {
+  SubClass(Type componentType) : super(
+            /*Type*/ componentType);
+}
+
+method1(Class c, Type type, [o]) {
+  if (/*Class*/ c /*invoke: [Class]->bool*/ == null) {
+    if (/*dynamic*/ o /*invoke: [dynamic]->bool*/ != null) {
+      c = new Class(String);
+    }
+    /*Class*/ c;
+    print(/*Type*/ type /*invoke: [Type]->bool*/ == /*Class*/ c?.componentType);
+  }
+}
+
+method2(Class c, Type type, [o]) {
+  if (/*Class*/ c /*invoke: [Class]->bool*/ == null) {
+    if (/*dynamic*/ o /*invoke: [dynamic]->bool*/ != null) {
+      c = new SubClass(String);
+    }
+    /*Class*/ c;
+    print(/*Type*/ type /*invoke: [Type]->bool*/ == /*Class*/ c?.componentType);
+  }
+}
+
+method3(Class c, Type type, [o]) {
+  if (/*Class*/ c is SubClass) {
+    if (/*SubClass*/ c /*invoke: [SubClass]->bool*/ == null) {
+      if (/*dynamic*/ o /*invoke: [dynamic]->bool*/ != null) {
+        c = new SubClass(String);
+      }
+      /*SubClass*/ c;
+      print(/*Type*/ type /*invoke: [Type]->bool*/ ==
+          /*SubClass*/ c?.componentType);
+    }
+  }
+}
+
+main() {
+  method1(new Class(Object), Object);
+  method1(new Class(Object), Object, true);
+  method1(null, Object);
+  method1(null, Object, true);
+
+  method2(new Class(Object), Object);
+  method2(new Class(Object), Object, true);
+  method2(null, Object);
+  method2(null, Object, true);
+
+  method3(new Class(Object), Object);
+  method3(new Class(Object), Object, true);
+  method3(null, Object);
+  method3(null, Object, true);
+}
diff --git a/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart b/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart
new file mode 100644
index 0000000..56a8cd0
--- /dev/null
+++ b/pkg/compiler/test/static_type/type_promotion_data/issue42281.dart
@@ -0,0 +1,65 @@
+// 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 Class {
+  final Type componentType;
+
+  Class(this.componentType);
+}
+
+class SubClass extends Class {
+  SubClass(Type componentType) : super(/*{}*/ componentType);
+}
+
+method1(Class c, Type type, [o]) {
+  if (/*{}*/ c == null) {
+    if (/*{c:[{false:Class}|Class]}*/ o != null) {
+      c = new Class(String);
+    }
+    /*{}*/ c;
+    print(/*{}*/ type == /*{}*/ c?.componentType);
+  }
+}
+
+method2(Class c, Type type, [o]) {
+  if (/*{}*/ c == null) {
+    if (/*{c:[{false:Class}|Class]}*/ o != null) {
+      c = new SubClass(String);
+    }
+    /*{}*/ c;
+    print(/*{}*/ type == /*{}*/ c?.componentType);
+  }
+}
+
+method3(Class c, Type type, [o]) {
+  if (/*{}*/ c is SubClass) {
+    if (/*{c:[{true:SubClass}|SubClass]}*/ c == null) {
+      if (/*{c:[{true:SubClass,false:Class}|SubClass,Class]}*/ o != null) {
+        c = new SubClass(String);
+      }
+      /*{c:[{true:SubClass},{false:Class}|SubClass,Class]}*/ c;
+      print(
+          /*{c:[{true:SubClass},{false:Class}|SubClass,Class]}*/ type ==
+              /*{c:[{true:SubClass},{false:Class}|SubClass,Class]}*/ c
+                  ?.componentType);
+    }
+  }
+}
+
+main() {
+  method1(new Class(Object), Object);
+  method1(new Class(Object), Object, true);
+  method1(null, Object);
+  method1(null, Object, true);
+
+  method2(new Class(Object), Object);
+  method2(new Class(Object), Object, true);
+  method2(null, Object);
+  method2(null, Object, true);
+
+  method3(new Class(Object), Object);
+  method3(new Class(Object), Object, true);
+  method3(null, Object);
+  method3(null, Object, true);
+}
diff --git a/pkg/dartdev/README.md b/pkg/dartdev/README.md
index 3d88cff..6be1917 100644
--- a/pkg/dartdev/README.md
+++ b/pkg/dartdev/README.md
@@ -1,7 +1,31 @@
-# dartdev
+# Dart CLI tooling
 
+```
 A command-line utility for Dart development.
 
-## Docs
+Usage: dart [<vm-flags>] <command|dart-file> [<arguments>]
 
-This tool is currently under active development.
+Global options:
+-h, --help                 Print this usage information.
+-v, --verbose              Show verbose output.
+    --version              Print the Dart SDK version.
+    --enable-analytics     Enable anonymous analytics.
+    --disable-analytics    Disable anonymous analytics.
+
+Available commands:
+  analyze   Analyze the project's Dart code.
+  create    Create a new project.
+  format    Format Dart source code.
+  migrate   Perform a null safety migration on a project or package.
+  pub       Work with packages.
+  run       Run a Dart file.
+  test      Runs tests in this project.
+
+Run "dart help <command>" for more information about a command.
+```
+
+## Features and bugs
+
+Please file feature requests and bugs in the Dart SDK [issue tracker][tracker] with label `area-dart-cli`.
+
+[tracker]: https://github.com/dart-lang/sdk/labels/area-dart-cli
diff --git a/pkg/dartdev/bin/dartdev.dart b/pkg/dartdev/bin/dartdev.dart
index a68e139..c0a850e9 100644
--- a/pkg/dartdev/bin/dartdev.dart
+++ b/pkg/dartdev/bin/dartdev.dart
@@ -2,25 +2,9 @@
 // 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:args/command_runner.dart';
 import 'package:dartdev/dartdev.dart';
 
 /// The entry point for dartdev.
-main(List<String> args) async {
-  final runner = DartdevRunner(args);
-  try {
-    dynamic result = await runner.run(args);
-    exit(result is int ? result : 0);
-  } catch (e, st) {
-    if (e is UsageException) {
-      stderr.writeln('$e');
-      exit(64);
-    } else {
-      stderr.writeln('$e');
-      stderr.writeln('$st');
-      exit(1);
-    }
-  }
+void main(List<String> args) async {
+  await runDartdev(args);
 }
diff --git a/pkg/dartdev/lib/dartdev.dart b/pkg/dartdev/lib/dartdev.dart
index 7a35b53..c0afd77 100644
--- a/pkg/dartdev/lib/dartdev.dart
+++ b/pkg/dartdev/lib/dartdev.dart
@@ -2,13 +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:io';
+import 'dart:io' as io;
 
 import 'package:args/args.dart';
 import 'package:args/command_runner.dart';
 import 'package:cli_util/cli_logging.dart';
 import 'package:nnbd_migration/migration_cli.dart';
+import 'package:usage/usage.dart';
 
+import 'src/analytics.dart';
 import 'src/commands/analyze.dart';
 import 'src/commands/create.dart';
 import 'src/commands/format.dart';
@@ -17,6 +19,124 @@
 import 'src/commands/test.dart';
 import 'src/core.dart';
 
+/// This is typically called from bin/, but given the length of the method and
+/// analytics logic, it has been moved here. Also note that this method calls
+/// [io.exit(code)] directly.
+void runDartdev(List<String> args) async {
+  final stopwatch = Stopwatch();
+  dynamic result;
+
+  // The Analytics instance used to report information back to Google Analytics,
+  // see lib/src/analytics.dart.
+  Analytics analytics;
+
+  // The exit code for the dartdev process, null indicates that it has not yet
+  // been set yet. The value is set in the catch and finally blocks below.
+  int exitCode;
+
+  // Any caught non-UsageExceptions when running the sub command
+  Exception exception;
+  StackTrace stackTrace;
+
+  var runner;
+
+  analytics =
+      createAnalyticsInstance(args.contains('--disable-dartdev-analytics'));
+
+  // On the first run, print the message to alert users that anonymous data will
+  // be collected by default.
+  if (analytics.firstRun) {
+    print(analyticsNoticeOnFirstRunMessage);
+  }
+
+  // When `--disable-analytics` or `--enable-analytics` are called we perform
+  // the respective intention and print any notices to standard out and exit.
+  if (args.contains('--disable-analytics')) {
+    // This block also potentially catches the case of (disableAnalytics &&
+    // enableAnalytics), in which we favor the disabling of analytics.
+    analytics.enabled = false;
+
+    // Alert the user that analytics have been disabled:
+    print(analyticsDisabledNoticeMessage);
+    io.exit(0);
+  } else if (args.contains('--enable-analytics')) {
+    analytics.enabled = true;
+
+    // Alert the user again that anonymous data will be collected:
+    print(analyticsNoticeOnFirstRunMessage);
+    io.exit(0);
+  }
+
+  var commandName;
+
+  try {
+    stopwatch.start();
+    runner = DartdevRunner(args);
+    // Run can't be called with the '--disable-dartdev-analytics' flag, remove
+    // it if it is contained in args.
+    if (args.contains('--disable-dartdev-analytics')) {
+      args = List.from(args)..remove('--disable-dartdev-analytics');
+    }
+
+    // Before calling to run, send the first ping to analytics to have the first
+    // ping, as well as the command itself, running in parallel.
+    if (analytics.enabled) {
+      analytics.setSessionValue(flagsParam, getFlags(args));
+      commandName = getCommandStr(args, runner.commands.keys.toList());
+      // ignore: unawaited_futures
+      analytics.sendEvent(eventCategory, commandName);
+    }
+
+    // Finally, call the runner to execute the command, see DartdevRunner.
+    result = await runner.run(args);
+  } catch (e, st) {
+    if (e is UsageException) {
+      io.stderr.writeln('$e');
+      exitCode = 64;
+    } else {
+      // Set the exception and stack trace only for non-UsageException cases:
+      exception = e;
+      stackTrace = st;
+      io.stderr.writeln('$e');
+      io.stderr.writeln('$st');
+      exitCode = 1;
+    }
+  } finally {
+    stopwatch.stop();
+
+    // Set the exitCode, if it wasn't set in the catch block above.
+    if (exitCode == null) {
+      exitCode = result is int ? result : 0;
+    }
+
+    // Send analytics before exiting
+    if (analytics.enabled) {
+      analytics.setSessionValue(exitCodeParam, exitCode);
+      // ignore: unawaited_futures
+      analytics.sendTiming(commandName, stopwatch.elapsedMilliseconds,
+          category: 'commands');
+
+      // And now send the exceptions and events to Google Analytics:
+      if (exception != null) {
+        // ignore: unawaited_futures
+        analytics.sendException(
+            '${exception.runtimeType}\n${sanitizeStacktrace(stackTrace)}',
+            fatal: true);
+      }
+
+      await analytics.waitForLastPing(timeout: Duration(milliseconds: 200));
+    }
+
+    // As the notification to the user read on the first run, analytics are
+    // enabled by default, on the first run only.
+    if (analytics.firstRun) {
+      analytics.enabled = true;
+    }
+    analytics.close();
+    io.exit(exitCode);
+  }
+}
+
 class DartdevRunner<int> extends CommandRunner {
   static const String dartdevDescription =
       'A command-line utility for Dart development';
@@ -28,6 +148,18 @@
         abbr: 'v', negatable: false, help: 'Show verbose output.');
     argParser.addFlag('version',
         negatable: false, help: 'Print the Dart SDK version.');
+    argParser.addFlag('enable-analytics',
+        negatable: false, help: 'Enable anonymous analytics.');
+    argParser.addFlag('disable-analytics',
+        negatable: false, help: 'Disable anonymous analytics.');
+
+    // A hidden flag to disable analytics on this run, this constructor can be
+    // called with this flag, but should be removed before run() is called as
+    // the flag has not been added to all sub-commands.
+    argParser.addFlag('disable-dartdev-analytics',
+        negatable: false,
+        help: 'Disable anonymous analytics for this `dart *` run',
+        hide: true);
 
     addCommand(AnalyzeCommand(verbose: verbose));
     addCommand(CreateCommand(verbose: verbose));
@@ -44,14 +176,15 @@
 
   @override
   Future<int> runCommand(ArgResults results) async {
+    assert(!results.arguments.contains('--disable-dartdev-analytics'));
     if (results.command == null && results.arguments.isNotEmpty) {
       final firstArg = results.arguments.first;
       // If we make it this far, it means the VM couldn't find the file on disk.
       if (firstArg.endsWith('.dart')) {
-        stderr.writeln(
+        io.stderr.writeln(
             "Error when reading '$firstArg': No such file or directory.");
         // This is the exit code used by the frontend.
-        exit(254);
+        io.exit(254);
       }
     }
     isVerbose = results['verbose'];
diff --git a/pkg/dartdev/lib/src/analytics.dart b/pkg/dartdev/lib/src/analytics.dart
new file mode 100644
index 0000000..112eb70
--- /dev/null
+++ b/pkg/dartdev/lib/src/analytics.dart
@@ -0,0 +1,161 @@
+// 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:path/path.dart' as path;
+import 'package:telemetry/telemetry.dart' as telemetry show isRunningOnBot;
+import 'package:usage/src/usage_impl.dart';
+import 'package:usage/src/usage_impl_io.dart';
+import 'package:usage/usage_io.dart';
+
+const String analyticsNoticeOnFirstRunMessage = '''
+  ╔════════════════════════════════════════════════════════════════════════════╗
+  ║ The Dart tool uses Google Analytics to anonymously report feature usage    ║
+  ║ statistics, and crash reporting to send basic crash reports. This data is  ║
+  ║ used to help improve the Dart platform and tools over time.                ║
+  ║                                                                            ║
+  ║ To disable reporting of anonymous tool usage statistics in general, run    ║
+  ║ the command: `dart --disable-analytics`.                                   ║
+  ╚════════════════════════════════════════════════════════════════════════════╝
+''';
+const String analyticsDisabledNoticeMessage = '''
+  ╔════════════════════════════════════════════════════════════════════════════╗
+  ║ Anonymous analytics disabled. To enable again, run the command:            ║
+  ║ `dart --enable-analytics`                                                  ║
+  ╚════════════════════════════════════════════════════════════════════════════╝
+''';
+const String _unknown_command = '<unknown>';
+const String _appName = 'dartdev';
+const String _dartDirectoryName = '.dart';
+const String _settingsFileName = 'dartdev.json';
+const String _trackingId = 'UA-26406144-37';
+
+const String eventCategory = 'dartdev';
+const String exitCodeParam = 'exitCode';
+const String flagsParam = 'flags';
+
+Analytics instance;
+
+/// Create and return an [Analytics] instance, this value is cached and returned
+/// on subsequent calls.
+Analytics createAnalyticsInstance(bool disableAnalytics) {
+  if (instance != null) {
+    return instance;
+  }
+
+  // Dartdev tests pass a hidden 'disable-dartdev-analytics' flag which is
+  // handled here
+  if (disableAnalytics) {
+    instance = DisabledAnalytics(_trackingId, _appName);
+    return instance;
+  }
+
+  var settingsDir = getDartStorageDirectory();
+  if (settingsDir == null) {
+    // Some systems don't support user home directories; for those, fail
+    // gracefully by returning a disabled analytics object.
+    instance = DisabledAnalytics(_trackingId, _appName);
+    return instance;
+  }
+
+  if (!settingsDir.existsSync()) {
+    try {
+      settingsDir.createSync();
+    } catch (e) {
+      // If we can't create the directory for the analytics settings, fail
+      // gracefully by returning a disabled analytics object.
+      instance = DisabledAnalytics(_trackingId, _appName);
+      return instance;
+    }
+  }
+
+  var settingsFile = File(path.join(settingsDir.path, _settingsFileName));
+  instance = DartdevAnalytics(_trackingId, settingsFile, _appName);
+  return instance;
+}
+
+/// Return the first member from [args] that occurs in [allCommands], otherwise
+/// '<unknown>' is returned.
+///
+/// 'help' is special cased to have 'dart analyze help', 'dart help analyze',
+/// and 'dart analyze --help' all be recorded as a call to 'help' instead of
+/// 'help' and 'analyze'.
+String getCommandStr(List<String> args, List<String> allCommands) {
+  if (args.contains('help') || args.contains('-h') || args.contains('--help')) {
+    return 'help';
+  }
+  return args.firstWhere((arg) => allCommands.contains(arg),
+      orElse: () => _unknown_command);
+}
+
+/// Given some set of arguments and parameters, this returns a proper subset
+/// of the arguments that start with '-', joined by a space character.
+String getFlags(List<String> args) {
+  if (args == null || args.isEmpty) {
+    return '';
+  }
+  var argSubset = <String>[];
+  for (var arg in args) {
+    if (arg.startsWith('-')) {
+      if (arg.contains('=')) {
+        argSubset.add(arg.substring(0, arg.indexOf('=') + 1));
+      } else {
+        argSubset.add(arg);
+      }
+    }
+  }
+  return argSubset.join(' ');
+}
+
+/// The directory used to store the analytics settings file.
+///
+/// Typically, the directory is `~/.dart/` (and the settings file is
+/// `dartdev.json`).
+///
+/// This can return null under some conditions, including when the user's home
+/// directory does not exist.
+Directory getDartStorageDirectory() {
+  var homeDir = Directory(userHomeDir());
+  if (!homeDir.existsSync()) {
+    return null;
+  }
+  return Directory(path.join(homeDir.path, _dartDirectoryName));
+}
+
+class DartdevAnalytics extends AnalyticsImpl {
+  DartdevAnalytics(String trackingId, File settingsFile, String appName)
+      : super(
+          trackingId,
+          IOPersistentProperties.fromFile(settingsFile),
+          IOPostHandler(),
+          applicationName: appName,
+          applicationVersion: getDartVersion(),
+        );
+
+  @override
+  bool get enabled {
+    if (telemetry.isRunningOnBot()) {
+      return false;
+    }
+
+    // If there's no explicit setting (enabled or disabled) then we don't send.
+    return (properties['enabled'] as bool) ?? false;
+  }
+}
+
+class DisabledAnalytics extends AnalyticsMock {
+  @override
+  final String trackingId;
+  @override
+  final String applicationName;
+
+  DisabledAnalytics(this.trackingId, this.applicationName);
+
+  @override
+  bool get enabled => false;
+
+  @override
+  bool get firstRun => false;
+}
diff --git a/pkg/dartdev/lib/src/core.dart b/pkg/dartdev/lib/src/core.dart
index ea897d1..ea7cb9b 100644
--- a/pkg/dartdev/lib/src/core.dart
+++ b/pkg/dartdev/lib/src/core.dart
@@ -20,7 +20,10 @@
 
   Project _project;
 
-  DartdevCommand(this._name, this._description);
+  @override
+  final bool hidden;
+
+  DartdevCommand(this._name, this._description, {this.hidden = false});
 
   @override
   String get name => _name;
diff --git a/pkg/dartdev/lib/src/sdk.dart b/pkg/dartdev/lib/src/sdk.dart
index 9c039f9..e7c1c97 100644
--- a/pkg/dartdev/lib/src/sdk.dart
+++ b/pkg/dartdev/lib/src/sdk.dart
@@ -54,7 +54,4 @@
 
   static String _binName(String base) =>
       Platform.isWindows ? '$base.bat' : base;
-
-  static String _exeName(String base) =>
-      Platform.isWindows ? '$base.exe' : base;
 }
diff --git a/pkg/dartdev/test/analytics_test.dart b/pkg/dartdev/test/analytics_test.dart
new file mode 100644
index 0000000..6f7d3d3
--- /dev/null
+++ b/pkg/dartdev/test/analytics_test.dart
@@ -0,0 +1,63 @@
+// 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:dartdev/src/analytics.dart';
+import 'package:test/test.dart';
+
+void main() {
+  group('DisabledAnalytics', disabledAnalytics_object);
+  group('utils', utils);
+}
+
+void disabledAnalytics_object() {
+  test('object', () {
+    var diabledAnalytics = DisabledAnalytics('trackingId', 'appName');
+    expect(diabledAnalytics.trackingId, 'trackingId');
+    expect(diabledAnalytics.applicationName, 'appName');
+    expect(diabledAnalytics.enabled, isFalse);
+    expect(diabledAnalytics.firstRun, isFalse);
+  });
+}
+
+void utils() {
+  test('getFlags', () {
+    // base cases
+    expect(getFlags(null), '');
+    expect(getFlags(['']), '');
+    expect(getFlags(['', '']), '');
+
+    // non-trivial tests
+    expect(getFlags(['help', 'foo', 'bar']), '');
+    expect(getFlags(['--some-flag', '--some-option=1', '-v']),
+        '--some-flag --some-option= -v');
+    expect(
+        getFlags(['help', '--some-flag', '--some-option=two', '-v', 'analyze']),
+        '--some-flag --some-option= -v');
+    expect(
+        getFlags([
+          'help',
+          '--some-flag',
+          'analyze',
+          '--some-option=three=three',
+          '-v'
+        ]),
+        '--some-flag --some-option= -v');
+  });
+
+  test('getCommandStr', () {
+    var commands = <String>['help', 'foo', 'bar', 'baz'];
+
+    // base cases
+    expect(getCommandStr(['help'], commands), 'help');
+    expect(getCommandStr(['bar', 'help'], commands), 'help');
+    expect(getCommandStr(['help', 'bar'], commands), 'help');
+    expect(getCommandStr(['bar', '-h'], commands), 'help');
+    expect(getCommandStr(['bar', '--help'], commands), 'help');
+
+    // non-trivial tests
+    expect(getCommandStr(['foo'], commands), 'foo');
+    expect(getCommandStr(['bar', 'baz'], commands), 'bar');
+    expect(getCommandStr(['bazz'], commands), '<unknown>');
+  });
+}
diff --git a/pkg/dartdev/test/commands/flag_test.dart b/pkg/dartdev/test/commands/flag_test.dart
index 4224db2..7e35ef8 100644
--- a/pkg/dartdev/test/commands/flag_test.dart
+++ b/pkg/dartdev/test/commands/flag_test.dart
@@ -17,7 +17,9 @@
   // For each command description, assert that the values are not empty, don't
   // have trailing white space and end with a period.
   test('description formatting', () {
-    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+    DartdevRunner(['--disable-dartdev-analytics'])
+        .commands
+        .forEach((String commandKey, Command command) {
       expect(commandKey, isNotEmpty);
       expect(command.description, isNotEmpty);
       expect(command.description.split('\n').first, endsWith('.'));
@@ -27,7 +29,9 @@
 
   // Assert that all found usageLineLengths are the same and null
   test('argParser usageLineLength isNull', () {
-    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+    DartdevRunner(['--disable-dartdev-analytics'])
+        .commands
+        .forEach((String commandKey, Command command) {
       if (command.argParser != null) {
         expect(command.argParser.usageLineLength, isNull);
       }
diff --git a/pkg/dartdev/test/commands/help_test.dart b/pkg/dartdev/test/commands/help_test.dart
index eef0589..2cc0bfb 100644
--- a/pkg/dartdev/test/commands/help_test.dart
+++ b/pkg/dartdev/test/commands/help_test.dart
@@ -21,7 +21,9 @@
   List<String> _commandsNotTested = <String>[
     'help', // `dart help help` is redundant
   ];
-  DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+  DartdevRunner(['--disable-dartdev-analytics'])
+      .commands
+      .forEach((String commandKey, Command command) {
     if (!_commandsNotTested.contains(commandKey)) {
       test('(help $commandKey == $commandKey --help)', () {
         p = project();
@@ -37,14 +39,16 @@
   test('(help pub == pub help)', () {
     p = project();
     var result = p.runSync('help', ['pub']);
-
     var pubHelpResult = p.runSync('pub', ['help']);
+
     expect(result.stdout, contains(pubHelpResult.stdout));
     expect(result.stderr, contains(pubHelpResult.stderr));
   });
 
   test('(--help flags also have -h abbr)', () {
-    DartdevRunner([]).commands.forEach((String commandKey, Command command) {
+    DartdevRunner(['--disable-dartdev-analytics'])
+        .commands
+        .forEach((String commandKey, Command command) {
       var helpOption = command.argParser.options['help'];
       // Some commands (like pub which use
       // "argParser = ArgParser.allowAnything()") may not have the help Option
diff --git a/pkg/dartdev/test/test_all.dart b/pkg/dartdev/test/test_all.dart
index ae71878..8811904 100644
--- a/pkg/dartdev/test/test_all.dart
+++ b/pkg/dartdev/test/test_all.dart
@@ -4,6 +4,7 @@
 
 import 'package:test/test.dart';
 
+import 'analytics_test.dart' as analytics;
 import 'commands/analyze_test.dart' as analyze;
 import 'commands/create_test.dart' as create;
 import 'commands/flag_test.dart' as flag;
@@ -19,6 +20,7 @@
 
 main() {
   group('dart', () {
+    analytics.main();
     analyze.main();
     create.main();
     flag.main();
diff --git a/pkg/dartdev/test/utils.dart b/pkg/dartdev/test/utils.dart
index 7e978ba..c1fdab7 100644
--- a/pkg/dartdev/test/utils.dart
+++ b/pkg/dartdev/test/utils.dart
@@ -64,6 +64,8 @@
       ...?args,
     ];
 
+    arguments.add('--disable-dartdev-analytics');
+
     return Process.runSync(
       Platform.resolvedExecutable,
       arguments,
diff --git a/pkg/dds/CHANGELOG.md b/pkg/dds/CHANGELOG.md
index 09fffb4..2884166 100644
--- a/pkg/dds/CHANGELOG.md
+++ b/pkg/dds/CHANGELOG.md
@@ -1,3 +1,13 @@
+# 1.2.1
+
+- Fixed issue where `evaluate` and `evaluateInFrame` were not invoking client
+  provided implementations of `compileExpression`.
+
+# 1.2.0
+
+- Fixed issue where forwarding requests with no RPC parameters would return an
+  RPC error.
+
 # 1.1.0
 
 - Added `getDartDevelopmentServiceVersion` RPC.
diff --git a/pkg/dds/lib/dds.dart b/pkg/dds/lib/dds.dart
index 79d5768..90461e6 100644
--- a/pkg/dds/lib/dds.dart
+++ b/pkg/dds/lib/dds.dart
@@ -29,6 +29,7 @@
 part 'src/client_manager.dart';
 part 'src/constants.dart';
 part 'src/dds_impl.dart';
+part 'src/expression_evaluator.dart';
 part 'src/logging_repository.dart';
 part 'src/isolate_manager.dart';
 part 'src/named_lookup.dart';
diff --git a/pkg/dds/lib/src/client.dart b/pkg/dds/lib/src/client.dart
index 7d9d5c0..4099128 100644
--- a/pkg/dds/lib/src/client.dart
+++ b/pkg/dds/lib/src/client.dart
@@ -13,7 +13,19 @@
     json_rpc.Peer vmServicePeer,
   ) : _vmServicePeer = vmServicePeer {
     _clientPeer = json_rpc.Peer(
-      ws.cast<String>(),
+      // Manually create a StreamChannel<String> instead of calling
+      // ws.cast<String>() as cast() results in addStream() being called,
+      // binding the underlying sink. This results in a StateError being thrown
+      // if we try and add directly to the sink, which we do for binary events
+      // in _StreamManager's streamNotify().
+      StreamChannel<String>(
+        ws.stream.cast(),
+        StreamController(sync: true)
+          ..stream
+              .cast()
+              .listen((event) => ws.sink.add(event))
+              .onDone(() => ws.sink.close()),
+      ),
       strictProtocolChecks: false,
     );
     _registerJsonRpcMethods();
@@ -145,6 +157,19 @@
       return supportedProtocols;
     });
 
+    // `evaluate` and `evaluateInFrame` actually consist of multiple RPC
+    // invocations, including a call to `compileExpression` which can be
+    // overridden by clients which provide their own implementation (e.g.,
+    // Flutter Tools). We handle all of this in [_ExpressionEvaluator].
+    _clientPeer.registerMethod(
+      'evaluate',
+      dds.expressionEvaluator.execute,
+    );
+    _clientPeer.registerMethod(
+      'evaluateInFrame',
+      dds.expressionEvaluator.execute,
+    );
+
     // When invoked within a fallback, the next fallback will start executing.
     // The final fallback forwards the request to the VM service directly.
     @alwaysThrows
diff --git a/pkg/dds/lib/src/client_manager.dart b/pkg/dds/lib/src/client_manager.dart
index a7e066e..8527636 100644
--- a/pkg/dds/lib/src/client_manager.dart
+++ b/pkg/dds/lib/src/client_manager.dart
@@ -42,7 +42,8 @@
   Future<void> shutdown() async {
     // Close all incoming websocket connections.
     final futures = <Future>[];
-    for (final client in clients) {
+    // Copy `clients` to guard against modification while iterating.
+    for (final client in clients.toList()) {
       futures.add(client.close());
     }
     await Future.wait(futures);
@@ -132,6 +133,16 @@
     }
   }
 
+  _DartDevelopmentServiceClient findFirstClientThatHandlesService(
+      String service) {
+    for (final client in clients) {
+      if (client.services.containsKey(service)) {
+        return client;
+      }
+    }
+    return null;
+  }
+
   // Handles namespace generation for service extensions.
   static const _kServicePrologue = 's';
   final NamedLookup<_DartDevelopmentServiceClient> clients = NamedLookup(
diff --git a/pkg/dds/lib/src/dds_impl.dart b/pkg/dds/lib/src/dds_impl.dart
index 0ab172d..221b2c9 100644
--- a/pkg/dds/lib/src/dds_impl.dart
+++ b/pkg/dds/lib/src/dds_impl.dart
@@ -11,6 +11,7 @@
     this._authCodesEnabled,
   ) {
     _clientManager = _ClientManager(this);
+    _expressionEvaluator = _ExpressionEvaluator(this);
     _isolateManager = _IsolateManager(this);
     _loggingRepository = _LoggingRepository();
     _streamManager = _StreamManager(this);
@@ -197,6 +198,9 @@
   _ClientManager get clientManager => _clientManager;
   _ClientManager _clientManager;
 
+  _ExpressionEvaluator get expressionEvaluator => _expressionEvaluator;
+  _ExpressionEvaluator _expressionEvaluator;
+
   _IsolateManager get isolateManager => _isolateManager;
   _IsolateManager _isolateManager;
 
diff --git a/pkg/dds/lib/src/expression_evaluator.dart b/pkg/dds/lib/src/expression_evaluator.dart
new file mode 100644
index 0000000..e10af00
--- /dev/null
+++ b/pkg/dds/lib/src/expression_evaluator.dart
@@ -0,0 +1,128 @@
+// 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.
+
+part of dds;
+
+/// A helper class which handles `evaluate` and `evaluateInFrame` calls by
+/// potentially forwarding compilation requests to an external compilation
+/// service like Flutter Tools.
+class _ExpressionEvaluator {
+  _ExpressionEvaluator(this.dds);
+
+  Future<Map<String, dynamic>> execute(json_rpc.Parameters parameters) async {
+    final isolateId = parameters['isolateId'].asString;
+    final expression = parameters['expression'].asString;
+    Map<String, dynamic> buildScopeResponse;
+
+    try {
+      buildScopeResponse = await _buildScope(parameters);
+    } on json_rpc.RpcException catch (e) {
+      throw _RpcErrorCodes.buildRpcException(
+        _RpcErrorCodes.kExpressionCompilationError,
+        data: e.data,
+      );
+    }
+    String kernelBase64;
+    try {
+      kernelBase64 =
+          await _compileExpression(isolateId, expression, buildScopeResponse);
+    } on json_rpc.RpcException catch (e) {
+      throw _RpcErrorCodes.buildRpcException(
+        _RpcErrorCodes.kExpressionCompilationError,
+        data: e.data,
+      );
+    }
+    return await _evaluateCompiledExpression(
+        parameters, isolateId, kernelBase64);
+  }
+
+  Future<Map<String, dynamic>> _buildScope(
+      json_rpc.Parameters parameters) async {
+    final params = _setupParams(parameters);
+    params['isolateId'] = parameters['isolateId'].asString;
+    if (parameters['scope'].asMapOr(null) != null) {
+      params['scope'] = parameters['scope'].asMap;
+    }
+    return await dds._vmServiceClient.sendRequest(
+      '_buildExpressionEvaluationScope',
+      params,
+    );
+  }
+
+  Future<String> _compileExpression(String isolateId, String expression,
+      Map<String, dynamic> buildScopeResponseResult) async {
+    _DartDevelopmentServiceClient externalClient =
+        dds.clientManager.findFirstClientThatHandlesService(
+      'compileExpression',
+    );
+
+    final compileParams = <String, dynamic>{
+      'isolateId': isolateId,
+      'expression': expression,
+      'definitions': buildScopeResponseResult['param_names'],
+      'typeDefinitions': buildScopeResponseResult['type_params_names'],
+      'libraryUri': buildScopeResponseResult['libraryUri'],
+      'isStatic': buildScopeResponseResult['isStatic'],
+    };
+
+    final klass = buildScopeResponseResult['klass'];
+    if (klass != null) {
+      compileParams['klass'] = klass;
+    }
+    // TODO(bkonyi): handle service disappeared case?
+    try {
+      if (externalClient != null) {
+        return (await externalClient.sendRequest(
+          'compileExpression',
+          compileParams,
+        ))['result']['kernelBytes'];
+      } else {
+        // Fallback to compiling using the kernel service.
+        return (await dds._vmServiceClient.sendRequest(
+          '_compileExpression',
+          compileParams,
+        ))['kernelBytes'];
+      }
+    } on json_rpc.RpcException catch (e) {
+      throw _RpcErrorCodes.buildRpcException(
+        _RpcErrorCodes.kExpressionCompilationError,
+        data: e.data,
+      );
+    }
+  }
+
+  Future<Map<String, dynamic>> _evaluateCompiledExpression(
+    json_rpc.Parameters parameters,
+    String isolateId,
+    String kernelBase64,
+  ) async {
+    final params = _setupParams(parameters);
+    params['isolateId'] = isolateId;
+    params['kernelBytes'] = kernelBase64;
+    params['disableBreakpoints'] =
+        parameters['disableBreakpoints'].asBoolOr(false);
+    if (parameters['scope'].asMapOr(null) != null) {
+      params['scope'] = parameters['scope'].asMap;
+    }
+    return await dds._vmServiceClient.sendRequest(
+      '_evaluateCompiledExpression',
+      params,
+    );
+  }
+
+  Map<String, dynamic> _setupParams(json_rpc.Parameters parameters) {
+    if (parameters.method == 'evaluateInFrame') {
+      return <String, dynamic>{
+        'frameIndex': parameters['frameIndex'].asInt,
+      };
+    } else {
+      assert(parameters.method == 'evaluate');
+      return <String, dynamic>{
+        'targetId': parameters['targetId'].asString,
+      };
+    }
+  }
+
+  final _DartDevelopmentService dds;
+}
diff --git a/pkg/dds/lib/src/rpc_error_codes.dart b/pkg/dds/lib/src/rpc_error_codes.dart
index 84b1f62..8826a51 100644
--- a/pkg/dds/lib/src/rpc_error_codes.dart
+++ b/pkg/dds/lib/src/rpc_error_codes.dart
@@ -5,10 +5,11 @@
 part of dds;
 
 abstract class _RpcErrorCodes {
-  static json_rpc.RpcException buildRpcException(int code) {
+  static json_rpc.RpcException buildRpcException(int code, {dynamic data}) {
     return json_rpc.RpcException(
       code,
       errorMessages[code],
+      data: data,
     );
   }
 
@@ -34,7 +35,7 @@
   // static const kIsolateMustHaveReloaded = 110;
   static const kServiceAlreadyRegistered = 111;
   static const kServiceDisappeared = 112;
-  // static const kExpressionCompilationError = 113;
+  static const kExpressionCompilationError = 113;
   // static const kInvalidTimelineRequest = 114;
 
   // Experimental (used in private rpcs).
@@ -48,5 +49,6 @@
     kStreamNotSubscribed: 'Stream not subscribed',
     kServiceAlreadyRegistered: 'Service already registered',
     kServiceDisappeared: 'Service has disappeared',
+    kExpressionCompilationError: 'Expression compilation error',
   };
 }
diff --git a/pkg/dds/pubspec.yaml b/pkg/dds/pubspec.yaml
index bec795a..7513031 100644
--- a/pkg/dds/pubspec.yaml
+++ b/pkg/dds/pubspec.yaml
@@ -3,7 +3,7 @@
   A library used to spawn the Dart Developer Service, used to communicate with
   a Dart VM Service instance.
 
-version: 1.1.0
+version: 1.2.1
 
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/dds
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index cf51e41..5b1adc5 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2831,17 +2831,19 @@
   js_ast.Expression _emitTypeParameterType(TypeParameterType type,
       {bool emitNullability = true}) {
     var typeParam = _emitTypeParameter(type.parameter);
-    if (!emitNullability ||
-        !_cacheTypes ||
-        // Emit non-nullable version directly.
-        type.isPotentiallyNonNullable) {
-      return typeParam;
-    }
+
+    // Avoid wrapping the type parameter in a nullability or hoisting a type
+    // that has no nullability wrappers.
+    if (!emitNullability || type.isPotentiallyNonNullable) return typeParam;
+
+    var typeWithNullability =
+        _emitNullabilityWrapper(typeParam, type.nullability);
+
+    if (!_cacheTypes) return typeWithNullability;
 
     // Hoist the wrapped version to the top level and use it everywhere this
     // type appears.
-    return _typeTable.nameType(
-        type, _emitNullabilityWrapper(typeParam, type.nullability));
+    return _typeTable.nameType(type, typeWithNullability);
   }
 
   js_ast.Identifier _emitTypeParameter(TypeParameter t) =>
diff --git a/pkg/dev_compiler/lib/src/kernel/js_interop.dart b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
index 3825bfe..2f929ab 100644
--- a/pkg/dev_compiler/lib/src/kernel/js_interop.dart
+++ b/pkg/dev_compiler/lib/src/kernel/js_interop.dart
@@ -23,8 +23,12 @@
 
 /// Returns true if [library] represents any library from `package:js` or is the
 /// internal `dart:_js_helper` library.
-bool _isJSLibrary(Library library) => _isLibrary(
-    library, ['package:js', 'dart:_js_helper', 'dart:_foreign_helper']);
+bool _isJSLibrary(Library library) => _isLibrary(library, [
+      'package:js',
+      'dart:_js_helper',
+      'dart:_foreign_helper',
+      'dart:_js_annotations'
+    ]);
 
 /// Whether [node] is a direct call to `allowInterop`.
 bool isAllowInterop(Expression node) {
diff --git a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
index d213c3a..2f6957b 100644
--- a/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
+++ b/pkg/dev_compiler/tool/dartdevc_nnbd_sdk_error_golden.txt
@@ -1,8 +1,8 @@
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3719|5|94|Const constructors can't throw exceptions.
-ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7909|5|97|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|3722|5|94|Const constructors can't throw exceptions.
+ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|7912|5|97|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|940|5|95|Const constructors can't throw exceptions.
 ERROR|COMPILE_TIME_ERROR|CONST_CONSTRUCTOR_THROWS_EXCEPTION|lib/core/core.dart|973|5|94|Const constructors can't throw exceptions.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3717|3|5|Only redirecting factory constructors can be declared to be 'const'.
-ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7907|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|3720|3|5|Only redirecting factory constructors can be declared to be 'const'.
+ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|7910|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|938|3|5|Only redirecting factory constructors can be declared to be 'const'.
 ERROR|SYNTACTIC_ERROR|CONST_FACTORY|lib/core/core.dart|971|3|5|Only redirecting factory constructors can be declared to be 'const'.
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index b2cc5a7..e832549 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -747,7 +747,7 @@
 }
 
 /// A [FileSystem] that only allows access to files that have been explicitly
-/// whitelisted.
+/// allowlisted.
 class HermeticFileSystem implements FileSystem {
   final Set<Uri> includedFiles;
   final FileSystem _realFileSystem;
diff --git a/pkg/front_end/lib/src/fasta/blacklisted_classes.dart b/pkg/front_end/lib/src/fasta/blacklisted_classes.dart
deleted file mode 100644
index 37dc7a7..0000000
--- a/pkg/front_end/lib/src/fasta/blacklisted_classes.dart
+++ /dev/null
@@ -1,13 +0,0 @@
-// 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.
-
-// List of special classes in dart:core that can't be subclassed.
-const List<String> blacklistedCoreClasses = [
-  "bool",
-  "int",
-  "num",
-  "double",
-  "String",
-  "Null"
-];
diff --git a/pkg/front_end/lib/src/fasta/denylisted_classes.dart b/pkg/front_end/lib/src/fasta/denylisted_classes.dart
new file mode 100644
index 0000000..c722cbe
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/denylisted_classes.dart
@@ -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.
+
+// List of special classes in dart:core that can't be subclassed.
+const List<String> denylistedCoreClasses = [
+  "bool",
+  "int",
+  "num",
+  "double",
+  "String",
+  "Null"
+];
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 7359ca9..3efb93e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1065,7 +1065,7 @@
 
   @override
   Constant visitTypeLiteral(TypeLiteral node) {
-    final DartType type = evaluateDartType(node, convertType(node.type));
+    final DartType type = evaluateDartType(node, node.type);
     return canonicalize(new TypeLiteralConstant(type));
   }
 
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 8f95981..e8d844c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_labeler.dart
@@ -42,7 +42,7 @@
 
 import 'package:kernel/visitor.dart' show ConstantVisitor, DartTypeVisitor;
 
-import '../blacklisted_classes.dart' show blacklistedCoreClasses;
+import '../denylisted_classes.dart' show denylistedCoreClasses;
 
 import '../fasta_codes.dart'
     show Message, templateTypeOrigin, templateTypeOriginWithFileUri;
@@ -407,8 +407,8 @@
 
   String get originMessage {
     if (importUri.scheme == 'dart' && importUri.path == 'core') {
-      if (node is Class && blacklistedCoreClasses.contains(name)) {
-        // Blacklisted core class. Only print if ambiguous.
+      if (node is Class && denylistedCoreClasses.contains(name)) {
+        // Denylisted core class. Only print if ambiguous.
         List<LabeledNode> entityForName = typeLabeler.nameMap[name];
         if (entityForName.length == 1) {
           return "";
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 34a3675..e6cf582 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -60,7 +60,7 @@
 
 import '../../base/nnbd_mode.dart';
 
-import '../blacklisted_classes.dart' show blacklistedCoreClasses;
+import '../denylisted_classes.dart' show denylistedCoreClasses;
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
@@ -663,10 +663,10 @@
       }
     }
 
-    Set<ClassBuilder> blackListedClasses = new Set<ClassBuilder>();
-    for (int i = 0; i < blacklistedCoreClasses.length; i++) {
-      blackListedClasses.add(coreLibrary
-          .lookupLocalMember(blacklistedCoreClasses[i], required: true));
+    Set<ClassBuilder> denyListedClasses = new Set<ClassBuilder>();
+    for (int i = 0; i < denylistedCoreClasses.length; i++) {
+      denyListedClasses.add(coreLibrary
+          .lookupLocalMember(denylistedCoreClasses[i], required: true));
     }
 
     // Sort the classes topologically.
@@ -698,7 +698,7 @@
         }
         if (allSupertypesProcessed) {
           topologicallySortedClasses.add(cls);
-          checkClassSupertypes(cls, directSupertypeMap, blackListedClasses);
+          checkClassSupertypes(cls, directSupertypeMap, denyListedClasses);
         } else {
           workList.add(cls);
         }
@@ -748,8 +748,8 @@
   void checkClassSupertypes(
       SourceClassBuilder cls,
       Map<TypeDeclarationBuilder, TypeAliasBuilder> directSupertypeMap,
-      Set<ClassBuilder> blackListedClasses) {
-    // Check that the direct supertypes aren't black-listed or enums.
+      Set<ClassBuilder> denyListedClasses) {
+    // Check that the direct supertypes aren't deny-listed or enums.
     List<TypeDeclarationBuilder> directSupertypes =
         directSupertypeMap.keys.toList();
     for (int i = 0; i < directSupertypes.length; i++) {
@@ -758,7 +758,7 @@
         cls.addProblem(templateExtendingEnum.withArguments(supertype.name),
             cls.charOffset, noLength);
       } else if (!cls.library.mayImplementRestrictedTypes &&
-          blackListedClasses.contains(supertype)) {
+          denyListedClasses.contains(supertype)) {
         TypeAliasBuilder aliasBuilder = directSupertypeMap[supertype];
         if (aliasBuilder != null) {
           cls.addProblem(
@@ -801,7 +801,7 @@
                 ]);
             return;
           } else if (!cls.library.mayImplementRestrictedTypes &&
-              blackListedClasses.contains(builder)) {
+              denyListedClasses.contains(builder)) {
             cls.addProblem(
                 templateExtendingRestricted
                     .withArguments(mixedInTypeBuilder.fullNameForErrors),
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart
new file mode 100644
index 0000000..39aa295
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart
@@ -0,0 +1 @@
+Stream<List<>>
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.expect
new file mode 100644
index 0000000..9efa6dc
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.expect
@@ -0,0 +1,40 @@
+Problems reported:
+
+parser/error_recovery/issue_42229.crash:1:8: Expected '>' after this.
+Stream<List<>>
+       ^^^^
+
+parser/error_recovery/issue_42229.crash:1:1: A function declaration needs an explicit list of parameters.
+Stream<List<>>
+^^^^^^
+
+parser/error_recovery/issue_42229.crash:1:15: Expected a function body, but got ''.
+Stream<List<>>
+              ^...
+
+beginCompilationUnit(Stream)
+  beginMetadataStar(Stream)
+  endMetadataStar(0)
+  beginTopLevelMember(Stream)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(Stream, topLevelFunctionDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(List)
+        endMetadataStar(0)
+        handleIdentifier(List, typeVariableDeclaration)
+        beginTypeVariable(List)
+          handleTypeVariablesDefined(List, 1)
+          handleNoType(List)
+        endTypeVariable(<, 0, null, null)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+      endTypeVariables(<, )
+      handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+      handleInvalidFunctionBody({)
+    endTopLevelMethod(Stream, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.intertwined.expect
new file mode 100644
index 0000000..099ee94
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.intertwined.expect
@@ -0,0 +1,57 @@
+parseUnit(Stream)
+  skipErrorTokens(Stream)
+  listener: beginCompilationUnit(Stream)
+  syntheticPreviousToken(Stream)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(Stream)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(Stream)
+      isReservedKeyword(<)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, Stream, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(Stream, topLevelFunctionDeclaration)
+        parseMethodTypeVar(Stream)
+          listener: beginTypeVariables(<)
+          parseMetadataStar(<)
+            listener: beginMetadataStar(List)
+            listener: endMetadataStar(0)
+          ensureIdentifier(<, typeVariableDeclaration)
+            listener: handleIdentifier(List, typeVariableDeclaration)
+          listener: beginTypeVariable(List)
+          listener: handleTypeVariablesDefined(List, 1)
+          listener: handleNoType(List)
+          listener: endTypeVariable(<, 0, null, null)
+          reportRecoverableError(List, Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+          parseMetadataStar(<)
+          ensureIdentifier(<, typeVariableDeclaration)
+            reportRecoverableErrorWithToken(>>, Instance of 'Template<(Token) => Message>')
+            rewriter()
+          listener: endTypeVariables(<, )
+        parseGetterOrFormalParameters(, Stream, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(Stream, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(, Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(Stream, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(Stream)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.parser.expect
new file mode 100644
index 0000000..96c4fba
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.parser.expect
@@ -0,0 +1,11 @@
+NOTICE: Stream was rewritten by parser!
+
+Stream<List<>>>(){}
+
+ERROR: Loop in tokens:  (SimpleToken, EOF, 14)) was seen before (linking to (, SyntheticBeginToken, OPEN_PAREN, 14)!
+
+
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]>>[SimpleToken][SyntheticStringToken]>[SyntheticToken][SimpleToken]([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken]
+
+ERROR: Loop in tokens:  (SimpleToken, EOF, 14)) was seen before (linking to (, SyntheticBeginToken, OPEN_PAREN, 14)!
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.scanner.expect
new file mode 100644
index 0000000..6ca03d9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229.crash_dart.scanner.expect
@@ -0,0 +1,3 @@
+Stream<List<>>
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]>>[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart
new file mode 100644
index 0000000..7a64def
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart
@@ -0,0 +1 @@
+Stream<List<> >
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.expect
new file mode 100644
index 0000000..0f7bb9e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.expect
@@ -0,0 +1,40 @@
+Problems reported:
+
+parser/error_recovery/issue_42229_prime.crash:1:8: Expected '>' after this.
+Stream<List<> >
+       ^^^^
+
+parser/error_recovery/issue_42229_prime.crash:1:1: A function declaration needs an explicit list of parameters.
+Stream<List<> >
+^^^^^^
+
+parser/error_recovery/issue_42229_prime.crash:1:16: Expected a function body, but got ''.
+Stream<List<> >
+               ^...
+
+beginCompilationUnit(Stream)
+  beginMetadataStar(Stream)
+  endMetadataStar(0)
+  beginTopLevelMember(Stream)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(Stream, topLevelFunctionDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(List)
+        endMetadataStar(0)
+        handleIdentifier(List, typeVariableDeclaration)
+        beginTypeVariable(List)
+          handleTypeVariablesDefined(List, 1)
+          handleNoType(List)
+        endTypeVariable(<, 0, null, null)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+      endTypeVariables(<, >)
+      handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+      handleInvalidFunctionBody({)
+    endTopLevelMethod(Stream, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.intertwined.expect
new file mode 100644
index 0000000..a66f17e
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.intertwined.expect
@@ -0,0 +1,57 @@
+parseUnit(Stream)
+  skipErrorTokens(Stream)
+  listener: beginCompilationUnit(Stream)
+  syntheticPreviousToken(Stream)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(Stream)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(Stream)
+      isReservedKeyword(<)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, Stream, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(Stream, topLevelFunctionDeclaration)
+        parseMethodTypeVar(Stream)
+          listener: beginTypeVariables(<)
+          parseMetadataStar(<)
+            listener: beginMetadataStar(List)
+            listener: endMetadataStar(0)
+          ensureIdentifier(<, typeVariableDeclaration)
+            listener: handleIdentifier(List, typeVariableDeclaration)
+          listener: beginTypeVariable(List)
+          listener: handleTypeVariablesDefined(List, 1)
+          listener: handleNoType(List)
+          listener: endTypeVariable(<, 0, null, null)
+          reportRecoverableError(List, Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+          parseMetadataStar(<)
+          ensureIdentifier(<, typeVariableDeclaration)
+            reportRecoverableErrorWithToken(>, Instance of 'Template<(Token) => Message>')
+            rewriter()
+          listener: endTypeVariables(<, >)
+        parseGetterOrFormalParameters(>, Stream, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(Stream, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(, Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(Stream, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(Stream)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.parser.expect
new file mode 100644
index 0000000..69e3549
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.parser.expect
@@ -0,0 +1,5 @@
+NOTICE: Stream was rewritten by parser!
+
+Stream<List<> >(){}
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken][SyntheticStringToken]>[SimpleToken] >[SimpleToken]([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.scanner.expect
new file mode 100644
index 0000000..057cfa6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime.crash_dart.scanner.expect
@@ -0,0 +1,3 @@
+Stream<List<> >
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]>[SimpleToken] >[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart
new file mode 100644
index 0000000..2d65a64
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart
@@ -0,0 +1 @@
+Stream<List<>> foo() {}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.expect
new file mode 100644
index 0000000..7dd3706c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.expect
@@ -0,0 +1,33 @@
+Problems reported:
+
+parser/error_recovery/issue_42229_prime_2.crash:1:13: Expected a type, but got '>>'.
+Stream<List<>> foo() {}
+            ^^
+
+beginCompilationUnit(Stream)
+  beginMetadataStar(Stream)
+  endMetadataStar(0)
+  beginTopLevelMember(Stream)
+    beginTopLevelMethod(, null)
+      handleIdentifier(Stream, typeReference)
+      beginTypeArguments(<)
+        handleIdentifier(List, typeReference)
+        beginTypeArguments(<)
+          handleRecoverableError(Message[ExpectedType, Expected a type, but got '>>'., null, {token: >>}], >>, >>)
+          handleIdentifier(, typeReference)
+          handleNoTypeArguments(>>)
+          handleType(, null)
+        endTypeArguments(1, <, >)
+        handleType(List, null)
+      endTypeArguments(1, <, >)
+      handleType(Stream, null)
+      handleIdentifier(foo, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+      endBlockFunctionBody(0, {, })
+    endTopLevelMethod(Stream, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.intertwined.expect
new file mode 100644
index 0000000..695a462
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.intertwined.expect
@@ -0,0 +1,48 @@
+parseUnit(Stream)
+  skipErrorTokens(Stream)
+  listener: beginCompilationUnit(Stream)
+  syntheticPreviousToken(Stream)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(Stream)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(Stream)
+      parseTopLevelMethod(, null, , Instance of 'ComplexTypeInfo', null, foo, false)
+        listener: beginTopLevelMethod(, null)
+        ensureIdentifier(, typeReference)
+          listener: handleIdentifier(Stream, typeReference)
+        listener: beginTypeArguments(<)
+        ensureIdentifier(<, typeReference)
+          listener: handleIdentifier(List, typeReference)
+        listener: beginTypeArguments(<)
+        reportRecoverableErrorWithToken(>>, Instance of 'Template<(Token) => Message>')
+          listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '>>'., null, {token: >>}], >>, >>)
+        rewriter()
+        listener: handleIdentifier(, typeReference)
+        listener: handleNoTypeArguments(>>)
+        listener: handleType(, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(List, null)
+        listener: endTypeArguments(1, <, >)
+        listener: handleType(Stream, null)
+        ensureIdentifierPotentiallyRecovered(>, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(foo, topLevelFunctionDeclaration)
+        parseMethodTypeVar(foo)
+          listener: handleNoTypeVariables(()
+        parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
+          parseFormalParameters(foo, 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(Stream, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(Stream)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.parser.expect
new file mode 100644
index 0000000..33d84d2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.parser.expect
@@ -0,0 +1,5 @@
+NOTICE: Stream was rewritten by parser!
+
+Stream<List<>> foo() {}
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken][SyntheticStringToken]>[SimpleToken]>[SimpleToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.scanner.expect
new file mode 100644
index 0000000..a607bb8
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_2.crash_dart.scanner.expect
@@ -0,0 +1,3 @@
+Stream<List<>> foo() {}
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]>>[SimpleToken] foo[StringToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart
new file mode 100644
index 0000000..a9fc273
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart
@@ -0,0 +1 @@
+Stream<List<x>> 
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.expect
new file mode 100644
index 0000000..adf4aeb
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.expect
@@ -0,0 +1,40 @@
+Problems reported:
+
+parser/error_recovery/issue_42229_prime_3.crash:1:8: Expected '>' after this.
+Stream<List<x>> 
+       ^^^^
+
+parser/error_recovery/issue_42229_prime_3.crash:1:1: A function declaration needs an explicit list of parameters.
+Stream<List<x>> 
+^^^^^^
+
+parser/error_recovery/issue_42229_prime_3.crash:1:17: Expected a function body, but got ''.
+Stream<List<x>> 
+                ^...
+
+beginCompilationUnit(Stream)
+  beginMetadataStar(Stream)
+  endMetadataStar(0)
+  beginTopLevelMember(Stream)
+    beginTopLevelMethod(, null)
+      handleNoType()
+      handleIdentifier(Stream, topLevelFunctionDeclaration)
+      beginTypeVariables(<)
+        beginMetadataStar(List)
+        endMetadataStar(0)
+        handleIdentifier(List, typeVariableDeclaration)
+        beginTypeVariable(List)
+          handleTypeVariablesDefined(List, 1)
+          handleNoType(List)
+        endTypeVariable(<, 0, null, null)
+        handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+      endTypeVariables(<, >)
+      handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+      handleInvalidFunctionBody({)
+    endTopLevelMethod(Stream, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.intertwined.expect
new file mode 100644
index 0000000..12b92e9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.intertwined.expect
@@ -0,0 +1,53 @@
+parseUnit(Stream)
+  skipErrorTokens(Stream)
+  listener: beginCompilationUnit(Stream)
+  syntheticPreviousToken(Stream)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(Stream)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(Stream)
+      isReservedKeyword(<)
+      parseTopLevelMethod(, null, , Instance of 'NoType', null, Stream, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleNoType()
+        ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
+          listener: handleIdentifier(Stream, topLevelFunctionDeclaration)
+        parseMethodTypeVar(Stream)
+          listener: beginTypeVariables(<)
+          parseMetadataStar(<)
+            listener: beginMetadataStar(List)
+            listener: endMetadataStar(0)
+          ensureIdentifier(<, typeVariableDeclaration)
+            listener: handleIdentifier(List, typeVariableDeclaration)
+          listener: beginTypeVariable(List)
+          listener: handleTypeVariablesDefined(List, 1)
+          listener: handleNoType(List)
+          listener: endTypeVariable(<, 0, null, null)
+          reportRecoverableError(List, Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}])
+            listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected '>' after this., null, {string: >}], List, List)
+          listener: endTypeVariables(<, >)
+        parseGetterOrFormalParameters(>, Stream, false, MemberKind.TopLevelMethod)
+          missingParameterMessage(MemberKind.TopLevelMethod)
+          reportRecoverableError(Stream, MissingFunctionParameters)
+            listener: handleRecoverableError(MissingFunctionParameters, Stream, Stream)
+          rewriter()
+          parseFormalParametersRest((, MemberKind.TopLevelMethod)
+            listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+            listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+        parseAsyncModifierOpt())
+          listener: handleAsyncModifier(null, null)
+          inPlainSync()
+        parseFunctionBody(), false, false)
+          ensureBlock(), Instance of 'Template<(Token) => Message>', null)
+            reportRecoverableError(, Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }])
+              listener: handleRecoverableError(Message[ExpectedFunctionBody, Expected a function body, but got ''., null, {token: }], , )
+            insertBlock())
+              rewriter()
+              rewriter()
+          listener: handleInvalidFunctionBody({)
+        listener: endTopLevelMethod(Stream, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(Stream)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.parser.expect
new file mode 100644
index 0000000..356a3d2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.parser.expect
@@ -0,0 +1,5 @@
+NOTICE: Stream was rewritten by parser!
+
+Stream<List<x>> (){}
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]x[StringToken]>[SimpleToken]>[SimpleToken] ([SyntheticBeginToken])[SyntheticToken]{[SyntheticBeginToken]}[SyntheticToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.scanner.expect
new file mode 100644
index 0000000..af2c2ee
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42229_prime_3.crash_dart.scanner.expect
@@ -0,0 +1,3 @@
+Stream<List<x>> 
+
+Stream[StringToken]<[BeginToken]List[StringToken]<[BeginToken]x[StringToken]>>[SimpleToken] [SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart
new file mode 100644
index 0000000..3718069
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart
@@ -0,0 +1,8 @@
+void main() {
+  builder..foo[bar];
+  FilterSet((builder) => builder..foo[bar]);
+  builder..foo[];
+  FilterSet((builder) => builder..foo[]);
+  builder..foo[ ];
+  FilterSet((builder) => builder..foo[ ]);
+}
\ No newline at end of file
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.expect
new file mode 100644
index 0000000..9cf60f7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.expect
@@ -0,0 +1,197 @@
+Problems reported:
+
+parser/error_recovery/issue_42267:4:16: Expected an identifier, but got ']'.
+  builder..foo[];
+               ^
+
+parser/error_recovery/issue_42267:5:39: Expected an identifier, but got ']'.
+  FilterSet((builder) => builder..foo[]);
+                                      ^
+
+parser/error_recovery/issue_42267:6:17: Expected an identifier, but got ']'.
+  builder..foo[ ];
+                ^
+
+parser/error_recovery/issue_42267:7:40: Expected an identifier, but got ']'.
+  FilterSet((builder) => builder..foo[ ]);
+                                       ^
+
+beginCompilationUnit(void)
+  beginMetadataStar(void)
+  endMetadataStar(0)
+  beginTopLevelMember(void)
+    beginTopLevelMethod(, null)
+      handleVoidKeyword(void)
+      handleIdentifier(main, topLevelFunctionDeclaration)
+      handleNoTypeVariables(()
+      beginFormalParameters((, MemberKind.TopLevelMethod)
+      endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
+      handleAsyncModifier(null, null)
+      beginBlockFunctionBody({)
+        handleIdentifier(builder, expression)
+        handleNoTypeArguments(..)
+        handleNoArguments(..)
+        handleSend(builder, ..)
+        beginCascade(..)
+          handleIdentifier(foo, expressionContinuation)
+          handleNoTypeArguments([)
+          handleNoArguments([)
+          handleSend(foo, [)
+          endBinaryExpression(..)
+          handleIdentifier(bar, expression)
+          handleNoTypeArguments(])
+          handleNoArguments(])
+          handleSend(bar, ])
+          handleIndexedExpression(null, [, ])
+        endCascade()
+        handleExpressionStatement(;)
+        handleIdentifier(FilterSet, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleNoTypeVariables(()
+          beginFunctionExpression(()
+            beginFormalParameters((, MemberKind.Local)
+              beginMetadataStar(builder)
+              endMetadataStar(0)
+              beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                handleNoType(()
+                handleIdentifier(builder, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+            endFormalParameters(1, (, ), MemberKind.Local)
+            handleAsyncModifier(null, null)
+            handleIdentifier(builder, expression)
+            handleNoTypeArguments(..)
+            handleNoArguments(..)
+            handleSend(builder, ..)
+            beginCascade(..)
+              handleIdentifier(foo, expressionContinuation)
+              handleNoTypeArguments([)
+              handleNoArguments([)
+              handleSend(foo, [)
+              endBinaryExpression(..)
+              handleIdentifier(bar, expression)
+              handleNoTypeArguments(])
+              handleNoArguments(])
+              handleSend(bar, ])
+              handleIndexedExpression(null, [, ])
+            endCascade()
+            handleExpressionFunctionBody(=>, null)
+          endFunctionExpression((, ))
+        endArguments(1, (, ))
+        handleSend(FilterSet, ;)
+        handleExpressionStatement(;)
+        handleIdentifier(builder, expression)
+        handleNoTypeArguments(..)
+        handleNoArguments(..)
+        handleSend(builder, ..)
+        beginCascade(..)
+          handleIdentifier(foo, expressionContinuation)
+          handleNoTypeArguments([])
+          handleNoArguments([])
+          handleSend(foo, [])
+          endBinaryExpression(..)
+          handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+          handleIdentifier(, expression)
+          handleNoTypeArguments(])
+          handleNoArguments(])
+          handleSend(, ])
+          handleIndexedExpression(null, [, ])
+        endCascade()
+        handleExpressionStatement(;)
+        handleIdentifier(FilterSet, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleNoTypeVariables(()
+          beginFunctionExpression(()
+            beginFormalParameters((, MemberKind.Local)
+              beginMetadataStar(builder)
+              endMetadataStar(0)
+              beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                handleNoType(()
+                handleIdentifier(builder, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+            endFormalParameters(1, (, ), MemberKind.Local)
+            handleAsyncModifier(null, null)
+            handleIdentifier(builder, expression)
+            handleNoTypeArguments(..)
+            handleNoArguments(..)
+            handleSend(builder, ..)
+            beginCascade(..)
+              handleIdentifier(foo, expressionContinuation)
+              handleNoTypeArguments([])
+              handleNoArguments([])
+              handleSend(foo, [])
+              endBinaryExpression(..)
+              handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+              handleIdentifier(, expression)
+              handleNoTypeArguments(])
+              handleNoArguments(])
+              handleSend(, ])
+              handleIndexedExpression(null, [, ])
+            endCascade()
+            handleExpressionFunctionBody(=>, null)
+          endFunctionExpression((, ))
+        endArguments(1, (, ))
+        handleSend(FilterSet, ;)
+        handleExpressionStatement(;)
+        handleIdentifier(builder, expression)
+        handleNoTypeArguments(..)
+        handleNoArguments(..)
+        handleSend(builder, ..)
+        beginCascade(..)
+          handleIdentifier(foo, expressionContinuation)
+          handleNoTypeArguments([)
+          handleNoArguments([)
+          handleSend(foo, [)
+          endBinaryExpression(..)
+          handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+          handleIdentifier(, expression)
+          handleNoTypeArguments(])
+          handleNoArguments(])
+          handleSend(, ])
+          handleIndexedExpression(null, [, ])
+        endCascade()
+        handleExpressionStatement(;)
+        handleIdentifier(FilterSet, expression)
+        handleNoTypeArguments(()
+        beginArguments(()
+          handleNoTypeVariables(()
+          beginFunctionExpression(()
+            beginFormalParameters((, MemberKind.Local)
+              beginMetadataStar(builder)
+              endMetadataStar(0)
+              beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                handleNoType(()
+                handleIdentifier(builder, formalParameterDeclaration)
+                handleFormalParameterWithoutValue())
+              endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+            endFormalParameters(1, (, ), MemberKind.Local)
+            handleAsyncModifier(null, null)
+            handleIdentifier(builder, expression)
+            handleNoTypeArguments(..)
+            handleNoArguments(..)
+            handleSend(builder, ..)
+            beginCascade(..)
+              handleIdentifier(foo, expressionContinuation)
+              handleNoTypeArguments([)
+              handleNoArguments([)
+              handleSend(foo, [)
+              endBinaryExpression(..)
+              handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+              handleIdentifier(, expression)
+              handleNoTypeArguments(])
+              handleNoArguments(])
+              handleSend(, ])
+              handleIndexedExpression(null, [, ])
+            endCascade()
+            handleExpressionFunctionBody(=>, null)
+          endFunctionExpression((, ))
+        endArguments(1, (, ))
+        handleSend(FilterSet, ;)
+        handleExpressionStatement(;)
+      endBlockFunctionBody(6, {, })
+    endTopLevelMethod(void, null, })
+  endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.intertwined.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.intertwined.expect
new file mode 100644
index 0000000..d09cea7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.intertwined.expect
@@ -0,0 +1,464 @@
+parseUnit(void)
+  skipErrorTokens(void)
+  listener: beginCompilationUnit(void)
+  syntheticPreviousToken(void)
+  parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+    parseMetadataStar()
+      listener: beginMetadataStar(void)
+      listener: endMetadataStar(0)
+    parseTopLevelMemberImpl()
+      listener: beginTopLevelMember(void)
+      parseTopLevelMethod(, null, , Instance of 'VoidType', null, main, false)
+        listener: beginTopLevelMethod(, null)
+        listener: handleVoidKeyword(void)
+        ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+          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(}, builder)
+          parseStatement({)
+            parseStatementX({)
+              parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
+                looksLikeLocalFunction(builder)
+                parseExpressionStatement({)
+                  parseExpression({)
+                    parsePrecedenceExpression({, 1, true)
+                      parseUnaryExpression({, true)
+                        parsePrimary({, expression)
+                          parseSendOrFunctionLiteral({, expression)
+                            parseSend({, expression)
+                              ensureIdentifier({, expression)
+                                listener: handleIdentifier(builder, expression)
+                              listener: handleNoTypeArguments(..)
+                              parseArgumentsOpt(builder)
+                                listener: handleNoArguments(..)
+                              listener: handleSend(builder, ..)
+                      parseCascadeExpression(builder)
+                        listener: beginCascade(..)
+                        parseSend(.., expressionContinuation)
+                          ensureIdentifier(.., expressionContinuation)
+                            listener: handleIdentifier(foo, expressionContinuation)
+                          listener: handleNoTypeArguments([)
+                          parseArgumentsOpt(foo)
+                            listener: handleNoArguments([)
+                          listener: handleSend(foo, [)
+                        listener: endBinaryExpression(..)
+                        parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSendOrFunctionLiteral([, expression)
+                                    parseSend([, expression)
+                                      ensureIdentifier([, expression)
+                                        listener: handleIdentifier(bar, expression)
+                                      listener: handleNoTypeArguments(])
+                                      parseArgumentsOpt(bar)
+                                        listener: handleNoArguments(])
+                                      listener: handleSend(bar, ])
+                          listener: handleIndexedExpression(null, [, ])
+                        parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                        listener: endCascade()
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, FilterSet)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(FilterSet)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(FilterSet, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(FilterSet)
+                                parseArguments(FilterSet)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              listener: handleNoTypeVariables(()
+                                              parseFunctionExpression(()
+                                                listener: beginFunctionExpression(()
+                                                parseFormalParametersRequiredOpt((, MemberKind.Local)
+                                                  parseFormalParametersRest((, MemberKind.Local)
+                                                    listener: beginFormalParameters((, MemberKind.Local)
+                                                    parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.Local)
+                                                      parseMetadataStar(()
+                                                        listener: beginMetadataStar(builder)
+                                                        listener: endMetadataStar(0)
+                                                      listener: beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                                                      listener: handleNoType(()
+                                                      ensureIdentifier((, formalParameterDeclaration)
+                                                        listener: handleIdentifier(builder, formalParameterDeclaration)
+                                                      listener: handleFormalParameterWithoutValue())
+                                                      listener: endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+                                                    listener: endFormalParameters(1, (, ), MemberKind.Local)
+                                                parseAsyncOptBody(), true, false)
+                                                  parseAsyncModifierOpt())
+                                                    listener: handleAsyncModifier(null, null)
+                                                    inPlainSync()
+                                                  parseFunctionBody(), true, false)
+                                                    parseExpressionFunctionBody(=>, true)
+                                                      parseExpression(=>)
+                                                        parsePrecedenceExpression(=>, 1, true)
+                                                          parseUnaryExpression(=>, true)
+                                                            parsePrimary(=>, expression)
+                                                              parseSendOrFunctionLiteral(=>, expression)
+                                                                parseSend(=>, expression)
+                                                                  ensureIdentifier(=>, expression)
+                                                                    listener: handleIdentifier(builder, expression)
+                                                                  listener: handleNoTypeArguments(..)
+                                                                  parseArgumentsOpt(builder)
+                                                                    listener: handleNoArguments(..)
+                                                                  listener: handleSend(builder, ..)
+                                                          parseCascadeExpression(builder)
+                                                            listener: beginCascade(..)
+                                                            parseSend(.., expressionContinuation)
+                                                              ensureIdentifier(.., expressionContinuation)
+                                                                listener: handleIdentifier(foo, expressionContinuation)
+                                                              listener: handleNoTypeArguments([)
+                                                              parseArgumentsOpt(foo)
+                                                                listener: handleNoArguments([)
+                                                              listener: handleSend(foo, [)
+                                                            listener: endBinaryExpression(..)
+                                                            parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                                                              parseExpression([)
+                                                                parsePrecedenceExpression([, 1, true)
+                                                                  parseUnaryExpression([, true)
+                                                                    parsePrimary([, expression)
+                                                                      parseSendOrFunctionLiteral([, expression)
+                                                                        parseSend([, expression)
+                                                                          ensureIdentifier([, expression)
+                                                                            listener: handleIdentifier(bar, expression)
+                                                                          listener: handleNoTypeArguments(])
+                                                                          parseArgumentsOpt(bar)
+                                                                            listener: handleNoArguments(])
+                                                                          listener: handleSend(bar, ])
+                                                              listener: handleIndexedExpression(null, [, ])
+                                                            parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                                                            listener: endCascade()
+                                                      listener: handleExpressionFunctionBody(=>, null)
+                                                      inGenerator()
+                                                listener: endFunctionExpression((, ))
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(FilterSet, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, builder)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(builder)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(builder, expression)
+                              listener: handleNoTypeArguments(..)
+                              parseArgumentsOpt(builder)
+                                listener: handleNoArguments(..)
+                              listener: handleSend(builder, ..)
+                      parseCascadeExpression(builder)
+                        listener: beginCascade(..)
+                        parseSend(.., expressionContinuation)
+                          ensureIdentifier(.., expressionContinuation)
+                            listener: handleIdentifier(foo, expressionContinuation)
+                          listener: handleNoTypeArguments([])
+                          parseArgumentsOpt(foo)
+                            listener: handleNoArguments([])
+                          listener: handleSend(foo, [])
+                        listener: endBinaryExpression(..)
+                        rewriteSquareBrackets(foo)
+                          link([, ])
+                          rewriter()
+                        parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      reportRecoverableErrorWithToken(], Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(, ])
+                          listener: handleIndexedExpression(null, [, ])
+                        parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                        listener: endCascade()
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, FilterSet)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(FilterSet)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(FilterSet, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(FilterSet)
+                                parseArguments(FilterSet)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              listener: handleNoTypeVariables(()
+                                              parseFunctionExpression(()
+                                                listener: beginFunctionExpression(()
+                                                parseFormalParametersRequiredOpt((, MemberKind.Local)
+                                                  parseFormalParametersRest((, MemberKind.Local)
+                                                    listener: beginFormalParameters((, MemberKind.Local)
+                                                    parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.Local)
+                                                      parseMetadataStar(()
+                                                        listener: beginMetadataStar(builder)
+                                                        listener: endMetadataStar(0)
+                                                      listener: beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                                                      listener: handleNoType(()
+                                                      ensureIdentifier((, formalParameterDeclaration)
+                                                        listener: handleIdentifier(builder, formalParameterDeclaration)
+                                                      listener: handleFormalParameterWithoutValue())
+                                                      listener: endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+                                                    listener: endFormalParameters(1, (, ), MemberKind.Local)
+                                                parseAsyncOptBody(), true, false)
+                                                  parseAsyncModifierOpt())
+                                                    listener: handleAsyncModifier(null, null)
+                                                    inPlainSync()
+                                                  parseFunctionBody(), true, false)
+                                                    parseExpressionFunctionBody(=>, true)
+                                                      parseExpression(=>)
+                                                        parsePrecedenceExpression(=>, 1, true)
+                                                          parseUnaryExpression(=>, true)
+                                                            parsePrimary(=>, expression)
+                                                              parseSendOrFunctionLiteral(=>, expression)
+                                                                parseSend(=>, expression)
+                                                                  ensureIdentifier(=>, expression)
+                                                                    listener: handleIdentifier(builder, expression)
+                                                                  listener: handleNoTypeArguments(..)
+                                                                  parseArgumentsOpt(builder)
+                                                                    listener: handleNoArguments(..)
+                                                                  listener: handleSend(builder, ..)
+                                                          parseCascadeExpression(builder)
+                                                            listener: beginCascade(..)
+                                                            parseSend(.., expressionContinuation)
+                                                              ensureIdentifier(.., expressionContinuation)
+                                                                listener: handleIdentifier(foo, expressionContinuation)
+                                                              listener: handleNoTypeArguments([])
+                                                              parseArgumentsOpt(foo)
+                                                                listener: handleNoArguments([])
+                                                              listener: handleSend(foo, [])
+                                                            listener: endBinaryExpression(..)
+                                                            rewriteSquareBrackets(foo)
+                                                              link([, ])
+                                                              rewriter()
+                                                            parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                                                              parseExpression([)
+                                                                parsePrecedenceExpression([, 1, true)
+                                                                  parseUnaryExpression([, true)
+                                                                    parsePrimary([, expression)
+                                                                      parseSend([, expression)
+                                                                        ensureIdentifier([, expression)
+                                                                          reportRecoverableErrorWithToken(], Instance of 'Template<(Token) => Message>')
+                                                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+                                                                          rewriter()
+                                                                          listener: handleIdentifier(, expression)
+                                                                        listener: handleNoTypeArguments(])
+                                                                        parseArgumentsOpt()
+                                                                          listener: handleNoArguments(])
+                                                                        listener: handleSend(, ])
+                                                              listener: handleIndexedExpression(null, [, ])
+                                                            parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                                                            listener: endCascade()
+                                                      listener: handleExpressionFunctionBody(=>, null)
+                                                      inGenerator()
+                                                listener: endFunctionExpression((, ))
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(FilterSet, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, builder)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(builder)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(builder, expression)
+                              listener: handleNoTypeArguments(..)
+                              parseArgumentsOpt(builder)
+                                listener: handleNoArguments(..)
+                              listener: handleSend(builder, ..)
+                      parseCascadeExpression(builder)
+                        listener: beginCascade(..)
+                        parseSend(.., expressionContinuation)
+                          ensureIdentifier(.., expressionContinuation)
+                            listener: handleIdentifier(foo, expressionContinuation)
+                          listener: handleNoTypeArguments([)
+                          parseArgumentsOpt(foo)
+                            listener: handleNoArguments([)
+                          listener: handleSend(foo, [)
+                        listener: endBinaryExpression(..)
+                        parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                          parseExpression([)
+                            parsePrecedenceExpression([, 1, true)
+                              parseUnaryExpression([, true)
+                                parsePrimary([, expression)
+                                  parseSend([, expression)
+                                    ensureIdentifier([, expression)
+                                      reportRecoverableErrorWithToken(], Instance of 'Template<(Token) => Message>')
+                                        listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+                                      rewriter()
+                                      listener: handleIdentifier(, expression)
+                                    listener: handleNoTypeArguments(])
+                                    parseArgumentsOpt()
+                                      listener: handleNoArguments(])
+                                    listener: handleSend(, ])
+                          listener: handleIndexedExpression(null, [, ])
+                        parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                        listener: endCascade()
+                  ensureSemicolon(])
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, FilterSet)
+          parseStatement(;)
+            parseStatementX(;)
+              parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, false)
+                looksLikeLocalFunction(FilterSet)
+                parseExpressionStatement(;)
+                  parseExpression(;)
+                    parsePrecedenceExpression(;, 1, true)
+                      parseUnaryExpression(;, true)
+                        parsePrimary(;, expression)
+                          parseSendOrFunctionLiteral(;, expression)
+                            looksLikeFunctionBody(;)
+                            parseSend(;, expression)
+                              ensureIdentifier(;, expression)
+                                listener: handleIdentifier(FilterSet, expression)
+                              listener: handleNoTypeArguments(()
+                              parseArgumentsOpt(FilterSet)
+                                parseArguments(FilterSet)
+                                  parseArgumentsRest(()
+                                    listener: beginArguments(()
+                                    parseExpression(()
+                                      parsePrecedenceExpression((, 1, true)
+                                        parseUnaryExpression((, true)
+                                          parsePrimary((, expression)
+                                            parseParenthesizedExpressionOrFunctionLiteral(()
+                                              listener: handleNoTypeVariables(()
+                                              parseFunctionExpression(()
+                                                listener: beginFunctionExpression(()
+                                                parseFormalParametersRequiredOpt((, MemberKind.Local)
+                                                  parseFormalParametersRest((, MemberKind.Local)
+                                                    listener: beginFormalParameters((, MemberKind.Local)
+                                                    parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.Local)
+                                                      parseMetadataStar(()
+                                                        listener: beginMetadataStar(builder)
+                                                        listener: endMetadataStar(0)
+                                                      listener: beginFormalParameter(builder, MemberKind.Local, null, null, null)
+                                                      listener: handleNoType(()
+                                                      ensureIdentifier((, formalParameterDeclaration)
+                                                        listener: handleIdentifier(builder, formalParameterDeclaration)
+                                                      listener: handleFormalParameterWithoutValue())
+                                                      listener: endFormalParameter(null, null, builder, null, null, FormalParameterKind.mandatory, MemberKind.Local)
+                                                    listener: endFormalParameters(1, (, ), MemberKind.Local)
+                                                parseAsyncOptBody(), true, false)
+                                                  parseAsyncModifierOpt())
+                                                    listener: handleAsyncModifier(null, null)
+                                                    inPlainSync()
+                                                  parseFunctionBody(), true, false)
+                                                    parseExpressionFunctionBody(=>, true)
+                                                      parseExpression(=>)
+                                                        parsePrecedenceExpression(=>, 1, true)
+                                                          parseUnaryExpression(=>, true)
+                                                            parsePrimary(=>, expression)
+                                                              parseSendOrFunctionLiteral(=>, expression)
+                                                                parseSend(=>, expression)
+                                                                  ensureIdentifier(=>, expression)
+                                                                    listener: handleIdentifier(builder, expression)
+                                                                  listener: handleNoTypeArguments(..)
+                                                                  parseArgumentsOpt(builder)
+                                                                    listener: handleNoArguments(..)
+                                                                  listener: handleSend(builder, ..)
+                                                          parseCascadeExpression(builder)
+                                                            listener: beginCascade(..)
+                                                            parseSend(.., expressionContinuation)
+                                                              ensureIdentifier(.., expressionContinuation)
+                                                                listener: handleIdentifier(foo, expressionContinuation)
+                                                              listener: handleNoTypeArguments([)
+                                                              parseArgumentsOpt(foo)
+                                                                listener: handleNoArguments([)
+                                                              listener: handleSend(foo, [)
+                                                            listener: endBinaryExpression(..)
+                                                            parseArgumentOrIndexStar(foo, Instance of 'NoTypeParamOrArg', false)
+                                                              parseExpression([)
+                                                                parsePrecedenceExpression([, 1, true)
+                                                                  parseUnaryExpression([, true)
+                                                                    parsePrimary([, expression)
+                                                                      parseSend([, expression)
+                                                                        ensureIdentifier([, expression)
+                                                                          reportRecoverableErrorWithToken(], Instance of 'Template<(Token) => Message>')
+                                                                            listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ']'., null, {token: ]}], ], ])
+                                                                          rewriter()
+                                                                          listener: handleIdentifier(, expression)
+                                                                        listener: handleNoTypeArguments(])
+                                                                        parseArgumentsOpt()
+                                                                          listener: handleNoArguments(])
+                                                                        listener: handleSend(, ])
+                                                              listener: handleIndexedExpression(null, [, ])
+                                                            parseArgumentOrIndexStar(], Instance of 'NoTypeParamOrArg', false)
+                                                            listener: endCascade()
+                                                      listener: handleExpressionFunctionBody(=>, null)
+                                                      inGenerator()
+                                                listener: endFunctionExpression((, ))
+                                    listener: endArguments(1, (, ))
+                              listener: handleSend(FilterSet, ;)
+                  ensureSemicolon())
+                  listener: handleExpressionStatement(;)
+          notEofOrValue(}, })
+          listener: endBlockFunctionBody(6, {, })
+        listener: endTopLevelMethod(void, null, })
+  listener: endTopLevelDeclaration()
+  reportAllErrorTokens(void)
+  listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.parser.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.parser.expect
new file mode 100644
index 0000000..ab5a595
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.parser.expect
@@ -0,0 +1,19 @@
+NOTICE: Stream was rewritten by parser!
+
+void main() {
+builder..foo[bar];
+FilterSet((builder) => builder..foo[bar]);
+builder..foo[];
+FilterSet((builder) => builder..foo[]);
+builder..foo[ ];
+FilterSet((builder) => builder..foo[ ]);
+}
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken]bar[StringToken]][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken]bar[StringToken]][SimpleToken])[SimpleToken];[SimpleToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken][SyntheticStringToken]][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken][SyntheticStringToken]][SimpleToken])[SimpleToken];[SimpleToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken] [SyntheticStringToken]][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken] [SyntheticStringToken]][SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.scanner.expect b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.scanner.expect
new file mode 100644
index 0000000..8c8dfca
--- /dev/null
+++ b/pkg/front_end/parser_testcases/error_recovery/issue_42267.dart.scanner.expect
@@ -0,0 +1,17 @@
+void main() {
+builder..foo[bar];
+FilterSet((builder) => builder..foo[bar]);
+builder..foo[];
+FilterSet((builder) => builder..foo[]);
+builder..foo[ ];
+FilterSet((builder) => builder..foo[ ]);
+}
+
+void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken]bar[StringToken]][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken]bar[StringToken]][SimpleToken])[SimpleToken];[SimpleToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][][SimpleToken])[SimpleToken];[SimpleToken]
+builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken] ][SimpleToken];[SimpleToken]
+FilterSet[StringToken]([BeginToken]([BeginToken]builder[StringToken])[SimpleToken] =>[SimpleToken] builder[StringToken]..[SimpleToken]foo[StringToken][[BeginToken] ][SimpleToken])[SimpleToken];[SimpleToken]
+}[SimpleToken][SimpleToken]
diff --git a/pkg/front_end/test/deps_test.dart b/pkg/front_end/test/deps_test.dart
index 6360a93..64cce4a 100644
--- a/pkg/front_end/test/deps_test.dart
+++ b/pkg/front_end/test/deps_test.dart
@@ -18,7 +18,7 @@
 
 final Uri repoDir = computeRepoDirUri();
 
-Set<String> whitelistedExternalDartFiles = {
+Set<String> allowlistedExternalDartFiles = {
   "third_party/pkg/charcode/lib/ascii.dart",
 
   "third_party/pkg_tested/package_config/lib/package_config.dart",
@@ -114,7 +114,7 @@
   // * Everything in frontEndUris is okay --- the frontend can import itself.
   // * Everything in kernel is okay --- the frontend is allowed to
   //   import package:kernel.
-  // * For other entries, remove whitelisted entries.
+  // * For other entries, remove allowlisted entries.
   // * Everything else is an error.
 
   // Remove white-listed non-dart files.
@@ -123,12 +123,12 @@
   otherNonDartUris.remove(repoDir.resolve(".dart_tool/package_config.json"));
 
   // Remove white-listed dart files.
-  for (String s in whitelistedExternalDartFiles) {
+  for (String s in allowlistedExternalDartFiles) {
     otherDartUris.remove(repoDir.resolve(s));
   }
 
   if (otherNonDartUris.isNotEmpty || otherDartUris.isNotEmpty) {
-    print("The following files was imported without being whitelisted:");
+    print("The following files was imported without being allowlisted:");
     for (Uri uri in otherNonDartUris) {
       print(" - $uri");
     }
diff --git a/pkg/front_end/test/fasta/parser/parser.status b/pkg/front_end/test/fasta/parser/parser.status
index 3dd8e24..5a6bc42 100644
--- a/pkg/front_end/test/fasta/parser/parser.status
+++ b/pkg/front_end/test/fasta/parser/parser.status
@@ -1546,6 +1546,113 @@
 tests/corelib/from_environment_const_type_test: Fail
 tests/corelib/from_environment_const_type_undefined_test: Fail
 tests/corelib/symbol_reserved_word_test: Fail
+tests/dart2js/deferred_custom_loader_test: Fail
+tests/dart2js/empty_negative_test: Fail
+tests/dart2js/invalid_annotation_test: Fail
+tests/dart2js/invalid_annotation2_test: Fail
+tests/dart2js/invalid_length_negative_test: Fail
+tests/dart2js/LayoutTests_fast_mediastream_getusermedia_t01_test: Fail
+tests/dart2js/switch_test: Fail
+tests/dart2js/timer_negative_test: Fail
+tests/dart2js/typed_locals_test: Fail
+tests/dart2js/native/abstract_class_test: Fail
+tests/dart2js/native/bound_closure_test: Fail
+tests/dart2js/native/browser_compat_1_prepatched_test: Fail
+tests/dart2js/native/browser_compat_1_unpatched_test: Fail
+tests/dart2js/native/browser_compat_2_test: Fail
+tests/dart2js/native/core_type_check_native_test: Fail
+tests/dart2js/native/dispatch_property_initialization_test: Fail
+tests/dart2js/native/downcast_test: Fail
+tests/dart2js/native/error_safeToString_test: Fail
+tests/dart2js/native/event_loop_test: Fail
+tests/dart2js/native/fake_thing_2_test: Fail
+tests/dart2js/native/fake_thing_test: Fail
+tests/dart2js/native/field_type_test: Fail
+tests/dart2js/native/field_type2_test: Fail
+tests/dart2js/native/fixup_get_tag_test: Fail
+tests/dart2js/native/hash_code_test: Fail
+tests/dart2js/native/issue9182_test: Fail
+tests/dart2js/native/jsobject_test: Fail
+tests/dart2js/native/native_call_arity1_frog_test: Fail
+tests/dart2js/native/native_call_arity2_frog_test: Fail
+tests/dart2js/native/native_call_arity3_frog_test: Fail
+tests/dart2js/native/native_checked_arguments1_frog_test: Fail
+tests/dart2js/native/native_checked_fields_frog_test: Fail
+tests/dart2js/native/native_class_avoids_hidden_name_frog_test: Fail
+tests/dart2js/native/native_class_fields_2_test: Fail
+tests/dart2js/native/native_class_fields_3_test: Fail
+tests/dart2js/native/native_class_fields_test: Fail
+tests/dart2js/native/native_class_inheritance1_frog_test: Fail
+tests/dart2js/native/native_class_inheritance2_frog_test: Fail
+tests/dart2js/native/native_class_inheritance3_frog_test: Fail
+tests/dart2js/native/native_class_inheritance4_frog_test: Fail
+tests/dart2js/native/native_class_is_check1_frog_test: Fail
+tests/dart2js/native/native_class_is_check3_frog_test: Fail
+tests/dart2js/native/native_class_with_dart_methods_frog_test: Fail
+tests/dart2js/native/native_closure_identity_frog_test: Fail
+tests/dart2js/native/native_constructor_name_test: Fail
+tests/dart2js/native/native_equals_frog_test: Fail
+tests/dart2js/native/native_exception2_test: Fail
+tests/dart2js/native/native_exceptions1_frog_test: Fail
+tests/dart2js/native/native_field_invocation_test: Fail
+tests/dart2js/native/native_field_invocation2_test: Fail
+tests/dart2js/native/native_field_invocation3_test: Fail
+tests/dart2js/native/native_field_invocation4_test: Fail
+tests/dart2js/native/native_field_invocation5_test: Fail
+tests/dart2js/native/native_field_invocation6_test: Fail
+tests/dart2js/native/native_field_name_test: Fail
+tests/dart2js/native/native_field_optimization_test: Fail
+tests/dart2js/native/native_field_rename_1_frog_test: Fail
+tests/dart2js/native/native_field_rename_2_frog_test: Fail
+tests/dart2js/native/native_library_same_name_used_frog_test: Fail
+tests/dart2js/native/native_library_same_name_used_lib2: Fail
+tests/dart2js/native/native_method_inlining_test: Fail
+tests/dart2js/native/native_method_rename1_frog_test: Fail
+tests/dart2js/native/native_method_rename2_frog_test: Fail
+tests/dart2js/native/native_method_rename3_frog_test: Fail
+tests/dart2js/native/native_method_with_keyword_name_test: Fail
+tests/dart2js/native/native_missing_method1_frog_test: Fail
+tests/dart2js/native/native_missing_method2_frog_test: Fail
+tests/dart2js/native/native_mixin_field_test: Fail
+tests/dart2js/native/native_mixin_multiple_test: Fail
+tests/dart2js/native/native_mixin_multiple2_test: Fail
+tests/dart2js/native/native_mixin_multiple3_test: Fail
+tests/dart2js/native/native_mixin_test: Fail
+tests/dart2js/native/native_mixin_with_plain_test: Fail
+tests/dart2js/native/native_named_constructors2_frog_test: Fail
+tests/dart2js/native/native_named_constructors3_frog_test: Fail
+tests/dart2js/native/native_no_such_method_exception_frog_test: Fail
+tests/dart2js/native/native_no_such_method_exception2_frog_test: Fail
+tests/dart2js/native/native_no_such_method_exception3_frog_test: Fail
+tests/dart2js/native/native_no_such_method_exception4_frog_test: Fail
+tests/dart2js/native/native_no_such_method_exception5_frog_test: Fail
+tests/dart2js/native/native_novel_html_test: Fail
+tests/dart2js/native/native_null_closure_frog_test: Fail
+tests/dart2js/native/native_null_frog_test: Fail
+tests/dart2js/native/native_property_frog_test: Fail
+tests/dart2js/native/native_testing: Fail
+tests/dart2js/native/native_to_string_frog_test: Fail
+tests/dart2js/native/native_use_native_name_in_table_frog_test: Fail
+tests/dart2js/native/native_wrapping_function_frog_test: Fail
+tests/dart2js/native/native_wrapping_function3_frog_test: Fail
+tests/dart2js/native/oddly_named_fields_test: Fail
+tests/dart2js/native/runtimetype_test: Fail
+tests/dart2js/native/static_methods_test: Fail
+tests/dart2js/native/subclassing_1_test: Fail
+tests/dart2js/native/subclassing_2_test: Fail
+tests/dart2js/native/subclassing_3_test: Fail
+tests/dart2js/native/subclassing_4_test: Fail
+tests/dart2js/native/subclassing_5_test: Fail
+tests/dart2js/native/subclassing_constructor_1_test: Fail
+tests/dart2js/native/subclassing_super_call_test: Fail
+tests/dart2js/native/subclassing_super_field_1_test: Fail
+tests/dart2js/native/subclassing_super_field_2_test: Fail
+tests/dart2js/native/subclassing_type_test: Fail
+tests/dart2js/native/super_call_test: Fail
+tests/dart2js/native/super_property_test: Fail
+tests/dart2js/switch_test: Fail
+tests/dart2js/timer_negative_test: Fail
+tests/dart2js/typed_locals_test: Fail
 tests/dart2js_2/deferred_custom_loader_test: Fail
 tests/dart2js_2/empty_negative_test: Fail
 tests/dart2js_2/invalid_annotation_test: Fail
diff --git a/pkg/front_end/test/parser_suite.dart b/pkg/front_end/test/parser_suite.dart
index cbbf1219..f4d996b 100644
--- a/pkg/front_end/test/parser_suite.dart
+++ b/pkg/front_end/test/parser_suite.dart
@@ -253,6 +253,7 @@
     lineStartsIterator.moveNext();
     lineStartsIteratorLine++;
 
+    Set<Token> seenTokens = new Set<Token>.identity();
     while (token != null) {
       if (errorTokens && token is! ErrorToken) return token;
       if (!errorTokens && token is ErrorToken) {
@@ -286,6 +287,15 @@
       endOfLast = token.end;
       if (token == token.next) break;
       token = token.next;
+      if (!seenTokens.add(token)) {
+        // Loop in tokens: Print error and break to avoid infinite loop.
+        sb.write("\n\nERROR: Loop in tokens: $token "
+            "(${token.runtimeType}, ${token.type}, ${token.offset})) "
+            "was seen before "
+            "(linking to ${token.next}, ${token.next.runtimeType}, "
+            "${token.next.type}, ${token.next.offset})!\n\n");
+        break;
+      }
     }
 
     return token;
diff --git a/pkg/front_end/test/parser_test_listener.dart b/pkg/front_end/test/parser_test_listener.dart
index ce3d1bd..e0aa818 100644
--- a/pkg/front_end/test/parser_test_listener.dart
+++ b/pkg/front_end/test/parser_test_listener.dart
@@ -31,7 +31,7 @@
   String createTrace() {
     List<String> traceLines = StackTrace.current.toString().split("\n");
     for (int i = 0; i < traceLines.length; i++) {
-      // Find first one that's not any of the blacklisted ones.
+      // Find first one that's not any of the denylisted ones.
       String line = traceLines[i];
       if (line.contains("parser_test_listener.dart:") ||
           line.contains("parser_suite.dart:")) continue;
diff --git a/pkg/front_end/test/parser_test_listener_creator.dart b/pkg/front_end/test/parser_test_listener_creator.dart
index f330b23..67c2268 100644
--- a/pkg/front_end/test/parser_test_listener_creator.dart
+++ b/pkg/front_end/test/parser_test_listener_creator.dart
@@ -71,7 +71,7 @@
   String createTrace() {
     List<String> traceLines = StackTrace.current.toString().split("\n");
     for (int i = 0; i < traceLines.length; i++) {
-      // Find first one that's not any of the blacklisted ones.
+      // Find first one that's not any of the denylisted ones.
       String line = traceLines[i];
       if (line.contains("parser_test_listener.dart:") ||
           line.contains("parser_suite.dart:")) continue;
diff --git a/pkg/front_end/test/parser_test_parser.dart b/pkg/front_end/test/parser_test_parser.dart
index 0e3ccce..a0499fb 100644
--- a/pkg/front_end/test/parser_test_parser.dart
+++ b/pkg/front_end/test/parser_test_parser.dart
@@ -35,7 +35,7 @@
   String createTrace() {
     List<String> traceLines = StackTrace.current.toString().split("\n");
     for (int i = 0; i < traceLines.length; i++) {
-      // Find first one that's not any of the blacklisted ones.
+      // Find first one that's not any of the denylisted ones.
       String line = traceLines[i];
       if (line.contains("parser_test_listener.dart:") ||
           line.contains("parser_suite.dart:") ||
diff --git a/pkg/front_end/test/parser_test_parser_creator.dart b/pkg/front_end/test/parser_test_parser_creator.dart
index 47ac23a..aa1e573 100644
--- a/pkg/front_end/test/parser_test_parser_creator.dart
+++ b/pkg/front_end/test/parser_test_parser_creator.dart
@@ -69,7 +69,7 @@
   String createTrace() {
     List<String> traceLines = StackTrace.current.toString().split("\n");
     for (int i = 0; i < traceLines.length; i++) {
-      // Find first one that's not any of the blacklisted ones.
+      // Find first one that's not any of the denylisted ones.
       String line = traceLines[i];
       if (line.contains("parser_test_listener.dart:") ||
           line.contains("parser_suite.dart:") ||
diff --git a/pkg/front_end/test/spell_checking_list_blacklist.txt b/pkg/front_end/test/spell_checking_list_blacklist.txt
deleted file mode 100644
index 3978cf1..0000000
--- a/pkg/front_end/test/spell_checking_list_blacklist.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-# 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.
-
-# Blank lines and comments are ignored.
-# Comments can also be inline like 'correct # this is ok'.
-# Note that at least one space before the hash is required.
-
-# Comments on a line by itself will be considered a header of the file and
-# automatic tools might move it to the top of the file.
-
-alread
-chnage
-clonable
-comile
-complation
-conditoinal
-conected
-constructer
-constructers
-contaning
-contol
-covarint
-depencencies
-detemination
-diagnotics
-down't
-effeciency
-erronious
-errornious
-evaluted
-explaination
-expresison
-expressoin
-gurantees
-hiearchy
-hierachy
-independendent
-infered
-instantaite
-instantating
-instantition
-instesection
-internel
-keybord
-libarary
-librares
-neame
-neccessary
-normaly
-nullabiliity
-obect
-occured
-occurence
-ocurred
-opreations
-Orignially
-outtermost
-phisical
-plaform
-poluted
-preceeded
-previosly
-priotity
-proram
-recomile
-resently
-reuslt
-satifying
-seach
-singluar
-Specifiction
-staments
-statment
-stubstitution
-subsitutions
-subtring
-suffient
-terminted
-tood
-unlinke
-valiation
\ No newline at end of file
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index a942ecd2..4fc2204 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -603,6 +603,7 @@
 manipulation
 markdown
 masking
+master
 matcher
 mb
 md
diff --git a/pkg/front_end/test/spell_checking_list_common.txt b/pkg/front_end/test/spell_checking_list_common.txt
index 4a1e4e1..ef9be39 100644
--- a/pkg/front_end/test/spell_checking_list_common.txt
+++ b/pkg/front_end/test/spell_checking_list_common.txt
@@ -296,7 +296,7 @@
 bits
 bitwise
 black
-blacklisted
+denylisted
 block
 blocks
 blogs
@@ -772,6 +772,7 @@
 denoted
 denotes
 denoting
+deny
 depend
 dependence
 dependencies
@@ -1769,7 +1770,6 @@
 marking
 marks
 mask
-master
 match
 matched
 matcher
@@ -3250,7 +3250,7 @@
 which
 while
 white
-whitelisted
+allowlisted
 whitespace
 whole
 whose
diff --git a/pkg/front_end/test/spell_checking_list_denylist.txt b/pkg/front_end/test/spell_checking_list_denylist.txt
new file mode 100644
index 0000000..84dded9
--- /dev/null
+++ b/pkg/front_end/test/spell_checking_list_denylist.txt
@@ -0,0 +1,91 @@
+# 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.
+
+# Blank lines and comments are ignored.
+# Comments can also be inline like 'correct # this is ok'.
+# Note that at least one space before the hash is required.
+
+# Comments on a line by itself will be considered a header of the file and
+# automatic tools might move it to the top of the file.
+
+alread
+blacklist
+black-list
+blacklisted
+black-listed
+chnage
+clonable
+comile
+complation
+conditoinal
+conected
+constructer
+constructers
+contaning
+contol
+covarint
+depencencies
+detemination
+diagnotics
+down't
+effeciency
+erronious
+errornious
+evaluted
+explaination
+expresison
+expressoin
+gurantees
+hiearchy
+hierachy
+independendent
+infered
+instantaite
+instantating
+instantition
+instesection
+internel
+keybord
+libarary
+librares
+neame
+neccessary
+normaly
+nullabiliity
+obect
+occured
+occurence
+ocurred
+opreations
+Orignially
+outtermost
+phisical
+plaform
+poluted
+preceeded
+previosly
+priotity
+proram
+recomile
+resently
+reuslt
+satifying
+seach
+singluar
+slave
+Specifiction
+staments
+statment
+stubstitution
+subsitutions
+subtring
+suffient
+terminted
+tood
+unlinke
+valiation
+whitelist
+white-list
+whitelisted
+white-listed
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index 4a9c1b6..e6deb54 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -54,7 +54,7 @@
 besides
 beta
 bigger
-blacklist
+denylist
 blah
 blindly
 blocked
@@ -552,8 +552,8 @@
 walt
 warmup
 wherever
-whitelist
-whitelisting
+allowlist
+allowlisting
 wins
 workflow
 worlds
diff --git a/pkg/front_end/test/spell_checking_utils.dart b/pkg/front_end/test/spell_checking_utils.dart
index 26e9959..e29b233 100644
--- a/pkg/front_end/test/spell_checking_utils.dart
+++ b/pkg/front_end/test/spell_checking_utils.dart
@@ -9,8 +9,8 @@
   cfeMessages,
   cfeCode,
   cfeTests,
-  // The blacklist is special and is always loaded!
-  blacklist,
+  // The denylist is special and is always loaded!
+  denylist,
 }
 
 Map<Dictionaries, Set<String>> loadedDictionaries;
@@ -23,14 +23,14 @@
   List<String> wrongWords;
   List<List<String>> wrongWordsAlternatives;
   List<int> wrongWordsOffset;
-  List<bool> wrongWordBlacklisted;
+  List<bool> wrongWordDenylisted;
   List<int> wordOffsets = new List<int>();
   List<String> words =
       splitStringIntoWords(s, wordOffsets, splitAsCode: splitAsCode);
   List<Set<String>> dictionariesUnpacked = [];
   for (int j = 0; j < dictionaries.length; j++) {
     Dictionaries dictionaryType = dictionaries[j];
-    if (dictionaryType == Dictionaries.blacklist) continue;
+    if (dictionaryType == Dictionaries.denylist) continue;
     Set<String> dictionary = loadedDictionaries[dictionaryType];
     dictionariesUnpacked.add(dictionary);
   }
@@ -53,13 +53,13 @@
       wrongWordsAlternatives.add(findAlternatives(word, dictionariesUnpacked));
       wrongWordsOffset ??= new List<int>();
       wrongWordsOffset.add(offset);
-      wrongWordBlacklisted ??= new List<bool>();
-      wrongWordBlacklisted
-          .add(loadedDictionaries[Dictionaries.blacklist].contains(word));
+      wrongWordDenylisted ??= new List<bool>();
+      wrongWordDenylisted
+          .add(loadedDictionaries[Dictionaries.denylist].contains(word));
     }
   }
 
-  return new SpellingResult(wrongWords, wrongWordsOffset, wrongWordBlacklisted,
+  return new SpellingResult(wrongWords, wrongWordsOffset, wrongWordDenylisted,
       wrongWordsAlternatives);
 }
 
@@ -107,11 +107,11 @@
 class SpellingResult {
   final List<String> misspelledWords;
   final List<int> misspelledWordsOffset;
-  final List<bool> misspelledWordsBlacklisted;
+  final List<bool> misspelledWordsDenylisted;
   final List<List<String>> misspelledWordsAlternatives;
 
   SpellingResult(this.misspelledWords, this.misspelledWordsOffset,
-      this.misspelledWordsBlacklisted, this.misspelledWordsAlternatives);
+      this.misspelledWordsDenylisted, this.misspelledWordsAlternatives);
 }
 
 void ensureDictionariesLoaded(List<Dictionaries> dictionaries) {
@@ -133,12 +133,12 @@
   }
 
   loadedDictionaries ??= new Map<Dictionaries, Set<String>>();
-  // Ensure the blacklist is loaded.
-  Set<String> blacklistDictionary = loadedDictionaries[Dictionaries.blacklist];
-  if (blacklistDictionary == null) {
-    blacklistDictionary = new Set<String>();
-    loadedDictionaries[Dictionaries.blacklist] = blacklistDictionary;
-    addWords(dictionaryToUri(Dictionaries.blacklist), blacklistDictionary);
+  // Ensure the denylist is loaded.
+  Set<String> denylistDictionary = loadedDictionaries[Dictionaries.denylist];
+  if (denylistDictionary == null) {
+    denylistDictionary = new Set<String>();
+    loadedDictionaries[Dictionaries.denylist] = denylistDictionary;
+    addWords(dictionaryToUri(Dictionaries.denylist), denylistDictionary);
   }
 
   for (int j = 0; j < dictionaries.length; j++) {
@@ -148,11 +148,11 @@
       dictionary = new Set<String>();
       loadedDictionaries[dictionaryType] = dictionary;
       addWords(dictionaryToUri(dictionaryType), dictionary);
-      // Check that no good words occur in the blacklist.
+      // Check that no good words occur in the denylist.
       for (String s in dictionary) {
-        if (blacklistDictionary.contains(s)) {
+        if (denylistDictionary.contains(s)) {
           throw "Word '$s' in dictionary $dictionaryType "
-              "is also in the blacklist.";
+              "is also in the denylist.";
         }
       }
     }
@@ -173,9 +173,9 @@
     case Dictionaries.cfeTests:
       return Uri.base
           .resolve("pkg/front_end/test/spell_checking_list_tests.txt");
-    case Dictionaries.blacklist:
+    case Dictionaries.denylist:
       return Uri.base
-          .resolve("pkg/front_end/test/spell_checking_list_blacklist.txt");
+          .resolve("pkg/front_end/test/spell_checking_list_denylist.txt");
   }
   throw "Unknown Dictionary";
 }
diff --git a/pkg/front_end/test/spelling_test_base.dart b/pkg/front_end/test/spelling_test_base.dart
index 9f8d58a..056d0e7 100644
--- a/pkg/front_end/test/spelling_test_base.dart
+++ b/pkg/front_end/test/spelling_test_base.dart
@@ -46,19 +46,19 @@
 
   List<spell.Dictionaries> get dictionaries;
 
-  bool get onlyBlacklisted;
+  bool get onlyDenylisted;
 
   Set<String> reportedWords = {};
-  Set<String> reportedWordsBlacklisted = {};
+  Set<String> reportedWordsDenylisted = {};
 
   @override
   Future<void> postRun() {
-    if (reportedWordsBlacklisted.isNotEmpty) {
+    if (reportedWordsDenylisted.isNotEmpty) {
       print("\n\n\n");
       print("================");
-      print("The following words was reported as used and blacklisted:");
+      print("The following words was reported as used and denylisted:");
       print("----------------");
-      for (String s in reportedWordsBlacklisted) {
+      for (String s in reportedWordsDenylisted) {
         print("$s");
       }
       print("================");
@@ -184,12 +184,12 @@
     Source source = new Source(
         scanner.lineStarts, rawBytes, description.uri, description.uri);
     void addErrorMessage(
-        int offset, String word, bool blacklisted, List<String> alternatives) {
+        int offset, String word, bool denylisted, List<String> alternatives) {
       errors ??= new List<String>();
       String message;
-      if (blacklisted) {
-        message = "Misspelled word: '$word' has explicitly been blacklisted.";
-        context.reportedWordsBlacklisted.add(word);
+      if (denylisted) {
+        message = "Misspelled word: '$word' has explicitly been denylisted.";
+        context.reportedWordsDenylisted.add(word);
       } else {
         message = "The word '$word' is not in our dictionary.";
         context.reportedWords.add(word);
@@ -230,12 +230,12 @@
               dictionaries: context.dictionaries);
           if (spellingResult.misspelledWords != null) {
             for (int i = 0; i < spellingResult.misspelledWords.length; i++) {
-              bool blacklisted = spellingResult.misspelledWordsBlacklisted[i];
-              if (context.onlyBlacklisted && !blacklisted) continue;
+              bool denylisted = spellingResult.misspelledWordsDenylisted[i];
+              if (context.onlyDenylisted && !denylisted) continue;
               int offset =
                   comment.offset + spellingResult.misspelledWordsOffset[i];
               addErrorMessage(offset, spellingResult.misspelledWords[i],
-                  blacklisted, spellingResult.misspelledWordsAlternatives[i]);
+                  denylisted, spellingResult.misspelledWordsAlternatives[i]);
             }
           }
           comment = comment.next;
@@ -248,11 +248,11 @@
             dictionaries: context.dictionaries);
         if (spellingResult.misspelledWords != null) {
           for (int i = 0; i < spellingResult.misspelledWords.length; i++) {
-            bool blacklisted = spellingResult.misspelledWordsBlacklisted[i];
-            if (context.onlyBlacklisted && !blacklisted) continue;
+            bool denylisted = spellingResult.misspelledWordsDenylisted[i];
+            if (context.onlyDenylisted && !denylisted) continue;
             int offset = token.offset + spellingResult.misspelledWordsOffset[i];
             addErrorMessage(offset, spellingResult.misspelledWords[i],
-                blacklisted, spellingResult.misspelledWordsAlternatives[i]);
+                denylisted, spellingResult.misspelledWordsAlternatives[i]);
           }
         }
       } else if (token is KeywordToken || token is BeginToken) {
diff --git a/pkg/front_end/test/spelling_test_external_targets.dart b/pkg/front_end/test/spelling_test_external_targets.dart
index 12a601b..98faa82 100644
--- a/pkg/front_end/test/spelling_test_external_targets.dart
+++ b/pkg/front_end/test/spelling_test_external_targets.dart
@@ -29,7 +29,7 @@
   List<spell.Dictionaries> get dictionaries => const <spell.Dictionaries>[];
 
   @override
-  bool get onlyBlacklisted => true;
+  bool get onlyDenylisted => true;
 
   Stream<TestDescription> list(Chain suite) async* {
     for (String subdir in const ["pkg/", "sdk/"]) {
diff --git a/pkg/front_end/test/spelling_test_not_src_suite.dart b/pkg/front_end/test/spelling_test_not_src_suite.dart
index a67d668..32627a6 100644
--- a/pkg/front_end/test/spelling_test_not_src_suite.dart
+++ b/pkg/front_end/test/spelling_test_not_src_suite.dart
@@ -30,5 +30,5 @@
       ];
 
   @override
-  bool get onlyBlacklisted => false;
+  bool get onlyDenylisted => false;
 }
diff --git a/pkg/front_end/test/spelling_test_src_suite.dart b/pkg/front_end/test/spelling_test_src_suite.dart
index 39c42f3..3e4f1f5 100644
--- a/pkg/front_end/test/spelling_test_src_suite.dart
+++ b/pkg/front_end/test/spelling_test_src_suite.dart
@@ -29,5 +29,5 @@
       ];
 
   @override
-  bool get onlyBlacklisted => false;
+  bool get onlyDenylisted => false;
 }
diff --git a/pkg/front_end/testcases/nnbd/constants.dart b/pkg/front_end/testcases/nnbd/constants.dart
new file mode 100644
index 0000000..87572ea
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart
@@ -0,0 +1,72 @@
+// 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 '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);
+
+main() {
+  test(objectTypeLiteral, lib.objectTypeLiteral);
+  test(partialInstantiation, lib.partialInstantiation);
+  test(instance, lib.instance);
+  test(functionTypeLiteral, lib.functionTypeLiteral);
+  test(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
+  test(listLiteral, lib.listLiteral);
+  test(setLiteral, lib.setLiteral);
+  test(mapLiteral, lib.mapLiteral);
+  test(listConcatenation, lib.listConcatenation);
+  test(setConcatenation, lib.setConcatenation);
+  test(mapConcatenation, lib.mapConcatenation);
+
+  test(true, objectTypeLiteralIdentical);
+  test(true, partialInstantiationIdentical);
+  test(true, instanceIdentical);
+  test(true, functionTypeLiteralIdentical);
+  test(true, genericFunctionTypeLiteralIdentical);
+  test(true, listLiteralIdentical);
+  test(true, setLiteralIdentical);
+  test(true, mapLiteralIdentical);
+  test(true, listConcatenationIdentical);
+  test(true, setConcatenationIdentical);
+  test(true, mapConcatenationIdentical);
+}
+
+test(expected, actual) {
+  print('test($expected, $actual)');
+  if (!identical(expected, actual)) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.outline.expect b/pkg/front_end/testcases/nnbd/constants.dart.outline.expect
new file mode 100644
index 0000000..ec25785
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.outline.expect
@@ -0,0 +1,62 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "constants_lib.dart" as con;
+
+import "org-dartlang-testcase:///constants_lib.dart" as lib;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::Type objectTypeLiteral = core::Object;
+static const field (core::int) → core::int partialInstantiation = con::id<core::int>;
+static const field con::Class<core::int> instance = const con::Class::•<core::int>(0);
+static const field core::Type functionTypeLiteral = (dynamic) → dynamic;
+static const field core::Type genericFunctionTypeLiteral = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::List<core::int> listLiteral = const <core::int>[0];
+static const field core::Set<core::int> setLiteral = const <core::int>{0};
+static const field core::Map<core::int, core::String> mapLiteral = const <core::int, core::String>{0: "foo"};
+static const field core::List<core::int> listConcatenation = self::listLiteral;
+static const field core::Set<core::int> setConcatenation = self::setLiteral;
+static const field core::Map<core::int, core::String> mapConcatenation = self::mapLiteral;
+static const field core::bool objectTypeLiteralIdentical = core::identical(self::objectTypeLiteral, con::objectTypeLiteral);
+static const field core::bool partialInstantiationIdentical = core::identical(self::partialInstantiation, con::partialInstantiation);
+static const field core::bool instanceIdentical = core::identical(self::instance, con::instance);
+static const field core::bool functionTypeLiteralIdentical = core::identical(self::functionTypeLiteral, con::functionTypeLiteral);
+static const field core::bool genericFunctionTypeLiteralIdentical = core::identical(self::genericFunctionTypeLiteral, con::genericFunctionTypeLiteral);
+static const field core::bool listLiteralIdentical = core::identical(self::listLiteral, con::listLiteral);
+static const field core::bool setLiteralIdentical = core::identical(self::setLiteral, con::setLiteral);
+static const field core::bool mapLiteralIdentical = core::identical(self::mapLiteral, con::mapLiteral);
+static const field core::bool listConcatenationIdentical = core::identical(self::listConcatenation, con::listConcatenation);
+static const field core::bool setConcatenationIdentical = core::identical(self::setConcatenation, con::setConcatenation);
+static const field core::bool mapConcatenationIdentical = core::identical(self::mapConcatenation, con::mapConcatenation);
+static method main() → dynamic
+  ;
+static method test(dynamic expected, dynamic actual) → dynamic
+  ;
+
+library /*isNonNullableByDefault*/;
+import self as con;
+import "dart:core" as core;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field con::Class::T% field;
+  const constructor •(con::Class::T% field) → con::Class<con::Class::T%>
+    : con::Class::field = field, super core::Object::•()
+    ;
+}
+static const field core::Type objectTypeLiteral = core::Object;
+static const field (core::Object?, core::Object?) → core::bool c2 = core::identical;
+static const field (core::int) → core::int partialInstantiation = con::id<core::int>;
+static const field con::Class<core::int> instance = const con::Class::•<core::int>(0);
+static const field core::Type functionTypeLiteral = (dynamic) → dynamic;
+static const field core::Type genericFunctionTypeLiteral = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::List<core::int> listLiteral = const <core::int>[0];
+static const field core::Set<core::int> setLiteral = const <core::int>{0};
+static const field core::Map<core::int, core::String> mapLiteral = const <core::int, core::String>{0: "foo"};
+static const field core::List<core::int> listConcatenation = con::listLiteral;
+static const field core::Set<core::int> setConcatenation = con::setLiteral;
+static const field core::Map<core::int, core::String> mapConcatenation = con::mapLiteral;
+static method id<T extends core::Object? = dynamic>(con::id::T% t) → con::id::T%
+  ;
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.strong.expect b/pkg/front_end/testcases/nnbd/constants.dart.strong.expect
new file mode 100644
index 0000000..6ff5eb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.strong.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "constants_lib.dart" as con;
+
+import "org-dartlang-testcase:///constants_lib.dart" as lib;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static const field core::bool objectTypeLiteralIdentical = #C16;
+static const field core::bool partialInstantiationIdentical = #C16;
+static const field core::bool instanceIdentical = #C16;
+static const field core::bool functionTypeLiteralIdentical = #C16;
+static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
+static const field core::bool listLiteralIdentical = #C16;
+static const field core::bool setLiteralIdentical = #C16;
+static const field core::bool mapLiteralIdentical = #C16;
+static const field core::bool listConcatenationIdentical = #C16;
+static const field core::bool setConcatenationIdentical = #C16;
+static const field core::bool mapConcatenationIdentical = #C16;
+static method main() → dynamic {
+  self::test(#C1, #C1);
+  self::test(#C3, #C3);
+  self::test(#C5, #C5);
+  self::test(#C6, #C6);
+  self::test(#C7, #C7);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+}
+static method test(dynamic expected, dynamic actual) → dynamic {
+  core::print("test(${expected}, ${actual})");
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as con;
+import "dart:core" as core;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field con::Class::T% field;
+  const constructor •(con::Class::T% field) → con::Class<con::Class::T%>
+    : con::Class::field = field, super core::Object::•()
+    ;
+}
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::Object?, core::Object?) → core::bool c2 = #C17;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static method id<T extends core::Object? = dynamic>(con::id::T% t) → con::id::T%
+  return t;
+
+constants  {
+  #C1 = TypeLiteralConstant(core::Object)
+  #C2 = tearoff con::id
+  #C3 = partial-instantiation con::id <core::int>
+  #C4 = 0
+  #C5 = con::Class<core::int> {field:#C4}
+  #C6 = TypeLiteralConstant((dynamic) → dynamic)
+  #C7 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C8 = <core::int>[#C4]
+  #C9 = null
+  #C10 = <dynamic>[#C4, #C9]
+  #C11 = core::_ImmutableMap<core::int, core::Null?> {_kvPairs:#C10}
+  #C12 = col::_UnmodifiableSet<core::int> {_map:#C11}
+  #C13 = "foo"
+  #C14 = <dynamic>[#C4, #C13]
+  #C15 = core::_ImmutableMap<core::int, core::String> {_kvPairs:#C14}
+  #C16 = true
+  #C17 = tearoff core::identical
+}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/constants.dart.strong.transformed.expect
new file mode 100644
index 0000000..6ff5eb2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.strong.transformed.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "constants_lib.dart" as con;
+
+import "org-dartlang-testcase:///constants_lib.dart" as lib;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static const field core::bool objectTypeLiteralIdentical = #C16;
+static const field core::bool partialInstantiationIdentical = #C16;
+static const field core::bool instanceIdentical = #C16;
+static const field core::bool functionTypeLiteralIdentical = #C16;
+static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
+static const field core::bool listLiteralIdentical = #C16;
+static const field core::bool setLiteralIdentical = #C16;
+static const field core::bool mapLiteralIdentical = #C16;
+static const field core::bool listConcatenationIdentical = #C16;
+static const field core::bool setConcatenationIdentical = #C16;
+static const field core::bool mapConcatenationIdentical = #C16;
+static method main() → dynamic {
+  self::test(#C1, #C1);
+  self::test(#C3, #C3);
+  self::test(#C5, #C5);
+  self::test(#C6, #C6);
+  self::test(#C7, #C7);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+}
+static method test(dynamic expected, dynamic actual) → dynamic {
+  core::print("test(${expected}, ${actual})");
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as con;
+import "dart:core" as core;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field con::Class::T% field;
+  const constructor •(con::Class::T% field) → con::Class<con::Class::T%>
+    : con::Class::field = field, super core::Object::•()
+    ;
+}
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::Object?, core::Object?) → core::bool c2 = #C17;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static method id<T extends core::Object? = dynamic>(con::id::T% t) → con::id::T%
+  return t;
+
+constants  {
+  #C1 = TypeLiteralConstant(core::Object)
+  #C2 = tearoff con::id
+  #C3 = partial-instantiation con::id <core::int>
+  #C4 = 0
+  #C5 = con::Class<core::int> {field:#C4}
+  #C6 = TypeLiteralConstant((dynamic) → dynamic)
+  #C7 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C8 = <core::int>[#C4]
+  #C9 = null
+  #C10 = <dynamic>[#C4, #C9]
+  #C11 = core::_ImmutableMap<core::int, core::Null?> {_kvPairs:#C10}
+  #C12 = col::_UnmodifiableSet<core::int> {_map:#C11}
+  #C13 = "foo"
+  #C14 = <dynamic>[#C4, #C13]
+  #C15 = core::_ImmutableMap<core::int, core::String> {_kvPairs:#C14}
+  #C16 = true
+  #C17 = tearoff core::identical
+}
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..1258f5e
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline.expect
@@ -0,0 +1,35 @@
+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);
+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..0187c66
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.textual_outline_modelled.expect
@@ -0,0 +1,35 @@
+import 'constants_lib.dart' as lib;
+
+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);
+main() {}
+test(expected, actual) {}
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.weak.expect b/pkg/front_end/testcases/nnbd/constants.dart.weak.expect
new file mode 100644
index 0000000..787be87
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.weak.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "constants_lib.dart" as con;
+
+import "org-dartlang-testcase:///constants_lib.dart" as lib;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static const field core::bool objectTypeLiteralIdentical = #C16;
+static const field core::bool partialInstantiationIdentical = #C16;
+static const field core::bool instanceIdentical = #C16;
+static const field core::bool functionTypeLiteralIdentical = #C16;
+static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
+static const field core::bool listLiteralIdentical = #C16;
+static const field core::bool setLiteralIdentical = #C16;
+static const field core::bool mapLiteralIdentical = #C16;
+static const field core::bool listConcatenationIdentical = #C16;
+static const field core::bool setConcatenationIdentical = #C16;
+static const field core::bool mapConcatenationIdentical = #C16;
+static method main() → dynamic {
+  self::test(#C1, #C1);
+  self::test(#C3, #C3);
+  self::test(#C5, #C5);
+  self::test(#C6, #C6);
+  self::test(#C7, #C7);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+}
+static method test(dynamic expected, dynamic actual) → dynamic {
+  core::print("test(${expected}, ${actual})");
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as con;
+import "dart:core" as core;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field con::Class::T% field;
+  const constructor •(con::Class::T% field) → con::Class<con::Class::T%>
+    : con::Class::field = field, super core::Object::•()
+    ;
+}
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::Object?, core::Object?) → core::bool c2 = #C17;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static method id<T extends core::Object? = dynamic>(con::id::T% t) → con::id::T%
+  return t;
+
+constants  {
+  #C1 = TypeLiteralConstant(core::Object)
+  #C2 = tearoff con::id
+  #C3 = partial-instantiation con::id <core::int*>
+  #C4 = 0
+  #C5 = con::Class<core::int*> {field:#C4}
+  #C6 = TypeLiteralConstant((dynamic) → dynamic)
+  #C7 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C8 = <core::int*>[#C4]
+  #C9 = null
+  #C10 = <dynamic>[#C4, #C9]
+  #C11 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C10}
+  #C12 = col::_UnmodifiableSet<core::int*> {_map:#C11}
+  #C13 = "foo"
+  #C14 = <dynamic>[#C4, #C13]
+  #C15 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C14}
+  #C16 = true
+  #C17 = tearoff core::identical
+}
diff --git a/pkg/front_end/testcases/nnbd/constants.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/constants.dart.weak.transformed.expect
new file mode 100644
index 0000000..787be87
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants.dart.weak.transformed.expect
@@ -0,0 +1,108 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+import "constants_lib.dart" as con;
+
+import "org-dartlang-testcase:///constants_lib.dart" as lib;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static const field core::bool objectTypeLiteralIdentical = #C16;
+static const field core::bool partialInstantiationIdentical = #C16;
+static const field core::bool instanceIdentical = #C16;
+static const field core::bool functionTypeLiteralIdentical = #C16;
+static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
+static const field core::bool listLiteralIdentical = #C16;
+static const field core::bool setLiteralIdentical = #C16;
+static const field core::bool mapLiteralIdentical = #C16;
+static const field core::bool listConcatenationIdentical = #C16;
+static const field core::bool setConcatenationIdentical = #C16;
+static const field core::bool mapConcatenationIdentical = #C16;
+static method main() → dynamic {
+  self::test(#C1, #C1);
+  self::test(#C3, #C3);
+  self::test(#C5, #C5);
+  self::test(#C6, #C6);
+  self::test(#C7, #C7);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(#C8, #C8);
+  self::test(#C12, #C12);
+  self::test(#C15, #C15);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+  self::test(true, #C16);
+}
+static method test(dynamic expected, dynamic actual) → dynamic {
+  core::print("test(${expected}, ${actual})");
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
+  }
+}
+
+library /*isNonNullableByDefault*/;
+import self as con;
+import "dart:core" as core;
+
+typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
+typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
+class Class<T extends core::Object? = dynamic> extends core::Object /*hasConstConstructor*/  {
+  final field con::Class::T% field;
+  const constructor •(con::Class::T% field) → con::Class<con::Class::T%>
+    : con::Class::field = field, super core::Object::•()
+    ;
+}
+static const field core::Type objectTypeLiteral = #C1;
+static const field (core::Object?, core::Object?) → core::bool c2 = #C17;
+static const field (core::int) → core::int partialInstantiation = #C3;
+static const field con::Class<core::int> instance = #C5;
+static const field core::Type functionTypeLiteral = #C6;
+static const field core::Type genericFunctionTypeLiteral = #C7;
+static const field core::List<core::int> listLiteral = #C8;
+static const field core::Set<core::int> setLiteral = #C12;
+static const field core::Map<core::int, core::String> mapLiteral = #C15;
+static const field core::List<core::int> listConcatenation = #C8;
+static const field core::Set<core::int> setConcatenation = #C12;
+static const field core::Map<core::int, core::String> mapConcatenation = #C15;
+static method id<T extends core::Object? = dynamic>(con::id::T% t) → con::id::T%
+  return t;
+
+constants  {
+  #C1 = TypeLiteralConstant(core::Object)
+  #C2 = tearoff con::id
+  #C3 = partial-instantiation con::id <core::int*>
+  #C4 = 0
+  #C5 = con::Class<core::int*> {field:#C4}
+  #C6 = TypeLiteralConstant((dynamic) → dynamic)
+  #C7 = TypeLiteralConstant(<T extends core::Object? = dynamic>(T%) → T%)
+  #C8 = <core::int*>[#C4]
+  #C9 = null
+  #C10 = <dynamic>[#C4, #C9]
+  #C11 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C10}
+  #C12 = col::_UnmodifiableSet<core::int*> {_map:#C11}
+  #C13 = "foo"
+  #C14 = <dynamic>[#C4, #C13]
+  #C15 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C14}
+  #C16 = true
+  #C17 = tearoff core::identical
+}
diff --git a/pkg/front_end/testcases/nnbd/constants_lib.dart b/pkg/front_end/testcases/nnbd/constants_lib.dart
new file mode 100644
index 0000000..c5a8ebd
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/constants_lib.dart
@@ -0,0 +1,27 @@
+// 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 Class<T> {
+  final T field;
+
+  const Class(this.field);
+}
+
+T id<T>(T t) => t;
+
+typedef F1<T> = T Function(T);
+typedef F2 = T Function<T>(T);
+
+const objectTypeLiteral = Object;
+const c2 = identical;
+const int Function(int) partialInstantiation = id;
+const instance = const 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};
diff --git a/pkg/front_end/testcases/nnbd_mixed/constants.dart b/pkg/front_end/testcases/nnbd_mixed/constants.dart
index 3335767..f019b83 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/constants.dart
@@ -4,14 +4,8 @@
 
 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'};
@@ -19,15 +13,9 @@
 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);
@@ -38,19 +26,9 @@
 const mapConcatenationIdentical =
     identical(mapConcatenation, lib.mapConcatenation);
 
-final bool inStrongMode = _inStrongMode();
-
-bool _inStrongMode() {
-  const List<int?> list = const <int?>[];
-  return list is! List<int>;
-}
-
 main() {
-  test(objectTypeLiteral, lib.objectTypeLiteral);
   test(partialInstantiation, lib.partialInstantiation);
   test(instance, lib.instance);
-  test(functionTypeLiteral, lib.functionTypeLiteral);
-  test(genericFunctionTypeLiteral, lib.genericFunctionTypeLiteral);
   test(listLiteral, lib.listLiteral);
   test(setLiteral, lib.setLiteral);
   test(mapLiteral, lib.mapLiteral);
@@ -58,11 +36,8 @@
   test(setConcatenation, lib.setConcatenation);
   test(mapConcatenation, lib.mapConcatenation);
 
-  test(true, objectTypeLiteralIdentical);
   test(true, partialInstantiationIdentical);
   test(true, instanceIdentical);
-  test(true, functionTypeLiteralIdentical);
-  test(true, genericFunctionTypeLiteralIdentical);
   test(true, listLiteralIdentical);
   test(true, setLiteralIdentical);
   test(true, mapLiteralIdentical);
@@ -73,13 +48,7 @@
 
 test(expected, actual) {
   print('test($expected, $actual)');
-  if (inStrongMode) {
-    if (identical(expected, actual)) {
-      throw 'Unexpected identical for $expected and $actual';
-    }
-  } else {
-    if (!identical(expected, actual)) {
-      throw 'Expected $expected, actual $actual';
-    }
+  if (!identical(expected, actual)) {
+    throw 'Expected $expected, actual $actual';
   }
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline.expect
index abf8e2f..4d03b3b 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline.expect
@@ -1,27 +1,16 @@
 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);
@@ -31,7 +20,5 @@
     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_mixed/constants.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline_modelled.expect
index 03b68b2..4233487 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline_modelled.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constants.dart.textual_outline_modelled.expect
@@ -1,12 +1,5 @@
 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;
@@ -20,9 +13,6 @@
     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};
@@ -30,8 +20,5 @@
     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_mixed/constants.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.expect
index 92a1fb8..bb3f969 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.expect
@@ -5,69 +5,44 @@
 
 import "org-dartlang-testcase:///constants_lib.dart" as lib;
 
-typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
-typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
-static const field core::Type objectTypeLiteral = #C1;
-static const field (core::int) → core::int partialInstantiation = #C3;
-static const field con::Class<core::int> instance = #C5;
-static const field core::Type functionTypeLiteral = #C6;
-static const field core::Type genericFunctionTypeLiteral = #C7;
-static const field core::List<core::int> listLiteral = #C8;
-static const field core::Set<core::int> setLiteral = #C12;
-static const field core::Map<core::int, core::String> mapLiteral = #C15;
-static const field core::List<core::int> listConcatenation = #C8;
-static const field core::Set<core::int> setConcatenation = #C12;
-static const field core::Map<core::int, core::String> mapConcatenation = #C15;
-static const field core::bool objectTypeLiteralIdentical = #C16;
-static const field core::bool partialInstantiationIdentical = #C16;
-static const field core::bool instanceIdentical = #C16;
-static const field core::bool functionTypeLiteralIdentical = #C16;
-static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
-static const field core::bool listLiteralIdentical = #C16;
-static const field core::bool setLiteralIdentical = #C16;
-static const field core::bool mapLiteralIdentical = #C16;
-static const field core::bool listConcatenationIdentical = #C16;
-static const field core::bool setConcatenationIdentical = #C16;
-static const field core::bool mapConcatenationIdentical = #C16;
-static final field core::bool inStrongMode = self::_inStrongMode();
-static method _inStrongMode() → core::bool {
-  return !((#C17) is{ForNonNullableByDefault} core::List<core::int>);
-}
+static const field (core::int) → core::int partialInstantiation = #C2;
+static const field con::Class<core::int> instance = #C4;
+static const field core::List<core::int> listLiteral = #C5;
+static const field core::Set<core::int> setLiteral = #C9;
+static const field core::Map<core::int, core::String> mapLiteral = #C12;
+static const field core::List<core::int> listConcatenation = #C5;
+static const field core::Set<core::int> setConcatenation = #C9;
+static const field core::Map<core::int, core::String> mapConcatenation = #C12;
+static const field core::bool partialInstantiationIdentical = #C13;
+static const field core::bool instanceIdentical = #C13;
+static const field core::bool listLiteralIdentical = #C13;
+static const field core::bool setLiteralIdentical = #C13;
+static const field core::bool mapLiteralIdentical = #C13;
+static const field core::bool listConcatenationIdentical = #C13;
+static const field core::bool setConcatenationIdentical = #C13;
+static const field core::bool mapConcatenationIdentical = #C13;
 static method main() → dynamic {
-  self::test(#C1, #C1);
-  self::test(#C3, #C3);
+  self::test(#C2, #C2);
+  self::test(#C4, #C4);
   self::test(#C5, #C5);
-  self::test(#C6, #C6);
-  self::test(#C7, #C7);
-  self::test(#C8, #C8);
+  self::test(#C9, #C9);
   self::test(#C12, #C12);
-  self::test(#C15, #C15);
-  self::test(#C8, #C8);
+  self::test(#C5, #C5);
+  self::test(#C9, #C9);
   self::test(#C12, #C12);
-  self::test(#C15, #C15);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
 }
 static method test(dynamic expected, dynamic actual) → dynamic {
   core::print("test(${expected}, ${actual})");
-  if(self::inStrongMode) {
-    if(core::identical(expected, actual)) {
-      throw "Unexpected identical for ${expected} and ${actual}";
-    }
-  }
-  else {
-    if(!core::identical(expected, actual)) {
-      throw "Expected ${expected}, actual ${actual}";
-    }
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
   }
 }
 
@@ -93,38 +68,31 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
   abstract member-signature get runtimeType() → core::Type*;
 }
-static const field core::Type* objectTypeLiteral = #C1;
-static const field (core::Object*, core::Object*) →* core::bool* c2 = #C18;
-static const field (core::int*) →* core::int* partialInstantiation = #C3;
-static const field con::Class<core::int*>* instance = #C5;
-static const field core::Type* functionTypeLiteral = #C6;
-static const field core::Type* genericFunctionTypeLiteral = #C7;
-static const field core::List<core::int*>* listLiteral = #C8;
-static const field core::Set<core::int*>* setLiteral = #C12;
-static const field core::Map<core::int*, core::String*>* mapLiteral = #C15;
-static const field core::List<core::int*>* listConcatenation = #C8;
-static const field core::Set<core::int*>* setConcatenation = #C12;
-static const field core::Map<core::int*, core::String*>* mapConcatenation = #C15;
+static const field (core::Object*, core::Object*) →* core::bool* c2 = #C14;
+static const field (core::int*) →* core::int* partialInstantiation = #C2;
+static const field con::Class<core::int*>* instance = #C4;
+static const field core::List<core::int*>* listLiteral = #C5;
+static const field core::Set<core::int*>* setLiteral = #C9;
+static const field core::Map<core::int*, core::String*>* mapLiteral = #C12;
+static const field core::List<core::int*>* listConcatenation = #C5;
+static const field core::Set<core::int*>* setConcatenation = #C9;
+static const field core::Map<core::int*, core::String*>* mapConcatenation = #C12;
 static method id<T extends core::Object* = dynamic>(con::id::T* t) → con::id::T*
   return t;
 
 constants  {
-  #C1 = TypeLiteralConstant(core::Object*)
-  #C2 = tearoff con::id
-  #C3 = partial-instantiation con::id <core::int*>
-  #C4 = 0
-  #C5 = con::Class<core::int*> {field:#C4}
-  #C6 = TypeLiteralConstant((dynamic) →* dynamic)
-  #C7 = TypeLiteralConstant(<T extends core::Object* = dynamic>(T*) →* T*)
-  #C8 = <core::int*>[#C4]
-  #C9 = null
-  #C10 = <dynamic>[#C4, #C9]
-  #C11 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C10}
-  #C12 = col::_UnmodifiableSet<core::int*> {_map:#C11}
-  #C13 = "foo"
-  #C14 = <dynamic>[#C4, #C13]
-  #C15 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C14}
-  #C16 = true
-  #C17 = <core::int*>[]
-  #C18 = tearoff core::identical
+  #C1 = tearoff con::id
+  #C2 = partial-instantiation con::id <core::int*>
+  #C3 = 0
+  #C4 = con::Class<core::int*> {field:#C3}
+  #C5 = <core::int*>[#C3]
+  #C6 = null
+  #C7 = <dynamic>[#C3, #C6]
+  #C8 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C7}
+  #C9 = col::_UnmodifiableSet<core::int*> {_map:#C8}
+  #C10 = "foo"
+  #C11 = <dynamic>[#C3, #C10]
+  #C12 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C11}
+  #C13 = true
+  #C14 = tearoff core::identical
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.transformed.expect
index 92a1fb8..bb3f969 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/constants.dart.weak.transformed.expect
@@ -5,69 +5,44 @@
 
 import "org-dartlang-testcase:///constants_lib.dart" as lib;
 
-typedef F1<invariant T extends core::Object? = dynamic> = (T%) → T%;
-typedef F2 = <T extends core::Object? = dynamic>(T%) → T%;
-static const field core::Type objectTypeLiteral = #C1;
-static const field (core::int) → core::int partialInstantiation = #C3;
-static const field con::Class<core::int> instance = #C5;
-static const field core::Type functionTypeLiteral = #C6;
-static const field core::Type genericFunctionTypeLiteral = #C7;
-static const field core::List<core::int> listLiteral = #C8;
-static const field core::Set<core::int> setLiteral = #C12;
-static const field core::Map<core::int, core::String> mapLiteral = #C15;
-static const field core::List<core::int> listConcatenation = #C8;
-static const field core::Set<core::int> setConcatenation = #C12;
-static const field core::Map<core::int, core::String> mapConcatenation = #C15;
-static const field core::bool objectTypeLiteralIdentical = #C16;
-static const field core::bool partialInstantiationIdentical = #C16;
-static const field core::bool instanceIdentical = #C16;
-static const field core::bool functionTypeLiteralIdentical = #C16;
-static const field core::bool genericFunctionTypeLiteralIdentical = #C16;
-static const field core::bool listLiteralIdentical = #C16;
-static const field core::bool setLiteralIdentical = #C16;
-static const field core::bool mapLiteralIdentical = #C16;
-static const field core::bool listConcatenationIdentical = #C16;
-static const field core::bool setConcatenationIdentical = #C16;
-static const field core::bool mapConcatenationIdentical = #C16;
-static final field core::bool inStrongMode = self::_inStrongMode();
-static method _inStrongMode() → core::bool {
-  return !((#C17) is{ForNonNullableByDefault} core::List<core::int>);
-}
+static const field (core::int) → core::int partialInstantiation = #C2;
+static const field con::Class<core::int> instance = #C4;
+static const field core::List<core::int> listLiteral = #C5;
+static const field core::Set<core::int> setLiteral = #C9;
+static const field core::Map<core::int, core::String> mapLiteral = #C12;
+static const field core::List<core::int> listConcatenation = #C5;
+static const field core::Set<core::int> setConcatenation = #C9;
+static const field core::Map<core::int, core::String> mapConcatenation = #C12;
+static const field core::bool partialInstantiationIdentical = #C13;
+static const field core::bool instanceIdentical = #C13;
+static const field core::bool listLiteralIdentical = #C13;
+static const field core::bool setLiteralIdentical = #C13;
+static const field core::bool mapLiteralIdentical = #C13;
+static const field core::bool listConcatenationIdentical = #C13;
+static const field core::bool setConcatenationIdentical = #C13;
+static const field core::bool mapConcatenationIdentical = #C13;
 static method main() → dynamic {
-  self::test(#C1, #C1);
-  self::test(#C3, #C3);
+  self::test(#C2, #C2);
+  self::test(#C4, #C4);
   self::test(#C5, #C5);
-  self::test(#C6, #C6);
-  self::test(#C7, #C7);
-  self::test(#C8, #C8);
+  self::test(#C9, #C9);
   self::test(#C12, #C12);
-  self::test(#C15, #C15);
-  self::test(#C8, #C8);
+  self::test(#C5, #C5);
+  self::test(#C9, #C9);
   self::test(#C12, #C12);
-  self::test(#C15, #C15);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
-  self::test(true, #C16);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
+  self::test(true, #C13);
 }
 static method test(dynamic expected, dynamic actual) → dynamic {
   core::print("test(${expected}, ${actual})");
-  if(self::inStrongMode) {
-    if(core::identical(expected, actual)) {
-      throw "Unexpected identical for ${expected} and ${actual}";
-    }
-  }
-  else {
-    if(!core::identical(expected, actual)) {
-      throw "Expected ${expected}, actual ${actual}";
-    }
+  if(!core::identical(expected, actual)) {
+    throw "Expected ${expected}, actual ${actual}";
   }
 }
 
@@ -93,38 +68,31 @@
   abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic;
   abstract member-signature get runtimeType() → core::Type*;
 }
-static const field core::Type* objectTypeLiteral = #C1;
-static const field (core::Object*, core::Object*) →* core::bool* c2 = #C18;
-static const field (core::int*) →* core::int* partialInstantiation = #C3;
-static const field con::Class<core::int*>* instance = #C5;
-static const field core::Type* functionTypeLiteral = #C6;
-static const field core::Type* genericFunctionTypeLiteral = #C7;
-static const field core::List<core::int*>* listLiteral = #C8;
-static const field core::Set<core::int*>* setLiteral = #C12;
-static const field core::Map<core::int*, core::String*>* mapLiteral = #C15;
-static const field core::List<core::int*>* listConcatenation = #C8;
-static const field core::Set<core::int*>* setConcatenation = #C12;
-static const field core::Map<core::int*, core::String*>* mapConcatenation = #C15;
+static const field (core::Object*, core::Object*) →* core::bool* c2 = #C14;
+static const field (core::int*) →* core::int* partialInstantiation = #C2;
+static const field con::Class<core::int*>* instance = #C4;
+static const field core::List<core::int*>* listLiteral = #C5;
+static const field core::Set<core::int*>* setLiteral = #C9;
+static const field core::Map<core::int*, core::String*>* mapLiteral = #C12;
+static const field core::List<core::int*>* listConcatenation = #C5;
+static const field core::Set<core::int*>* setConcatenation = #C9;
+static const field core::Map<core::int*, core::String*>* mapConcatenation = #C12;
 static method id<T extends core::Object* = dynamic>(con::id::T* t) → con::id::T*
   return t;
 
 constants  {
-  #C1 = TypeLiteralConstant(core::Object*)
-  #C2 = tearoff con::id
-  #C3 = partial-instantiation con::id <core::int*>
-  #C4 = 0
-  #C5 = con::Class<core::int*> {field:#C4}
-  #C6 = TypeLiteralConstant((dynamic) →* dynamic)
-  #C7 = TypeLiteralConstant(<T extends core::Object* = dynamic>(T*) →* T*)
-  #C8 = <core::int*>[#C4]
-  #C9 = null
-  #C10 = <dynamic>[#C4, #C9]
-  #C11 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C10}
-  #C12 = col::_UnmodifiableSet<core::int*> {_map:#C11}
-  #C13 = "foo"
-  #C14 = <dynamic>[#C4, #C13]
-  #C15 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C14}
-  #C16 = true
-  #C17 = <core::int*>[]
-  #C18 = tearoff core::identical
+  #C1 = tearoff con::id
+  #C2 = partial-instantiation con::id <core::int*>
+  #C3 = 0
+  #C4 = con::Class<core::int*> {field:#C3}
+  #C5 = <core::int*>[#C3]
+  #C6 = null
+  #C7 = <dynamic>[#C3, #C6]
+  #C8 = core::_ImmutableMap<core::int*, core::Null?> {_kvPairs:#C7}
+  #C9 = col::_UnmodifiableSet<core::int*> {_map:#C8}
+  #C10 = "foo"
+  #C11 = <dynamic>[#C3, #C10]
+  #C12 = core::_ImmutableMap<core::int*, core::String*> {_kvPairs:#C11}
+  #C13 = true
+  #C14 = tearoff core::identical
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/constants_lib.dart b/pkg/front_end/testcases/nnbd_mixed/constants_lib.dart
index afa7bf1..592f558 100644
--- a/pkg/front_end/testcases/nnbd_mixed/constants_lib.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/constants_lib.dart
@@ -15,12 +15,9 @@
 typedef F1<T> = T Function(T);
 typedef F2 = T Function<T>(T);
 
-const objectTypeLiteral = Object;
 const c2 = identical;
 const int Function(int) partialInstantiation = id;
 const instance = const Class<int>(0);
-const functionTypeLiteral = F1;
-const genericFunctionTypeLiteral = F2;
 const listLiteral = <int>[0];
 const setLiteral = <int>{0};
 const mapLiteral = <int, String>{0: 'foo'};
diff --git a/pkg/front_end/testing.json b/pkg/front_end/testing.json
index 794af63..5551b0d 100644
--- a/pkg/front_end/testing.json
+++ b/pkg/front_end/testing.json
@@ -458,7 +458,8 @@
       "tool/",
       "test/",
       "../kernel/lib/",
-      "../testing/"
+      "../testing/",
+      "../_fe_analyzer_shared/lib/"
     ],
     "git grep": {
       "pathspecs": [
diff --git a/pkg/front_end/tool/fasta_perf.dart b/pkg/front_end/tool/fasta_perf.dart
index 2037866..89234b2 100644
--- a/pkg/front_end/tool/fasta_perf.dart
+++ b/pkg/front_end/tool/fasta_perf.dart
@@ -95,7 +95,7 @@
   var options = new CompilerOptions()
     ..sdkRoot = sdkRoot
     // Because this is only used to create a uriResolver, we don't allow any
-    // whitelisting of error messages in the error handler.
+    // allowlisting of error messages in the error handler.
     ..onDiagnostic = onDiagnosticMessageHandler()
     ..compileSdk = true
     ..packagesFileUri = Uri.base.resolve('.packages')
diff --git a/pkg/front_end/tool/perf_common.dart b/pkg/front_end/tool/perf_common.dart
index 3b7293c..7da7dcb 100644
--- a/pkg/front_end/tool/perf_common.dart
+++ b/pkg/front_end/tool/perf_common.dart
@@ -26,14 +26,14 @@
 /// Error messages that we temporarily allow when compiling benchmarks in strong
 /// mode.
 ///
-/// This whitelist lets us run the compiler benchmarks while those errors get
+/// This allowlist lets us run the compiler benchmarks while those errors get
 /// fixed. We don't blindly allow any error message because we would then miss
 /// situations where the benchmarks are actually broken.
 ///
 /// Note: the performance bots compile both dart2js and the flutter-gallery app
 /// as benchmarks, so they both need to be checked before we remove a message
 /// from this set.
-final whitelistMessageCode = new Set<fastaCodes.Code>.from(<fastaCodes.Code>[
+final allowlistMessageCode = new Set<fastaCodes.Code>.from(<fastaCodes.Code>[
   // Code names in this list should match the key used in messages.yaml
   fastaCodes.codeInvalidAssignmentError,
   fastaCodes.codeOverrideTypeMismatchParameter,
@@ -53,12 +53,12 @@
   return (DiagnosticMessage m) {
     if (m.severity == Severity.internalProblem ||
         m.severity == Severity.error) {
-      if (!whitelistMessageCode.contains(getMessageCodeObject(m))) {
+      if (!allowlistMessageCode.contains(getMessageCodeObject(m))) {
         printDiagnosticMessage(m, stderr.writeln);
         exitCode = 1;
       } else if (!messageReported) {
         messageReported = true;
-        stderr.writeln('Whitelisted error messages omitted');
+        stderr.writeln('Allowlisted error messages omitted');
       }
     }
   };
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index dfd9a79..456b204 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -345,19 +345,14 @@
 
   static bool isStatementNotSupported(Statement node) =>
       node is BreakStatement ||
-      node is AssertBlock ||
       node is VariableDeclaration &&
           (node.parent is! Block || node.name == null) ||
       node is SwitchStatement ||
       node is TryFinally ||
-      node is EmptyStatement ||
       node is LabeledStatement ||
-      node is ForInStatement && node.isAsync ||
       node is TryCatch ||
       node is FunctionDeclaration ||
-      node is ContinueSwitchStatement ||
-      node is AssertStatement ||
-      node is ReturnStatement && node.expression == null;
+      node is ContinueSwitchStatement;
 
   static bool isSupported(Node node) => !isNotSupported(node);
 
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 2f071d7..0d3f673 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -1017,7 +1017,10 @@
   String tag(Statement statement) => statement.accept(this);
 
   String visitExpressionStatement(ExpressionStatement _) => "expr";
-  String visitReturnStatement(ReturnStatement _) => "ret";
+  String visitReturnStatement(ReturnStatement node) {
+    return node.expression == null ? "ret-void" : "ret";
+  }
+
   String visitYieldStatement(YieldStatement _) => "yield";
   String visitBlock(Block _) => "block";
   String visitVariableDeclaration(VariableDeclaration _) => "local";
@@ -1029,7 +1032,12 @@
   String visitWhileStatement(WhileStatement node) => "while";
   String visitDoStatement(DoStatement node) => "do-while";
   String visitForStatement(ForStatement node) => "for";
-  String visitForInStatement(ForInStatement node) => "for-in";
+  String visitForInStatement(ForInStatement node) {
+    return node.isAsync ? "await-for-in" : "for-in";
+  }
+
+  String visitAssertStatement(AssertStatement node) => "assert";
+  String visitAssertBlock(AssertBlock node) => "assert-block";
 }
 
 TextSerializer<ExpressionStatement> expressionStatementSerializer = new Wrapped(
@@ -1054,6 +1062,13 @@
   return new ReturnStatement(expression);
 }
 
+TextSerializer<ReturnStatement> returnVoidStatementSerializer = new Wrapped(
+    unwrapReturnVoidStatement, wrapReturnVoidStatement, const Nothing());
+
+void unwrapReturnVoidStatement(void ignored) {}
+
+ReturnStatement wrapReturnVoidStatement(void ignored) => new ReturnStatement();
+
 TextSerializer<YieldStatement> yieldStatementSerializer =
     new Wrapped(unwrapYieldStatement, wrapYieldStatement, expressionSerializer);
 
@@ -1063,6 +1078,19 @@
   return new YieldStatement(expression);
 }
 
+TextSerializer<AssertStatement> assertStatementSerializer = new Wrapped(
+    unwrapAssertStatement,
+    wrapAssertStatement,
+    new Tuple2Serializer(expressionSerializer, expressionSerializer));
+
+Tuple2<Expression, Expression> unwrapAssertStatement(AssertStatement node) {
+  return new Tuple2<Expression, Expression>(node.condition, node.message);
+}
+
+AssertStatement wrapAssertStatement(Tuple2<Expression, Expression> tuple) {
+  return new AssertStatement(tuple.first, message: tuple.second);
+}
+
 TextSerializer<Block> blockSerializer =
     new Wrapped(unwrapBlock, wrapBlock, const BlockSerializer());
 
@@ -1070,6 +1098,14 @@
 
 Block wrapBlock(List<Statement> statements) => new Block(statements);
 
+TextSerializer<AssertBlock> assertBlockSerializer =
+    new Wrapped(unwrapAssertBlock, wrapAssertBlock, const BlockSerializer());
+
+List<Statement> unwrapAssertBlock(AssertBlock node) => node.statements;
+
+AssertBlock wrapAssertBlock(List<Statement> statements) =>
+    new AssertBlock(statements);
+
 /// Serializer for [Block]s.
 ///
 /// [BlockSerializer] is a combination of [ListSerializer] and [Bind].  As in
@@ -1223,6 +1259,19 @@
       tuple.second.first, tuple.first, tuple.second.second);
 }
 
+TextSerializer<ForInStatement> awaitForInStatementSerializer = new Wrapped(
+    unwrapForInStatement,
+    wrapAwaitForInStatement,
+    new Tuple2Serializer(expressionSerializer,
+        new Bind(variableDeclarationSerializer, statementSerializer)));
+
+ForInStatement wrapAwaitForInStatement(
+    Tuple2<Expression, Tuple2<VariableDeclaration, Statement>> tuple) {
+  return new ForInStatement(
+      tuple.second.first, tuple.first, tuple.second.second,
+      isAsync: true);
+}
+
 Case<Statement> statementSerializer =
     new Case.uninitialized(const StatementTagger());
 
@@ -1533,6 +1582,7 @@
   statementSerializer.registerTags({
     "expr": expressionStatementSerializer,
     "ret": returnStatementSerializer,
+    "ret-void": returnVoidStatementSerializer,
     "yield": yieldStatementSerializer,
     "block": blockSerializer,
     "local": variableDeclarationSerializer,
@@ -1543,6 +1593,9 @@
     "do-while": doStatementSerializer,
     "for": forStatementSerializer,
     "for-in": forInStatementSerializer,
+    "await-for-in": awaitForInStatementSerializer,
+    "assert": assertStatementSerializer,
+    "assert-block": assertBlockSerializer,
   });
   functionNodeSerializer.registerTags({
     "sync": syncFunctionNodeSerializer,
diff --git a/pkg/nnbd_migration/README.md b/pkg/nnbd_migration/README.md
index 9719fda..ed021dd 100644
--- a/pkg/nnbd_migration/README.md
+++ b/pkg/nnbd_migration/README.md
@@ -1,18 +1,18 @@
-# Null Safety Migration Tooling
+# Null safety migration tooling
 
 **Note**:
 
   * The null safety migration tooling is in an early state and may have bugs and
     other issues.
   * As null safety is still in preview, we recommend only doing trial
-    migrations. The final migration of apps and packages, should not be done
+    migrations. The final migration of apps and packages should not be done
     until the feature is more complete.
   * For best results, use SDK version 2.9.0-10.0.dev or higher.
 
-## How Migration Works
+## How migration works
 
-The migration uses a _new interactive algorithm_ designed specifically for Dart
-null safety.
+The migration uses a _new interactive algorithm_ designed specifically for [Dart
+null safety](https://dart.dev/null-safety).
 
 Typical code migration tools are designed to be run once, handle most cases, and
 let the developer do manual cleanup on the result. This does **not work well**
@@ -42,12 +42,12 @@
 quality.
 
 The high level workflow of the tool is therefore driven through an interactive
-web UI. After running `dart migrate`, open the resulting URL in a browser. Scan
-through the changes, use the "nullability trace" feature to find the best place
-to add a nullability hint (adding a hint in the best place can prevent dozens of
-types from being made nullable). Rerun the migration and repeat, committing the
-hints as you go. When the output is correct and acceptable, apply the migration
-and publish your null-safe code!
+web UI. After starting the tool with `dart migrate`, open the presented URL in a
+browser. Scan through the changes, use the "nullability trace" feature to find
+the best place to add a nullability hint (adding a hint in the best place can
+prevent dozens of types from being made nullable). Rerun the migration and
+repeat, committing the hints as you go. When the output is correct and
+acceptable, apply the migration.
 
 For example,
 
@@ -92,12 +92,25 @@
 your intent has been lost. A long migration effort (such as one on a large
 project) can be done incrementally, by committing these hints over time.
 
+<!-- TODO(srawlins): We should explain (or point to explanation of) "migrated"
+code. I don't see any documents pointing out how null safety is enabled via
+pubspec.yaml, or library-by-library comments. -->
+
 ## Migrating a package
 
 1. Select a package to work on, and open a command terminal in the top-level of
    the package directory.
 2. Run `pub get` in order to make available all dependencies of the package.
-3. Run the migration tool from the top-level of the package directory:
+3. It is best to migrate a package to null safety _after_ the package's
+   dependencies have migrated to null safety. Run
+   `pub outdated --mode=null-safety` to learn the migration status of the
+   package's dependencies. See the
+   [pub outdated documentation](https://dart.dev/tools/pub/cmd/pub-outdated)
+   for more information.
+4. It is best to migrate a package starting from a clean code repository state
+   (`git status`, for example), in case you must revert the migration. Ensure
+   there are no pending changes in the package's code repository.
+5. Run the migration tool from the top-level of the package directory:
 
    ```
    dart migrate
@@ -117,10 +130,16 @@
     1. Use the "trace view" in the bottom right to find the root cause
     2. Either click on an "add hint" button to correct it at the root, or open
        your editor and make the change manually.
-        1. Some changes are as simple as adding a `/*!*/` hint on a type. The
-           tool has buttons to do this for you.
-        2. Others may require larger refactors. These changes can be made in
-           your editor, and may often be committed and published immediately.
+        * Some changes are as simple as adding a `/*!*/` hint on a type. The
+          tool has buttons to do this for you.
+        * Others may require larger refactors. These changes can be made in
+          your editor.
+        * Changes may even be committed to source code management before finally
+         _applying_ the migration. In this way, a migration of a large package
+         can be carried out over multiple sessions, or between multiple
+         engineers. Committing hints and other adjustments along the way helps
+         to separate the concerns of describing user intent vs committing to the
+         migration result.
     3. Periodically rerun the migration and repeat.
 6. Once you are satisfied with the proposed migration:
     1. Save your work using git or other means. Applying the migration will
@@ -134,12 +153,16 @@
        interface.
     3. Tip: leaving the web UI open may help you if you later have test failures
        or analysis errors.
-7. Rerun `pub get` and test your package.
-    1. If a test fails, you may still use the preview to help you figure out
-       what went wrong.
+7. Rerun `pub get`, then analyze and test your package.
+    1. If there are new static analysis issues, or if a test fails, you may
+       still use the preview to help you figure out what went wrong.
     2. If large changes are required, revert the migration, and go back to step
-       one.
-8. Commit and/or publish your migrated null-safe code.
+       one. The tool does not provide any revert capability; this must be done
+       via source code management (for example, `git checkout`).
+
+<!-- TODO(srawlins): direct the user to publish, only after null safety leaves
+tech preview. See the big note at https://dart.dev/null-safety.
+8. Commit and/or publish your migrated null-safe code. -->
 
 ## Providing feedback
 
diff --git a/pkg/nnbd_migration/lib/migration_cli.dart b/pkg/nnbd_migration/lib/migration_cli.dart
index c87c188..2c45a14 100644
--- a/pkg/nnbd_migration/lib/migration_cli.dart
+++ b/pkg/nnbd_migration/lib/migration_cli.dart
@@ -25,9 +25,11 @@
 import 'package:cli_util/cli_logging.dart';
 import 'package:meta/meta.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/exceptions.dart';
 import 'package:nnbd_migration/src/front_end/dartfix_listener.dart';
 import 'package:nnbd_migration/src/front_end/driver_provider_impl.dart';
 import 'package:nnbd_migration/src/front_end/non_nullable_fix.dart';
+import 'package:nnbd_migration/src/messages.dart';
 import 'package:nnbd_migration/src/utilities/json.dart' as json;
 import 'package:nnbd_migration/src/utilities/source_edit_diff_formatter.dart';
 import 'package:path/path.dart' show Context;
@@ -47,6 +49,7 @@
   static const applyChangesFlag = 'apply-changes';
   static const helpFlag = 'help';
   static const ignoreErrorsFlag = 'ignore-errors';
+  static const ignoreExceptionsFlag = 'ignore-exceptions';
   static const previewPortOption = 'preview-port';
   static const sdkPathOption = 'sdk-path';
   static const skipPubOutdatedFlag = 'skip-pub-outdated';
@@ -60,6 +63,8 @@
 
   final bool ignoreErrors;
 
+  final bool ignoreExceptions;
+
   final int previewPort;
 
   final String sdkPath;
@@ -74,6 +79,7 @@
       {@required this.applyChanges,
       @required this.directory,
       @required this.ignoreErrors,
+      @required this.ignoreExceptions,
       @required this.previewPort,
       @required this.sdkPath,
       @required this.skipPubOutdated,
@@ -232,21 +238,31 @@
 
   final Map<String, LineInfo> lineInfo = {};
 
+  /// The environment variables, tracked to help users debug if SDK_PATH was
+  /// specified and that resulted in any [ExperimentStatusException]s.
+  final Map<String, String> _environmentVariables;
+
   DartFixListener _dartFixListener;
 
   _FixCodeProcessor _fixCodeProcessor;
 
   AnalysisContextCollection _contextCollection;
 
-  MigrationCli(
-      {@required this.binaryName,
-      @visibleForTesting this.loggerFactory = _defaultLoggerFactory,
-      @visibleForTesting this.defaultSdkPathOverride,
-      @visibleForTesting ResourceProvider resourceProvider,
-      @visibleForTesting this.processManager = const ProcessManager.system()})
-      : logger = loggerFactory(false),
+  bool _hasExceptions = false;
+
+  bool _hasAnalysisErrors = false;
+
+  MigrationCli({
+    @required this.binaryName,
+    @visibleForTesting this.loggerFactory = _defaultLoggerFactory,
+    @visibleForTesting this.defaultSdkPathOverride,
+    @visibleForTesting ResourceProvider resourceProvider,
+    @visibleForTesting this.processManager = const ProcessManager.system(),
+    @visibleForTesting Map<String, String> environmentVariables,
+  })  : logger = loggerFactory(false),
         resourceProvider =
-            resourceProvider ?? PhysicalResourceProvider.INSTANCE;
+            resourceProvider ?? PhysicalResourceProvider.INSTANCE,
+        _environmentVariables = environmentVariables ?? Platform.environment;
 
   @visibleForTesting
   DriverBasedAnalysisContext get analysisContext {
@@ -275,6 +291,10 @@
     return contextCollection.contexts.length > 1;
   }
 
+  @visibleForTesting
+  bool get isPreviewServerRunning =>
+      _fixCodeProcessor?.isPreviewServerRunnning ?? false;
+
   Context get pathContext => resourceProvider.pathContext;
 
   /// Blocks until an interrupt signal (control-C) is received.  Tests may
@@ -289,12 +309,10 @@
       ResourceProvider resourceProvider, LineInfo getLineInfo(String path),
       {List<String> included = const <String>[],
       int preferredPort,
-      bool enablePreview = true,
       String summaryPath}) {
     return NonNullableFix(listener, resourceProvider, getLineInfo,
         included: included,
         preferredPort: preferredPort,
-        enablePreview: enablePreview,
         summaryPath: summaryPath);
   }
 
@@ -349,6 +367,8 @@
           applyChanges: applyChanges,
           directory: migratePath,
           ignoreErrors: argResults[CommandLineOptions.ignoreErrorsFlag] as bool,
+          ignoreExceptions:
+              argResults[CommandLineOptions.ignoreExceptionsFlag] as bool,
           previewPort: previewPort,
           sdkPath: argResults[CommandLineOptions.sdkPathOption] as String ??
               defaultSdkPathOverride ??
@@ -405,34 +425,36 @@
     List<String> previewUrls;
     NonNullableFix nonNullableFix;
 
-    await _withProgress(
-        '${ansi.emphasized('Generating migration suggestions')}', () async {
-      _fixCodeProcessor = _FixCodeProcessor(context, this);
-      _dartFixListener =
-          DartFixListener(DriverProviderImpl(resourceProvider, context));
-      nonNullableFix = createNonNullableFix(
-          _dartFixListener, resourceProvider, _fixCodeProcessor.getLineInfo,
-          included: [options.directory],
-          preferredPort: options.previewPort,
-          enablePreview: options.webPreview,
-          summaryPath: options.summary);
-      nonNullableFix.rerunFunction = _rerunFunction;
-      _fixCodeProcessor.registerCodeTask(nonNullableFix);
-      _fixCodeProcessor.nonNullableFixTask = nonNullableFix;
+    logger.stdout(ansi.emphasized('Analyzing project...'));
+    _fixCodeProcessor = _FixCodeProcessor(context, this);
+    _dartFixListener = DartFixListener(
+        DriverProviderImpl(resourceProvider, context), _exceptionReported);
+    nonNullableFix = createNonNullableFix(
+        _dartFixListener, resourceProvider, _fixCodeProcessor.getLineInfo,
+        included: [options.directory],
+        preferredPort: options.previewPort,
+        summaryPath: options.summary);
+    nonNullableFix.rerunFunction = _rerunFunction;
+    _fixCodeProcessor.registerCodeTask(nonNullableFix);
+    _fixCodeProcessor.nonNullableFixTask = nonNullableFix;
 
-      try {
-        // TODO(devoncarew): The progress written by the fix processor conflicts
-        // with the progress written by the ansi logger above.
-        await _fixCodeProcessor.runFirstPhase();
-        _fixCodeProcessor._progressBar.clear();
-        _checkForErrors();
-      } on StateError catch (e) {
-        logger.stdout(e.toString());
-        exitCode = 1;
+    try {
+      await _fixCodeProcessor.runFirstPhase(singlePhaseProgress: true);
+      _checkForErrors();
+    } on ExperimentStatusException catch (e) {
+      logger.stdout(e.toString());
+      final sdkPathVar = _environmentVariables['SDK_PATH'];
+      if (sdkPathVar != null) {
+        logger.stdout('$sdkPathEnvironmentVariableSet: $sdkPathVar');
       }
-      if (exitCode != null) return;
-      previewUrls = await _fixCodeProcessor.runLaterPhases();
-    });
+      exitCode = 1;
+    }
+    if (exitCode != null) return;
+
+    logger.stdout('');
+    logger.stdout(ansi.emphasized('Generating migration suggestions...'));
+    previewUrls = await _fixCodeProcessor.runLaterPhases(resetProgress: true);
+
     if (exitCode != null) return;
 
     if (options.applyChanges) {
@@ -468,6 +490,7 @@
 
       logger.stdout('When finished with the preview, hit ctrl-c '
           'to terminate this process.');
+      logger.stdout('');
 
       // Block until sigint (ctrl-c).
       await blockUntilSignalInterrupt();
@@ -547,6 +570,7 @@
       logger.stdout(
           'Note: analysis errors will result in erroneous migration suggestions.');
 
+      _hasAnalysisErrors = true;
       if (options.ignoreErrors) {
         logger.stdout('Continuing with migration suggestions due to the use of '
             '--${CommandLineOptions.ignoreErrorsFlag}.');
@@ -620,10 +644,49 @@
     }
   }
 
+  void _exceptionReported(String detail) {
+    if (_hasExceptions) return;
+    _hasExceptions = true;
+    if (options.ignoreExceptions) {
+      logger.stdout('''
+Exception(s) occurred during migration.  Attempting to perform
+migration anyway due to the use of --${CommandLineOptions.ignoreExceptionsFlag}.
+
+To see exception details, re-run without --${CommandLineOptions.ignoreExceptionsFlag}.
+''');
+    } else {
+      exitCode = 1;
+      if (_hasAnalysisErrors) {
+        logger.stderr('''
+Aborting migration due to an exception.  This may be due to a bug in
+the migration tool, or it may be due to errors in the source code
+being migrated.  If possible, try to fix errors in the source code and
+re-try migrating.  If that doesn't work, consider filing a bug report
+at:
+''');
+      } else {
+        logger.stderr('''
+Aborting migration due to an exception.  This most likely is due to a
+bug in the migration tool.  Please consider filing a bug report at:
+''');
+      }
+      logger.stderr('https://github.com/dart-lang/sdk/issues/new');
+      logger.stderr('''
+To attempt to perform migration anyway, you may re-run with
+--${CommandLineOptions.ignoreExceptionsFlag}.
+
+Exception details:
+''');
+      logger.stderr(detail);
+    }
+  }
+
   bool _isUriError(AnalysisError error) =>
       error.errorCode == CompileTimeErrorCode.URI_DOES_NOT_EXIST;
 
   Future<void> _rerunFunction() async {
+    logger.stdout(ansi.emphasized('Recalculating migration suggestions...'));
+
     _dartFixListener.reset();
     _fixCodeProcessor.prepareToRerun();
     await _fixCodeProcessor.runFirstPhase();
@@ -654,16 +717,6 @@
     return edits;
   }
 
-  Future<void> _withProgress(String message, FutureOr<void> callback()) async {
-    var progress = logger.progress(message);
-    try {
-      await callback();
-      progress.finish(showTiming: true);
-    } finally {
-      progress.cancel();
-    }
-  }
-
   static ArgParser createParser({bool hide = true}) {
     var parser = ArgParser();
     parser.addFlag(CommandLineOptions.helpFlag,
@@ -697,6 +750,12 @@
       help: 'Attempt to perform null safety analysis even if there are '
           'analysis errors in the project.',
     );
+    parser.addFlag(CommandLineOptions.ignoreExceptionsFlag,
+        defaultsTo: false,
+        negatable: false,
+        help:
+            'Attempt to perform null safety analysis even if exceptions occur.',
+        hide: hide);
     parser.addOption(CommandLineOptions.previewPortOption,
         help:
             'Run the preview server on the specified port.  If not specified, '
@@ -780,6 +839,9 @@
   _FixCodeProcessor(this.context, this._migrationCli)
       : pathsToProcess = _computePathsToProcess(context);
 
+  bool get isPreviewServerRunnning =>
+      nonNullableFixTask?.isPreviewServerRunning ?? false;
+
   LineInfo getLineInfo(String path) =>
       context.currentSession.getFile(path).lineInfo;
 
@@ -809,6 +871,7 @@
               if (pathsToProcess.contains(unit.path) &&
                   !pathsProcessed.contains(unit.path)) {
                 await process(unit);
+                if (_migrationCli.exitCode != null) return;
                 pathsProcessed.add(unit.path);
               }
             }
@@ -825,6 +888,7 @@
         continue;
       }
       await process(result);
+      if (_migrationCli.exitCode != null) return;
     }
   }
 
@@ -832,9 +896,10 @@
     _task = task;
   }
 
-  Future<void> runFirstPhase() async {
+  Future<void> runFirstPhase({bool singlePhaseProgress = false}) async {
     // All tasks should be registered; [numPhases] should be finalized.
-    _progressBar = _ProgressBar(pathsToProcess.length * _task.numPhases);
+    _progressBar = _ProgressBar(
+        pathsToProcess.length * (singlePhaseProgress ? 1 : _task.numPhases));
 
     // Process package
     _task.processPackage(context.contextRoot.root);
@@ -856,14 +921,22 @@
     });
   }
 
-  Future<List<String>> runLaterPhases() async {
+  Future<List<String>> runLaterPhases({bool resetProgress = false}) async {
+    if (resetProgress) {
+      _progressBar =
+          _ProgressBar(pathsToProcess.length * (_task.numPhases - 1));
+    }
+
     for (var phase = 1; phase < _task.numPhases; phase++) {
       await processResources((ResolvedUnitResult result) async {
         _progressBar.tick();
         await _task.processUnit(phase, result);
       });
     }
-    await _task.finish();
+    var state = await _task.finish();
+    if (_migrationCli.exitCode == null && _migrationCli.options.webPreview) {
+      await _task.startPreviewServer(state);
+    }
     _progressBar.complete();
 
     return nonNullableFixTask.previewUrls;
diff --git a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
index 3f3c9e6..b8c1649 100644
--- a/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
+++ b/pkg/nnbd_migration/lib/src/already_migrated_code_decorator.dart
@@ -91,6 +91,8 @@
       return DecoratedType(type, node);
     } else if (type is TypeParameterType) {
       return DecoratedType(type, node);
+    } else if (type.isBottom) {
+      return DecoratedType(type, node);
     } else {
       // TODO(paulberry)
       throw UnimplementedError(
diff --git a/pkg/nnbd_migration/lib/src/edge_builder.dart b/pkg/nnbd_migration/lib/src/edge_builder.dart
index e9c3f1d..cbfb4cc 100644
--- a/pkg/nnbd_migration/lib/src/edge_builder.dart
+++ b/pkg/nnbd_migration/lib/src/edge_builder.dart
@@ -127,7 +127,7 @@
       _flowAnalysis;
 
   /// If we are visiting a function body or initializer, assigned variable
-  /// information  used in flow analysis.  Otherwise `null`.
+  /// information used in flow analysis.  Otherwise `null`.
   AssignedVariables<AstNode, PromotableElement> _assignedVariables;
 
   /// The [DecoratedType] of the innermost function or method being visited, or
@@ -236,7 +236,8 @@
       } else {
         assert(enclosingElement is ExtensionElement);
         final extensionElement = enclosingElement as ExtensionElement;
-        final extendedType = extensionElement.extendedType;
+        final extendedType =
+            _typeSystem.resolveToBound(extensionElement.extendedType);
         if (extendedType is InterfaceType) {
           if (extensionElement.typeParameters.isNotEmpty) {
             substitution = _decoratedClassHierarchy
@@ -281,6 +282,32 @@
   }
 
   @override
+  // TODO(srawlins): Theoretically, edges should be connected between arguments
+  // and parameters, as in an instance creation. It is quite rare though, to
+  // declare a class and use it as an annotation in the same package.
+  DecoratedType visitAnnotation(Annotation node) {
+    var previousFlowAnalysis = _flowAnalysis;
+    var previousAssignedVariables = _assignedVariables;
+    if (_flowAnalysis == null) {
+      _assignedVariables = AssignedVariables();
+      _flowAnalysis = FlowAnalysis<AstNode, Statement, Expression,
+              PromotableElement, DecoratedType>(
+          DecoratedTypeOperations(_typeSystem, _variables, _graph),
+          _assignedVariables);
+    }
+    try {
+      _dispatch(node.name);
+      _dispatch(node.constructorName);
+      _dispatchList(node.arguments?.arguments);
+    } finally {
+      _flowAnalysis = previousFlowAnalysis;
+      _assignedVariables = previousAssignedVariables;
+    }
+    annotationVisited(node);
+    return null;
+  }
+
+  @override
   DecoratedType visitAsExpression(AsExpression node) {
     if (BestPracticesVerifier.isUnnecessaryCast(
         node, _typeSystem as TypeSystemImpl)) {
@@ -743,6 +770,7 @@
 
   DecoratedType visitExtensionDeclaration(ExtensionDeclaration node) {
     visitClassOrMixinOrExtensionDeclaration(node);
+    _dispatch(node.typeParameters);
     _dispatch(node.extendedType);
     return null;
   }
@@ -2610,7 +2638,7 @@
       if (name != null) {
         parameterType = calleeType.namedParameters[name];
         if (parameterType == null) {
-          // TODO(paulberry)
+          // TODO(#42327)
           _unimplemented(expression, 'Missing type for named parameter');
         }
         suppliedNamedParameters.add(name);
@@ -2917,6 +2945,8 @@
                     NullabilityNode.forInferredType(
                         target.typeArgument(index++))))
                 .toList());
+      } else if (type is TypeParameterType) {
+        return DecoratedType(type, NullabilityNode.forInferredType(target));
       } else {
         _unimplemented(node, 'extension of $type (${type.runtimeType}');
       }
@@ -2925,16 +2955,18 @@
 
   @alwaysThrows
   void _unimplemented(AstNode node, String message) {
-    CompilationUnit unit = node.root as CompilationUnit;
     StringBuffer buffer = StringBuffer();
     buffer.write(message);
-    buffer.write(' in "');
-    buffer.write(node.toSource());
-    buffer.write('" on line ');
-    buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
-    buffer.write(' of "');
-    buffer.write(unit.declaredElement.source.fullName);
-    buffer.write('"');
+    if (node != null) {
+      CompilationUnit unit = node.root as CompilationUnit;
+      buffer.write(' in "');
+      buffer.write(node.toSource());
+      buffer.write('" on line ');
+      buffer.write(unit.lineInfo.getLocation(node.offset).lineNumber);
+      buffer.write(' of "');
+      buffer.write(unit.declaredElement.source.fullName);
+      buffer.write('"');
+    }
     throw UnimplementedError(buffer.toString());
   }
 
diff --git a/pkg/nnbd_migration/lib/src/exceptions.dart b/pkg/nnbd_migration/lib/src/exceptions.dart
new file mode 100644
index 0000000..e862bdb
--- /dev/null
+++ b/pkg/nnbd_migration/lib/src/exceptions.dart
@@ -0,0 +1,39 @@
+import 'package:analyzer/dart/analysis/features.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:nnbd_migration/src/messages.dart';
+
+/// A [StateError] specific to the ways that the NNBD experiment can be
+/// misconfigured which may prevent the tool from working.
+class ExperimentStatusException extends StateError {
+  /// A file included in the migration dir has already been migrated.
+  ExperimentStatusException.migratedAlready(String path)
+      : super('$migratedAlready: $path');
+
+  /// The SDK was analyzed without NNBD semantics.
+  ExperimentStatusException.sdkExperimentDisabled() : super(nnbdExperimentOff);
+
+  /// The SDK does not contain the NNBD sources, it is the pre-unfork copy.
+  ExperimentStatusException.sdkPreforkSources() : super(sdkNnbdOff);
+
+  /// Throw an [ExperimentStatusException] if the [result] seems to have
+  /// incorrectly configured experiment flags/nnbd sources.
+  static void sanityCheck(ResolvedUnitResult result) {
+    final equalsParamType = result.typeProvider.objectType
+        .getMethod('==')
+        .parameters[0]
+        .type
+        .getDisplayString(withNullability: true);
+    if (equalsParamType == 'Object*') {
+      throw ExperimentStatusException.sdkExperimentDisabled();
+    }
+
+    if (equalsParamType != 'Object') {
+      throw ExperimentStatusException.sdkPreforkSources();
+    }
+
+    if (result.unit.featureSet.isEnabled(Feature.non_nullable)) {
+      // TODO(mfairhurst): Allow for skipping already migrated compilation units.
+      throw ExperimentStatusException.migratedAlready(result.path);
+    }
+  }
+}
diff --git a/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
index 0ff6f8c..378b136 100644
--- a/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/dartfix_listener.dart
@@ -15,13 +15,11 @@
 
   final List<DartFixSuggestion> suggestions = [];
 
-  DartFixListener(this.server);
-
   /// Add the given [detail] to the list of details to be returned to the
   /// client.
-  void addDetail(String detail) {
-    throw UnimplementedError('TODO(paulberry)');
-  }
+  final void Function(String detail) reportException;
+
+  DartFixListener(this.server, this.reportException);
 
   /// Record an edit to be sent to the client.
   ///
diff --git a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
index ed37a85..bf769d4 100644
--- a/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
+++ b/pkg/nnbd_migration/lib/src/front_end/non_nullable_fix.dart
@@ -26,9 +26,6 @@
 /// and determines whether the associated variable or parameter can be null
 /// then adds or removes a '?' trailing the named type as appropriate.
 class NonNullableFix {
-  /// TODO(paulberry): allow this to be controlled by a command-line parameter.
-  static const bool _usePermissiveMode = false;
-
   // TODO(srawlins): Refactor to use
   //  `Feature.non_nullable.firstSupportedVersion` when this becomes non-null.
   static const String _intendedMinimumSdkVersion = '2.9.0';
@@ -52,9 +49,6 @@
   /// which all included paths share.
   final String includedRoot;
 
-  /// Indicates whether the web preview of migration results should be launched.
-  final bool enablePreview;
-
   /// If non-null, the path to which a machine-readable summary of migration
   /// results should be written.
   final String summaryPath;
@@ -89,44 +83,26 @@
   List<String> previewUrls;
 
   NonNullableFix(this.listener, this.resourceProvider, this._getLineInfo,
-      {List<String> included = const [],
-      this.preferredPort,
-      this.enablePreview = true,
-      this.summaryPath})
+      {List<String> included = const [], this.preferredPort, this.summaryPath})
       : includedRoot =
             _getIncludedRoot(included, listener.server.resourceProvider) {
     reset();
   }
 
+  bool get isPreviewServerRunning => _server != null;
+
   int get numPhases => 3;
 
   InstrumentationListener createInstrumentationListener(
           {MigrationSummary migrationSummary}) =>
       InstrumentationListener(migrationSummary: migrationSummary);
 
-  Future<void> finish() async {
+  Future<MigrationState> finish() async {
     migration.finish();
     final state = MigrationState(
         migration, includedRoot, listener, instrumentationListener);
     await state.refresh();
-
-    if (enablePreview && _server == null) {
-      _server = HttpPreviewServer(state, rerun, preferredPort);
-      _server.serveHttp();
-      _allServers.add(_server);
-      port = await _server.boundPort;
-      authToken = await _server.authToken;
-
-      previewUrls = [
-        // TODO(jcollins-g): Change protocol to only return a single string.
-        Uri(
-            scheme: 'http',
-            host: 'localhost',
-            port: port,
-            path: state.pathMapper.map(includedRoot),
-            queryParameters: {'authToken': authToken}).toString()
-      ];
-    }
+    return state;
   }
 
   /// Processes the non-source files of the package rooted at [pkgFolder].
@@ -197,12 +173,32 @@
             : MigrationSummary(summaryPath, resourceProvider, includedRoot));
     adapter = NullabilityMigrationAdapter(listener);
     migration = NullabilityMigration(adapter, _getLineInfo,
-        permissive: _usePermissiveMode,
-        instrumentation: instrumentationListener);
+        permissive: true, instrumentation: instrumentationListener);
   }
 
   void shutdownServer() {
     _server?.close();
+    _server = null;
+  }
+
+  Future<void> startPreviewServer(MigrationState state) async {
+    if (_server == null) {
+      _server = HttpPreviewServer(state, rerun, preferredPort);
+      _server.serveHttp();
+      _allServers.add(_server);
+      port = await _server.boundPort;
+      authToken = await _server.authToken;
+
+      previewUrls = [
+        // TODO(jcollins-g): Change protocol to only return a single string.
+        Uri(
+            scheme: 'http',
+            host: 'localhost',
+            port: port,
+            path: state.pathMapper.map(includedRoot),
+            queryParameters: {'authToken': authToken}).toString()
+      ];
+    }
   }
 
   /// Updates the Package Config file to specify a minimum Dart SDK version
@@ -447,7 +443,7 @@
   @override
   void reportException(
       Source source, AstNode node, Object exception, StackTrace stackTrace) {
-    listener.addDetail('''
+    listener.reportException('''
 $exception
 
 $stackTrace''');
diff --git a/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
index dbe773f..102750a 100644
--- a/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
+++ b/pkg/nnbd_migration/lib/src/front_end/resources/highlight.pack.js
@@ -1,2 +1,6 @@
-/*! highlight.js v9.15.10 | BSD3 License | git.io/hljslicense */
-!function(e){var n="object"==typeof window&&window||"object"==typeof self&&self;"undefined"==typeof exports||exports.nodeType?n&&(n.hljs=e({}),"function"==typeof define&&define.amd&&define([],function(){return n.hljs})):e(exports)}(function(a){var f=[],u=Object.keys,N={},c={},n=/^(no-?highlight|plain|text)$/i,s=/\blang(?:uage)?-([\w-]+)\b/i,t=/((^(<[^>]+>|\t|)+|(?:\n)))/gm,r={case_insensitive:"cI",lexemes:"l",contains:"c",keywords:"k",subLanguage:"sL",className:"cN",begin:"b",beginKeywords:"bK",end:"e",endsWithParent:"eW",illegal:"i",excludeBegin:"eB",excludeEnd:"eE",returnBegin:"rB",returnEnd:"rE",relevance:"r",variants:"v",IDENT_RE:"IR",UNDERSCORE_IDENT_RE:"UIR",NUMBER_RE:"NR",C_NUMBER_RE:"CNR",BINARY_NUMBER_RE:"BNR",RE_STARTERS_RE:"RSR",BACKSLASH_ESCAPE:"BE",APOS_STRING_MODE:"ASM",QUOTE_STRING_MODE:"QSM",PHRASAL_WORDS_MODE:"PWM",C_LINE_COMMENT_MODE:"CLCM",C_BLOCK_COMMENT_MODE:"CBCM",HASH_COMMENT_MODE:"HCM",NUMBER_MODE:"NM",C_NUMBER_MODE:"CNM",BINARY_NUMBER_MODE:"BNM",CSS_NUMBER_MODE:"CSSNM",REGEXP_MODE:"RM",TITLE_MODE:"TM",UNDERSCORE_TITLE_MODE:"UTM",COMMENT:"C",beginRe:"bR",endRe:"eR",illegalRe:"iR",lexemesRe:"lR",terminators:"t",terminator_end:"tE"},b="</span>",h={classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:void 0};function _(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;")}function E(e){return e.nodeName.toLowerCase()}function v(e,n){var t=e&&e.exec(n);return t&&0===t.index}function l(e){return n.test(e)}function g(e){var n,t={},r=Array.prototype.slice.call(arguments,1);for(n in e)t[n]=e[n];return r.forEach(function(e){for(n in e)t[n]=e[n]}),t}function R(e){var a=[];return function e(n,t){for(var r=n.firstChild;r;r=r.nextSibling)3===r.nodeType?t+=r.nodeValue.length:1===r.nodeType&&(a.push({event:"start",offset:t,node:r}),t=e(r,t),E(r).match(/br|hr|img|input/)||a.push({event:"stop",offset:t,node:r}));return t}(e,0),a}function i(e){if(r&&!e.langApiRestored){for(var n in e.langApiRestored=!0,r)e[n]&&(e[r[n]]=e[n]);(e.c||[]).concat(e.v||[]).forEach(i)}}function m(o){function s(e){return e&&e.source||e}function c(e,n){return new RegExp(s(e),"m"+(o.cI?"i":"")+(n?"g":""))}!function n(t,e){if(!t.compiled){if(t.compiled=!0,t.k=t.k||t.bK,t.k){function r(t,e){o.cI&&(e=e.toLowerCase()),e.split(" ").forEach(function(e){var n=e.split("|");a[n[0]]=[t,n[1]?Number(n[1]):1]})}var a={};"string"==typeof t.k?r("keyword",t.k):u(t.k).forEach(function(e){r(e,t.k[e])}),t.k=a}t.lR=c(t.l||/\w+/,!0),e&&(t.bK&&(t.b="\\b("+t.bK.split(" ").join("|")+")\\b"),t.b||(t.b=/\B|\b/),t.bR=c(t.b),t.endSameAsBegin&&(t.e=t.b),t.e||t.eW||(t.e=/\B|\b/),t.e&&(t.eR=c(t.e)),t.tE=s(t.e)||"",t.eW&&e.tE&&(t.tE+=(t.e?"|":"")+e.tE)),t.i&&(t.iR=c(t.i)),null==t.r&&(t.r=1),t.c||(t.c=[]),t.c=Array.prototype.concat.apply([],t.c.map(function(e){return function(n){return n.v&&!n.cached_variants&&(n.cached_variants=n.v.map(function(e){return g(n,{v:null},e)})),n.cached_variants||n.eW&&[g(n)]||[n]}("self"===e?t:e)})),t.c.forEach(function(e){n(e,t)}),t.starts&&n(t.starts,e);var i=t.c.map(function(e){return e.bK?"\\.?(?:"+e.b+")\\.?":e.b}).concat([t.tE,t.i]).map(s).filter(Boolean);t.t=i.length?c(function(e,n){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var o=r,c=s(e[i]);for(0<i&&(a+=n);0<c.length;){var u=t.exec(c);if(null==u){a+=c;break}a+=c.substring(0,u.index),c=c.substring(u.index+u[0].length),"\\"==u[0][0]&&u[1]?a+="\\"+String(Number(u[1])+o):(a+=u[0],"("==u[0]&&r++)}}return a}(i,"|"),!0):{exec:function(){return null}}}}(o)}function C(e,n,i,t){function c(e,n,t,r){var a='<span class="'+(r?"":h.classPrefix);return e?(a+=e+'">')+n+(t?"":b):n}function o(){E+=null!=l.sL?function(){var e="string"==typeof l.sL;if(e&&!N[l.sL])return _(g);var n=e?C(l.sL,g,!0,f[l.sL]):O(g,l.sL.length?l.sL:void 0);return 0<l.r&&(R+=n.r),e&&(f[l.sL]=n.top),c(n.language,n.value,!1,!0)}():function(){var e,n,t,r,a,i,o;if(!l.k)return _(g);for(r="",n=0,l.lR.lastIndex=0,t=l.lR.exec(g);t;)r+=_(g.substring(n,t.index)),a=l,i=t,void 0,o=s.cI?i[0].toLowerCase():i[0],(e=a.k.hasOwnProperty(o)&&a.k[o])?(R+=e[1],r+=c(e[0],_(t[0]))):r+=_(t[0]),n=l.lR.lastIndex,t=l.lR.exec(g);return r+_(g.substr(n))}(),g=""}function u(e){E+=e.cN?c(e.cN,"",!0):"",l=Object.create(e,{parent:{value:l}})}function r(e,n){if(g+=e,null==n)return o(),0;var t=function(e,n){var t,r,a;for(t=0,r=n.c.length;t<r;t++)if(v(n.c[t].bR,e))return n.c[t].endSameAsBegin&&(n.c[t].eR=(a=n.c[t].bR.exec(e)[0],new RegExp(a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&"),"m"))),n.c[t]}(n,l);if(t)return t.skip?g+=n:(t.eB&&(g+=n),o(),t.rB||t.eB||(g=n)),u(t),t.rB?0:n.length;var r=function e(n,t){if(v(n.eR,t)){for(;n.endsParent&&n.parent;)n=n.parent;return n}if(n.eW)return e(n.parent,t)}(l,n);if(r){var a=l;for(a.skip?g+=n:(a.rE||a.eE||(g+=n),o(),a.eE&&(g=n));l.cN&&(E+=b),l.skip||l.sL||(R+=l.r),(l=l.parent)!==r.parent;);return r.starts&&(r.endSameAsBegin&&(r.starts.eR=r.eR),u(r.starts)),a.rE?0:n.length}if(function(e,n){return!i&&v(n.iR,e)}(n,l))throw new Error('Illegal lexeme "'+n+'" for mode "'+(l.cN||"<unnamed>")+'"');return g+=n,n.length||1}var s=B(e);if(!s)throw new Error('Unknown language: "'+e+'"');m(s);var a,l=t||s,f={},E="";for(a=l;a!==s;a=a.parent)a.cN&&(E=c(a.cN,"",!0)+E);var g="",R=0;try{for(var d,p,M=0;l.t.lastIndex=M,d=l.t.exec(n);)p=r(n.substring(M,d.index),d[0]),M=d.index+p;for(r(n.substr(M)),a=l;a.parent;a=a.parent)a.cN&&(E+=b);return{r:R,value:E,language:e,top:l}}catch(e){if(e.message&&-1!==e.message.indexOf("Illegal"))return{r:0,value:_(n)};throw e}}function O(t,e){e=e||h.languages||u(N);var r={r:0,value:_(t)},a=r;return e.filter(B).filter(M).forEach(function(e){var n=C(e,t,!1);n.language=e,n.r>a.r&&(a=n),n.r>r.r&&(a=r,r=n)}),a.language&&(r.second_best=a),r}function d(e){return h.tabReplace||h.useBR?e.replace(t,function(e,n){return h.useBR&&"\n"===e?"<br>":h.tabReplace?n.replace(/\t/g,h.tabReplace):""}):e}function o(e){var n,t,r,a,i,o=function(e){var n,t,r,a,i=e.className+" ";if(i+=e.parentNode?e.parentNode.className:"",t=s.exec(i))return B(t[1])?t[1]:"no-highlight";for(n=0,r=(i=i.split(/\s+/)).length;n<r;n++)if(l(a=i[n])||B(a))return a}(e);l(o)||(h.useBR?(n=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ \/]*>/g,"\n"):n=e,i=n.textContent,r=o?C(o,i,!0):O(i),(t=R(n)).length&&((a=document.createElementNS("http://www.w3.org/1999/xhtml","div")).innerHTML=r.value,r.value=function(e,n,t){var r=0,a="",i=[];function o(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){a+="<"+E(e)+f.map.call(e.attributes,function(e){return" "+e.nodeName+'="'+_(e.value).replace('"',"&quot;")+'"'}).join("")+">"}function u(e){a+="</"+E(e)+">"}function s(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var l=o();if(a+=_(t.substring(r,l[0].offset)),r=l[0].offset,l===e){for(i.reverse().forEach(u);s(l.splice(0,1)[0]),(l=o())===e&&l.length&&l[0].offset===r;);i.reverse().forEach(c)}else"start"===l[0].event?i.push(l[0].node):i.pop(),s(l.splice(0,1)[0])}return a+_(t.substr(r))}(t,R(a),i)),r.value=d(r.value),e.innerHTML=r.value,e.className=function(e,n,t){var r=n?c[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),-1===e.indexOf(r)&&a.push(r),a.join(" ").trim()}(e.className,o,r.language),e.result={language:r.language,re:r.r},r.second_best&&(e.second_best={language:r.second_best.language,re:r.second_best.r}))}function p(){if(!p.called){p.called=!0;var e=document.querySelectorAll("pre code");f.forEach.call(e,o)}}function B(e){return e=(e||"").toLowerCase(),N[e]||N[c[e]]}function M(e){var n=B(e);return n&&!n.disableAutodetect}return a.highlight=C,a.highlightAuto=O,a.fixMarkup=d,a.highlightBlock=o,a.configure=function(e){h=g(h,e)},a.initHighlighting=p,a.initHighlightingOnLoad=function(){addEventListener("DOMContentLoaded",p,!1),addEventListener("load",p,!1)},a.registerLanguage=function(n,e){var t=N[n]=e(a);i(t),t.aliases&&t.aliases.forEach(function(e){c[e]=n})},a.listLanguages=function(){return u(N)},a.getLanguage=B,a.autoDetection=M,a.inherit=g,a.IR=a.IDENT_RE="[a-zA-Z]\\w*",a.UIR=a.UNDERSCORE_IDENT_RE="[a-zA-Z_]\\w*",a.NR=a.NUMBER_RE="\\b\\d+(\\.\\d+)?",a.CNR=a.C_NUMBER_RE="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",a.BNR=a.BINARY_NUMBER_RE="\\b(0b[01]+)",a.RSR=a.RE_STARTERS_RE="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",a.BE=a.BACKSLASH_ESCAPE={b:"\\\\[\\s\\S]",r:0},a.ASM=a.APOS_STRING_MODE={cN:"string",b:"'",e:"'",i:"\\n",c:[a.BE]},a.QSM=a.QUOTE_STRING_MODE={cN:"string",b:'"',e:'"',i:"\\n",c:[a.BE]},a.PWM=a.PHRASAL_WORDS_MODE={b:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},a.C=a.COMMENT=function(e,n,t){var r=a.inherit({cN:"comment",b:e,e:n,c:[]},t||{});return r.c.push(a.PWM),r.c.push({cN:"doctag",b:"(?:TODO|FIXME|NOTE|BUG|XXX):",r:0}),r},a.CLCM=a.C_LINE_COMMENT_MODE=a.C("//","$"),a.CBCM=a.C_BLOCK_COMMENT_MODE=a.C("/\\*","\\*/"),a.HCM=a.HASH_COMMENT_MODE=a.C("#","$"),a.NM=a.NUMBER_MODE={cN:"number",b:a.NR,r:0},a.CNM=a.C_NUMBER_MODE={cN:"number",b:a.CNR,r:0},a.BNM=a.BINARY_NUMBER_MODE={cN:"number",b:a.BNR,r:0},a.CSSNM=a.CSS_NUMBER_MODE={cN:"number",b:a.NR+"(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",r:0},a.RM=a.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gimuy]*/,i:/\n/,c:[a.BE,{b:/\[/,e:/\]/,r:0,c:[a.BE]}]},a.TM=a.TITLE_MODE={cN:"title",b:a.IR,r:0},a.UTM=a.UNDERSCORE_TITLE_MODE={cN:"title",b:a.UIR,r:0},a.METHOD_GUARD={b:"\\.\\s*"+a.UIR,r:0},a});hljs.registerLanguage("xml",function(s){var e={eW:!0,i:/</,r:0,c:[{cN:"attr",b:"[A-Za-z0-9\\._:-]+",r:0},{b:/=\s*/,r:0,c:[{cN:"string",endsParent:!0,v:[{b:/"/,e:/"/},{b:/'/,e:/'/},{b:/[^\s"'=<>`]+/}]}]}]};return{aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf"],cI:!0,c:[{cN:"meta",b:"<!DOCTYPE",e:">",r:10,c:[{b:"\\[",e:"\\]"}]},s.C("\x3c!--","--\x3e",{r:10}),{b:"<\\!\\[CDATA\\[",e:"\\]\\]>",r:10},{cN:"meta",b:/<\?xml/,e:/\?>/,r:10},{b:/<\?(php)?/,e:/\?>/,sL:"php",c:[{b:"/\\*",e:"\\*/",skip:!0},{b:'b"',e:'"',skip:!0},{b:"b'",e:"'",skip:!0},s.inherit(s.ASM,{i:null,cN:null,c:null,skip:!0}),s.inherit(s.QSM,{i:null,cN:null,c:null,skip:!0})]},{cN:"tag",b:"<style(?=\\s|>|$)",e:">",k:{name:"style"},c:[e],starts:{e:"</style>",rE:!0,sL:["css","xml"]}},{cN:"tag",b:"<script(?=\\s|>|$)",e:">",k:{name:"script"},c:[e],starts:{e:"<\/script>",rE:!0,sL:["actionscript","javascript","handlebars","xml","vbscript"]}},{cN:"tag",b:"</?",e:"/?>",c:[{cN:"name",b:/[^\/><\s]+/,r:0},e]}]}});hljs.registerLanguage("markdown",function(e){return{aliases:["md","mkdown","mkd"],c:[{cN:"section",v:[{b:"^#{1,6}",e:"$"},{b:"^.+?\\n[=-]{2,}$"}]},{b:"<",e:">",sL:"xml",r:0},{cN:"bullet",b:"^\\s*([*+-]|(\\d+\\.))\\s+"},{cN:"strong",b:"[*_]{2}.+?[*_]{2}"},{cN:"emphasis",v:[{b:"\\*.+?\\*"},{b:"_.+?_",r:0}]},{cN:"quote",b:"^>\\s+",e:"$"},{cN:"code",v:[{b:"^```w*s*$",e:"^```s*$"},{b:"`.+?`"},{b:"^( {4}|\t)",e:"$",r:0}]},{b:"^[-\\*]{3,}",e:"$"},{b:"\\[.+?\\][\\(\\[].*?[\\)\\]]",rB:!0,c:[{cN:"string",b:"\\[",e:"\\]",eB:!0,rE:!0,r:0},{cN:"link",b:"\\]\\(",e:"\\)",eB:!0,eE:!0},{cN:"symbol",b:"\\]\\[",e:"\\]",eB:!0,eE:!0}],r:10},{b:/^\[[^\n]+\]:/,rB:!0,c:[{cN:"symbol",b:/\[/,e:/\]/,eB:!0,eE:!0},{cN:"link",b:/:\s*/,e:/$/,eB:!0}]}]}});hljs.registerLanguage("dart",function(e){var t={cN:"subst",v:[{b:"\\$[A-Za-z0-9_]+"}]},r={cN:"subst",v:[{b:"\\${",e:"}"}],k:"true false null this is new super"},n={cN:"string",v:[{b:"r'''",e:"'''"},{b:'r"""',e:'"""'},{b:"r'",e:"'",i:"\\n"},{b:'r"',e:'"',i:"\\n"},{b:"'''",e:"'''",c:[e.BE,t,r]},{b:'"""',e:'"""',c:[e.BE,t,r]},{b:"'",e:"'",i:"\\n",c:[e.BE,t,r]},{b:'"',e:'"',i:"\\n",c:[e.BE,t,r]}]};r.c=[e.CNM,n];return{k:{keyword:"assert async await break case catch class const continue default do else enum extends false final finally for if in is new null rethrow return super switch sync this throw true try var void while with yield abstract as dynamic export external factory get implements import library operator part set static typedef",built_in:"print Comparable DateTime Duration Function Iterable Iterator List Map Match Null Object Pattern RegExp Set Stopwatch String StringBuffer StringSink Symbol Type Uri bool double int num document window querySelector querySelectorAll Element ElementList"},c:[n,e.C("/\\*\\*","\\*/",{sL:"markdown"}),e.C("///","$",{sL:"markdown"}),e.CLCM,e.CBCM,{cN:"class",bK:"class interface",e:"{",eE:!0,c:[{bK:"extends implements"},e.UTM]},e.CNM,{cN:"meta",b:"@[A-Za-z]+"},{b:"=>"}]}});
+/*
+  Highlight.js 10.1.0 (74de6eaa)
+  License: BSD-3-Clause
+  Copyright (c) 2006-2020, Ivan Sagalaev
+*/
+var hljs=function(){"use strict";function e(n){Object.freeze(n);var t="function"==typeof n;return Object.getOwnPropertyNames(n).forEach((function(r){!Object.hasOwnProperty.call(n,r)||null===n[r]||"object"!=typeof n[r]&&"function"!=typeof n[r]||t&&("caller"===r||"callee"===r||"arguments"===r)||Object.isFrozen(n[r])||e(n[r])})),n}class n{constructor(e){void 0===e.data&&(e.data={}),this.data=e.data}ignoreMatch(){this.ignore=!0}}function t(e){return e.replace(/&/g,"&amp;").replace(/</g,"&lt;").replace(/>/g,"&gt;").replace(/"/g,"&quot;").replace(/'/g,"&#x27;")}function r(e,...n){var t={};for(const n in e)t[n]=e[n];return n.forEach((function(e){for(const n in e)t[n]=e[n]})),t}function a(e){return e.nodeName.toLowerCase()}var i=Object.freeze({__proto__:null,escapeHTML:t,inherit:r,nodeStream:function(e){var n=[];return function e(t,r){for(var i=t.firstChild;i;i=i.nextSibling)3===i.nodeType?r+=i.nodeValue.length:1===i.nodeType&&(n.push({event:"start",offset:r,node:i}),r=e(i,r),a(i).match(/br|hr|img|input/)||n.push({event:"stop",offset:r,node:i}));return r}(e,0),n},mergeStreams:function(e,n,r){var i=0,s="",o=[];function l(){return e.length&&n.length?e[0].offset!==n[0].offset?e[0].offset<n[0].offset?e:n:"start"===n[0].event?e:n:e.length?e:n}function c(e){s+="<"+a(e)+[].map.call(e.attributes,(function(e){return" "+e.nodeName+'="'+t(e.value)+'"'})).join("")+">"}function u(e){s+="</"+a(e)+">"}function d(e){("start"===e.event?c:u)(e.node)}for(;e.length||n.length;){var g=l();if(s+=t(r.substring(i,g[0].offset)),i=g[0].offset,g===e){o.reverse().forEach(u);do{d(g.splice(0,1)[0]),g=l()}while(g===e&&g.length&&g[0].offset===i);o.reverse().forEach(c)}else"start"===g[0].event?o.push(g[0].node):o.pop(),d(g.splice(0,1)[0])}return s+t(r.substr(i))}});const s="</span>",o=e=>!!e.kind;class l{constructor(e,n){this.buffer="",this.classPrefix=n.classPrefix,e.walk(this)}addText(e){this.buffer+=t(e)}openNode(e){if(!o(e))return;let n=e.kind;e.sublanguage||(n=`${this.classPrefix}${n}`),this.span(n)}closeNode(e){o(e)&&(this.buffer+=s)}value(){return this.buffer}span(e){this.buffer+=`<span class="${e}">`}}class c{constructor(){this.rootNode={children:[]},this.stack=[this.rootNode]}get top(){return this.stack[this.stack.length-1]}get root(){return this.rootNode}add(e){this.top.children.push(e)}openNode(e){const n={kind:e,children:[]};this.add(n),this.stack.push(n)}closeNode(){if(this.stack.length>1)return this.stack.pop()}closeAllNodes(){for(;this.closeNode(););}toJSON(){return JSON.stringify(this.rootNode,null,4)}walk(e){return this.constructor._walk(e,this.rootNode)}static _walk(e,n){return"string"==typeof n?e.addText(n):n.children&&(e.openNode(n),n.children.forEach(n=>this._walk(e,n)),e.closeNode(n)),e}static _collapse(e){"string"!=typeof e&&e.children&&(e.children.every(e=>"string"==typeof e)?e.children=[e.children.join("")]:e.children.forEach(e=>{c._collapse(e)}))}}class u extends c{constructor(e){super(),this.options=e}addKeyword(e,n){""!==e&&(this.openNode(n),this.addText(e),this.closeNode())}addText(e){""!==e&&this.add(e)}addSublanguage(e,n){const t=e.root;t.kind=n,t.sublanguage=!0,this.add(t)}toHTML(){return new l(this,this.options).value()}finalize(){return!0}}function d(e){return e?"string"==typeof e?e:e.source:null}const g="(-?)(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)",h={begin:"\\\\[\\s\\S]",relevance:0},f={className:"string",begin:"'",end:"'",illegal:"\\n",contains:[h]},p={className:"string",begin:'"',end:'"',illegal:"\\n",contains:[h]},b={begin:/\b(a|an|the|are|I'm|isn't|don't|doesn't|won't|but|just|should|pretty|simply|enough|gonna|going|wtf|so|such|will|you|your|they|like|more)\b/},m=function(e,n,t={}){var a=r({className:"comment",begin:e,end:n,contains:[]},t);return a.contains.push(b),a.contains.push({className:"doctag",begin:"(?:TODO|FIXME|NOTE|BUG|OPTIMIZE|HACK|XXX):",relevance:0}),a},v=m("//","$"),x=m("/\\*","\\*/"),E=m("#","$");var _=Object.freeze({__proto__:null,IDENT_RE:"[a-zA-Z]\\w*",UNDERSCORE_IDENT_RE:"[a-zA-Z_]\\w*",NUMBER_RE:"\\b\\d+(\\.\\d+)?",C_NUMBER_RE:g,BINARY_NUMBER_RE:"\\b(0b[01]+)",RE_STARTERS_RE:"!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~",SHEBANG:(e={})=>{const n=/^#![ ]*\//;return e.binary&&(e.begin=function(...e){return e.map(e=>d(e)).join("")}(n,/.*\b/,e.binary,/\b.*/)),r({className:"meta",begin:n,end:/$/,relevance:0,"on:begin":(e,n)=>{0!==e.index&&n.ignoreMatch()}},e)},BACKSLASH_ESCAPE:h,APOS_STRING_MODE:f,QUOTE_STRING_MODE:p,PHRASAL_WORDS_MODE:b,COMMENT:m,C_LINE_COMMENT_MODE:v,C_BLOCK_COMMENT_MODE:x,HASH_COMMENT_MODE:E,NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?",relevance:0},C_NUMBER_MODE:{className:"number",begin:g,relevance:0},BINARY_NUMBER_MODE:{className:"number",begin:"\\b(0b[01]+)",relevance:0},CSS_NUMBER_MODE:{className:"number",begin:"\\b\\d+(\\.\\d+)?(%|em|ex|ch|rem|vw|vh|vmin|vmax|cm|mm|in|pt|pc|px|deg|grad|rad|turn|s|ms|Hz|kHz|dpi|dpcm|dppx)?",relevance:0},REGEXP_MODE:{begin:/(?=\/[^/\n]*\/)/,contains:[{className:"regexp",begin:/\//,end:/\/[gimuy]*/,illegal:/\n/,contains:[h,{begin:/\[/,end:/\]/,relevance:0,contains:[h]}]}]},TITLE_MODE:{className:"title",begin:"[a-zA-Z]\\w*",relevance:0},UNDERSCORE_TITLE_MODE:{className:"title",begin:"[a-zA-Z_]\\w*",relevance:0},METHOD_GUARD:{begin:"\\.\\s*[a-zA-Z_]\\w*",relevance:0},END_SAME_AS_BEGIN:function(e){return Object.assign(e,{"on:begin":(e,n)=>{n.data._beginMatch=e[1]},"on:end":(e,n)=>{n.data._beginMatch!==e[1]&&n.ignoreMatch()}})}}),N="of and for in not or if then".split(" ");function w(e,n){return n?+n:function(e){return N.includes(e.toLowerCase())}(e)?0:1}const R=t,y=r,{nodeStream:k,mergeStreams:O}=i,M=Symbol("nomatch");return function(t){var a=[],i={},s={},o=[],l=!0,c=/(^(<[^>]+>|\t|)+|\n)/gm,g="Could not find the language '{}', did you forget to load/include a language module?";const h={disableAutodetect:!0,name:"Plain text",contains:[]};var f={noHighlightRe:/^(no-?highlight)$/i,languageDetectRe:/\blang(?:uage)?-([\w-]+)\b/i,classPrefix:"hljs-",tabReplace:null,useBR:!1,languages:null,__emitter:u};function p(e){return f.noHighlightRe.test(e)}function b(e,n,t,r){var a={code:n,language:e};S("before:highlight",a);var i=a.result?a.result:m(a.language,a.code,t,r);return i.code=a.code,S("after:highlight",i),i}function m(e,t,a,s){var o=t;function c(e,n){var t=E.case_insensitive?n[0].toLowerCase():n[0];return Object.prototype.hasOwnProperty.call(e.keywords,t)&&e.keywords[t]}function u(){null!=y.subLanguage?function(){if(""!==A){var e=null;if("string"==typeof y.subLanguage){if(!i[y.subLanguage])return void O.addText(A);e=m(y.subLanguage,A,!0,k[y.subLanguage]),k[y.subLanguage]=e.top}else e=v(A,y.subLanguage.length?y.subLanguage:null);y.relevance>0&&(I+=e.relevance),O.addSublanguage(e.emitter,e.language)}}():function(){if(!y.keywords)return void O.addText(A);let e=0;y.keywordPatternRe.lastIndex=0;let n=y.keywordPatternRe.exec(A),t="";for(;n;){t+=A.substring(e,n.index);const r=c(y,n);if(r){const[e,a]=r;O.addText(t),t="",I+=a,O.addKeyword(n[0],e)}else t+=n[0];e=y.keywordPatternRe.lastIndex,n=y.keywordPatternRe.exec(A)}t+=A.substr(e),O.addText(t)}(),A=""}function h(e){return e.className&&O.openNode(e.className),y=Object.create(e,{parent:{value:y}})}function p(e){return 0===y.matcher.regexIndex?(A+=e[0],1):(L=!0,0)}var b={};function x(t,r){var i=r&&r[0];if(A+=t,null==i)return u(),0;if("begin"===b.type&&"end"===r.type&&b.index===r.index&&""===i){if(A+=o.slice(r.index,r.index+1),!l){const n=Error("0 width match regex");throw n.languageName=e,n.badRule=b.rule,n}return 1}if(b=r,"begin"===r.type)return function(e){var t=e[0],r=e.rule;const a=new n(r),i=[r.__beforeBegin,r["on:begin"]];for(const n of i)if(n&&(n(e,a),a.ignore))return p(t);return r&&r.endSameAsBegin&&(r.endRe=RegExp(t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),"m")),r.skip?A+=t:(r.excludeBegin&&(A+=t),u(),r.returnBegin||r.excludeBegin||(A=t)),h(r),r.returnBegin?0:t.length}(r);if("illegal"===r.type&&!a){const e=Error('Illegal lexeme "'+i+'" for mode "'+(y.className||"<unnamed>")+'"');throw e.mode=y,e}if("end"===r.type){var s=function(e){var t=e[0],r=o.substr(e.index),a=function e(t,r,a){let i=function(e,n){var t=e&&e.exec(n);return t&&0===t.index}(t.endRe,a);if(i){if(t["on:end"]){const e=new n(t);t["on:end"](r,e),e.ignore&&(i=!1)}if(i){for(;t.endsParent&&t.parent;)t=t.parent;return t}}if(t.endsWithParent)return e(t.parent,r,a)}(y,e,r);if(!a)return M;var i=y;i.skip?A+=t:(i.returnEnd||i.excludeEnd||(A+=t),u(),i.excludeEnd&&(A=t));do{y.className&&O.closeNode(),y.skip||y.subLanguage||(I+=y.relevance),y=y.parent}while(y!==a.parent);return a.starts&&(a.endSameAsBegin&&(a.starts.endRe=a.endRe),h(a.starts)),i.returnEnd?0:t.length}(r);if(s!==M)return s}if("illegal"===r.type&&""===i)return 1;if(B>1e5&&B>3*r.index)throw Error("potential infinite loop, way more iterations than matches");return A+=i,i.length}var E=T(e);if(!E)throw console.error(g.replace("{}",e)),Error('Unknown language: "'+e+'"');var _=function(e){function n(n,t){return RegExp(d(n),"m"+(e.case_insensitive?"i":"")+(t?"g":""))}class t{constructor(){this.matchIndexes={},this.regexes=[],this.matchAt=1,this.position=0}addRule(e,n){n.position=this.position++,this.matchIndexes[this.matchAt]=n,this.regexes.push([n,e]),this.matchAt+=function(e){return RegExp(e.toString()+"|").exec("").length-1}(e)+1}compile(){0===this.regexes.length&&(this.exec=()=>null);const e=this.regexes.map(e=>e[1]);this.matcherRe=n(function(e,n="|"){for(var t=/\[(?:[^\\\]]|\\.)*\]|\(\??|\\([1-9][0-9]*)|\\./,r=0,a="",i=0;i<e.length;i++){var s=r+=1,o=d(e[i]);for(i>0&&(a+=n),a+="(";o.length>0;){var l=t.exec(o);if(null==l){a+=o;break}a+=o.substring(0,l.index),o=o.substring(l.index+l[0].length),"\\"===l[0][0]&&l[1]?a+="\\"+(+l[1]+s):(a+=l[0],"("===l[0]&&r++)}a+=")"}return a}(e),!0),this.lastIndex=0}exec(e){this.matcherRe.lastIndex=this.lastIndex;const n=this.matcherRe.exec(e);if(!n)return null;const t=n.findIndex((e,n)=>n>0&&void 0!==e),r=this.matchIndexes[t];return n.splice(0,t),Object.assign(n,r)}}class a{constructor(){this.rules=[],this.multiRegexes=[],this.count=0,this.lastIndex=0,this.regexIndex=0}getMatcher(e){if(this.multiRegexes[e])return this.multiRegexes[e];const n=new t;return this.rules.slice(e).forEach(([e,t])=>n.addRule(e,t)),n.compile(),this.multiRegexes[e]=n,n}considerAll(){this.regexIndex=0}addRule(e,n){this.rules.push([e,n]),"begin"===n.type&&this.count++}exec(e){const n=this.getMatcher(this.regexIndex);n.lastIndex=this.lastIndex;const t=n.exec(e);return t&&(this.regexIndex+=t.position+1,this.regexIndex===this.count&&(this.regexIndex=0)),t}}function i(e,n){const t=e.input[e.index-1],r=e.input[e.index+e[0].length];"."!==t&&"."!==r||n.ignoreMatch()}if(e.contains&&e.contains.includes("self"))throw Error("ERR: contains `self` is not supported at the top-level of a language.  See documentation.");return function t(s,o){const l=s;if(s.compiled)return l;s.compiled=!0,s.__beforeBegin=null,s.keywords=s.keywords||s.beginKeywords;let c=null;if("object"==typeof s.keywords&&(c=s.keywords.$pattern,delete s.keywords.$pattern),s.keywords&&(s.keywords=function(e,n){var t={};return"string"==typeof e?r("keyword",e):Object.keys(e).forEach((function(n){r(n,e[n])})),t;function r(e,r){n&&(r=r.toLowerCase()),r.split(" ").forEach((function(n){var r=n.split("|");t[r[0]]=[e,w(r[0],r[1])]}))}}(s.keywords,e.case_insensitive)),s.lexemes&&c)throw Error("ERR: Prefer `keywords.$pattern` to `mode.lexemes`, BOTH are not allowed. (see mode reference) ");return l.keywordPatternRe=n(s.lexemes||c||/\w+/,!0),o&&(s.beginKeywords&&(s.begin="\\b("+s.beginKeywords.split(" ").join("|")+")(?=\\b|\\s)",s.__beforeBegin=i),s.begin||(s.begin=/\B|\b/),l.beginRe=n(s.begin),s.endSameAsBegin&&(s.end=s.begin),s.end||s.endsWithParent||(s.end=/\B|\b/),s.end&&(l.endRe=n(s.end)),l.terminator_end=d(s.end)||"",s.endsWithParent&&o.terminator_end&&(l.terminator_end+=(s.end?"|":"")+o.terminator_end)),s.illegal&&(l.illegalRe=n(s.illegal)),void 0===s.relevance&&(s.relevance=1),s.contains||(s.contains=[]),s.contains=[].concat(...s.contains.map((function(e){return function(e){return e.variants&&!e.cached_variants&&(e.cached_variants=e.variants.map((function(n){return r(e,{variants:null},n)}))),e.cached_variants?e.cached_variants:function e(n){return!!n&&(n.endsWithParent||e(n.starts))}(e)?r(e,{starts:e.starts?r(e.starts):null}):Object.isFrozen(e)?r(e):e}("self"===e?s:e)}))),s.contains.forEach((function(e){t(e,l)})),s.starts&&t(s.starts,o),l.matcher=function(e){const n=new a;return e.contains.forEach(e=>n.addRule(e.begin,{rule:e,type:"begin"})),e.terminator_end&&n.addRule(e.terminator_end,{type:"end"}),e.illegal&&n.addRule(e.illegal,{type:"illegal"}),n}(l),l}(e)}(E),N="",y=s||_,k={},O=new f.__emitter(f);!function(){for(var e=[],n=y;n!==E;n=n.parent)n.className&&e.unshift(n.className);e.forEach(e=>O.openNode(e))}();var A="",I=0,S=0,B=0,L=!1;try{for(y.matcher.considerAll();;){B++,L?L=!1:(y.matcher.lastIndex=S,y.matcher.considerAll());const e=y.matcher.exec(o);if(!e)break;const n=x(o.substring(S,e.index),e);S=e.index+n}return x(o.substr(S)),O.closeAllNodes(),O.finalize(),N=O.toHTML(),{relevance:I,value:N,language:e,illegal:!1,emitter:O,top:y}}catch(n){if(n.message&&n.message.includes("Illegal"))return{illegal:!0,illegalBy:{msg:n.message,context:o.slice(S-100,S+100),mode:n.mode},sofar:N,relevance:0,value:R(o),emitter:O};if(l)return{illegal:!1,relevance:0,value:R(o),emitter:O,language:e,top:y,errorRaised:n};throw n}}function v(e,n){n=n||f.languages||Object.keys(i);var t=function(e){const n={relevance:0,emitter:new f.__emitter(f),value:R(e),illegal:!1,top:h};return n.emitter.addText(e),n}(e),r=t;return n.filter(T).filter(I).forEach((function(n){var a=m(n,e,!1);a.language=n,a.relevance>r.relevance&&(r=a),a.relevance>t.relevance&&(r=t,t=a)})),r.language&&(t.second_best=r),t}function x(e){return f.tabReplace||f.useBR?e.replace(c,e=>"\n"===e?f.useBR?"<br>":e:f.tabReplace?e.replace(/\t/g,f.tabReplace):e):e}function E(e){let n=null;const t=function(e){var n=e.className+" ";n+=e.parentNode?e.parentNode.className:"";const t=f.languageDetectRe.exec(n);if(t){var r=T(t[1]);return r||(console.warn(g.replace("{}",t[1])),console.warn("Falling back to no-highlight mode for this block.",e)),r?t[1]:"no-highlight"}return n.split(/\s+/).find(e=>p(e)||T(e))}(e);if(p(t))return;S("before:highlightBlock",{block:e,language:t}),f.useBR?(n=document.createElement("div")).innerHTML=e.innerHTML.replace(/\n/g,"").replace(/<br[ /]*>/g,"\n"):n=e;const r=n.textContent,a=t?b(t,r,!0):v(r),i=k(n);if(i.length){const e=document.createElement("div");e.innerHTML=a.value,a.value=O(i,k(e),r)}a.value=x(a.value),S("after:highlightBlock",{block:e,result:a}),e.innerHTML=a.value,e.className=function(e,n,t){var r=n?s[n]:t,a=[e.trim()];return e.match(/\bhljs\b/)||a.push("hljs"),e.includes(r)||a.push(r),a.join(" ").trim()}(e.className,t,a.language),e.result={language:a.language,re:a.relevance,relavance:a.relevance},a.second_best&&(e.second_best={language:a.second_best.language,re:a.second_best.relevance,relavance:a.second_best.relevance})}const N=()=>{if(!N.called){N.called=!0;var e=document.querySelectorAll("pre code");a.forEach.call(e,E)}};function T(e){return e=(e||"").toLowerCase(),i[e]||i[s[e]]}function A(e,{languageName:n}){"string"==typeof e&&(e=[e]),e.forEach(e=>{s[e]=n})}function I(e){var n=T(e);return n&&!n.disableAutodetect}function S(e,n){var t=e;o.forEach((function(e){e[t]&&e[t](n)}))}Object.assign(t,{highlight:b,highlightAuto:v,fixMarkup:x,highlightBlock:E,configure:function(e){f=y(f,e)},initHighlighting:N,initHighlightingOnLoad:function(){window.addEventListener("DOMContentLoaded",N,!1)},registerLanguage:function(e,n){var r=null;try{r=n(t)}catch(n){if(console.error("Language definition for '{}' could not be registered.".replace("{}",e)),!l)throw n;console.error(n),r=h}r.name||(r.name=e),i[e]=r,r.rawDefinition=n.bind(null,t),r.aliases&&A(r.aliases,{languageName:e})},listLanguages:function(){return Object.keys(i)},getLanguage:T,registerAliases:A,requireLanguage:function(e){var n=T(e);if(n)return n;throw Error("The '{}' language is required, but not loaded.".replace("{}",e))},autoDetection:I,inherit:y,addPlugin:function(e){o.push(e)}}),t.debugMode=function(){l=!1},t.safeMode=function(){l=!0},t.versionString="10.1.0";for(const n in _)"object"==typeof _[n]&&e(_[n]);return Object.assign(t,_),t}({})}();"object"==typeof exports&&"undefined"!=typeof module&&(module.exports=hljs);hljs.registerLanguage("xml",function(){"use strict";return function(e){var n={className:"symbol",begin:"&[a-z]+;|&#[0-9]+;|&#x[a-f0-9]+;"},a={begin:"\\s",contains:[{className:"meta-keyword",begin:"#?[a-z_][a-z1-9_-]+",illegal:"\\n"}]},s=e.inherit(a,{begin:"\\(",end:"\\)"}),t=e.inherit(e.APOS_STRING_MODE,{className:"meta-string"}),i=e.inherit(e.QUOTE_STRING_MODE,{className:"meta-string"}),c={endsWithParent:!0,illegal:/</,relevance:0,contains:[{className:"attr",begin:"[A-Za-z0-9\\._:-]+",relevance:0},{begin:/=\s*/,relevance:0,contains:[{className:"string",endsParent:!0,variants:[{begin:/"/,end:/"/,contains:[n]},{begin:/'/,end:/'/,contains:[n]},{begin:/[^\s"'=<>`]+/}]}]}]};return{name:"HTML, XML",aliases:["html","xhtml","rss","atom","xjb","xsd","xsl","plist","wsf","svg"],case_insensitive:!0,contains:[{className:"meta",begin:"<![a-z]",end:">",relevance:10,contains:[a,i,t,s,{begin:"\\[",end:"\\]",contains:[{className:"meta",begin:"<![a-z]",end:">",contains:[a,s,i,t]}]}]},e.COMMENT("\x3c!--","--\x3e",{relevance:10}),{begin:"<\\!\\[CDATA\\[",end:"\\]\\]>",relevance:10},n,{className:"meta",begin:/<\?xml/,end:/\?>/,relevance:10},{className:"tag",begin:"<style(?=\\s|>)",end:">",keywords:{name:"style"},contains:[c],starts:{end:"</style>",returnEnd:!0,subLanguage:["css","xml"]}},{className:"tag",begin:"<script(?=\\s|>)",end:">",keywords:{name:"script"},contains:[c],starts:{end:"<\/script>",returnEnd:!0,subLanguage:["javascript","handlebars","xml"]}},{className:"tag",begin:"</?",end:"/?>",contains:[{className:"name",begin:/[^\/><\s]+/,relevance:0},c]}]}}}());hljs.registerLanguage("markdown",function(){"use strict";return function(n){const e={begin:"<",end:">",subLanguage:"xml",relevance:0},a={begin:"\\[.+?\\][\\(\\[].*?[\\)\\]]",returnBegin:!0,contains:[{className:"string",begin:"\\[",end:"\\]",excludeBegin:!0,returnEnd:!0,relevance:0},{className:"link",begin:"\\]\\(",end:"\\)",excludeBegin:!0,excludeEnd:!0},{className:"symbol",begin:"\\]\\[",end:"\\]",excludeBegin:!0,excludeEnd:!0}],relevance:10},i={className:"strong",contains:[],variants:[{begin:/_{2}/,end:/_{2}/},{begin:/\*{2}/,end:/\*{2}/}]},s={className:"emphasis",contains:[],variants:[{begin:/\*(?!\*)/,end:/\*/},{begin:/_(?!_)/,end:/_/,relevance:0}]};i.contains.push(s),s.contains.push(i);var c=[e,a];return i.contains=i.contains.concat(c),s.contains=s.contains.concat(c),{name:"Markdown",aliases:["md","mkdown","mkd"],contains:[{className:"section",variants:[{begin:"^#{1,6}",end:"$",contains:c=c.concat(i,s)},{begin:"(?=^.+?\\n[=-]{2,}$)",contains:[{begin:"^[=-]*$"},{begin:"^",end:"\\n",contains:c}]}]},e,{className:"bullet",begin:"^[ \t]*([*+-]|(\\d+\\.))(?=\\s+)",end:"\\s+",excludeEnd:!0},i,s,{className:"quote",begin:"^>\\s+",contains:c,end:"$"},{className:"code",variants:[{begin:"(`{3,})(.|\\n)*?\\1`*[ ]*"},{begin:"(~{3,})(.|\\n)*?\\1~*[ ]*"},{begin:"```",end:"```+[ ]*$"},{begin:"~~~",end:"~~~+[ ]*$"},{begin:"`.+?`"},{begin:"(?=^( {4}|\\t))",contains:[{begin:"^( {4}|\\t)",end:"(\\n)$"}],relevance:0}]},{begin:"^[-\\*]{3,}",end:"$"},a,{begin:/^\[[^\n]+\]:/,returnBegin:!0,contains:[{className:"symbol",begin:/\[/,end:/\]/,excludeBegin:!0,excludeEnd:!0},{className:"link",begin:/:\s*/,end:/$/,excludeBegin:!0}]}]}}}());hljs.registerLanguage("dart",function(){"use strict";return function(e){const n={className:"subst",variants:[{begin:"\\$[A-Za-z0-9_]+"}]},t={className:"subst",variants:[{begin:"\\${",end:"}"}],keywords:"true false null this is new super"},a={className:"string",variants:[{begin:"r'''",end:"'''"},{begin:'r"""',end:'"""'},{begin:"r'",end:"'",illegal:"\\n"},{begin:'r"',end:'"',illegal:"\\n"},{begin:"'''",end:"'''",contains:[e.BACKSLASH_ESCAPE,n,t]},{begin:'"""',end:'"""',contains:[e.BACKSLASH_ESCAPE,n,t]},{begin:"'",end:"'",illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n,t]},{begin:'"',end:'"',illegal:"\\n",contains:[e.BACKSLASH_ESCAPE,n,t]}]};t.contains=[e.C_NUMBER_MODE,a];const i=["Comparable","DateTime","Duration","Function","Iterable","Iterator","List","Map","Match","Object","Pattern","RegExp","Set","Stopwatch","String","StringBuffer","StringSink","Symbol","Type","Uri","bool","double","int","num","Element","ElementList"],r=i.map(e=>`${e}?`);return{name:"Dart",keywords:{keyword:"abstract as assert async await break case catch class const continue covariant default deferred do dynamic else enum export extends extension external factory false final finally for Function get hide if implements import in inferface is late library mixin new null on operator part required rethrow return set show static super switch sync this throw true try typedef var void while with yield",built_in:i.concat(r).concat(["Never","Null","dynamic","print","document","querySelector","querySelectorAll","window"]).join(" "),$pattern:/[A-Za-z][A-Za-z0-9_]*\??/},contains:[a,e.COMMENT("/\\*\\*","\\*/",{subLanguage:"markdown",relevance:0}),e.COMMENT("///+\\s*","$",{contains:[{subLanguage:"markdown",begin:".",end:"$",relevance:0}]}),e.C_LINE_COMMENT_MODE,e.C_BLOCK_COMMENT_MODE,{className:"class",beginKeywords:"class interface",end:"{",excludeEnd:!0,contains:[{beginKeywords:"extends implements"},e.UNDERSCORE_TITLE_MODE]},e.C_NUMBER_MODE,{className:"meta",begin:"@[A-Za-z]+"},{begin:"=>"}]}}}());
\ No newline at end of file
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 ef4f63a..d6e90ed 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
@@ -53,220 +53,371 @@
 ''';
 
 String _highlight_pack_js;
-// highlight_pack_js md5 is '9104bfe8b056f8e00da50b0ea3d6e6d4'
+// highlight_pack_js md5 is 'e2de0572f5426885d35e366c9bf60f05'
 String _highlight_pack_js_base64 = '''
-LyohIGhpZ2hsaWdodC5qcyB2OS4xNS4xMCB8IEJTRDMgTGljZW5zZSB8IGdpdC5pby9obGpzbGljZW5z
-ZSAqLwohZnVuY3Rpb24oZSl7dmFyIG49Im9iamVjdCI9PXR5cGVvZiB3aW5kb3cmJndpbmRvd3x8Im9i
-amVjdCI9PXR5cGVvZiBzZWxmJiZzZWxmOyJ1bmRlZmluZWQiPT10eXBlb2YgZXhwb3J0c3x8ZXhwb3J0
-cy5ub2RlVHlwZT9uJiYobi5obGpzPWUoe30pLCJmdW5jdGlvbiI9PXR5cGVvZiBkZWZpbmUmJmRlZmlu
-ZS5hbWQmJmRlZmluZShbXSxmdW5jdGlvbigpe3JldHVybiBuLmhsanN9KSk6ZShleHBvcnRzKX0oZnVu
-Y3Rpb24oYSl7dmFyIGY9W10sdT1PYmplY3Qua2V5cyxOPXt9LGM9e30sbj0vXihuby0/aGlnaGxpZ2h0
-fHBsYWlufHRleHQpJC9pLHM9L1xibGFuZyg/OnVhZ2UpPy0oW1x3LV0rKVxiL2ksdD0vKCheKDxbXj5d
-Kz58XHR8KSt8KD86XG4pKSkvZ20scj17Y2FzZV9pbnNlbnNpdGl2ZToiY0kiLGxleGVtZXM6ImwiLGNv
-bnRhaW5zOiJjIixrZXl3b3JkczoiayIsc3ViTGFuZ3VhZ2U6InNMIixjbGFzc05hbWU6ImNOIixiZWdp
-bjoiYiIsYmVnaW5LZXl3b3JkczoiYksiLGVuZDoiZSIsZW5kc1dpdGhQYXJlbnQ6ImVXIixpbGxlZ2Fs
-OiJpIixleGNsdWRlQmVnaW46ImVCIixleGNsdWRlRW5kOiJlRSIscmV0dXJuQmVnaW46InJCIixyZXR1
-cm5FbmQ6InJFIixyZWxldmFuY2U6InIiLHZhcmlhbnRzOiJ2IixJREVOVF9SRToiSVIiLFVOREVSU0NP
-UkVfSURFTlRfUkU6IlVJUiIsTlVNQkVSX1JFOiJOUiIsQ19OVU1CRVJfUkU6IkNOUiIsQklOQVJZX05V
-TUJFUl9SRToiQk5SIixSRV9TVEFSVEVSU19SRToiUlNSIixCQUNLU0xBU0hfRVNDQVBFOiJCRSIsQVBP
-U19TVFJJTkdfTU9ERToiQVNNIixRVU9URV9TVFJJTkdfTU9ERToiUVNNIixQSFJBU0FMX1dPUkRTX01P
-REU6IlBXTSIsQ19MSU5FX0NPTU1FTlRfTU9ERToiQ0xDTSIsQ19CTE9DS19DT01NRU5UX01PREU6IkNC
-Q00iLEhBU0hfQ09NTUVOVF9NT0RFOiJIQ00iLE5VTUJFUl9NT0RFOiJOTSIsQ19OVU1CRVJfTU9ERToi
-Q05NIixCSU5BUllfTlVNQkVSX01PREU6IkJOTSIsQ1NTX05VTUJFUl9NT0RFOiJDU1NOTSIsUkVHRVhQ
-X01PREU6IlJNIixUSVRMRV9NT0RFOiJUTSIsVU5ERVJTQ09SRV9USVRMRV9NT0RFOiJVVE0iLENPTU1F
-TlQ6IkMiLGJlZ2luUmU6ImJSIixlbmRSZToiZVIiLGlsbGVnYWxSZToiaVIiLGxleGVtZXNSZToibFIi
-LHRlcm1pbmF0b3JzOiJ0Iix0ZXJtaW5hdG9yX2VuZDoidEUifSxiPSI8L3NwYW4+IixoPXtjbGFzc1By
-ZWZpeDoiaGxqcy0iLHRhYlJlcGxhY2U6bnVsbCx1c2VCUjohMSxsYW5ndWFnZXM6dm9pZCAwfTtmdW5j
-dGlvbiBfKGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsi
-KS5yZXBsYWNlKC8+L2csIiZndDsiKX1mdW5jdGlvbiBFKGUpe3JldHVybiBlLm5vZGVOYW1lLnRvTG93
-ZXJDYXNlKCl9ZnVuY3Rpb24gdihlLG4pe3ZhciB0PWUmJmUuZXhlYyhuKTtyZXR1cm4gdCYmMD09PXQu
-aW5kZXh9ZnVuY3Rpb24gbChlKXtyZXR1cm4gbi50ZXN0KGUpfWZ1bmN0aW9uIGcoZSl7dmFyIG4sdD17
-fSxyPUFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKGFyZ3VtZW50cywxKTtmb3IobiBpbiBlKXRbbl09
-ZVtuXTtyZXR1cm4gci5mb3JFYWNoKGZ1bmN0aW9uKGUpe2ZvcihuIGluIGUpdFtuXT1lW25dfSksdH1m
-dW5jdGlvbiBSKGUpe3ZhciBhPVtdO3JldHVybiBmdW5jdGlvbiBlKG4sdCl7Zm9yKHZhciByPW4uZmly
-c3RDaGlsZDtyO3I9ci5uZXh0U2libGluZykzPT09ci5ub2RlVHlwZT90Kz1yLm5vZGVWYWx1ZS5sZW5n
-dGg6MT09PXIubm9kZVR5cGUmJihhLnB1c2goe2V2ZW50OiJzdGFydCIsb2Zmc2V0OnQsbm9kZTpyfSks
-dD1lKHIsdCksRShyKS5tYXRjaCgvYnJ8aHJ8aW1nfGlucHV0Lyl8fGEucHVzaCh7ZXZlbnQ6InN0b3Ai
-LG9mZnNldDp0LG5vZGU6cn0pKTtyZXR1cm4gdH0oZSwwKSxhfWZ1bmN0aW9uIGkoZSl7aWYociYmIWUu
-bGFuZ0FwaVJlc3RvcmVkKXtmb3IodmFyIG4gaW4gZS5sYW5nQXBpUmVzdG9yZWQ9ITAscillW25dJiYo
-ZVtyW25dXT1lW25dKTsoZS5jfHxbXSkuY29uY2F0KGUudnx8W10pLmZvckVhY2goaSl9fWZ1bmN0aW9u
-IG0obyl7ZnVuY3Rpb24gcyhlKXtyZXR1cm4gZSYmZS5zb3VyY2V8fGV9ZnVuY3Rpb24gYyhlLG4pe3Jl
-dHVybiBuZXcgUmVnRXhwKHMoZSksIm0iKyhvLmNJPyJpIjoiIikrKG4/ImciOiIiKSl9IWZ1bmN0aW9u
-IG4odCxlKXtpZighdC5jb21waWxlZCl7aWYodC5jb21waWxlZD0hMCx0Lms9dC5rfHx0LmJLLHQuayl7
-ZnVuY3Rpb24gcih0LGUpe28uY0kmJihlPWUudG9Mb3dlckNhc2UoKSksZS5zcGxpdCgiICIpLmZvckVh
-Y2goZnVuY3Rpb24oZSl7dmFyIG49ZS5zcGxpdCgifCIpO2FbblswXV09W3QsblsxXT9OdW1iZXIoblsx
-XSk6MV19KX12YXIgYT17fTsic3RyaW5nIj09dHlwZW9mIHQuaz9yKCJrZXl3b3JkIix0LmspOnUodC5r
-KS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3IoZSx0LmtbZV0pfSksdC5rPWF9dC5sUj1jKHQubHx8L1x3Ky8s
-ITApLGUmJih0LmJLJiYodC5iPSJcXGIoIit0LmJLLnNwbGl0KCIgIikuam9pbigifCIpKyIpXFxiIiks
-dC5ifHwodC5iPS9cQnxcYi8pLHQuYlI9Yyh0LmIpLHQuZW5kU2FtZUFzQmVnaW4mJih0LmU9dC5iKSx0
-LmV8fHQuZVd8fCh0LmU9L1xCfFxiLyksdC5lJiYodC5lUj1jKHQuZSkpLHQudEU9cyh0LmUpfHwiIix0
-LmVXJiZlLnRFJiYodC50RSs9KHQuZT8ifCI6IiIpK2UudEUpKSx0LmkmJih0LmlSPWModC5pKSksbnVs
-bD09dC5yJiYodC5yPTEpLHQuY3x8KHQuYz1bXSksdC5jPUFycmF5LnByb3RvdHlwZS5jb25jYXQuYXBw
-bHkoW10sdC5jLm1hcChmdW5jdGlvbihlKXtyZXR1cm4gZnVuY3Rpb24obil7cmV0dXJuIG4udiYmIW4u
-Y2FjaGVkX3ZhcmlhbnRzJiYobi5jYWNoZWRfdmFyaWFudHM9bi52Lm1hcChmdW5jdGlvbihlKXtyZXR1
-cm4gZyhuLHt2Om51bGx9LGUpfSkpLG4uY2FjaGVkX3ZhcmlhbnRzfHxuLmVXJiZbZyhuKV18fFtuXX0o
-InNlbGYiPT09ZT90OmUpfSkpLHQuYy5mb3JFYWNoKGZ1bmN0aW9uKGUpe24oZSx0KX0pLHQuc3RhcnRz
-JiZuKHQuc3RhcnRzLGUpO3ZhciBpPXQuYy5tYXAoZnVuY3Rpb24oZSl7cmV0dXJuIGUuYks/IlxcLj8o
-PzoiK2UuYisiKVxcLj8iOmUuYn0pLmNvbmNhdChbdC50RSx0LmldKS5tYXAocykuZmlsdGVyKEJvb2xl
-YW4pO3QudD1pLmxlbmd0aD9jKGZ1bmN0aW9uKGUsbil7Zm9yKHZhciB0PS9cWyg/OlteXFxcXV18XFwu
-KSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixpPTA7aTxlLmxlbmd0aDtpKysp
-e3ZhciBvPXIsYz1zKGVbaV0pO2ZvcigwPGkmJihhKz1uKTswPGMubGVuZ3RoOyl7dmFyIHU9dC5leGVj
-KGMpO2lmKG51bGw9PXUpe2ErPWM7YnJlYWt9YSs9Yy5zdWJzdHJpbmcoMCx1LmluZGV4KSxjPWMuc3Vi
-c3RyaW5nKHUuaW5kZXgrdVswXS5sZW5ndGgpLCJcXCI9PXVbMF1bMF0mJnVbMV0/YSs9IlxcIitTdHJp
-bmcoTnVtYmVyKHVbMV0pK28pOihhKz11WzBdLCIoIj09dVswXSYmcisrKX19cmV0dXJuIGF9KGksInwi
-KSwhMCk6e2V4ZWM6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH19fX0obyl9ZnVuY3Rpb24gQyhlLG4saSx0
-KXtmdW5jdGlvbiBjKGUsbix0LHIpe3ZhciBhPSc8c3BhbiBjbGFzcz0iJysocj8iIjpoLmNsYXNzUHJl
-Zml4KTtyZXR1cm4gZT8oYSs9ZSsnIj4nKStuKyh0PyIiOmIpOm59ZnVuY3Rpb24gbygpe0UrPW51bGwh
-PWwuc0w/ZnVuY3Rpb24oKXt2YXIgZT0ic3RyaW5nIj09dHlwZW9mIGwuc0w7aWYoZSYmIU5bbC5zTF0p
-cmV0dXJuIF8oZyk7dmFyIG49ZT9DKGwuc0wsZywhMCxmW2wuc0xdKTpPKGcsbC5zTC5sZW5ndGg/bC5z
-TDp2b2lkIDApO3JldHVybiAwPGwuciYmKFIrPW4uciksZSYmKGZbbC5zTF09bi50b3ApLGMobi5sYW5n
-dWFnZSxuLnZhbHVlLCExLCEwKX0oKTpmdW5jdGlvbigpe3ZhciBlLG4sdCxyLGEsaSxvO2lmKCFsLmsp
-cmV0dXJuIF8oZyk7Zm9yKHI9IiIsbj0wLGwubFIubGFzdEluZGV4PTAsdD1sLmxSLmV4ZWMoZyk7dDsp
-cis9XyhnLnN1YnN0cmluZyhuLHQuaW5kZXgpKSxhPWwsaT10LHZvaWQgMCxvPXMuY0k/aVswXS50b0xv
-d2VyQ2FzZSgpOmlbMF0sKGU9YS5rLmhhc093blByb3BlcnR5KG8pJiZhLmtbb10pPyhSKz1lWzFdLHIr
-PWMoZVswXSxfKHRbMF0pKSk6cis9Xyh0WzBdKSxuPWwubFIubGFzdEluZGV4LHQ9bC5sUi5leGVjKGcp
-O3JldHVybiByK18oZy5zdWJzdHIobikpfSgpLGc9IiJ9ZnVuY3Rpb24gdShlKXtFKz1lLmNOP2MoZS5j
-TiwiIiwhMCk6IiIsbD1PYmplY3QuY3JlYXRlKGUse3BhcmVudDp7dmFsdWU6bH19KX1mdW5jdGlvbiBy
-KGUsbil7aWYoZys9ZSxudWxsPT1uKXJldHVybiBvKCksMDt2YXIgdD1mdW5jdGlvbihlLG4pe3ZhciB0
-LHIsYTtmb3IodD0wLHI9bi5jLmxlbmd0aDt0PHI7dCsrKWlmKHYobi5jW3RdLmJSLGUpKXJldHVybiBu
-LmNbdF0uZW5kU2FtZUFzQmVnaW4mJihuLmNbdF0uZVI9KGE9bi5jW3RdLmJSLmV4ZWMoZSlbMF0sbmV3
-IFJlZ0V4cChhLnJlcGxhY2UoL1stXC9cXF4kKis/LigpfFtcXXt9XS9nLCJcXCQmIiksIm0iKSkpLG4u
-Y1t0XX0obixsKTtpZih0KXJldHVybiB0LnNraXA/Zys9bjoodC5lQiYmKGcrPW4pLG8oKSx0LnJCfHx0
-LmVCfHwoZz1uKSksdSh0KSx0LnJCPzA6bi5sZW5ndGg7dmFyIHI9ZnVuY3Rpb24gZShuLHQpe2lmKHYo
-bi5lUix0KSl7Zm9yKDtuLmVuZHNQYXJlbnQmJm4ucGFyZW50OyluPW4ucGFyZW50O3JldHVybiBufWlm
-KG4uZVcpcmV0dXJuIGUobi5wYXJlbnQsdCl9KGwsbik7aWYocil7dmFyIGE9bDtmb3IoYS5za2lwP2cr
-PW46KGEuckV8fGEuZUV8fChnKz1uKSxvKCksYS5lRSYmKGc9bikpO2wuY04mJihFKz1iKSxsLnNraXB8
-fGwuc0x8fChSKz1sLnIpLChsPWwucGFyZW50KSE9PXIucGFyZW50Oyk7cmV0dXJuIHIuc3RhcnRzJiYo
-ci5lbmRTYW1lQXNCZWdpbiYmKHIuc3RhcnRzLmVSPXIuZVIpLHUoci5zdGFydHMpKSxhLnJFPzA6bi5s
-ZW5ndGh9aWYoZnVuY3Rpb24oZSxuKXtyZXR1cm4haSYmdihuLmlSLGUpfShuLGwpKXRocm93IG5ldyBF
-cnJvcignSWxsZWdhbCBsZXhlbWUgIicrbisnIiBmb3IgbW9kZSAiJysobC5jTnx8Ijx1bm5hbWVkPiIp
-KyciJyk7cmV0dXJuIGcrPW4sbi5sZW5ndGh8fDF9dmFyIHM9QihlKTtpZighcyl0aHJvdyBuZXcgRXJy
-b3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTttKHMpO3ZhciBhLGw9dHx8cyxmPXt9LEU9IiI7
-Zm9yKGE9bDthIT09czthPWEucGFyZW50KWEuY04mJihFPWMoYS5jTiwiIiwhMCkrRSk7dmFyIGc9IiIs
-Uj0wO3RyeXtmb3IodmFyIGQscCxNPTA7bC50Lmxhc3RJbmRleD1NLGQ9bC50LmV4ZWMobik7KXA9cihu
-LnN1YnN0cmluZyhNLGQuaW5kZXgpLGRbMF0pLE09ZC5pbmRleCtwO2ZvcihyKG4uc3Vic3RyKE0pKSxh
-PWw7YS5wYXJlbnQ7YT1hLnBhcmVudClhLmNOJiYoRSs9Yik7cmV0dXJue3I6Uix2YWx1ZTpFLGxhbmd1
-YWdlOmUsdG9wOmx9fWNhdGNoKGUpe2lmKGUubWVzc2FnZSYmLTEhPT1lLm1lc3NhZ2UuaW5kZXhPZigi
-SWxsZWdhbCIpKXJldHVybntyOjAsdmFsdWU6XyhuKX07dGhyb3cgZX19ZnVuY3Rpb24gTyh0LGUpe2U9
-ZXx8aC5sYW5ndWFnZXN8fHUoTik7dmFyIHI9e3I6MCx2YWx1ZTpfKHQpfSxhPXI7cmV0dXJuIGUuZmls
-dGVyKEIpLmZpbHRlcihNKS5mb3JFYWNoKGZ1bmN0aW9uKGUpe3ZhciBuPUMoZSx0LCExKTtuLmxhbmd1
-YWdlPWUsbi5yPmEuciYmKGE9biksbi5yPnIuciYmKGE9cixyPW4pfSksYS5sYW5ndWFnZSYmKHIuc2Vj
-b25kX2Jlc3Q9YSkscn1mdW5jdGlvbiBkKGUpe3JldHVybiBoLnRhYlJlcGxhY2V8fGgudXNlQlI/ZS5y
-ZXBsYWNlKHQsZnVuY3Rpb24oZSxuKXtyZXR1cm4gaC51c2VCUiYmIlxuIj09PWU/Ijxicj4iOmgudGFi
-UmVwbGFjZT9uLnJlcGxhY2UoL1x0L2csaC50YWJSZXBsYWNlKToiIn0pOmV9ZnVuY3Rpb24gbyhlKXt2
-YXIgbix0LHIsYSxpLG89ZnVuY3Rpb24oZSl7dmFyIG4sdCxyLGEsaT1lLmNsYXNzTmFtZSsiICI7aWYo
-aSs9ZS5wYXJlbnROb2RlP2UucGFyZW50Tm9kZS5jbGFzc05hbWU6IiIsdD1zLmV4ZWMoaSkpcmV0dXJu
-IEIodFsxXSk/dFsxXToibm8taGlnaGxpZ2h0Ijtmb3Iobj0wLHI9KGk9aS5zcGxpdCgvXHMrLykpLmxl
-bmd0aDtuPHI7bisrKWlmKGwoYT1pW25dKXx8QihhKSlyZXR1cm4gYX0oZSk7bChvKXx8KGgudXNlQlI/
-KG49ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8xOTk5L3hodG1sIiwi
-ZGl2IikpLmlubmVySFRNTD1lLmlubmVySFRNTC5yZXBsYWNlKC9cbi9nLCIiKS5yZXBsYWNlKC88YnJb
-IFwvXSo+L2csIlxuIik6bj1lLGk9bi50ZXh0Q29udGVudCxyPW8/QyhvLGksITApOk8oaSksKHQ9Uihu
-KSkubGVuZ3RoJiYoKGE9ZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKCJodHRwOi8vd3d3LnczLm9yZy8x
-OTk5L3hodG1sIiwiZGl2IikpLmlubmVySFRNTD1yLnZhbHVlLHIudmFsdWU9ZnVuY3Rpb24oZSxuLHQp
-e3ZhciByPTAsYT0iIixpPVtdO2Z1bmN0aW9uIG8oKXtyZXR1cm4gZS5sZW5ndGgmJm4ubGVuZ3RoP2Vb
-MF0ub2Zmc2V0IT09blswXS5vZmZzZXQ/ZVswXS5vZmZzZXQ8blswXS5vZmZzZXQ/ZTpuOiJzdGFydCI9
-PT1uWzBdLmV2ZW50P2U6bjplLmxlbmd0aD9lOm59ZnVuY3Rpb24gYyhlKXthKz0iPCIrRShlKStmLm1h
-cC5jYWxsKGUuYXR0cmlidXRlcyxmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsnPSInK18o
-ZS52YWx1ZSkucmVwbGFjZSgnIicsIiZxdW90OyIpKyciJ30pLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1
-KGUpe2ErPSI8LyIrRShlKSsiPiJ9ZnVuY3Rpb24gcyhlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShl
-Lm5vZGUpfWZvcig7ZS5sZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGw9bygpO2lmKGErPV8odC5zdWJzdHJp
-bmcocixsWzBdLm9mZnNldCkpLHI9bFswXS5vZmZzZXQsbD09PWUpe2ZvcihpLnJldmVyc2UoKS5mb3JF
-YWNoKHUpO3MobC5zcGxpY2UoMCwxKVswXSksKGw9bygpKT09PWUmJmwubGVuZ3RoJiZsWzBdLm9mZnNl
-dD09PXI7KTtpLnJldmVyc2UoKS5mb3JFYWNoKGMpfWVsc2Uic3RhcnQiPT09bFswXS5ldmVudD9pLnB1
-c2gobFswXS5ub2RlKTppLnBvcCgpLHMobC5zcGxpY2UoMCwxKVswXSl9cmV0dXJuIGErXyh0LnN1YnN0
-cihyKSl9KHQsUihhKSxpKSksci52YWx1ZT1kKHIudmFsdWUpLGUuaW5uZXJIVE1MPXIudmFsdWUsZS5j
-bGFzc05hbWU9ZnVuY3Rpb24oZSxuLHQpe3ZhciByPW4/Y1tuXTp0LGE9W2UudHJpbSgpXTtyZXR1cm4g
-ZS5tYXRjaCgvXGJobGpzXGIvKXx8YS5wdXNoKCJobGpzIiksLTE9PT1lLmluZGV4T2YocikmJmEucHVz
-aChyKSxhLmpvaW4oIiAiKS50cmltKCl9KGUuY2xhc3NOYW1lLG8sci5sYW5ndWFnZSksZS5yZXN1bHQ9
-e2xhbmd1YWdlOnIubGFuZ3VhZ2UscmU6ci5yfSxyLnNlY29uZF9iZXN0JiYoZS5zZWNvbmRfYmVzdD17
-bGFuZ3VhZ2U6ci5zZWNvbmRfYmVzdC5sYW5ndWFnZSxyZTpyLnNlY29uZF9iZXN0LnJ9KSl9ZnVuY3Rp
-b24gcCgpe2lmKCFwLmNhbGxlZCl7cC5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlTZWxlY3Rv
-ckFsbCgicHJlIGNvZGUiKTtmLmZvckVhY2guY2FsbChlLG8pfX1mdW5jdGlvbiBCKGUpe3JldHVybiBl
-PShlfHwiIikudG9Mb3dlckNhc2UoKSxOW2VdfHxOW2NbZV1dfWZ1bmN0aW9uIE0oZSl7dmFyIG49Qihl
-KTtyZXR1cm4gbiYmIW4uZGlzYWJsZUF1dG9kZXRlY3R9cmV0dXJuIGEuaGlnaGxpZ2h0PUMsYS5oaWdo
-bGlnaHRBdXRvPU8sYS5maXhNYXJrdXA9ZCxhLmhpZ2hsaWdodEJsb2NrPW8sYS5jb25maWd1cmU9ZnVu
-Y3Rpb24oZSl7aD1nKGgsZSl9LGEuaW5pdEhpZ2hsaWdodGluZz1wLGEuaW5pdEhpZ2hsaWdodGluZ09u
-TG9hZD1mdW5jdGlvbigpe2FkZEV2ZW50TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLHAsITEpLGFk
-ZEV2ZW50TGlzdGVuZXIoImxvYWQiLHAsITEpfSxhLnJlZ2lzdGVyTGFuZ3VhZ2U9ZnVuY3Rpb24obixl
-KXt2YXIgdD1OW25dPWUoYSk7aSh0KSx0LmFsaWFzZXMmJnQuYWxpYXNlcy5mb3JFYWNoKGZ1bmN0aW9u
-KGUpe2NbZV09bn0pfSxhLmxpc3RMYW5ndWFnZXM9ZnVuY3Rpb24oKXtyZXR1cm4gdShOKX0sYS5nZXRM
-YW5ndWFnZT1CLGEuYXV0b0RldGVjdGlvbj1NLGEuaW5oZXJpdD1nLGEuSVI9YS5JREVOVF9SRT0iW2Et
-ekEtWl1cXHcqIixhLlVJUj1hLlVOREVSU0NPUkVfSURFTlRfUkU9IlthLXpBLVpfXVxcdyoiLGEuTlI9
-YS5OVU1CRVJfUkU9IlxcYlxcZCsoXFwuXFxkKyk/IixhLkNOUj1hLkNfTlVNQkVSX1JFPSIoLT8pKFxc
-YjBbeFhdW2EtZkEtRjAtOV0rfChcXGJcXGQrKFxcLlxcZCopP3xcXC5cXGQrKShbZUVdWy0rXT9cXGQr
-KT8pIixhLkJOUj1hLkJJTkFSWV9OVU1CRVJfUkU9IlxcYigwYlswMV0rKSIsYS5SU1I9YS5SRV9TVEFS
-VEVSU19SRT0iIXwhPXwhPT18JXwlPXwmfCYmfCY9fFxcKnxcXCo9fFxcK3xcXCs9fCx8LXwtPXwvPXwv
-fDp8O3w8PHw8PD18PD18PHw9PT18PT18PXw+Pj49fD4+PXw+PXw+Pj58Pj58PnxcXD98XFxbfFxce3xc
-XCh8XFxefFxcXj18XFx8fFxcfD18XFx8XFx8fH4iLGEuQkU9YS5CQUNLU0xBU0hfRVNDQVBFPXtiOiJc
-XFxcW1xcc1xcU10iLHI6MH0sYS5BU009YS5BUE9TX1NUUklOR19NT0RFPXtjTjoic3RyaW5nIixiOiIn
-IixlOiInIixpOiJcXG4iLGM6W2EuQkVdfSxhLlFTTT1hLlFVT1RFX1NUUklOR19NT0RFPXtjTjoic3Ry
-aW5nIixiOiciJyxlOiciJyxpOiJcXG4iLGM6W2EuQkVdfSxhLlBXTT1hLlBIUkFTQUxfV09SRFNfTU9E
-RT17YjovXGIoYXxhbnx0aGV8YXJlfEknbXxpc24ndHxkb24ndHxkb2Vzbid0fHdvbid0fGJ1dHxqdXN0
-fHNob3VsZHxwcmV0dHl8c2ltcGx5fGVub3VnaHxnb25uYXxnb2luZ3x3dGZ8c298c3VjaHx3aWxsfHlv
-dXx5b3VyfHRoZXl8bGlrZXxtb3JlKVxiL30sYS5DPWEuQ09NTUVOVD1mdW5jdGlvbihlLG4sdCl7dmFy
-IHI9YS5pbmhlcml0KHtjTjoiY29tbWVudCIsYjplLGU6bixjOltdfSx0fHx7fSk7cmV0dXJuIHIuYy5w
-dXNoKGEuUFdNKSxyLmMucHVzaCh7Y046ImRvY3RhZyIsYjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xY
-WFgpOiIscjowfSkscn0sYS5DTENNPWEuQ19MSU5FX0NPTU1FTlRfTU9ERT1hLkMoIi8vIiwiJCIpLGEu
-Q0JDTT1hLkNfQkxPQ0tfQ09NTUVOVF9NT0RFPWEuQygiL1xcKiIsIlxcKi8iKSxhLkhDTT1hLkhBU0hf
-Q09NTUVOVF9NT0RFPWEuQygiIyIsIiQiKSxhLk5NPWEuTlVNQkVSX01PREU9e2NOOiJudW1iZXIiLGI6
-YS5OUixyOjB9LGEuQ05NPWEuQ19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLkNOUixyOjB9LGEu
-Qk5NPWEuQklOQVJZX05VTUJFUl9NT0RFPXtjTjoibnVtYmVyIixiOmEuQk5SLHI6MH0sYS5DU1NOTT1h
-LkNTU19OVU1CRVJfTU9ERT17Y046Im51bWJlciIsYjphLk5SKyIoJXxlbXxleHxjaHxyZW18dnd8dmh8
-dm1pbnx2bWF4fGNtfG1tfGlufHB0fHBjfHB4fGRlZ3xncmFkfHJhZHx0dXJufHN8bXN8SHp8a0h6fGRw
-aXxkcGNtfGRwcHgpPyIscjowfSxhLlJNPWEuUkVHRVhQX01PREU9e2NOOiJyZWdleHAiLGI6L1wvLyxl
-Oi9cL1tnaW11eV0qLyxpOi9cbi8sYzpbYS5CRSx7YjovXFsvLGU6L1xdLyxyOjAsYzpbYS5CRV19XX0s
-YS5UTT1hLlRJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLklSLHI6MH0sYS5VVE09YS5VTkRFUlNDT1JF
-X1RJVExFX01PREU9e2NOOiJ0aXRsZSIsYjphLlVJUixyOjB9LGEuTUVUSE9EX0dVQVJEPXtiOiJcXC5c
-XHMqIithLlVJUixyOjB9LGF9KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24ocyl7
-dmFyIGU9e2VXOiEwLGk6LzwvLHI6MCxjOlt7Y046ImF0dHIiLGI6IltBLVphLXowLTlcXC5fOi1dKyIs
-cjowfSx7YjovPVxzKi8scjowLGM6W3tjTjoic3RyaW5nIixlbmRzUGFyZW50OiEwLHY6W3tiOi8iLyxl
-Oi8iL30se2I6LycvLGU6LycvfSx7YjovW15ccyInPTw+YF0rL31dfV19XX07cmV0dXJue2FsaWFzZXM6
-WyJodG1sIiwieGh0bWwiLCJyc3MiLCJhdG9tIiwieGpiIiwieHNkIiwieHNsIiwicGxpc3QiLCJ3c2Yi
-XSxjSTohMCxjOlt7Y046Im1ldGEiLGI6IjwhRE9DVFlQRSIsZToiPiIscjoxMCxjOlt7YjoiXFxbIixl
-OiJcXF0ifV19LHMuQygiXHgzYyEtLSIsIi0tXHgzZSIse3I6MTB9KSx7YjoiPFxcIVxcW0NEQVRBXFxb
-IixlOiJcXF1cXF0+IixyOjEwfSx7Y046Im1ldGEiLGI6LzxcP3htbC8sZTovXD8+LyxyOjEwfSx7Yjov
-PFw/KHBocCk/LyxlOi9cPz4vLHNMOiJwaHAiLGM6W3tiOiIvXFwqIixlOiJcXCovIixza2lwOiEwfSx7
-YjonYiInLGU6JyInLHNraXA6ITB9LHtiOiJiJyIsZToiJyIsc2tpcDohMH0scy5pbmhlcml0KHMuQVNN
-LHtpOm51bGwsY046bnVsbCxjOm51bGwsc2tpcDohMH0pLHMuaW5oZXJpdChzLlFTTSx7aTpudWxsLGNO
-Om51bGwsYzpudWxsLHNraXA6ITB9KV19LHtjTjoidGFnIixiOiI8c3R5bGUoPz1cXHN8PnwkKSIsZToi
-PiIsazp7bmFtZToic3R5bGUifSxjOltlXSxzdGFydHM6e2U6Ijwvc3R5bGU+IixyRTohMCxzTDpbImNz
-cyIsInhtbCJdfX0se2NOOiJ0YWciLGI6IjxzY3JpcHQoPz1cXHN8PnwkKSIsZToiPiIsazp7bmFtZToi
-c2NyaXB0In0sYzpbZV0sc3RhcnRzOntlOiI8XC9zY3JpcHQ+IixyRTohMCxzTDpbImFjdGlvbnNjcmlw
-dCIsImphdmFzY3JpcHQiLCJoYW5kbGViYXJzIiwieG1sIiwidmJzY3JpcHQiXX19LHtjTjoidGFnIixi
-OiI8Lz8iLGU6Ii8/PiIsYzpbe2NOOiJuYW1lIixiOi9bXlwvPjxcc10rLyxyOjB9LGVdfV19fSk7aGxq
-cy5yZWdpc3Rlckxhbmd1YWdlKCJtYXJrZG93biIsZnVuY3Rpb24oZSl7cmV0dXJue2FsaWFzZXM6WyJt
-ZCIsIm1rZG93biIsIm1rZCJdLGM6W3tjTjoic2VjdGlvbiIsdjpbe2I6Il4jezEsNn0iLGU6IiQifSx7
-YjoiXi4rP1xcbls9LV17Mix9JCJ9XX0se2I6IjwiLGU6Ij4iLHNMOiJ4bWwiLHI6MH0se2NOOiJidWxs
-ZXQiLGI6Il5cXHMqKFsqKy1dfChcXGQrXFwuKSlcXHMrIn0se2NOOiJzdHJvbmciLGI6IlsqX117Mn0u
-Kz9bKl9dezJ9In0se2NOOiJlbXBoYXNpcyIsdjpbe2I6IlxcKi4rP1xcKiJ9LHtiOiJfLis/XyIscjow
-fV19LHtjTjoicXVvdGUiLGI6Il4+XFxzKyIsZToiJCJ9LHtjTjoiY29kZSIsdjpbe2I6Il5gYGB3KnMq
-JCIsZToiXmBgYHMqJCJ9LHtiOiJgLis/YCJ9LHtiOiJeKCB7NH18XHQpIixlOiIkIixyOjB9XX0se2I6
-Il5bLVxcKl17Myx9IixlOiIkIn0se2I6IlxcWy4rP1xcXVtcXChcXFtdLio/W1xcKVxcXV0iLHJCOiEw
-LGM6W3tjTjoic3RyaW5nIixiOiJcXFsiLGU6IlxcXSIsZUI6ITAsckU6ITAscjowfSx7Y046Imxpbmsi
-LGI6IlxcXVxcKCIsZToiXFwpIixlQjohMCxlRTohMH0se2NOOiJzeW1ib2wiLGI6IlxcXVxcWyIsZToi
-XFxdIixlQjohMCxlRTohMH1dLHI6MTB9LHtiOi9eXFtbXlxuXStcXTovLHJCOiEwLGM6W3tjTjoic3lt
-Ym9sIixiOi9cWy8sZTovXF0vLGVCOiEwLGVFOiEwfSx7Y046ImxpbmsiLGI6LzpccyovLGU6LyQvLGVC
-OiEwfV19XX19KTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoImRhcnQiLGZ1bmN0aW9uKGUpe3ZhciB0PXtj
-Tjoic3Vic3QiLHY6W3tiOiJcXCRbQS1aYS16MC05X10rIn1dfSxyPXtjTjoic3Vic3QiLHY6W3tiOiJc
-XCR7IixlOiJ9In1dLGs6InRydWUgZmFsc2UgbnVsbCB0aGlzIGlzIG5ldyBzdXBlciJ9LG49e2NOOiJz
-dHJpbmciLHY6W3tiOiJyJycnIixlOiInJycifSx7YjonciIiIicsZTonIiIiJ30se2I6InInIixlOiIn
-IixpOiJcXG4ifSx7YjonciInLGU6JyInLGk6IlxcbiJ9LHtiOiInJyciLGU6IicnJyIsYzpbZS5CRSx0
-LHJdfSx7YjonIiIiJyxlOiciIiInLGM6W2UuQkUsdCxyXX0se2I6IiciLGU6IiciLGk6IlxcbiIsYzpb
-ZS5CRSx0LHJdfSx7YjonIicsZTonIicsaToiXFxuIixjOltlLkJFLHQscl19XX07ci5jPVtlLkNOTSxu
-XTtyZXR1cm57azp7a2V5d29yZDoiYXNzZXJ0IGFzeW5jIGF3YWl0IGJyZWFrIGNhc2UgY2F0Y2ggY2xh
-c3MgY29uc3QgY29udGludWUgZGVmYXVsdCBkbyBlbHNlIGVudW0gZXh0ZW5kcyBmYWxzZSBmaW5hbCBm
-aW5hbGx5IGZvciBpZiBpbiBpcyBuZXcgbnVsbCByZXRocm93IHJldHVybiBzdXBlciBzd2l0Y2ggc3lu
-YyB0aGlzIHRocm93IHRydWUgdHJ5IHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQgYWJzdHJhY3QgYXMg
-ZHluYW1pYyBleHBvcnQgZXh0ZXJuYWwgZmFjdG9yeSBnZXQgaW1wbGVtZW50cyBpbXBvcnQgbGlicmFy
-eSBvcGVyYXRvciBwYXJ0IHNldCBzdGF0aWMgdHlwZWRlZiIsYnVpbHRfaW46InByaW50IENvbXBhcmFi
-bGUgRGF0ZVRpbWUgRHVyYXRpb24gRnVuY3Rpb24gSXRlcmFibGUgSXRlcmF0b3IgTGlzdCBNYXAgTWF0
-Y2ggTnVsbCBPYmplY3QgUGF0dGVybiBSZWdFeHAgU2V0IFN0b3B3YXRjaCBTdHJpbmcgU3RyaW5nQnVm
-ZmVyIFN0cmluZ1NpbmsgU3ltYm9sIFR5cGUgVXJpIGJvb2wgZG91YmxlIGludCBudW0gZG9jdW1lbnQg
-d2luZG93IHF1ZXJ5U2VsZWN0b3IgcXVlcnlTZWxlY3RvckFsbCBFbGVtZW50IEVsZW1lbnRMaXN0In0s
-YzpbbixlLkMoIi9cXCpcXCoiLCJcXCovIix7c0w6Im1hcmtkb3duIn0pLGUuQygiLy8vIiwiJCIse3NM
-OiJtYXJrZG93biJ9KSxlLkNMQ00sZS5DQkNNLHtjTjoiY2xhc3MiLGJLOiJjbGFzcyBpbnRlcmZhY2Ui
-LGU6InsiLGVFOiEwLGM6W3tiSzoiZXh0ZW5kcyBpbXBsZW1lbnRzIn0sZS5VVE1dfSxlLkNOTSx7Y046
-Im1ldGEiLGI6IkBbQS1aYS16XSsifSx7YjoiPT4ifV19fSk7Cg==
+LyoKICBIaWdobGlnaHQuanMgMTAuMS4wICg3NGRlNmVhYSkKICBMaWNlbnNlOiBCU0QtMy1DbGF1c2UK
+ICBDb3B5cmlnaHQgKGMpIDIwMDYtMjAyMCwgSXZhbiBTYWdhbGFldgoqLwp2YXIgaGxqcz1mdW5jdGlv
+bigpeyJ1c2Ugc3RyaWN0IjtmdW5jdGlvbiBlKG4pe09iamVjdC5mcmVlemUobik7dmFyIHQ9ImZ1bmN0
+aW9uIj09dHlwZW9mIG47cmV0dXJuIE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKG4pLmZvckVhY2go
+KGZ1bmN0aW9uKHIpeyFPYmplY3QuaGFzT3duUHJvcGVydHkuY2FsbChuLHIpfHxudWxsPT09bltyXXx8
+Im9iamVjdCIhPXR5cGVvZiBuW3JdJiYiZnVuY3Rpb24iIT10eXBlb2YgbltyXXx8dCYmKCJjYWxsZXIi
+PT09cnx8ImNhbGxlZSI9PT1yfHwiYXJndW1lbnRzIj09PXIpfHxPYmplY3QuaXNGcm96ZW4obltyXSl8
+fGUobltyXSl9KSksbn1jbGFzcyBue2NvbnN0cnVjdG9yKGUpe3ZvaWQgMD09PWUuZGF0YSYmKGUuZGF0
+YT17fSksdGhpcy5kYXRhPWUuZGF0YX1pZ25vcmVNYXRjaCgpe3RoaXMuaWdub3JlPSEwfX1mdW5jdGlv
+biB0KGUpe3JldHVybiBlLnJlcGxhY2UoLyYvZywiJmFtcDsiKS5yZXBsYWNlKC88L2csIiZsdDsiKS5y
+ZXBsYWNlKC8+L2csIiZndDsiKS5yZXBsYWNlKC8iL2csIiZxdW90OyIpLnJlcGxhY2UoLycvZywiJiN4
+Mjc7Iil9ZnVuY3Rpb24gcihlLC4uLm4pe3ZhciB0PXt9O2Zvcihjb25zdCBuIGluIGUpdFtuXT1lW25d
+O3JldHVybiBuLmZvckVhY2goKGZ1bmN0aW9uKGUpe2Zvcihjb25zdCBuIGluIGUpdFtuXT1lW25dfSkp
+LHR9ZnVuY3Rpb24gYShlKXtyZXR1cm4gZS5ub2RlTmFtZS50b0xvd2VyQ2FzZSgpfXZhciBpPU9iamVj
+dC5mcmVlemUoe19fcHJvdG9fXzpudWxsLGVzY2FwZUhUTUw6dCxpbmhlcml0OnIsbm9kZVN0cmVhbTpm
+dW5jdGlvbihlKXt2YXIgbj1bXTtyZXR1cm4gZnVuY3Rpb24gZSh0LHIpe2Zvcih2YXIgaT10LmZpcnN0
+Q2hpbGQ7aTtpPWkubmV4dFNpYmxpbmcpMz09PWkubm9kZVR5cGU/cis9aS5ub2RlVmFsdWUubGVuZ3Ro
+OjE9PT1pLm5vZGVUeXBlJiYobi5wdXNoKHtldmVudDoic3RhcnQiLG9mZnNldDpyLG5vZGU6aX0pLHI9
+ZShpLHIpLGEoaSkubWF0Y2goL2JyfGhyfGltZ3xpbnB1dC8pfHxuLnB1c2goe2V2ZW50OiJzdG9wIixv
+ZmZzZXQ6cixub2RlOml9KSk7cmV0dXJuIHJ9KGUsMCksbn0sbWVyZ2VTdHJlYW1zOmZ1bmN0aW9uKGUs
+bixyKXt2YXIgaT0wLHM9IiIsbz1bXTtmdW5jdGlvbiBsKCl7cmV0dXJuIGUubGVuZ3RoJiZuLmxlbmd0
+aD9lWzBdLm9mZnNldCE9PW5bMF0ub2Zmc2V0P2VbMF0ub2Zmc2V0PG5bMF0ub2Zmc2V0P2U6bjoic3Rh
+cnQiPT09blswXS5ldmVudD9lOm46ZS5sZW5ndGg/ZTpufWZ1bmN0aW9uIGMoZSl7cys9IjwiK2EoZSkr
+W10ubWFwLmNhbGwoZS5hdHRyaWJ1dGVzLChmdW5jdGlvbihlKXtyZXR1cm4iICIrZS5ub2RlTmFtZSsn
+PSInK3QoZS52YWx1ZSkrJyInfSkpLmpvaW4oIiIpKyI+In1mdW5jdGlvbiB1KGUpe3MrPSI8LyIrYShl
+KSsiPiJ9ZnVuY3Rpb24gZChlKXsoInN0YXJ0Ij09PWUuZXZlbnQ/Yzp1KShlLm5vZGUpfWZvcig7ZS5s
+ZW5ndGh8fG4ubGVuZ3RoOyl7dmFyIGc9bCgpO2lmKHMrPXQoci5zdWJzdHJpbmcoaSxnWzBdLm9mZnNl
+dCkpLGk9Z1swXS5vZmZzZXQsZz09PWUpe28ucmV2ZXJzZSgpLmZvckVhY2godSk7ZG97ZChnLnNwbGlj
+ZSgwLDEpWzBdKSxnPWwoKX13aGlsZShnPT09ZSYmZy5sZW5ndGgmJmdbMF0ub2Zmc2V0PT09aSk7by5y
+ZXZlcnNlKCkuZm9yRWFjaChjKX1lbHNlInN0YXJ0Ij09PWdbMF0uZXZlbnQ/by5wdXNoKGdbMF0ubm9k
+ZSk6by5wb3AoKSxkKGcuc3BsaWNlKDAsMSlbMF0pfXJldHVybiBzK3Qoci5zdWJzdHIoaSkpfX0pO2Nv
+bnN0IHM9Ijwvc3Bhbj4iLG89ZT0+ISFlLmtpbmQ7Y2xhc3MgbHtjb25zdHJ1Y3RvcihlLG4pe3RoaXMu
+YnVmZmVyPSIiLHRoaXMuY2xhc3NQcmVmaXg9bi5jbGFzc1ByZWZpeCxlLndhbGsodGhpcyl9YWRkVGV4
+dChlKXt0aGlzLmJ1ZmZlcis9dChlKX1vcGVuTm9kZShlKXtpZighbyhlKSlyZXR1cm47bGV0IG49ZS5r
+aW5kO2Uuc3VibGFuZ3VhZ2V8fChuPWAke3RoaXMuY2xhc3NQcmVmaXh9JHtufWApLHRoaXMuc3Bhbihu
+KX1jbG9zZU5vZGUoZSl7byhlKSYmKHRoaXMuYnVmZmVyKz1zKX12YWx1ZSgpe3JldHVybiB0aGlzLmJ1
+ZmZlcn1zcGFuKGUpe3RoaXMuYnVmZmVyKz1gPHNwYW4gY2xhc3M9IiR7ZX0iPmB9fWNsYXNzIGN7Y29u
+c3RydWN0b3IoKXt0aGlzLnJvb3ROb2RlPXtjaGlsZHJlbjpbXX0sdGhpcy5zdGFjaz1bdGhpcy5yb290
+Tm9kZV19Z2V0IHRvcCgpe3JldHVybiB0aGlzLnN0YWNrW3RoaXMuc3RhY2subGVuZ3RoLTFdfWdldCBy
+b290KCl7cmV0dXJuIHRoaXMucm9vdE5vZGV9YWRkKGUpe3RoaXMudG9wLmNoaWxkcmVuLnB1c2goZSl9
+b3Blbk5vZGUoZSl7Y29uc3Qgbj17a2luZDplLGNoaWxkcmVuOltdfTt0aGlzLmFkZChuKSx0aGlzLnN0
+YWNrLnB1c2gobil9Y2xvc2VOb2RlKCl7aWYodGhpcy5zdGFjay5sZW5ndGg+MSlyZXR1cm4gdGhpcy5z
+dGFjay5wb3AoKX1jbG9zZUFsbE5vZGVzKCl7Zm9yKDt0aGlzLmNsb3NlTm9kZSgpOyk7fXRvSlNPTigp
+e3JldHVybiBKU09OLnN0cmluZ2lmeSh0aGlzLnJvb3ROb2RlLG51bGwsNCl9d2FsayhlKXtyZXR1cm4g
+dGhpcy5jb25zdHJ1Y3Rvci5fd2FsayhlLHRoaXMucm9vdE5vZGUpfXN0YXRpYyBfd2FsayhlLG4pe3Jl
+dHVybiJzdHJpbmciPT10eXBlb2Ygbj9lLmFkZFRleHQobik6bi5jaGlsZHJlbiYmKGUub3Blbk5vZGUo
+biksbi5jaGlsZHJlbi5mb3JFYWNoKG49PnRoaXMuX3dhbGsoZSxuKSksZS5jbG9zZU5vZGUobikpLGV9
+c3RhdGljIF9jb2xsYXBzZShlKXsic3RyaW5nIiE9dHlwZW9mIGUmJmUuY2hpbGRyZW4mJihlLmNoaWxk
+cmVuLmV2ZXJ5KGU9PiJzdHJpbmciPT10eXBlb2YgZSk/ZS5jaGlsZHJlbj1bZS5jaGlsZHJlbi5qb2lu
+KCIiKV06ZS5jaGlsZHJlbi5mb3JFYWNoKGU9PntjLl9jb2xsYXBzZShlKX0pKX19Y2xhc3MgdSBleHRl
+bmRzIGN7Y29uc3RydWN0b3IoZSl7c3VwZXIoKSx0aGlzLm9wdGlvbnM9ZX1hZGRLZXl3b3JkKGUsbil7
+IiIhPT1lJiYodGhpcy5vcGVuTm9kZShuKSx0aGlzLmFkZFRleHQoZSksdGhpcy5jbG9zZU5vZGUoKSl9
+YWRkVGV4dChlKXsiIiE9PWUmJnRoaXMuYWRkKGUpfWFkZFN1Ymxhbmd1YWdlKGUsbil7Y29uc3QgdD1l
+LnJvb3Q7dC5raW5kPW4sdC5zdWJsYW5ndWFnZT0hMCx0aGlzLmFkZCh0KX10b0hUTUwoKXtyZXR1cm4g
+bmV3IGwodGhpcyx0aGlzLm9wdGlvbnMpLnZhbHVlKCl9ZmluYWxpemUoKXtyZXR1cm4hMH19ZnVuY3Rp
+b24gZChlKXtyZXR1cm4gZT8ic3RyaW5nIj09dHlwZW9mIGU/ZTplLnNvdXJjZTpudWxsfWNvbnN0IGc9
+IigtPykoXFxiMFt4WF1bYS1mQS1GMC05XSt8KFxcYlxcZCsoXFwuXFxkKik/fFxcLlxcZCspKFtlRV1b
+LStdP1xcZCspPykiLGg9e2JlZ2luOiJcXFxcW1xcc1xcU10iLHJlbGV2YW5jZTowfSxmPXtjbGFzc05h
+bWU6InN0cmluZyIsYmVnaW46IiciLGVuZDoiJyIsaWxsZWdhbDoiXFxuIixjb250YWluczpbaF19LHA9
+e2NsYXNzTmFtZToic3RyaW5nIixiZWdpbjonIicsZW5kOiciJyxpbGxlZ2FsOiJcXG4iLGNvbnRhaW5z
+OltoXX0sYj17YmVnaW46L1xiKGF8YW58dGhlfGFyZXxJJ218aXNuJ3R8ZG9uJ3R8ZG9lc24ndHx3b24n
+dHxidXR8anVzdHxzaG91bGR8cHJldHR5fHNpbXBseXxlbm91Z2h8Z29ubmF8Z29pbmd8d3RmfHNvfHN1
+Y2h8d2lsbHx5b3V8eW91cnx0aGV5fGxpa2V8bW9yZSlcYi99LG09ZnVuY3Rpb24oZSxuLHQ9e30pe3Zh
+ciBhPXIoe2NsYXNzTmFtZToiY29tbWVudCIsYmVnaW46ZSxlbmQ6bixjb250YWluczpbXX0sdCk7cmV0
+dXJuIGEuY29udGFpbnMucHVzaChiKSxhLmNvbnRhaW5zLnB1c2goe2NsYXNzTmFtZToiZG9jdGFnIixi
+ZWdpbjoiKD86VE9ET3xGSVhNRXxOT1RFfEJVR3xPUFRJTUlaRXxIQUNLfFhYWCk6IixyZWxldmFuY2U6
+MH0pLGF9LHY9bSgiLy8iLCIkIikseD1tKCIvXFwqIiwiXFwqLyIpLEU9bSgiIyIsIiQiKTt2YXIgXz1P
+YmplY3QuZnJlZXplKHtfX3Byb3RvX186bnVsbCxJREVOVF9SRToiW2EtekEtWl1cXHcqIixVTkRFUlND
+T1JFX0lERU5UX1JFOiJbYS16QS1aX11cXHcqIixOVU1CRVJfUkU6IlxcYlxcZCsoXFwuXFxkKyk/IixD
+X05VTUJFUl9SRTpnLEJJTkFSWV9OVU1CRVJfUkU6IlxcYigwYlswMV0rKSIsUkVfU1RBUlRFUlNfUkU6
+IiF8IT18IT09fCV8JT18JnwmJnwmPXxcXCp8XFwqPXxcXCt8XFwrPXwsfC18LT18Lz18L3w6fDt8PDx8
+PDw9fDw9fDx8PT09fD09fD18Pj4+PXw+Pj18Pj18Pj4+fD4+fD58XFw/fFxcW3xcXHt8XFwofFxcXnxc
+XF49fFxcfHxcXHw9fFxcfFxcfHx+IixTSEVCQU5HOihlPXt9KT0+e2NvbnN0IG49L14jIVsgXSpcLy87
+cmV0dXJuIGUuYmluYXJ5JiYoZS5iZWdpbj1mdW5jdGlvbiguLi5lKXtyZXR1cm4gZS5tYXAoZT0+ZChl
+KSkuam9pbigiIil9KG4sLy4qXGIvLGUuYmluYXJ5LC9cYi4qLykpLHIoe2NsYXNzTmFtZToibWV0YSIs
+YmVnaW46bixlbmQ6LyQvLHJlbGV2YW5jZTowLCJvbjpiZWdpbiI6KGUsbik9PnswIT09ZS5pbmRleCYm
+bi5pZ25vcmVNYXRjaCgpfX0sZSl9LEJBQ0tTTEFTSF9FU0NBUEU6aCxBUE9TX1NUUklOR19NT0RFOmYs
+UVVPVEVfU1RSSU5HX01PREU6cCxQSFJBU0FMX1dPUkRTX01PREU6YixDT01NRU5UOm0sQ19MSU5FX0NP
+TU1FTlRfTU9ERTp2LENfQkxPQ0tfQ09NTUVOVF9NT0RFOngsSEFTSF9DT01NRU5UX01PREU6RSxOVU1C
+RVJfTU9ERTp7Y2xhc3NOYW1lOiJudW1iZXIiLGJlZ2luOiJcXGJcXGQrKFxcLlxcZCspPyIscmVsZXZh
+bmNlOjB9LENfTlVNQkVSX01PREU6e2NsYXNzTmFtZToibnVtYmVyIixiZWdpbjpnLHJlbGV2YW5jZTow
+fSxCSU5BUllfTlVNQkVSX01PREU6e2NsYXNzTmFtZToibnVtYmVyIixiZWdpbjoiXFxiKDBiWzAxXSsp
+IixyZWxldmFuY2U6MH0sQ1NTX05VTUJFUl9NT0RFOntjbGFzc05hbWU6Im51bWJlciIsYmVnaW46Ilxc
+YlxcZCsoXFwuXFxkKyk/KCV8ZW18ZXh8Y2h8cmVtfHZ3fHZofHZtaW58dm1heHxjbXxtbXxpbnxwdHxw
+Y3xweHxkZWd8Z3JhZHxyYWR8dHVybnxzfG1zfEh6fGtIenxkcGl8ZHBjbXxkcHB4KT8iLHJlbGV2YW5j
+ZTowfSxSRUdFWFBfTU9ERTp7YmVnaW46Lyg/PVwvW14vXG5dKlwvKS8sY29udGFpbnM6W3tjbGFzc05h
+bWU6InJlZ2V4cCIsYmVnaW46L1wvLyxlbmQ6L1wvW2dpbXV5XSovLGlsbGVnYWw6L1xuLyxjb250YWlu
+czpbaCx7YmVnaW46L1xbLyxlbmQ6L1xdLyxyZWxldmFuY2U6MCxjb250YWluczpbaF19XX1dfSxUSVRM
+RV9NT0RFOntjbGFzc05hbWU6InRpdGxlIixiZWdpbjoiW2EtekEtWl1cXHcqIixyZWxldmFuY2U6MH0s
+VU5ERVJTQ09SRV9USVRMRV9NT0RFOntjbGFzc05hbWU6InRpdGxlIixiZWdpbjoiW2EtekEtWl9dXFx3
+KiIscmVsZXZhbmNlOjB9LE1FVEhPRF9HVUFSRDp7YmVnaW46IlxcLlxccypbYS16QS1aX11cXHcqIixy
+ZWxldmFuY2U6MH0sRU5EX1NBTUVfQVNfQkVHSU46ZnVuY3Rpb24oZSl7cmV0dXJuIE9iamVjdC5hc3Np
+Z24oZSx7Im9uOmJlZ2luIjooZSxuKT0+e24uZGF0YS5fYmVnaW5NYXRjaD1lWzFdfSwib246ZW5kIjoo
+ZSxuKT0+e24uZGF0YS5fYmVnaW5NYXRjaCE9PWVbMV0mJm4uaWdub3JlTWF0Y2goKX19KX19KSxOPSJv
+ZiBhbmQgZm9yIGluIG5vdCBvciBpZiB0aGVuIi5zcGxpdCgiICIpO2Z1bmN0aW9uIHcoZSxuKXtyZXR1
+cm4gbj8rbjpmdW5jdGlvbihlKXtyZXR1cm4gTi5pbmNsdWRlcyhlLnRvTG93ZXJDYXNlKCkpfShlKT8w
+OjF9Y29uc3QgUj10LHk9cix7bm9kZVN0cmVhbTprLG1lcmdlU3RyZWFtczpPfT1pLE09U3ltYm9sKCJu
+b21hdGNoIik7cmV0dXJuIGZ1bmN0aW9uKHQpe3ZhciBhPVtdLGk9e30scz17fSxvPVtdLGw9ITAsYz0v
+KF4oPFtePl0rPnxcdHwpK3xcbikvZ20sZz0iQ291bGQgbm90IGZpbmQgdGhlIGxhbmd1YWdlICd7fScs
+IGRpZCB5b3UgZm9yZ2V0IHRvIGxvYWQvaW5jbHVkZSBhIGxhbmd1YWdlIG1vZHVsZT8iO2NvbnN0IGg9
+e2Rpc2FibGVBdXRvZGV0ZWN0OiEwLG5hbWU6IlBsYWluIHRleHQiLGNvbnRhaW5zOltdfTt2YXIgZj17
+bm9IaWdobGlnaHRSZTovXihuby0/aGlnaGxpZ2h0KSQvaSxsYW5ndWFnZURldGVjdFJlOi9cYmxhbmco
+Pzp1YWdlKT8tKFtcdy1dKylcYi9pLGNsYXNzUHJlZml4OiJobGpzLSIsdGFiUmVwbGFjZTpudWxsLHVz
+ZUJSOiExLGxhbmd1YWdlczpudWxsLF9fZW1pdHRlcjp1fTtmdW5jdGlvbiBwKGUpe3JldHVybiBmLm5v
+SGlnaGxpZ2h0UmUudGVzdChlKX1mdW5jdGlvbiBiKGUsbix0LHIpe3ZhciBhPXtjb2RlOm4sbGFuZ3Vh
+Z2U6ZX07UygiYmVmb3JlOmhpZ2hsaWdodCIsYSk7dmFyIGk9YS5yZXN1bHQ/YS5yZXN1bHQ6bShhLmxh
+bmd1YWdlLGEuY29kZSx0LHIpO3JldHVybiBpLmNvZGU9YS5jb2RlLFMoImFmdGVyOmhpZ2hsaWdodCIs
+aSksaX1mdW5jdGlvbiBtKGUsdCxhLHMpe3ZhciBvPXQ7ZnVuY3Rpb24gYyhlLG4pe3ZhciB0PUUuY2Fz
+ZV9pbnNlbnNpdGl2ZT9uWzBdLnRvTG93ZXJDYXNlKCk6blswXTtyZXR1cm4gT2JqZWN0LnByb3RvdHlw
+ZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGUua2V5d29yZHMsdCkmJmUua2V5d29yZHNbdF19ZnVuY3Rpb24g
+dSgpe251bGwhPXkuc3ViTGFuZ3VhZ2U/ZnVuY3Rpb24oKXtpZigiIiE9PUEpe3ZhciBlPW51bGw7aWYo
+InN0cmluZyI9PXR5cGVvZiB5LnN1Ykxhbmd1YWdlKXtpZighaVt5LnN1Ykxhbmd1YWdlXSlyZXR1cm4g
+dm9pZCBPLmFkZFRleHQoQSk7ZT1tKHkuc3ViTGFuZ3VhZ2UsQSwhMCxrW3kuc3ViTGFuZ3VhZ2VdKSxr
+W3kuc3ViTGFuZ3VhZ2VdPWUudG9wfWVsc2UgZT12KEEseS5zdWJMYW5ndWFnZS5sZW5ndGg/eS5zdWJM
+YW5ndWFnZTpudWxsKTt5LnJlbGV2YW5jZT4wJiYoSSs9ZS5yZWxldmFuY2UpLE8uYWRkU3VibGFuZ3Vh
+Z2UoZS5lbWl0dGVyLGUubGFuZ3VhZ2UpfX0oKTpmdW5jdGlvbigpe2lmKCF5LmtleXdvcmRzKXJldHVy
+biB2b2lkIE8uYWRkVGV4dChBKTtsZXQgZT0wO3kua2V5d29yZFBhdHRlcm5SZS5sYXN0SW5kZXg9MDts
+ZXQgbj15LmtleXdvcmRQYXR0ZXJuUmUuZXhlYyhBKSx0PSIiO2Zvcig7bjspe3QrPUEuc3Vic3RyaW5n
+KGUsbi5pbmRleCk7Y29uc3Qgcj1jKHksbik7aWYocil7Y29uc3RbZSxhXT1yO08uYWRkVGV4dCh0KSx0
+PSIiLEkrPWEsTy5hZGRLZXl3b3JkKG5bMF0sZSl9ZWxzZSB0Kz1uWzBdO2U9eS5rZXl3b3JkUGF0dGVy
+blJlLmxhc3RJbmRleCxuPXkua2V5d29yZFBhdHRlcm5SZS5leGVjKEEpfXQrPUEuc3Vic3RyKGUpLE8u
+YWRkVGV4dCh0KX0oKSxBPSIifWZ1bmN0aW9uIGgoZSl7cmV0dXJuIGUuY2xhc3NOYW1lJiZPLm9wZW5O
+b2RlKGUuY2xhc3NOYW1lKSx5PU9iamVjdC5jcmVhdGUoZSx7cGFyZW50Ont2YWx1ZTp5fX0pfWZ1bmN0
+aW9uIHAoZSl7cmV0dXJuIDA9PT15Lm1hdGNoZXIucmVnZXhJbmRleD8oQSs9ZVswXSwxKTooTD0hMCww
+KX12YXIgYj17fTtmdW5jdGlvbiB4KHQscil7dmFyIGk9ciYmclswXTtpZihBKz10LG51bGw9PWkpcmV0
+dXJuIHUoKSwwO2lmKCJiZWdpbiI9PT1iLnR5cGUmJiJlbmQiPT09ci50eXBlJiZiLmluZGV4PT09ci5p
+bmRleCYmIiI9PT1pKXtpZihBKz1vLnNsaWNlKHIuaW5kZXgsci5pbmRleCsxKSwhbCl7Y29uc3Qgbj1F
+cnJvcigiMCB3aWR0aCBtYXRjaCByZWdleCIpO3Rocm93IG4ubGFuZ3VhZ2VOYW1lPWUsbi5iYWRSdWxl
+PWIucnVsZSxufXJldHVybiAxfWlmKGI9ciwiYmVnaW4iPT09ci50eXBlKXJldHVybiBmdW5jdGlvbihl
+KXt2YXIgdD1lWzBdLHI9ZS5ydWxlO2NvbnN0IGE9bmV3IG4ociksaT1bci5fX2JlZm9yZUJlZ2luLHJb
+Im9uOmJlZ2luIl1dO2Zvcihjb25zdCBuIG9mIGkpaWYobiYmKG4oZSxhKSxhLmlnbm9yZSkpcmV0dXJu
+IHAodCk7cmV0dXJuIHImJnIuZW5kU2FtZUFzQmVnaW4mJihyLmVuZFJlPVJlZ0V4cCh0LnJlcGxhY2Uo
+L1stL1xcXiQqKz8uKCl8W1xde31dL2csIlxcJCYiKSwibSIpKSxyLnNraXA/QSs9dDooci5leGNsdWRl
+QmVnaW4mJihBKz10KSx1KCksci5yZXR1cm5CZWdpbnx8ci5leGNsdWRlQmVnaW58fChBPXQpKSxoKHIp
+LHIucmV0dXJuQmVnaW4/MDp0Lmxlbmd0aH0ocik7aWYoImlsbGVnYWwiPT09ci50eXBlJiYhYSl7Y29u
+c3QgZT1FcnJvcignSWxsZWdhbCBsZXhlbWUgIicraSsnIiBmb3IgbW9kZSAiJysoeS5jbGFzc05hbWV8
+fCI8dW5uYW1lZD4iKSsnIicpO3Rocm93IGUubW9kZT15LGV9aWYoImVuZCI9PT1yLnR5cGUpe3ZhciBz
+PWZ1bmN0aW9uKGUpe3ZhciB0PWVbMF0scj1vLnN1YnN0cihlLmluZGV4KSxhPWZ1bmN0aW9uIGUodCxy
+LGEpe2xldCBpPWZ1bmN0aW9uKGUsbil7dmFyIHQ9ZSYmZS5leGVjKG4pO3JldHVybiB0JiYwPT09dC5p
+bmRleH0odC5lbmRSZSxhKTtpZihpKXtpZih0WyJvbjplbmQiXSl7Y29uc3QgZT1uZXcgbih0KTt0WyJv
+bjplbmQiXShyLGUpLGUuaWdub3JlJiYoaT0hMSl9aWYoaSl7Zm9yKDt0LmVuZHNQYXJlbnQmJnQucGFy
+ZW50Oyl0PXQucGFyZW50O3JldHVybiB0fX1pZih0LmVuZHNXaXRoUGFyZW50KXJldHVybiBlKHQucGFy
+ZW50LHIsYSl9KHksZSxyKTtpZighYSlyZXR1cm4gTTt2YXIgaT15O2kuc2tpcD9BKz10OihpLnJldHVy
+bkVuZHx8aS5leGNsdWRlRW5kfHwoQSs9dCksdSgpLGkuZXhjbHVkZUVuZCYmKEE9dCkpO2Rve3kuY2xh
+c3NOYW1lJiZPLmNsb3NlTm9kZSgpLHkuc2tpcHx8eS5zdWJMYW5ndWFnZXx8KEkrPXkucmVsZXZhbmNl
+KSx5PXkucGFyZW50fXdoaWxlKHkhPT1hLnBhcmVudCk7cmV0dXJuIGEuc3RhcnRzJiYoYS5lbmRTYW1l
+QXNCZWdpbiYmKGEuc3RhcnRzLmVuZFJlPWEuZW5kUmUpLGgoYS5zdGFydHMpKSxpLnJldHVybkVuZD8w
+OnQubGVuZ3RofShyKTtpZihzIT09TSlyZXR1cm4gc31pZigiaWxsZWdhbCI9PT1yLnR5cGUmJiIiPT09
+aSlyZXR1cm4gMTtpZihCPjFlNSYmQj4zKnIuaW5kZXgpdGhyb3cgRXJyb3IoInBvdGVudGlhbCBpbmZp
+bml0ZSBsb29wLCB3YXkgbW9yZSBpdGVyYXRpb25zIHRoYW4gbWF0Y2hlcyIpO3JldHVybiBBKz1pLGku
+bGVuZ3RofXZhciBFPVQoZSk7aWYoIUUpdGhyb3cgY29uc29sZS5lcnJvcihnLnJlcGxhY2UoInt9Iixl
+KSksRXJyb3IoJ1Vua25vd24gbGFuZ3VhZ2U6ICInK2UrJyInKTt2YXIgXz1mdW5jdGlvbihlKXtmdW5j
+dGlvbiBuKG4sdCl7cmV0dXJuIFJlZ0V4cChkKG4pLCJtIisoZS5jYXNlX2luc2Vuc2l0aXZlPyJpIjoi
+IikrKHQ/ImciOiIiKSl9Y2xhc3MgdHtjb25zdHJ1Y3Rvcigpe3RoaXMubWF0Y2hJbmRleGVzPXt9LHRo
+aXMucmVnZXhlcz1bXSx0aGlzLm1hdGNoQXQ9MSx0aGlzLnBvc2l0aW9uPTB9YWRkUnVsZShlLG4pe24u
+cG9zaXRpb249dGhpcy5wb3NpdGlvbisrLHRoaXMubWF0Y2hJbmRleGVzW3RoaXMubWF0Y2hBdF09bix0
+aGlzLnJlZ2V4ZXMucHVzaChbbixlXSksdGhpcy5tYXRjaEF0Kz1mdW5jdGlvbihlKXtyZXR1cm4gUmVn
+RXhwKGUudG9TdHJpbmcoKSsifCIpLmV4ZWMoIiIpLmxlbmd0aC0xfShlKSsxfWNvbXBpbGUoKXswPT09
+dGhpcy5yZWdleGVzLmxlbmd0aCYmKHRoaXMuZXhlYz0oKT0+bnVsbCk7Y29uc3QgZT10aGlzLnJlZ2V4
+ZXMubWFwKGU9PmVbMV0pO3RoaXMubWF0Y2hlclJlPW4oZnVuY3Rpb24oZSxuPSJ8Iil7Zm9yKHZhciB0
+PS9cWyg/OlteXFxcXV18XFwuKSpcXXxcKFw/P3xcXChbMS05XVswLTldKil8XFwuLyxyPTAsYT0iIixp
+PTA7aTxlLmxlbmd0aDtpKyspe3ZhciBzPXIrPTEsbz1kKGVbaV0pO2ZvcihpPjAmJihhKz1uKSxhKz0i
+KCI7by5sZW5ndGg+MDspe3ZhciBsPXQuZXhlYyhvKTtpZihudWxsPT1sKXthKz1vO2JyZWFrfWErPW8u
+c3Vic3RyaW5nKDAsbC5pbmRleCksbz1vLnN1YnN0cmluZyhsLmluZGV4K2xbMF0ubGVuZ3RoKSwiXFwi
+PT09bFswXVswXSYmbFsxXT9hKz0iXFwiKygrbFsxXStzKTooYSs9bFswXSwiKCI9PT1sWzBdJiZyKysp
+fWErPSIpIn1yZXR1cm4gYX0oZSksITApLHRoaXMubGFzdEluZGV4PTB9ZXhlYyhlKXt0aGlzLm1hdGNo
+ZXJSZS5sYXN0SW5kZXg9dGhpcy5sYXN0SW5kZXg7Y29uc3Qgbj10aGlzLm1hdGNoZXJSZS5leGVjKGUp
+O2lmKCFuKXJldHVybiBudWxsO2NvbnN0IHQ9bi5maW5kSW5kZXgoKGUsbik9Pm4+MCYmdm9pZCAwIT09
+ZSkscj10aGlzLm1hdGNoSW5kZXhlc1t0XTtyZXR1cm4gbi5zcGxpY2UoMCx0KSxPYmplY3QuYXNzaWdu
+KG4scil9fWNsYXNzIGF7Y29uc3RydWN0b3IoKXt0aGlzLnJ1bGVzPVtdLHRoaXMubXVsdGlSZWdleGVz
+PVtdLHRoaXMuY291bnQ9MCx0aGlzLmxhc3RJbmRleD0wLHRoaXMucmVnZXhJbmRleD0wfWdldE1hdGNo
+ZXIoZSl7aWYodGhpcy5tdWx0aVJlZ2V4ZXNbZV0pcmV0dXJuIHRoaXMubXVsdGlSZWdleGVzW2VdO2Nv
+bnN0IG49bmV3IHQ7cmV0dXJuIHRoaXMucnVsZXMuc2xpY2UoZSkuZm9yRWFjaCgoW2UsdF0pPT5uLmFk
+ZFJ1bGUoZSx0KSksbi5jb21waWxlKCksdGhpcy5tdWx0aVJlZ2V4ZXNbZV09bixufWNvbnNpZGVyQWxs
+KCl7dGhpcy5yZWdleEluZGV4PTB9YWRkUnVsZShlLG4pe3RoaXMucnVsZXMucHVzaChbZSxuXSksImJl
+Z2luIj09PW4udHlwZSYmdGhpcy5jb3VudCsrfWV4ZWMoZSl7Y29uc3Qgbj10aGlzLmdldE1hdGNoZXIo
+dGhpcy5yZWdleEluZGV4KTtuLmxhc3RJbmRleD10aGlzLmxhc3RJbmRleDtjb25zdCB0PW4uZXhlYyhl
+KTtyZXR1cm4gdCYmKHRoaXMucmVnZXhJbmRleCs9dC5wb3NpdGlvbisxLHRoaXMucmVnZXhJbmRleD09
+PXRoaXMuY291bnQmJih0aGlzLnJlZ2V4SW5kZXg9MCkpLHR9fWZ1bmN0aW9uIGkoZSxuKXtjb25zdCB0
+PWUuaW5wdXRbZS5pbmRleC0xXSxyPWUuaW5wdXRbZS5pbmRleCtlWzBdLmxlbmd0aF07Ii4iIT09dCYm
+Ii4iIT09cnx8bi5pZ25vcmVNYXRjaCgpfWlmKGUuY29udGFpbnMmJmUuY29udGFpbnMuaW5jbHVkZXMo
+InNlbGYiKSl0aHJvdyBFcnJvcigiRVJSOiBjb250YWlucyBgc2VsZmAgaXMgbm90IHN1cHBvcnRlZCBh
+dCB0aGUgdG9wLWxldmVsIG9mIGEgbGFuZ3VhZ2UuICBTZWUgZG9jdW1lbnRhdGlvbi4iKTtyZXR1cm4g
+ZnVuY3Rpb24gdChzLG8pe2NvbnN0IGw9cztpZihzLmNvbXBpbGVkKXJldHVybiBsO3MuY29tcGlsZWQ9
+ITAscy5fX2JlZm9yZUJlZ2luPW51bGwscy5rZXl3b3Jkcz1zLmtleXdvcmRzfHxzLmJlZ2luS2V5d29y
+ZHM7bGV0IGM9bnVsbDtpZigib2JqZWN0Ij09dHlwZW9mIHMua2V5d29yZHMmJihjPXMua2V5d29yZHMu
+JHBhdHRlcm4sZGVsZXRlIHMua2V5d29yZHMuJHBhdHRlcm4pLHMua2V5d29yZHMmJihzLmtleXdvcmRz
+PWZ1bmN0aW9uKGUsbil7dmFyIHQ9e307cmV0dXJuInN0cmluZyI9PXR5cGVvZiBlP3IoImtleXdvcmQi
+LGUpOk9iamVjdC5rZXlzKGUpLmZvckVhY2goKGZ1bmN0aW9uKG4pe3IobixlW25dKX0pKSx0O2Z1bmN0
+aW9uIHIoZSxyKXtuJiYocj1yLnRvTG93ZXJDYXNlKCkpLHIuc3BsaXQoIiAiKS5mb3JFYWNoKChmdW5j
+dGlvbihuKXt2YXIgcj1uLnNwbGl0KCJ8Iik7dFtyWzBdXT1bZSx3KHJbMF0sclsxXSldfSkpfX0ocy5r
+ZXl3b3JkcyxlLmNhc2VfaW5zZW5zaXRpdmUpKSxzLmxleGVtZXMmJmMpdGhyb3cgRXJyb3IoIkVSUjog
+UHJlZmVyIGBrZXl3b3Jkcy4kcGF0dGVybmAgdG8gYG1vZGUubGV4ZW1lc2AsIEJPVEggYXJlIG5vdCBh
+bGxvd2VkLiAoc2VlIG1vZGUgcmVmZXJlbmNlKSAiKTtyZXR1cm4gbC5rZXl3b3JkUGF0dGVyblJlPW4o
+cy5sZXhlbWVzfHxjfHwvXHcrLywhMCksbyYmKHMuYmVnaW5LZXl3b3JkcyYmKHMuYmVnaW49IlxcYigi
+K3MuYmVnaW5LZXl3b3Jkcy5zcGxpdCgiICIpLmpvaW4oInwiKSsiKSg/PVxcYnxcXHMpIixzLl9fYmVm
+b3JlQmVnaW49aSkscy5iZWdpbnx8KHMuYmVnaW49L1xCfFxiLyksbC5iZWdpblJlPW4ocy5iZWdpbiks
+cy5lbmRTYW1lQXNCZWdpbiYmKHMuZW5kPXMuYmVnaW4pLHMuZW5kfHxzLmVuZHNXaXRoUGFyZW50fHwo
+cy5lbmQ9L1xCfFxiLykscy5lbmQmJihsLmVuZFJlPW4ocy5lbmQpKSxsLnRlcm1pbmF0b3JfZW5kPWQo
+cy5lbmQpfHwiIixzLmVuZHNXaXRoUGFyZW50JiZvLnRlcm1pbmF0b3JfZW5kJiYobC50ZXJtaW5hdG9y
+X2VuZCs9KHMuZW5kPyJ8IjoiIikrby50ZXJtaW5hdG9yX2VuZCkpLHMuaWxsZWdhbCYmKGwuaWxsZWdh
+bFJlPW4ocy5pbGxlZ2FsKSksdm9pZCAwPT09cy5yZWxldmFuY2UmJihzLnJlbGV2YW5jZT0xKSxzLmNv
+bnRhaW5zfHwocy5jb250YWlucz1bXSkscy5jb250YWlucz1bXS5jb25jYXQoLi4ucy5jb250YWlucy5t
+YXAoKGZ1bmN0aW9uKGUpe3JldHVybiBmdW5jdGlvbihlKXtyZXR1cm4gZS52YXJpYW50cyYmIWUuY2Fj
+aGVkX3ZhcmlhbnRzJiYoZS5jYWNoZWRfdmFyaWFudHM9ZS52YXJpYW50cy5tYXAoKGZ1bmN0aW9uKG4p
+e3JldHVybiByKGUse3ZhcmlhbnRzOm51bGx9LG4pfSkpKSxlLmNhY2hlZF92YXJpYW50cz9lLmNhY2hl
+ZF92YXJpYW50czpmdW5jdGlvbiBlKG4pe3JldHVybiEhbiYmKG4uZW5kc1dpdGhQYXJlbnR8fGUobi5z
+dGFydHMpKX0oZSk/cihlLHtzdGFydHM6ZS5zdGFydHM/cihlLnN0YXJ0cyk6bnVsbH0pOk9iamVjdC5p
+c0Zyb3plbihlKT9yKGUpOmV9KCJzZWxmIj09PWU/czplKX0pKSkscy5jb250YWlucy5mb3JFYWNoKChm
+dW5jdGlvbihlKXt0KGUsbCl9KSkscy5zdGFydHMmJnQocy5zdGFydHMsbyksbC5tYXRjaGVyPWZ1bmN0
+aW9uKGUpe2NvbnN0IG49bmV3IGE7cmV0dXJuIGUuY29udGFpbnMuZm9yRWFjaChlPT5uLmFkZFJ1bGUo
+ZS5iZWdpbix7cnVsZTplLHR5cGU6ImJlZ2luIn0pKSxlLnRlcm1pbmF0b3JfZW5kJiZuLmFkZFJ1bGUo
+ZS50ZXJtaW5hdG9yX2VuZCx7dHlwZToiZW5kIn0pLGUuaWxsZWdhbCYmbi5hZGRSdWxlKGUuaWxsZWdh
+bCx7dHlwZToiaWxsZWdhbCJ9KSxufShsKSxsfShlKX0oRSksTj0iIix5PXN8fF8saz17fSxPPW5ldyBm
+Ll9fZW1pdHRlcihmKTshZnVuY3Rpb24oKXtmb3IodmFyIGU9W10sbj15O24hPT1FO249bi5wYXJlbnQp
+bi5jbGFzc05hbWUmJmUudW5zaGlmdChuLmNsYXNzTmFtZSk7ZS5mb3JFYWNoKGU9Pk8ub3Blbk5vZGUo
+ZSkpfSgpO3ZhciBBPSIiLEk9MCxTPTAsQj0wLEw9ITE7dHJ5e2Zvcih5Lm1hdGNoZXIuY29uc2lkZXJB
+bGwoKTs7KXtCKyssTD9MPSExOih5Lm1hdGNoZXIubGFzdEluZGV4PVMseS5tYXRjaGVyLmNvbnNpZGVy
+QWxsKCkpO2NvbnN0IGU9eS5tYXRjaGVyLmV4ZWMobyk7aWYoIWUpYnJlYWs7Y29uc3Qgbj14KG8uc3Vi
+c3RyaW5nKFMsZS5pbmRleCksZSk7Uz1lLmluZGV4K259cmV0dXJuIHgoby5zdWJzdHIoUykpLE8uY2xv
+c2VBbGxOb2RlcygpLE8uZmluYWxpemUoKSxOPU8udG9IVE1MKCkse3JlbGV2YW5jZTpJLHZhbHVlOk4s
+bGFuZ3VhZ2U6ZSxpbGxlZ2FsOiExLGVtaXR0ZXI6Tyx0b3A6eX19Y2F0Y2gobil7aWYobi5tZXNzYWdl
+JiZuLm1lc3NhZ2UuaW5jbHVkZXMoIklsbGVnYWwiKSlyZXR1cm57aWxsZWdhbDohMCxpbGxlZ2FsQnk6
+e21zZzpuLm1lc3NhZ2UsY29udGV4dDpvLnNsaWNlKFMtMTAwLFMrMTAwKSxtb2RlOm4ubW9kZX0sc29m
+YXI6TixyZWxldmFuY2U6MCx2YWx1ZTpSKG8pLGVtaXR0ZXI6T307aWYobClyZXR1cm57aWxsZWdhbDoh
+MSxyZWxldmFuY2U6MCx2YWx1ZTpSKG8pLGVtaXR0ZXI6TyxsYW5ndWFnZTplLHRvcDp5LGVycm9yUmFp
+c2VkOm59O3Rocm93IG59fWZ1bmN0aW9uIHYoZSxuKXtuPW58fGYubGFuZ3VhZ2VzfHxPYmplY3Qua2V5
+cyhpKTt2YXIgdD1mdW5jdGlvbihlKXtjb25zdCBuPXtyZWxldmFuY2U6MCxlbWl0dGVyOm5ldyBmLl9f
+ZW1pdHRlcihmKSx2YWx1ZTpSKGUpLGlsbGVnYWw6ITEsdG9wOmh9O3JldHVybiBuLmVtaXR0ZXIuYWRk
+VGV4dChlKSxufShlKSxyPXQ7cmV0dXJuIG4uZmlsdGVyKFQpLmZpbHRlcihJKS5mb3JFYWNoKChmdW5j
+dGlvbihuKXt2YXIgYT1tKG4sZSwhMSk7YS5sYW5ndWFnZT1uLGEucmVsZXZhbmNlPnIucmVsZXZhbmNl
+JiYocj1hKSxhLnJlbGV2YW5jZT50LnJlbGV2YW5jZSYmKHI9dCx0PWEpfSkpLHIubGFuZ3VhZ2UmJih0
+LnNlY29uZF9iZXN0PXIpLHR9ZnVuY3Rpb24geChlKXtyZXR1cm4gZi50YWJSZXBsYWNlfHxmLnVzZUJS
+P2UucmVwbGFjZShjLGU9PiJcbiI9PT1lP2YudXNlQlI/Ijxicj4iOmU6Zi50YWJSZXBsYWNlP2UucmVw
+bGFjZSgvXHQvZyxmLnRhYlJlcGxhY2UpOmUpOmV9ZnVuY3Rpb24gRShlKXtsZXQgbj1udWxsO2NvbnN0
+IHQ9ZnVuY3Rpb24oZSl7dmFyIG49ZS5jbGFzc05hbWUrIiAiO24rPWUucGFyZW50Tm9kZT9lLnBhcmVu
+dE5vZGUuY2xhc3NOYW1lOiIiO2NvbnN0IHQ9Zi5sYW5ndWFnZURldGVjdFJlLmV4ZWMobik7aWYodCl7
+dmFyIHI9VCh0WzFdKTtyZXR1cm4gcnx8KGNvbnNvbGUud2FybihnLnJlcGxhY2UoInt9Iix0WzFdKSks
+Y29uc29sZS53YXJuKCJGYWxsaW5nIGJhY2sgdG8gbm8taGlnaGxpZ2h0IG1vZGUgZm9yIHRoaXMgYmxv
+Y2suIixlKSkscj90WzFdOiJuby1oaWdobGlnaHQifXJldHVybiBuLnNwbGl0KC9ccysvKS5maW5kKGU9
+PnAoZSl8fFQoZSkpfShlKTtpZihwKHQpKXJldHVybjtTKCJiZWZvcmU6aGlnaGxpZ2h0QmxvY2siLHti
+bG9jazplLGxhbmd1YWdlOnR9KSxmLnVzZUJSPyhuPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIp
+KS5pbm5lckhUTUw9ZS5pbm5lckhUTUwucmVwbGFjZSgvXG4vZywiIikucmVwbGFjZSgvPGJyWyAvXSo+
+L2csIlxuIik6bj1lO2NvbnN0IHI9bi50ZXh0Q29udGVudCxhPXQ/Yih0LHIsITApOnYociksaT1rKG4p
+O2lmKGkubGVuZ3RoKXtjb25zdCBlPWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoImRpdiIpO2UuaW5uZXJI
+VE1MPWEudmFsdWUsYS52YWx1ZT1PKGksayhlKSxyKX1hLnZhbHVlPXgoYS52YWx1ZSksUygiYWZ0ZXI6
+aGlnaGxpZ2h0QmxvY2siLHtibG9jazplLHJlc3VsdDphfSksZS5pbm5lckhUTUw9YS52YWx1ZSxlLmNs
+YXNzTmFtZT1mdW5jdGlvbihlLG4sdCl7dmFyIHI9bj9zW25dOnQsYT1bZS50cmltKCldO3JldHVybiBl
+Lm1hdGNoKC9cYmhsanNcYi8pfHxhLnB1c2goImhsanMiKSxlLmluY2x1ZGVzKHIpfHxhLnB1c2gociks
+YS5qb2luKCIgIikudHJpbSgpfShlLmNsYXNzTmFtZSx0LGEubGFuZ3VhZ2UpLGUucmVzdWx0PXtsYW5n
+dWFnZTphLmxhbmd1YWdlLHJlOmEucmVsZXZhbmNlLHJlbGF2YW5jZTphLnJlbGV2YW5jZX0sYS5zZWNv
+bmRfYmVzdCYmKGUuc2Vjb25kX2Jlc3Q9e2xhbmd1YWdlOmEuc2Vjb25kX2Jlc3QubGFuZ3VhZ2UscmU6
+YS5zZWNvbmRfYmVzdC5yZWxldmFuY2UscmVsYXZhbmNlOmEuc2Vjb25kX2Jlc3QucmVsZXZhbmNlfSl9
+Y29uc3QgTj0oKT0+e2lmKCFOLmNhbGxlZCl7Ti5jYWxsZWQ9ITA7dmFyIGU9ZG9jdW1lbnQucXVlcnlT
+ZWxlY3RvckFsbCgicHJlIGNvZGUiKTthLmZvckVhY2guY2FsbChlLEUpfX07ZnVuY3Rpb24gVChlKXty
+ZXR1cm4gZT0oZXx8IiIpLnRvTG93ZXJDYXNlKCksaVtlXXx8aVtzW2VdXX1mdW5jdGlvbiBBKGUse2xh
+bmd1YWdlTmFtZTpufSl7InN0cmluZyI9PXR5cGVvZiBlJiYoZT1bZV0pLGUuZm9yRWFjaChlPT57c1tl
+XT1ufSl9ZnVuY3Rpb24gSShlKXt2YXIgbj1UKGUpO3JldHVybiBuJiYhbi5kaXNhYmxlQXV0b2RldGVj
+dH1mdW5jdGlvbiBTKGUsbil7dmFyIHQ9ZTtvLmZvckVhY2goKGZ1bmN0aW9uKGUpe2VbdF0mJmVbdF0o
+bil9KSl9T2JqZWN0LmFzc2lnbih0LHtoaWdobGlnaHQ6YixoaWdobGlnaHRBdXRvOnYsZml4TWFya3Vw
+OngsaGlnaGxpZ2h0QmxvY2s6RSxjb25maWd1cmU6ZnVuY3Rpb24oZSl7Zj15KGYsZSl9LGluaXRIaWdo
+bGlnaHRpbmc6Tixpbml0SGlnaGxpZ2h0aW5nT25Mb2FkOmZ1bmN0aW9uKCl7d2luZG93LmFkZEV2ZW50
+TGlzdGVuZXIoIkRPTUNvbnRlbnRMb2FkZWQiLE4sITEpfSxyZWdpc3Rlckxhbmd1YWdlOmZ1bmN0aW9u
+KGUsbil7dmFyIHI9bnVsbDt0cnl7cj1uKHQpfWNhdGNoKG4pe2lmKGNvbnNvbGUuZXJyb3IoIkxhbmd1
+YWdlIGRlZmluaXRpb24gZm9yICd7fScgY291bGQgbm90IGJlIHJlZ2lzdGVyZWQuIi5yZXBsYWNlKCJ7
+fSIsZSkpLCFsKXRocm93IG47Y29uc29sZS5lcnJvcihuKSxyPWh9ci5uYW1lfHwoci5uYW1lPWUpLGlb
+ZV09cixyLnJhd0RlZmluaXRpb249bi5iaW5kKG51bGwsdCksci5hbGlhc2VzJiZBKHIuYWxpYXNlcyx7
+bGFuZ3VhZ2VOYW1lOmV9KX0sbGlzdExhbmd1YWdlczpmdW5jdGlvbigpe3JldHVybiBPYmplY3Qua2V5
+cyhpKX0sZ2V0TGFuZ3VhZ2U6VCxyZWdpc3RlckFsaWFzZXM6QSxyZXF1aXJlTGFuZ3VhZ2U6ZnVuY3Rp
+b24oZSl7dmFyIG49VChlKTtpZihuKXJldHVybiBuO3Rocm93IEVycm9yKCJUaGUgJ3t9JyBsYW5ndWFn
+ZSBpcyByZXF1aXJlZCwgYnV0IG5vdCBsb2FkZWQuIi5yZXBsYWNlKCJ7fSIsZSkpfSxhdXRvRGV0ZWN0
+aW9uOkksaW5oZXJpdDp5LGFkZFBsdWdpbjpmdW5jdGlvbihlKXtvLnB1c2goZSl9fSksdC5kZWJ1Z01v
+ZGU9ZnVuY3Rpb24oKXtsPSExfSx0LnNhZmVNb2RlPWZ1bmN0aW9uKCl7bD0hMH0sdC52ZXJzaW9uU3Ry
+aW5nPSIxMC4xLjAiO2Zvcihjb25zdCBuIGluIF8pIm9iamVjdCI9PXR5cGVvZiBfW25dJiZlKF9bbl0p
+O3JldHVybiBPYmplY3QuYXNzaWduKHQsXyksdH0oe30pfSgpOyJvYmplY3QiPT10eXBlb2YgZXhwb3J0
+cyYmInVuZGVmaW5lZCIhPXR5cGVvZiBtb2R1bGUmJihtb2R1bGUuZXhwb3J0cz1obGpzKTtobGpzLnJl
+Z2lzdGVyTGFuZ3VhZ2UoInhtbCIsZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7cmV0dXJuIGZ1bmN0aW9u
+KGUpe3ZhciBuPXtjbGFzc05hbWU6InN5bWJvbCIsYmVnaW46IiZbYS16XSs7fCYjWzAtOV0rO3wmI3hb
+YS1mMC05XSs7In0sYT17YmVnaW46IlxccyIsY29udGFpbnM6W3tjbGFzc05hbWU6Im1ldGEta2V5d29y
+ZCIsYmVnaW46IiM/W2Etel9dW2EtejEtOV8tXSsiLGlsbGVnYWw6IlxcbiJ9XX0scz1lLmluaGVyaXQo
+YSx7YmVnaW46IlxcKCIsZW5kOiJcXCkifSksdD1lLmluaGVyaXQoZS5BUE9TX1NUUklOR19NT0RFLHtj
+bGFzc05hbWU6Im1ldGEtc3RyaW5nIn0pLGk9ZS5pbmhlcml0KGUuUVVPVEVfU1RSSU5HX01PREUse2Ns
+YXNzTmFtZToibWV0YS1zdHJpbmcifSksYz17ZW5kc1dpdGhQYXJlbnQ6ITAsaWxsZWdhbDovPC8scmVs
+ZXZhbmNlOjAsY29udGFpbnM6W3tjbGFzc05hbWU6ImF0dHIiLGJlZ2luOiJbQS1aYS16MC05XFwuXzot
+XSsiLHJlbGV2YW5jZTowfSx7YmVnaW46Lz1ccyovLHJlbGV2YW5jZTowLGNvbnRhaW5zOlt7Y2xhc3NO
+YW1lOiJzdHJpbmciLGVuZHNQYXJlbnQ6ITAsdmFyaWFudHM6W3tiZWdpbjovIi8sZW5kOi8iLyxjb250
+YWluczpbbl19LHtiZWdpbjovJy8sZW5kOi8nLyxjb250YWluczpbbl19LHtiZWdpbjovW15ccyInPTw+
+YF0rL31dfV19XX07cmV0dXJue25hbWU6IkhUTUwsIFhNTCIsYWxpYXNlczpbImh0bWwiLCJ4aHRtbCIs
+InJzcyIsImF0b20iLCJ4amIiLCJ4c2QiLCJ4c2wiLCJwbGlzdCIsIndzZiIsInN2ZyJdLGNhc2VfaW5z
+ZW5zaXRpdmU6ITAsY29udGFpbnM6W3tjbGFzc05hbWU6Im1ldGEiLGJlZ2luOiI8IVthLXpdIixlbmQ6
+Ij4iLHJlbGV2YW5jZToxMCxjb250YWluczpbYSxpLHQscyx7YmVnaW46IlxcWyIsZW5kOiJcXF0iLGNv
+bnRhaW5zOlt7Y2xhc3NOYW1lOiJtZXRhIixiZWdpbjoiPCFbYS16XSIsZW5kOiI+Iixjb250YWluczpb
+YSxzLGksdF19XX1dfSxlLkNPTU1FTlQoIlx4M2MhLS0iLCItLVx4M2UiLHtyZWxldmFuY2U6MTB9KSx7
+YmVnaW46IjxcXCFcXFtDREFUQVxcWyIsZW5kOiJcXF1cXF0+IixyZWxldmFuY2U6MTB9LG4se2NsYXNz
+TmFtZToibWV0YSIsYmVnaW46LzxcP3htbC8sZW5kOi9cPz4vLHJlbGV2YW5jZToxMH0se2NsYXNzTmFt
+ZToidGFnIixiZWdpbjoiPHN0eWxlKD89XFxzfD4pIixlbmQ6Ij4iLGtleXdvcmRzOntuYW1lOiJzdHls
+ZSJ9LGNvbnRhaW5zOltjXSxzdGFydHM6e2VuZDoiPC9zdHlsZT4iLHJldHVybkVuZDohMCxzdWJMYW5n
+dWFnZTpbImNzcyIsInhtbCJdfX0se2NsYXNzTmFtZToidGFnIixiZWdpbjoiPHNjcmlwdCg/PVxcc3w+
+KSIsZW5kOiI+IixrZXl3b3Jkczp7bmFtZToic2NyaXB0In0sY29udGFpbnM6W2NdLHN0YXJ0czp7ZW5k
+OiI8XC9zY3JpcHQ+IixyZXR1cm5FbmQ6ITAsc3ViTGFuZ3VhZ2U6WyJqYXZhc2NyaXB0IiwiaGFuZGxl
+YmFycyIsInhtbCJdfX0se2NsYXNzTmFtZToidGFnIixiZWdpbjoiPC8/IixlbmQ6Ii8/PiIsY29udGFp
+bnM6W3tjbGFzc05hbWU6Im5hbWUiLGJlZ2luOi9bXlwvPjxcc10rLyxyZWxldmFuY2U6MH0sY119XX19
+fSgpKTtobGpzLnJlZ2lzdGVyTGFuZ3VhZ2UoIm1hcmtkb3duIixmdW5jdGlvbigpeyJ1c2Ugc3RyaWN0
+IjtyZXR1cm4gZnVuY3Rpb24obil7Y29uc3QgZT17YmVnaW46IjwiLGVuZDoiPiIsc3ViTGFuZ3VhZ2U6
+InhtbCIscmVsZXZhbmNlOjB9LGE9e2JlZ2luOiJcXFsuKz9cXF1bXFwoXFxbXS4qP1tcXClcXF1dIixy
+ZXR1cm5CZWdpbjohMCxjb250YWluczpbe2NsYXNzTmFtZToic3RyaW5nIixiZWdpbjoiXFxbIixlbmQ6
+IlxcXSIsZXhjbHVkZUJlZ2luOiEwLHJldHVybkVuZDohMCxyZWxldmFuY2U6MH0se2NsYXNzTmFtZToi
+bGluayIsYmVnaW46IlxcXVxcKCIsZW5kOiJcXCkiLGV4Y2x1ZGVCZWdpbjohMCxleGNsdWRlRW5kOiEw
+fSx7Y2xhc3NOYW1lOiJzeW1ib2wiLGJlZ2luOiJcXF1cXFsiLGVuZDoiXFxdIixleGNsdWRlQmVnaW46
+ITAsZXhjbHVkZUVuZDohMH1dLHJlbGV2YW5jZToxMH0saT17Y2xhc3NOYW1lOiJzdHJvbmciLGNvbnRh
+aW5zOltdLHZhcmlhbnRzOlt7YmVnaW46L197Mn0vLGVuZDovX3syfS99LHtiZWdpbjovXCp7Mn0vLGVu
+ZDovXCp7Mn0vfV19LHM9e2NsYXNzTmFtZToiZW1waGFzaXMiLGNvbnRhaW5zOltdLHZhcmlhbnRzOlt7
+YmVnaW46L1wqKD8hXCopLyxlbmQ6L1wqL30se2JlZ2luOi9fKD8hXykvLGVuZDovXy8scmVsZXZhbmNl
+OjB9XX07aS5jb250YWlucy5wdXNoKHMpLHMuY29udGFpbnMucHVzaChpKTt2YXIgYz1bZSxhXTtyZXR1
+cm4gaS5jb250YWlucz1pLmNvbnRhaW5zLmNvbmNhdChjKSxzLmNvbnRhaW5zPXMuY29udGFpbnMuY29u
+Y2F0KGMpLHtuYW1lOiJNYXJrZG93biIsYWxpYXNlczpbIm1kIiwibWtkb3duIiwibWtkIl0sY29udGFp
+bnM6W3tjbGFzc05hbWU6InNlY3Rpb24iLHZhcmlhbnRzOlt7YmVnaW46Il4jezEsNn0iLGVuZDoiJCIs
+Y29udGFpbnM6Yz1jLmNvbmNhdChpLHMpfSx7YmVnaW46Iig/PV4uKz9cXG5bPS1dezIsfSQpIixjb250
+YWluczpbe2JlZ2luOiJeWz0tXSokIn0se2JlZ2luOiJeIixlbmQ6IlxcbiIsY29udGFpbnM6Y31dfV19
+LGUse2NsYXNzTmFtZToiYnVsbGV0IixiZWdpbjoiXlsgXHRdKihbKistXXwoXFxkK1xcLikpKD89XFxz
+KykiLGVuZDoiXFxzKyIsZXhjbHVkZUVuZDohMH0saSxzLHtjbGFzc05hbWU6InF1b3RlIixiZWdpbjoi
+Xj5cXHMrIixjb250YWluczpjLGVuZDoiJCJ9LHtjbGFzc05hbWU6ImNvZGUiLHZhcmlhbnRzOlt7YmVn
+aW46IihgezMsfSkoLnxcXG4pKj9cXDFgKlsgXSoifSx7YmVnaW46Iih+ezMsfSkoLnxcXG4pKj9cXDF+
+KlsgXSoifSx7YmVnaW46ImBgYCIsZW5kOiJgYGArWyBdKiQifSx7YmVnaW46In5+fiIsZW5kOiJ+fn4r
+WyBdKiQifSx7YmVnaW46ImAuKz9gIn0se2JlZ2luOiIoPz1eKCB7NH18XFx0KSkiLGNvbnRhaW5zOlt7
+YmVnaW46Il4oIHs0fXxcXHQpIixlbmQ6IihcXG4pJCJ9XSxyZWxldmFuY2U6MH1dfSx7YmVnaW46Il5b
+LVxcKl17Myx9IixlbmQ6IiQifSxhLHtiZWdpbjovXlxbW15cbl0rXF06LyxyZXR1cm5CZWdpbjohMCxj
+b250YWluczpbe2NsYXNzTmFtZToic3ltYm9sIixiZWdpbjovXFsvLGVuZDovXF0vLGV4Y2x1ZGVCZWdp
+bjohMCxleGNsdWRlRW5kOiEwfSx7Y2xhc3NOYW1lOiJsaW5rIixiZWdpbjovOlxzKi8sZW5kOi8kLyxl
+eGNsdWRlQmVnaW46ITB9XX1dfX19KCkpO2hsanMucmVnaXN0ZXJMYW5ndWFnZSgiZGFydCIsZnVuY3Rp
+b24oKXsidXNlIHN0cmljdCI7cmV0dXJuIGZ1bmN0aW9uKGUpe2NvbnN0IG49e2NsYXNzTmFtZToic3Vi
+c3QiLHZhcmlhbnRzOlt7YmVnaW46IlxcJFtBLVphLXowLTlfXSsifV19LHQ9e2NsYXNzTmFtZToic3Vi
+c3QiLHZhcmlhbnRzOlt7YmVnaW46IlxcJHsiLGVuZDoifSJ9XSxrZXl3b3JkczoidHJ1ZSBmYWxzZSBu
+dWxsIHRoaXMgaXMgbmV3IHN1cGVyIn0sYT17Y2xhc3NOYW1lOiJzdHJpbmciLHZhcmlhbnRzOlt7YmVn
+aW46InInJyciLGVuZDoiJycnIn0se2JlZ2luOidyIiIiJyxlbmQ6JyIiIid9LHtiZWdpbjoiciciLGVu
+ZDoiJyIsaWxsZWdhbDoiXFxuIn0se2JlZ2luOidyIicsZW5kOiciJyxpbGxlZ2FsOiJcXG4ifSx7YmVn
+aW46IicnJyIsZW5kOiInJyciLGNvbnRhaW5zOltlLkJBQ0tTTEFTSF9FU0NBUEUsbix0XX0se2JlZ2lu
+OiciIiInLGVuZDonIiIiJyxjb250YWluczpbZS5CQUNLU0xBU0hfRVNDQVBFLG4sdF19LHtiZWdpbjoi
+JyIsZW5kOiInIixpbGxlZ2FsOiJcXG4iLGNvbnRhaW5zOltlLkJBQ0tTTEFTSF9FU0NBUEUsbix0XX0s
+e2JlZ2luOiciJyxlbmQ6JyInLGlsbGVnYWw6IlxcbiIsY29udGFpbnM6W2UuQkFDS1NMQVNIX0VTQ0FQ
+RSxuLHRdfV19O3QuY29udGFpbnM9W2UuQ19OVU1CRVJfTU9ERSxhXTtjb25zdCBpPVsiQ29tcGFyYWJs
+ZSIsIkRhdGVUaW1lIiwiRHVyYXRpb24iLCJGdW5jdGlvbiIsIkl0ZXJhYmxlIiwiSXRlcmF0b3IiLCJM
+aXN0IiwiTWFwIiwiTWF0Y2giLCJPYmplY3QiLCJQYXR0ZXJuIiwiUmVnRXhwIiwiU2V0IiwiU3RvcHdh
+dGNoIiwiU3RyaW5nIiwiU3RyaW5nQnVmZmVyIiwiU3RyaW5nU2luayIsIlN5bWJvbCIsIlR5cGUiLCJV
+cmkiLCJib29sIiwiZG91YmxlIiwiaW50IiwibnVtIiwiRWxlbWVudCIsIkVsZW1lbnRMaXN0Il0scj1p
+Lm1hcChlPT5gJHtlfT9gKTtyZXR1cm57bmFtZToiRGFydCIsa2V5d29yZHM6e2tleXdvcmQ6ImFic3Ry
+YWN0IGFzIGFzc2VydCBhc3luYyBhd2FpdCBicmVhayBjYXNlIGNhdGNoIGNsYXNzIGNvbnN0IGNvbnRp
+bnVlIGNvdmFyaWFudCBkZWZhdWx0IGRlZmVycmVkIGRvIGR5bmFtaWMgZWxzZSBlbnVtIGV4cG9ydCBl
+eHRlbmRzIGV4dGVuc2lvbiBleHRlcm5hbCBmYWN0b3J5IGZhbHNlIGZpbmFsIGZpbmFsbHkgZm9yIEZ1
+bmN0aW9uIGdldCBoaWRlIGlmIGltcGxlbWVudHMgaW1wb3J0IGluIGluZmVyZmFjZSBpcyBsYXRlIGxp
+YnJhcnkgbWl4aW4gbmV3IG51bGwgb24gb3BlcmF0b3IgcGFydCByZXF1aXJlZCByZXRocm93IHJldHVy
+biBzZXQgc2hvdyBzdGF0aWMgc3VwZXIgc3dpdGNoIHN5bmMgdGhpcyB0aHJvdyB0cnVlIHRyeSB0eXBl
+ZGVmIHZhciB2b2lkIHdoaWxlIHdpdGggeWllbGQiLGJ1aWx0X2luOmkuY29uY2F0KHIpLmNvbmNhdChb
+Ik5ldmVyIiwiTnVsbCIsImR5bmFtaWMiLCJwcmludCIsImRvY3VtZW50IiwicXVlcnlTZWxlY3RvciIs
+InF1ZXJ5U2VsZWN0b3JBbGwiLCJ3aW5kb3ciXSkuam9pbigiICIpLCRwYXR0ZXJuOi9bQS1aYS16XVtB
+LVphLXowLTlfXSpcPz8vfSxjb250YWluczpbYSxlLkNPTU1FTlQoIi9cXCpcXCoiLCJcXCovIix7c3Vi
+TGFuZ3VhZ2U6Im1hcmtkb3duIixyZWxldmFuY2U6MH0pLGUuQ09NTUVOVCgiLy8vK1xccyoiLCIkIix7
+Y29udGFpbnM6W3tzdWJMYW5ndWFnZToibWFya2Rvd24iLGJlZ2luOiIuIixlbmQ6IiQiLHJlbGV2YW5j
+ZTowfV19KSxlLkNfTElORV9DT01NRU5UX01PREUsZS5DX0JMT0NLX0NPTU1FTlRfTU9ERSx7Y2xhc3NO
+YW1lOiJjbGFzcyIsYmVnaW5LZXl3b3JkczoiY2xhc3MgaW50ZXJmYWNlIixlbmQ6InsiLGV4Y2x1ZGVF
+bmQ6ITAsY29udGFpbnM6W3tiZWdpbktleXdvcmRzOiJleHRlbmRzIGltcGxlbWVudHMifSxlLlVOREVS
+U0NPUkVfVElUTEVfTU9ERV19LGUuQ19OVU1CRVJfTU9ERSx7Y2xhc3NOYW1lOiJtZXRhIixiZWdpbjoi
+QFtBLVphLXpdKyJ9LHtiZWdpbjoiPT4ifV19fX0oKSk7
 ''';
 
 String _index_html;
@@ -558,12 +709,12 @@
 czpzZXRPclVwZGF0ZUxlYWZUYWdzfX0oKQpmdW5jdGlvbiBpbml0aWFsaXplRGVmZXJyZWRIdW5rKGEp
 e3g9di50eXBlcy5sZW5ndGgKYShodW5rSGVscGVycyx2LHcsJCl9ZnVuY3Rpb24gZ2V0R2xvYmFsRnJv
 bU5hbWUoYSl7Zm9yKHZhciB0PTA7dDx3Lmxlbmd0aDt0Kyspe2lmKHdbdF09PUMpY29udGludWUKaWYo
-d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17Rks6ZnVuY3Rpb24gRksoKXt9LApvbzpm
+d1t0XVthXSlyZXR1cm4gd1t0XVthXX19dmFyIEM9e30sSD17ZW86ZnVuY3Rpb24gZW8oKXt9LApvbzpm
 dW5jdGlvbihhKXt2YXIgdCxzPWFeNDgKaWYoczw9OSlyZXR1cm4gcwp0PWF8MzIKaWYoOTc8PXQmJnQ8
 PTEwMilyZXR1cm4gdC04NwpyZXR1cm4tMX0sCnFDOmZ1bmN0aW9uKGEsYixjLGQpe1AuazEoYiwic3Rh
 cnQiKQppZihjIT1udWxsKXtQLmsxKGMsImVuZCIpCmlmKGI+YylILnZoKFAuVEUoYiwwLGMsInN0YXJ0
 IixudWxsKSl9cmV0dXJuIG5ldyBILm5IKGEsYixjLGQuQygibkg8MD4iKSl9LApLMTpmdW5jdGlvbihh
-LGIsYyxkKXtpZih1Lmd3LmIoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5D
+LGIsYyxkKXtpZih1Lmd3LmMoYSkpcmV0dXJuIG5ldyBILnh5KGEsYixjLkMoIkA8MD4iKS5LcShkKS5D
 KCJ4eTwxLDI+IikpCnJldHVybiBuZXcgSC5pMShhLGIsYy5DKCJAPDA+IikuS3EoZCkuQygiaTE8MSwy
 PiIpKX0sCldwOmZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBQLmxqKCJObyBlbGVtZW50Iil9LApkVTpmdW5j
 dGlvbigpe3JldHVybiBuZXcgUC5saigiVG9vIG1hbnkgZWxlbWVudHMiKX0sCmFyOmZ1bmN0aW9uKCl7
@@ -573,137 +724,137 @@
 biBhNyhhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9MApfLmQ9bnVsbApfLiR0aT1jfSwK
 aTE6ZnVuY3Rpb24gaTEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LAp4eTpmdW5j
 dGlvbiB4eShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sCk1IOmZ1bmN0aW9uIE1I
-KGEsYixjKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApsSjpmdW5jdGlv
-biBsSihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEs
-YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKdkc6ZnVuY3Rpb24gdkcoYSxiLGMpe3Ro
+KGEsYixjKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uJHRpPWN9LApBODpmdW5jdGlv
+biBBOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy4kdGk9Y30sClU1OmZ1bmN0aW9uIFU1KGEs
+YixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKU086ZnVuY3Rpb24gU08oYSxiLGMpe3Ro
 aXMuYT1hCnRoaXMuYj1iCnRoaXMuJHRpPWN9LApTVTpmdW5jdGlvbiBTVSgpe30sClJlOmZ1bmN0aW9u
-IFJlKCl7fSwKdzI6ZnVuY3Rpb24gdzIoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sCmRj
+IFJlKCl7fSwKWEM6ZnVuY3Rpb24gWEMoKXt9LAp3djpmdW5jdGlvbiB3dihhKXt0aGlzLmE9YX0sCmRj
 OmZ1bmN0aW9uKCl7dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgdW5tb2RpZmlhYmxlIE1hcCIp
 KX0sCk5ROmZ1bmN0aW9uKGEpe3ZhciB0LHM9SC5KZyhhKQppZih0eXBlb2Ygcz09InN0cmluZyIpcmV0
 dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVybiB0fSwKd1Y6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihi
-IT1udWxsKXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmIoYSl9LApkOmZ1bmN0
+IT1udWxsKXt0PWIueAppZih0IT1udWxsKXJldHVybiB0fXJldHVybiB1LmFVLmMoYSl9LApkOmZ1bmN0
 aW9uKGEpe3ZhciB0CmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZih0eXBlb2YgYT09Im51
 bWJlciIpe2lmKGEhPT0wKXJldHVybiIiK2F9ZWxzZSBpZighMD09PWEpcmV0dXJuInRydWUiCmVsc2Ug
-aWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouQWMo
-YSkKaWYodHlwZW9mIHQhPSJzdHJpbmciKXRocm93IEguYihILkkoYSkpCnJldHVybiB0fSwKZVE6ZnVu
+aWYoITE9PT1hKXJldHVybiJmYWxzZSIKZWxzZSBpZihhPT1udWxsKXJldHVybiJudWxsIgp0PUouaihh
+KQppZih0eXBlb2YgdCE9InN0cmluZyIpdGhyb3cgSC5iKEgudEwoYSkpCnJldHVybiB0fSwKZVE6ZnVu
 Y3Rpb24oYSl7dmFyIHQ9YS4kaWRlbnRpdHlIYXNoCmlmKHQ9PW51bGwpe3Q9TWF0aC5yYW5kb20oKSow
 eDNmZmZmZmZmfDAKYS4kaWRlbnRpdHlIYXNoPXR9cmV0dXJuIHR9LApIcDpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMscixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC5JKGEpKQp0PS9e
-XHMqWystXT8oKDB4W2EtZjAtOV0rKXwoXGQrKXwoW2EtejAtOV0rKSlccyokL2kuZXhlYyhhKQppZih0
-PT1udWxsKXJldHVybiBuCmlmKDM+PXQubGVuZ3RoKXJldHVybiBILmsodCwzKQpzPUguYyh0WzNdKQpp
-ZihiPT1udWxsKXtpZihzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQppZih0WzJdIT1udWxsKXJl
-dHVybiBwYXJzZUludChhLDE2KQpyZXR1cm4gbn1pZihiPDJ8fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwy
-LDM2LCJyYWRpeCIsbikpCmlmKGI9PT0xMCYmcyE9bnVsbClyZXR1cm4gcGFyc2VJbnQoYSwxMCkKaWYo
-YjwxMHx8cz09bnVsbCl7cj1iPD0xMD80NytiOjg2K2IKcT10WzFdCmZvcihwPXEubGVuZ3RoLG89MDtv
-PHA7KytvKWlmKChDLnhCLlcocSxvKXwzMik+cilyZXR1cm4gbn1yZXR1cm4gcGFyc2VJbnQoYSxiKX0s
-CmxoOmZ1bmN0aW9uKGEpe3ZhciB0PUguSDUoYSkKcmV0dXJuIHR9LApINTpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIKaWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIEguSihILnEoYSksbnVsbCkKaWYoSi5pYShh
-KT09PUMuT2t8fHUuYWsuYihhKSl7dD1DLndiKGEpCmlmKEguQmUodCkpcmV0dXJuIHQKcz1hLmNvbnN0
-cnVjdG9yCmlmKHR5cGVvZiBzPT0iZnVuY3Rpb24iKXtyPXMubmFtZQppZih0eXBlb2Ygcj09InN0cmlu
-ZyImJkguQmUocikpcmV0dXJuIHJ9fXJldHVybiBILkooSC5xKGEpLG51bGwpfSwKQmU6ZnVuY3Rpb24o
-YSl7dmFyIHQ9YSE9PSJPYmplY3QiJiZhIT09IiIKcmV0dXJuIHR9LApNMDpmdW5jdGlvbigpe2lmKCEh
-c2VsZi5sb2NhdGlvbilyZXR1cm4gc2VsZi5sb2NhdGlvbi5ocmVmCnJldHVybiBudWxsfSwKVks6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscD1hLmxlbmd0aAppZihwPD01MDApcmV0dXJuIFN0cmluZy5mcm9t
-Q2hhckNvZGUuYXBwbHkobnVsbCxhKQpmb3IodD0iIixzPTA7czxwO3M9cil7cj1zKzUwMApxPXI8cD9y
-OnAKdCs9U3RyaW5nLmZyb21DaGFyQ29kZS5hcHBseShudWxsLGEuc2xpY2UocyxxKSl9cmV0dXJuIHR9
-LApDcTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz0w
-O3M8YS5sZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpe3I9YVtzXQppZighSC5vayhy
-KSl0aHJvdyBILmIoSC5JKHIpKQppZihyPD02NTUzNSlDLk5tLmkocSxyKQplbHNlIGlmKHI8PTExMTQx
-MTEpe0MuTm0uaShxLDU1Mjk2KyhDLmpuLndHKHItNjU1MzYsMTApJjEwMjMpKQpDLk5tLmkocSw1NjMy
-MCsociYxMDIzKSl9ZWxzZSB0aHJvdyBILmIoSC5JKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFILm9r
-KHIpKXRocm93IEguYihILkkocikpCmlmKHI8MCl0aHJvdyBILmIoSC5JKHIpKQppZihyPjY1NTM1KXJl
-dHVybiBILkNxKGEpfXJldHVybiBILlZLKGEpfSwKZnc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
-CmlmKGM8PTUwMCYmYj09PTAmJmM9PT1hLmxlbmd0aClyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZS5h
-cHBseShudWxsLGEpCmZvcih0PWIscz0iIjt0PGM7dD1yKXtyPXQrNTAwCnE9cjxjP3I6YwpzKz1TdHJp
-bmcuZnJvbUNoYXJDb2RlLmFwcGx5KG51bGwsYS5zdWJhcnJheSh0LHEpKX1yZXR1cm4gc30sCkx3OmZ1
-bmN0aW9uKGEpe3ZhciB0CmlmKDA8PWEpe2lmKGE8PTY1NTM1KXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
-b2RlKGEpCmlmKGE8PTExMTQxMTEpe3Q9YS02NTUzNgpyZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZSgo
-NTUyOTZ8Qy5qbi53Ryh0LDEwKSk+Pj4wLDU2MzIwfHQmMTAyMyl9fXRocm93IEguYihQLlRFKGEsMCwx
-MTE0MTExLG51bGwsbnVsbCkpfSwKbzI6ZnVuY3Rpb24oYSl7aWYoYS5kYXRlPT09dm9pZCAwKWEuZGF0
-ZT1uZXcgRGF0ZShhLmEpCnJldHVybiBhLmRhdGV9LAp0SjpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEp
-LmdldEZ1bGxZZWFyKCkrMApyZXR1cm4gdH0sCk5TOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0
-TW9udGgoKSsxCnJldHVybiB0fSwKakE6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXREYXRlKCkr
-MApyZXR1cm4gdH0sCklYOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0SG91cnMoKSswCnJldHVy
-biB0fSwKY2g6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRNaW51dGVzKCkrMApyZXR1cm4gdH0s
-CkpkOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0U2Vjb25kcygpKzAKcmV0dXJuIHR9LApWYTpm
-dW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbGxpc2Vjb25kcygpKzAKcmV0dXJuIHR9LAp6bzpm
-dW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPXt9CnIuYT0wCnQ9W10Kcz1bXQpyLmE9Yi5sZW5ndGgKQy5O
-bS5GVih0LGIpCnIuYj0iIgppZihjIT1udWxsJiZjLmEhPT0wKWMuSygwLG5ldyBILkNqKHIscyx0KSkK
-IiIrci5hCnJldHVybiBKLkp5KGEsbmV3IEguTEkoQy5UZSwwLHQscywwKSl9LApFazpmdW5jdGlvbihh
-LGIsYyl7dmFyIHQscyxyLHEKaWYoYiBpbnN0YW5jZW9mIEFycmF5KXQ9Yz09bnVsbHx8Yy5hPT09MApl
-bHNlIHQ9ITEKaWYodCl7cz1iCnI9cy5sZW5ndGgKaWYocj09PTApe2lmKCEhYS4kMClyZXR1cm4gYS4k
-MCgpfWVsc2UgaWYocj09PTEpe2lmKCEhYS4kMSlyZXR1cm4gYS4kMShzWzBdKX1lbHNlIGlmKHI9PT0y
-KXtpZighIWEuJDIpcmV0dXJuIGEuJDIoc1swXSxzWzFdKX1lbHNlIGlmKHI9PT0zKXtpZighIWEuJDMp
-cmV0dXJuIGEuJDMoc1swXSxzWzFdLHNbMl0pfWVsc2UgaWYocj09PTQpe2lmKCEhYS4kNClyZXR1cm4g
-YS4kNChzWzBdLHNbMV0sc1syXSxzWzNdKX1lbHNlIGlmKHI9PT01KWlmKCEhYS4kNSlyZXR1cm4gYS4k
-NShzWzBdLHNbMV0sc1syXSxzWzNdLHNbNF0pCnE9YVsiIisiJCIrcl0KaWYocSE9bnVsbClyZXR1cm4g
-cS5hcHBseShhLHMpfXJldHVybiBILkV3KGEsYixjKX0sCkV3OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
-LHIscSxwLG8sbixtLGwsaz1iIGluc3RhbmNlb2YgQXJyYXk/YjpQLkNIKGIsITAsdS56KSxqPWsubGVu
-Z3RoLGk9YS4kUgppZihqPGkpcmV0dXJuIEguem8oYSxrLGMpCnQ9YS4kRApzPXQ9PW51bGwKcj0hcz90
-KCk6bnVsbApxPUouaWEoYSkKcD1xLiRDCmlmKHR5cGVvZiBwPT0ic3RyaW5nIilwPXFbcF0KaWYocyl7
-aWYoYyE9bnVsbCYmYy5hIT09MClyZXR1cm4gSC56byhhLGssYykKaWYoaj09PWkpcmV0dXJuIHAuYXBw
-bHkoYSxrKQpyZXR1cm4gSC56byhhLGssYyl9aWYociBpbnN0YW5jZW9mIEFycmF5KXtpZihjIT1udWxs
-JiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPmkrci5sZW5ndGgpcmV0dXJuIEguem8oYSxr
-LG51bGwpCkMuTm0uRlYoayxyLnNsaWNlKGotaSkpCnJldHVybiBwLmFwcGx5KGEsayl9ZWxzZXtpZihq
-PmkpcmV0dXJuIEguem8oYSxrLGMpCm89T2JqZWN0LmtleXMocikKaWYoYz09bnVsbClmb3Iocz1vLmxl
-bmd0aCxuPTA7bjxvLmxlbmd0aDtvLmxlbmd0aD09PXN8fCgwLEgubGspKG8pLCsrbilDLk5tLmkoayxy
-W0guYyhvW25dKV0pCmVsc2V7Zm9yKHM9by5sZW5ndGgsbT0wLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3Ro
-PT09c3x8KDAsSC5saykobyksKytuKXtsPUguYyhvW25dKQppZihjLng0KGwpKXsrK20KQy5ObS5pKGss
-Yy5xKDAsbCkpfWVsc2UgQy5ObS5pKGsscltsXSl9aWYobSE9PWMuYSlyZXR1cm4gSC56byhhLGssYyl9
-cmV0dXJuIHAuYXBwbHkoYSxrKX19LApwWTpmdW5jdGlvbihhKXt0aHJvdyBILmIoSC5JKGEpKX0sCms6
-ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUouSChhKQp0aHJvdyBILmIoSC5IWShhLGIpKX0sCkhZOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscyxyPSJpbmRleCIKaWYoIUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEw
-LGIscixudWxsKQp0PUguV1koSi5IKGEpKQppZighKGI8MCkpe2lmKHR5cGVvZiB0IT09Im51bWJlciIp
-cmV0dXJuIEgucFkodCkKcz1iPj10fWVsc2Ugcz0hMAppZihzKXJldHVybiBQLnQoYixhLHIsbnVsbCx0
-KQpyZXR1cm4gUC5PNyhiLHIpfSwKYXU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSJJbnZhbGlkIHZhbHVl
-IgppZihhPmMpcmV0dXJuIG5ldyBQLmJKKDAsYywhMCxhLCJzdGFydCIsdCkKaWYoYiE9bnVsbCl7aWYo
-IUgub2soYikpcmV0dXJuIG5ldyBQLkFUKCEwLGIsImVuZCIsbnVsbCkKaWYoYjxhfHxiPmMpcmV0dXJu
-IG5ldyBQLmJKKGEsYywhMCxiLCJlbmQiLHQpfXJldHVybiBuZXcgUC5BVCghMCxiLCJlbmQiLG51bGwp
-fSwKSTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuQVQoITAsYSxudWxsLG51bGwpfSwKYjpmdW5jdGlv
-bihhKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAuTEsoKQp0PW5ldyBFcnJvcigpCnQuZGFydEV4Y2Vw
-dGlvbj1hCmlmKCJkZWZpbmVQcm9wZXJ0eSIgaW4gT2JqZWN0KXtPYmplY3QuZGVmaW5lUHJvcGVydHko
-dCwibWVzc2FnZSIse2dldDpILkp1fSkKdC5uYW1lPSIifWVsc2UgdC50b1N0cmluZz1ILkp1CnJldHVy
-biB0fSwKSnU6ZnVuY3Rpb24oKXtyZXR1cm4gSi5BYyh0aGlzLmRhcnRFeGNlcHRpb24pfSwKdmg6ZnVu
-Y3Rpb24oYSl7dGhyb3cgSC5iKGEpfSwKbGs6ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKFAuYTQoYSkpfSwK
-Y006ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvCmE9SC5lQShhLnJlcGxhY2UoU3RyaW5nKHt9KSwn
-JHJlY2VpdmVyJCcpKQp0PWEubWF0Y2goL1xcXCRbYS16QS1aXStcXFwkL2cpCmlmKHQ9PW51bGwpdD1I
-LlZNKFtdLHUucykKcz10LmluZGV4T2YoIlxcJGFyZ3VtZW50c1xcJCIpCnI9dC5pbmRleE9mKCJcXCRh
-cmd1bWVudHNFeHByXFwkIikKcT10LmluZGV4T2YoIlxcJGV4cHJcXCQiKQpwPXQuaW5kZXhPZigiXFwk
-bWV0aG9kXFwkIikKbz10LmluZGV4T2YoIlxcJHJlY2VpdmVyXFwkIikKcmV0dXJuIG5ldyBILmY5KGEu
-cmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkYXJndW1lbnRzXFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154
-XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c0V4cHJcXFxcXFwkJywnZycp
-LCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkZXhwclxcXFxcXCQnLCdn
-JyksJygoPzp4fFteeF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRtZXRob2RcXFxcXFwk
-JywnZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkcmVjZWl2ZXJc
-XFxcXFwkJywnZycpLCcoKD86eHxbXnhdKSopJykscyxyLHEscCxvKX0sClM3OmZ1bmN0aW9uKGEpe3Jl
-dHVybiBmdW5jdGlvbigkZXhwciQpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7
-JGV4cHIkLiRtZXRob2QkKCRhcmd1bWVudHNFeHByJCl9Y2F0Y2godCl7cmV0dXJuIHQubWVzc2FnZX19
-KGEpfSwKTWo6ZnVuY3Rpb24oYSl7cmV0dXJuIGZ1bmN0aW9uKCRleHByJCl7dHJ5eyRleHByJC4kbWV0
-aG9kJH1jYXRjaCh0KXtyZXR1cm4gdC5tZXNzYWdlfX0oYSl9LApJajpmdW5jdGlvbihhLGIpe3JldHVy
-biBuZXcgSC5XMChhLGI9PW51bGw/bnVsbDpiLm1ldGhvZCl9LApUMzpmdW5jdGlvbihhLGIpe3ZhciB0
-PWI9PW51bGwscz10P251bGw6Yi5tZXRob2QKcmV0dXJuIG5ldyBILmF6KGEscyx0P251bGw6Yi5yZWNl
-aXZlcil9LApSdTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGY9bnVs
-bCxlPW5ldyBILkFtKGEpCmlmKGE9PW51bGwpcmV0dXJuIGYKaWYoYSBpbnN0YW5jZW9mIEguYnEpcmV0
-dXJuIGUuJDEoYS5hKQppZih0eXBlb2YgYSE9PSJvYmplY3QiKXJldHVybiBhCmlmKCJkYXJ0RXhjZXB0
-aW9uIiBpbiBhKXJldHVybiBlLiQxKGEuZGFydEV4Y2VwdGlvbikKZWxzZSBpZighKCJtZXNzYWdlIiBp
-biBhKSlyZXR1cm4gYQp0PWEubWVzc2FnZQppZigibnVtYmVyIiBpbiBhJiZ0eXBlb2YgYS5udW1iZXI9
-PSJudW1iZXIiKXtzPWEubnVtYmVyCnI9cyY2NTUzNQppZigoQy5qbi53RyhzLDE2KSY4MTkxKT09PTEw
-KXN3aXRjaChyKXtjYXNlIDQzODpyZXR1cm4gZS4kMShILlQzKEguZCh0KSsiIChFcnJvciAiK3IrIiki
-LGYpKQpjYXNlIDQ0NTpjYXNlIDUwMDc6cmV0dXJuIGUuJDEoSC5JaihILmQodCkrIiAoRXJyb3IgIity
-KyIpIixmKSl9fWlmKGEgaW5zdGFuY2VvZiBUeXBlRXJyb3Ipe3E9JC5TbigpCnA9JC5scSgpCm89JC5O
-OSgpCm49JC5pSSgpCm09JC5VTigpCmw9JC5aaCgpCms9JC5yTigpCiQuYzMoKQpqPSQuSEsoKQppPSQu
-cjEoKQpoPXEucVModCkKaWYoaCE9bnVsbClyZXR1cm4gZS4kMShILlQzKEguYyh0KSxoKSkKZWxzZXto
-PXAucVModCkKaWYoaCE9bnVsbCl7aC5tZXRob2Q9ImNhbGwiCnJldHVybiBlLiQxKEguVDMoSC5jKHQp
-LGgpKX1lbHNle2g9by5xUyh0KQppZihoPT1udWxsKXtoPW4ucVModCkKaWYoaD09bnVsbCl7aD1tLnFT
-KHQpCmlmKGg9PW51bGwpe2g9bC5xUyh0KQppZihoPT1udWxsKXtoPWsucVModCkKaWYoaD09bnVsbCl7
-aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9ai5xUyh0KQppZihoPT1udWxsKXtoPWkucVModCkKZz1oIT1u
-dWxsfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBn
-PSEwfWVsc2UgZz0hMAppZihnKXJldHVybiBlLiQxKEguSWooSC5jKHQpLGgpKX19cmV0dXJuIGUuJDEo
-bmV3IEgudlYodHlwZW9mIHQ9PSJzdHJpbmciP3Q6IiIpKX1pZihhIGluc3RhbmNlb2YgUmFuZ2VFcnJv
-cil7aWYodHlwZW9mIHQ9PSJzdHJpbmciJiZ0LmluZGV4T2YoImNhbGwgc3RhY2siKSE9PS0xKXJldHVy
-biBuZXcgUC5LWSgpCnQ9ZnVuY3Rpb24oYil7dHJ5e3JldHVybiBTdHJpbmcoYil9Y2F0Y2goZCl7fXJl
-dHVybiBudWxsfShhKQpyZXR1cm4gZS4kMShuZXcgUC5BVCghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmci
+ciB0LHMscixxLHAsbyxuPW51bGwKaWYodHlwZW9mIGEhPSJzdHJpbmciKUgudmgoSC50TChhKSkKdD0v
+XlxzKlsrLV0/KCgweFthLWYwLTldKyl8KFxkKyl8KFthLXowLTldKykpXHMqJC9pLmV4ZWMoYSkKaWYo
+dD09bnVsbClyZXR1cm4gbgppZigzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDMpCnM9SC55KHRbM10p
+CmlmKGI9PW51bGwpe2lmKHMhPW51bGwpcmV0dXJuIHBhcnNlSW50KGEsMTApCmlmKHRbMl0hPW51bGwp
+cmV0dXJuIHBhcnNlSW50KGEsMTYpCnJldHVybiBufWlmKGI8Mnx8Yj4zNil0aHJvdyBILmIoUC5URShi
+LDIsMzYsInJhZGl4IixuKSkKaWYoYj09PTEwJiZzIT1udWxsKXJldHVybiBwYXJzZUludChhLDEwKQpp
+ZihiPDEwfHxzPT1udWxsKXtyPWI8PTEwPzQ3K2I6ODYrYgpxPXRbMV0KZm9yKHA9cS5sZW5ndGgsbz0w
+O288cDsrK28paWYoKEMueEIuVyhxLG8pfDMyKT5yKXJldHVybiBufXJldHVybiBwYXJzZUludChhLGIp
+fSwKTTpmdW5jdGlvbihhKXt2YXIgdD1ILkg1KGEpCnJldHVybiB0fSwKSDU6ZnVuY3Rpb24oYSl7dmFy
+IHQscyxyCmlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIEguZG0oSC56SyhhKSxudWxsKQppZihKLmlh
+KGEpPT09Qy5Pa3x8dS5hay5jKGEpKXt0PUMuTzQoYSkKaWYoSC5mKHQpKXJldHVybiB0CnM9YS5jb25z
+dHJ1Y3RvcgppZih0eXBlb2Ygcz09ImZ1bmN0aW9uIil7cj1zLm5hbWUKaWYodHlwZW9mIHI9PSJzdHJp
+bmciJiZILmYocikpcmV0dXJuIHJ9fXJldHVybiBILmRtKEgueksoYSksbnVsbCl9LApmOmZ1bmN0aW9u
+KGEpe3ZhciB0PWEhPT0iT2JqZWN0IiYmYSE9PSIiCnJldHVybiB0fSwKTTA6ZnVuY3Rpb24oKXtpZigh
+IXNlbGYubG9jYXRpb24pcmV0dXJuIHNlbGYubG9jYXRpb24uaHJlZgpyZXR1cm4gbnVsbH0sClZLOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9YS5sZW5ndGgKaWYocDw9NTAwKXJldHVybiBTdHJpbmcuZnJv
+bUNoYXJDb2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9IiIscz0wO3M8cDtzPXIpe3I9cys1MDAKcT1yPHA/
+cjpwCnQrPVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnNsaWNlKHMscSkpfXJldHVybiB0
+fSwKQ3E6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9SC5WTShbXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9
+MDtzPGEubGVuZ3RoO2EubGVuZ3RoPT09dHx8KDAsSC5saykoYSksKytzKXtyPWFbc10KaWYoIUgub2so
+cikpdGhyb3cgSC5iKEgudEwocikpCmlmKHI8PTY1NTM1KUMuTm0uaShxLHIpCmVsc2UgaWYocjw9MTEx
+NDExMSl7Qy5ObS5pKHEsNTUyOTYrKEMuam4ud0coci02NTUzNiwxMCkmMTAyMykpCkMuTm0uaShxLDU2
+MzIwKyhyJjEwMjMpKX1lbHNlIHRocm93IEguYihILnRMKHIpKX1yZXR1cm4gSC5WSyhxKX0sCmVUOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1hW3NdCmlmKCFI
+Lm9rKHIpKXRocm93IEguYihILnRMKHIpKQppZihyPDApdGhyb3cgSC5iKEgudEwocikpCmlmKHI+NjU1
+MzUpcmV0dXJuIEguQ3EoYSl9cmV0dXJuIEguVksoYSl9LApmdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQs
+cyxyLHEKaWYoYzw9NTAwJiZiPT09MCYmYz09PWEubGVuZ3RoKXJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlLmFwcGx5KG51bGwsYSkKZm9yKHQ9YixzPSIiO3Q8Yzt0PXIpe3I9dCs1MDAKcT1yPGM/cjpjCnMr
+PVN0cmluZy5mcm9tQ2hhckNvZGUuYXBwbHkobnVsbCxhLnN1YmFycmF5KHQscSkpfXJldHVybiBzfSwK
+THc6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoMDw9YSl7aWYoYTw9NjU1MzUpcmV0dXJuIFN0cmluZy5mcm9t
+Q2hhckNvZGUoYSkKaWYoYTw9MTExNDExMSl7dD1hLTY1NTM2CnJldHVybiBTdHJpbmcuZnJvbUNoYXJD
+b2RlKCg1NTI5NnxDLmpuLndHKHQsMTApKT4+PjAsNTYzMjB8dCYxMDIzKX19dGhyb3cgSC5iKFAuVEUo
+YSwwLDExMTQxMTEsbnVsbCxudWxsKSl9LApvMjpmdW5jdGlvbihhKXtpZihhLmRhdGU9PT12b2lkIDAp
+YS5kYXRlPW5ldyBEYXRlKGEuYSkKcmV0dXJuIGEuZGF0ZX0sCnRKOmZ1bmN0aW9uKGEpe3ZhciB0PUgu
+bzIoYSkuZ2V0RnVsbFllYXIoKSswCnJldHVybiB0fSwKTlM6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihh
+KS5nZXRNb250aCgpKzEKcmV0dXJuIHR9LApqQTpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldERh
+dGUoKSswCnJldHVybiB0fSwKSVg6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRIb3VycygpKzAK
+cmV0dXJuIHR9LApjaDpmdW5jdGlvbihhKXt2YXIgdD1ILm8yKGEpLmdldE1pbnV0ZXMoKSswCnJldHVy
+biB0fSwKSmQ6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5vMihhKS5nZXRTZWNvbmRzKCkrMApyZXR1cm4gdH0s
+Cm8xOmZ1bmN0aW9uKGEpe3ZhciB0PUgubzIoYSkuZ2V0TWlsbGlzZWNvbmRzKCkrMApyZXR1cm4gdH0s
+CnpvOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHI9e30Kci5hPTAKdD1bXQpzPVtdCnIuYT1iLmxlbmd0
+aApDLk5tLkZWKHQsYikKci5iPSIiCmlmKGMhPW51bGwmJmMuYSE9PTApYy5LKDAsbmV3IEguQ2oocixz
+LHQpKQoiIityLmEKcmV0dXJuIEouSnkoYSxuZXcgSC5MSShDLlRlLDAsdCxzLDApKX0sCkVrOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiIGluc3RhbmNlb2YgQXJyYXkpdD1jPT1udWxsfHxjLmE9
+PT0wCmVsc2UgdD0hMQppZih0KXtzPWIKcj1zLmxlbmd0aAppZihyPT09MCl7aWYoISFhLiQwKXJldHVy
+biBhLiQwKCl9ZWxzZSBpZihyPT09MSl7aWYoISFhLiQxKXJldHVybiBhLiQxKHNbMF0pfWVsc2UgaWYo
+cj09PTIpe2lmKCEhYS4kMilyZXR1cm4gYS4kMihzWzBdLHNbMV0pfWVsc2UgaWYocj09PTMpe2lmKCEh
+YS4kMylyZXR1cm4gYS4kMyhzWzBdLHNbMV0sc1syXSl9ZWxzZSBpZihyPT09NCl7aWYoISFhLiQ0KXJl
+dHVybiBhLiQ0KHNbMF0sc1sxXSxzWzJdLHNbM10pfWVsc2UgaWYocj09PTUpaWYoISFhLiQ1KXJldHVy
+biBhLiQ1KHNbMF0sc1sxXSxzWzJdLHNbM10sc1s0XSkKcT1hWyIiKyIkIityXQppZihxIT1udWxsKXJl
+dHVybiBxLmFwcGx5KGEscyl9cmV0dXJuIEguRXcoYSxiLGMpfSwKRXc6ZnVuY3Rpb24oYSxiLGMpe3Zh
+ciB0LHMscixxLHAsbyxuLG0sbCxrPWIgaW5zdGFuY2VvZiBBcnJheT9iOlAuQ0goYiwhMCx1LnopLGo9
+ay5sZW5ndGgsaT1hLiRSCmlmKGo8aSlyZXR1cm4gSC56byhhLGssYykKdD1hLiRECnM9dD09bnVsbApy
+PSFzP3QoKTpudWxsCnE9Si5pYShhKQpwPXEuJEMKaWYodHlwZW9mIHA9PSJzdHJpbmciKXA9cVtwXQpp
+ZihzKXtpZihjIT1udWxsJiZjLmEhPT0wKXJldHVybiBILnpvKGEsayxjKQppZihqPT09aSlyZXR1cm4g
+cC5hcHBseShhLGspCnJldHVybiBILnpvKGEsayxjKX1pZihyIGluc3RhbmNlb2YgQXJyYXkpe2lmKGMh
+PW51bGwmJmMuYSE9PTApcmV0dXJuIEguem8oYSxrLGMpCmlmKGo+aStyLmxlbmd0aClyZXR1cm4gSC56
+byhhLGssbnVsbCkKQy5ObS5GVihrLHIuc2xpY2Uoai1pKSkKcmV0dXJuIHAuYXBwbHkoYSxrKX1lbHNl
+e2lmKGo+aSlyZXR1cm4gSC56byhhLGssYykKbz1PYmplY3Qua2V5cyhyKQppZihjPT1udWxsKWZvcihz
+PW8ubGVuZ3RoLG49MDtuPG8ubGVuZ3RoO28ubGVuZ3RoPT09c3x8KDAsSC5saykobyksKytuKUMuTm0u
+aShrLHJbSC55KG9bbl0pXSkKZWxzZXtmb3Iocz1vLmxlbmd0aCxtPTAsbj0wO248by5sZW5ndGg7by5s
+ZW5ndGg9PT1zfHwoMCxILmxrKShvKSwrK24pe2w9SC55KG9bbl0pCmlmKGMueDQobCkpeysrbQpDLk5t
+LmkoayxjLnEoMCxsKSl9ZWxzZSBDLk5tLmkoayxyW2xdKX1pZihtIT09Yy5hKXJldHVybiBILnpvKGEs
+ayxjKX1yZXR1cm4gcC5hcHBseShhLGspfX0sCnBZOmZ1bmN0aW9uKGEpe3Rocm93IEguYihILnRMKGEp
+KX0sCk9IOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClKLkhtKGEpCnRocm93IEguYihILkhZKGEsYikp
+fSwKSFk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9ImluZGV4IgppZighSC5vayhiKSlyZXR1cm4gbmV3
+IFAudSghMCxiLHIsbnVsbCkKdD1ILlNjKEouSG0oYSkpCmlmKCEoYjwwKSl7aWYodHlwZW9mIHQhPT0i
+bnVtYmVyIilyZXR1cm4gSC5wWSh0KQpzPWI+PXR9ZWxzZSBzPSEwCmlmKHMpcmV0dXJuIFAuQ2YoYixh
+LHIsbnVsbCx0KQpyZXR1cm4gUC54KGIscil9LAphdTpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9IkludmFs
+aWQgdmFsdWUiCmlmKGE+YylyZXR1cm4gbmV3IFAuYkooMCxjLCEwLGEsInN0YXJ0Iix0KQppZihiIT1u
+dWxsKXtpZighSC5vayhiKSlyZXR1cm4gbmV3IFAudSghMCxiLCJlbmQiLG51bGwpCmlmKGI8YXx8Yj5j
+KXJldHVybiBuZXcgUC5iSihhLGMsITAsYiwiZW5kIix0KX1yZXR1cm4gbmV3IFAudSghMCxiLCJlbmQi
+LG51bGwpfSwKdEw6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnUoITAsYSxudWxsLG51bGwpfSwKYjpm
+dW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9bmV3IEVycm9yKCkKdC5kYXJ0
+RXhjZXB0aW9uPWEKaWYoImRlZmluZVByb3BlcnR5IiBpbiBPYmplY3Qpe09iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LCJtZXNzYWdlIix7Z2V0OkguaH0pCnQubmFtZT0iIn1lbHNlIHQudG9TdHJpbmc9SC5oCnJl
+dHVybiB0fSwKaDpmdW5jdGlvbigpe3JldHVybiBKLmoodGhpcy5kYXJ0RXhjZXB0aW9uKX0sCnZoOmZ1
+bmN0aW9uKGEpe3Rocm93IEguYihhKX0sCmxrOmZ1bmN0aW9uKGEpe3Rocm93IEguYihQLmE0KGEpKX0s
+CmNNOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbwphPUguZUEoYS5yZXBsYWNlKFN0cmluZyh7fSks
+JyRyZWNlaXZlciQnKSkKdD1hLm1hdGNoKC9cXFwkW2EtekEtWl0rXFxcJC9nKQppZih0PT1udWxsKXQ9
+SC5WTShbXSx1LnMpCnM9dC5pbmRleE9mKCJcXCRhcmd1bWVudHNcXCQiKQpyPXQuaW5kZXhPZigiXFwk
+YXJndW1lbnRzRXhwclxcJCIpCnE9dC5pbmRleE9mKCJcXCRleHByXFwkIikKcD10LmluZGV4T2YoIlxc
+JG1ldGhvZFxcJCIpCm89dC5pbmRleE9mKCJcXCRyZWNlaXZlclxcJCIpCnJldHVybiBuZXcgSC5mOShh
+LnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGFyZ3VtZW50c1xcXFxcXCQnLCdnJyksJygoPzp4fFte
+eF0pKiknKS5yZXBsYWNlKG5ldyBSZWdFeHAoJ1xcXFxcXCRhcmd1bWVudHNFeHByXFxcXFxcJCcsJ2cn
+KSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJGV4cHJcXFxcXFwkJywn
+ZycpLCcoKD86eHxbXnhdKSopJykucmVwbGFjZShuZXcgUmVnRXhwKCdcXFxcXFwkbWV0aG9kXFxcXFxc
+JCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLnJlcGxhY2UobmV3IFJlZ0V4cCgnXFxcXFxcJHJlY2VpdmVy
+XFxcXFxcJCcsJ2cnKSwnKCg/Onh8W154XSkqKScpLHMscixxLHAsbyl9LApTNzpmdW5jdGlvbihhKXty
+ZXR1cm4gZnVuY3Rpb24oJGV4cHIkKXt2YXIgJGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5
+eyRleHByJC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHQpe3JldHVybiB0Lm1lc3NhZ2V9
+fShhKX0sCk1qOmZ1bmN0aW9uKGEpe3JldHVybiBmdW5jdGlvbigkZXhwciQpe3RyeXskZXhwciQuJG1l
+dGhvZCR9Y2F0Y2godCl7cmV0dXJuIHQubWVzc2FnZX19KGEpfSwKSWo6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gbmV3IEguVzAoYSxiPT1udWxsP251bGw6Yi5tZXRob2QpfSwKVDM6ZnVuY3Rpb24oYSxiKXt2YXIg
+dD1iPT1udWxsLHM9dD9udWxsOmIubWV0aG9kCnJldHVybiBuZXcgSC5heihhLHMsdD9udWxsOmIucmVj
+ZWl2ZXIpfSwKUnU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmPW51
+bGwsZT1uZXcgSC5BbShhKQppZihhPT1udWxsKXJldHVybiBmCmlmKGEgaW5zdGFuY2VvZiBILmJxKXJl
+dHVybiBlLiQxKGEuYSkKaWYodHlwZW9mIGEhPT0ib2JqZWN0IilyZXR1cm4gYQppZigiZGFydEV4Y2Vw
+dGlvbiIgaW4gYSlyZXR1cm4gZS4kMShhLmRhcnRFeGNlcHRpb24pCmVsc2UgaWYoISgibWVzc2FnZSIg
+aW4gYSkpcmV0dXJuIGEKdD1hLm1lc3NhZ2UKaWYoIm51bWJlciIgaW4gYSYmdHlwZW9mIGEubnVtYmVy
+PT0ibnVtYmVyIil7cz1hLm51bWJlcgpyPXMmNjU1MzUKaWYoKEMuam4ud0cocywxNikmODE5MSk9PT0x
+MClzd2l0Y2gocil7Y2FzZSA0Mzg6cmV0dXJuIGUuJDEoSC5UMyhILmQodCkrIiAoRXJyb3IgIityKyIp
+IixmKSkKY2FzZSA0NDU6Y2FzZSA1MDA3OnJldHVybiBlLiQxKEguSWooSC5kKHQpKyIgKEVycm9yICIr
+cisiKSIsZikpfX1pZihhIGluc3RhbmNlb2YgVHlwZUVycm9yKXtxPSQuU24oKQpwPSQubHEoKQpvPSQu
+TjkoKQpuPSQuaUkoKQptPSQuS2YoKQpsPSQuWmgoKQprPSQuck4oKQokLmMzKCkKaj0kLkhLKCkKaT0k
+LnIxKCkKaD1xLnFTKHQpCmlmKGghPW51bGwpcmV0dXJuIGUuJDEoSC5UMyhILnkodCksaCkpCmVsc2V7
+aD1wLnFTKHQpCmlmKGghPW51bGwpe2gubWV0aG9kPSJjYWxsIgpyZXR1cm4gZS4kMShILlQzKEgueSh0
+KSxoKSl9ZWxzZXtoPW8ucVModCkKaWYoaD09bnVsbCl7aD1uLnFTKHQpCmlmKGg9PW51bGwpe2g9bS5x
+Uyh0KQppZihoPT1udWxsKXtoPWwucVModCkKaWYoaD09bnVsbCl7aD1rLnFTKHQpCmlmKGg9PW51bGwp
+e2g9bi5xUyh0KQppZihoPT1udWxsKXtoPWoucVModCkKaWYoaD09bnVsbCl7aD1pLnFTKHQpCmc9aCE9
+bnVsbH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2UgZz0hMH1lbHNlIGc9ITB9ZWxzZSBnPSEwfWVsc2Ug
+Zz0hMH1lbHNlIGc9ITAKaWYoZylyZXR1cm4gZS4kMShILklqKEgueSh0KSxoKSl9fXJldHVybiBlLiQx
+KG5ldyBILnZWKHR5cGVvZiB0PT0ic3RyaW5nIj90OiIiKSl9aWYoYSBpbnN0YW5jZW9mIFJhbmdlRXJy
+b3Ipe2lmKHR5cGVvZiB0PT0ic3RyaW5nIiYmdC5pbmRleE9mKCJjYWxsIHN0YWNrIikhPT0tMSlyZXR1
+cm4gbmV3IFAuS1koKQp0PWZ1bmN0aW9uKGIpe3RyeXtyZXR1cm4gU3RyaW5nKGIpfWNhdGNoKGQpe31y
+ZXR1cm4gbnVsbH0oYSkKcmV0dXJuIGUuJDEobmV3IFAudSghMSxmLGYsdHlwZW9mIHQ9PSJzdHJpbmci
 P3QucmVwbGFjZSgvXlJhbmdlRXJyb3I6XHMqLywiIik6dCkpfWlmKHR5cGVvZiBJbnRlcm5hbEVycm9y
 PT0iZnVuY3Rpb24iJiZhIGluc3RhbmNlb2YgSW50ZXJuYWxFcnJvcilpZih0eXBlb2YgdD09InN0cmlu
 ZyImJnQ9PT0idG9vIG11Y2ggcmVjdXJzaW9uIilyZXR1cm4gbmV3IFAuS1koKQpyZXR1cm4gYX0sCnRz
@@ -711,7 +862,7 @@
 bClyZXR1cm4gbmV3IEguWE8oYSkKdD1hLiRjYWNoZWRUcmFjZQppZih0IT1udWxsKXJldHVybiB0CnJl
 dHVybiBhLiRjYWNoZWRUcmFjZT1uZXcgSC5YTyhhKX0sCkI3OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
 LHE9YS5sZW5ndGgKZm9yKHQ9MDt0PHE7dD1yKXtzPXQrMQpyPXMrMQpiLlkoMCxhW3RdLGFbc10pfXJl
-dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3UuWi5hKGEpCnN3aXRjaChILldZKGIpKXtj
+dHVybiBifSwKZnQ6ZnVuY3Rpb24oYSxiLGMsZCxlLGYpe3UuWi5iKGEpCnN3aXRjaChILlNjKGIpKXtj
 YXNlIDA6cmV0dXJuIGEuJDAoKQpjYXNlIDE6cmV0dXJuIGEuJDEoYykKY2FzZSAyOnJldHVybiBhLiQy
 KGMsZCkKY2FzZSAzOnJldHVybiBhLiQzKGMsZCxlKQpjYXNlIDQ6cmV0dXJuIGEuJDQoYyxkLGUsZil9
 dGhyb3cgSC5iKG5ldyBQLkNEKCJVbnN1cHBvcnRlZCBudW1iZXIgb2YgYXJndW1lbnRzIGZvciB3cmFw
@@ -720,7 +871,7 @@
 bmN0aW9uKGYsZyxoLGkpe3JldHVybiBlKGMsZCxmLGcsaCxpKX19KGEsYixILmZ0KQphLiRpZGVudGl0
 eT10CnJldHVybiB0fSwKaUE6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvLG4s
 bSxsPW51bGwsaz1iWzBdLGo9ay4kY2FsbE5hbWUsaT1lP09iamVjdC5jcmVhdGUobmV3IEguengoKS5j
-b25zdHJ1Y3Rvci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguankobCxsLGwsbCkuY29uc3Ry
+b25zdHJ1Y3Rvci5wcm90b3R5cGUpOk9iamVjdC5jcmVhdGUobmV3IEguclQobCxsLGwsbCkuY29uc3Ry
 dWN0b3IucHJvdG90eXBlKQppLiRpbml0aWFsaXplPWkuY29uc3RydWN0b3IKaWYoZSl0PWZ1bmN0aW9u
 IHN0YXRpY190ZWFyX29mZigpe3RoaXMuJGluaXRpYWxpemUoKX0KZWxzZXtzPSQueWoKaWYodHlwZW9m
 IHMhPT0ibnVtYmVyIilyZXR1cm4gcy5oKCkKJC55aj1zKzEKcz1uZXcgRnVuY3Rpb24oImEsYixjLGQi
@@ -781,3563 +932,3503 @@
 KHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCiQueWo9dCsxCnJldHVybiBuZXcgRnVuY3Rp
 b24obSt0KyJ9IikoKX0sCktxOmZ1bmN0aW9uKGEsYixjLGQsZSxmLGcpe3JldHVybiBILmlBKGEsYixj
 LGQsISFlLCEhZixnKX0sClRuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2Us
-SC5xKGEuYSksYil9LApQVzpmdW5jdGlvbihhLGIpe3JldHVybiBILmNFKHYudHlwZVVuaXZlcnNlLEgu
-cShhLmMpLGIpfSwKRFY6ZnVuY3Rpb24oYSl7cmV0dXJuIGEuYX0sCnlTOmZ1bmN0aW9uKGEpe3JldHVy
-biBhLmN9LApFMjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1uZXcgSC5qeSgic2VsZiIsInRhcmdldCIs
-InJlY2VpdmVyIiwibmFtZSIpLHA9Si5FcChPYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyhxKSkKZm9y
-KHQ9cC5sZW5ndGgscz0wO3M8dDsrK3Mpe3I9cFtzXQppZihxW3JdPT09YSlyZXR1cm4gcn19LApvVDpm
-dW5jdGlvbihhKXtpZihhPT1udWxsKUguZk8oImJvb2xlYW4gZXhwcmVzc2lvbiBtdXN0IG5vdCBiZSBu
-dWxsIikKcmV0dXJuIGF9LApmTzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IEgua1koYSkpfSwKYWc6
-ZnVuY3Rpb24oYSl7dGhyb3cgSC5iKG5ldyBQLnQ3KGEpKX0sCkVmOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgSC5FcShhKX0sCllnOmZ1bmN0aW9uKGEpe3JldHVybiB2LmdldElzb2xhdGVUYWcoYSl9LApWTTpm
-dW5jdGlvbihhLGIpe2Fbdi5hcnJheVJ0aV09YgpyZXR1cm4gYX0sCm9YOmZ1bmN0aW9uKGEpe2lmKGE9
-PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIGEuJHRpfSwKSU06ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBI
-Llk5KGFbIiRhIitILmQoYyldLEgub1goYikpfSwKWTk6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJl
-dHVybiBiCmE9YS5hcHBseShudWxsLGIpCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoQXJyYXkuaXNB
-cnJheShhKSlyZXR1cm4gYQppZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gYS5hcHBseShudWxs
-LGIpCnJldHVybiBifSwKSUc6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBhLmFwcGx5KGIsSC5ZOShKLmlh
-KGIpWyIkYSIrSC5kKGMpXSxILm9YKGIpKSl9LAppdzpmdW5jdGlvbihhLGIsYyl7T2JqZWN0LmRlZmlu
-ZVByb3BlcnR5KGEsYix7dmFsdWU6YyxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmln
-dXJhYmxlOnRydWV9KX0sCkc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1ILmMoJC55LiQxKGEpKSxv
-PSQualtwXQppZihvIT1udWxsKXtPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJvcGVy
-dHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
-dHJ1ZX0pCnJldHVybiBvLml9dD0kLnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0
-b3JzQnlUYWdbcF0KaWYocz09bnVsbCl7cD1ILmMoJC51LiQyKGEscCkpCmlmKHAhPW51bGwpe289JC5q
+SC56SyhhLmEpLGIpfSwKUFc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSC5jRSh2LnR5cGVVbml2ZXJzZSxI
+LnpLKGEuYyksYil9LApEVjpmdW5jdGlvbihhKXtyZXR1cm4gYS5hfSwKeVM6ZnVuY3Rpb24oYSl7cmV0
+dXJuIGEuY30sCkUyOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPW5ldyBILnJUKCJzZWxmIiwidGFyZ2V0
+IiwicmVjZWl2ZXIiLCJuYW1lIikscD1KLkVwKE9iamVjdC5nZXRPd25Qcm9wZXJ0eU5hbWVzKHEpKQpm
+b3IodD1wLmxlbmd0aCxzPTA7czx0Oysrcyl7cj1wW3NdCmlmKHFbcl09PT1hKXJldHVybiByfX0sCm9U
+OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpSC5mTygiYm9vbGVhbiBleHByZXNzaW9uIG11c3Qgbm90IGJl
+IG51bGwiKQpyZXR1cm4gYX0sCmZPOmZ1bmN0aW9uKGEpe3Rocm93IEguYihuZXcgSC5rWShhKSl9LAph
+ZzpmdW5jdGlvbihhKXt0aHJvdyBILmIobmV3IFAuYyhhKSl9LApFZjpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguRXEoYSl9LApZZzpmdW5jdGlvbihhKXtyZXR1cm4gdi5nZXRJc29sYXRlVGFnKGEpfSwKVk06
+ZnVuY3Rpb24oYSxiKXthLiR0aT1iCnJldHVybiBhfSwKb1g6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbCly
+ZXR1cm4gbnVsbApyZXR1cm4gYS4kdGl9LApJTTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEguWTkoYVsi
+JGEiK0guZChjKV0sSC5vWChiKSl9LApZOTpmdW5jdGlvbihhLGIpe2lmKGE9PW51bGwpcmV0dXJuIGIK
+YT1hLmFwcGx5KG51bGwsYikKaWYoYT09bnVsbClyZXR1cm4gbnVsbAppZihBcnJheS5pc0FycmF5KGEp
+KXJldHVybiBhCmlmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBhLmFwcGx5KG51bGwsYikKcmV0
+dXJuIGJ9LApJRzpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIGEuYXBwbHkoYixILlk5KEouaWEoYilbIiRh
+IitILmQoYyldLEgub1goYikpKX0sCml3OmZ1bmN0aW9uKGEsYixjKXtPYmplY3QuZGVmaW5lUHJvcGVy
+dHkoYSxiLHt2YWx1ZTpjLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6
+dHJ1ZX0pfSwKdzM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD1ILnkoJC5ORi4kMShhKSksbz0kLm53
 W3BdCmlmKG8hPW51bGwpe09iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQcm9wZXJ0eU5h
 bWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVl
-fSkKcmV0dXJuIG8uaX10PSQudltwXQppZih0IT1udWxsKXJldHVybiB0CnM9di5pbnRlcmNlcHRvcnNC
+fSkKcmV0dXJuIG8uaX10PSQudnZbcF0KaWYodCE9bnVsbClyZXR1cm4gdApzPXYuaW50ZXJjZXB0b3Jz
+QnlUYWdbcF0KaWYocz09bnVsbCl7cD1ILnkoJC5UWC4kMihhLHApKQppZihwIT1udWxsKXtvPSQubndb
+cF0KaWYobyE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KGEsdi5kaXNwYXRjaFByb3BlcnR5TmFt
+ZSx7dmFsdWU6byxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9
+KQpyZXR1cm4gby5pfXQ9JC52dltwXQppZih0IT1udWxsKXJldHVybiB0CnM9di5pbnRlcmNlcHRvcnNC
 eVRhZ1twXX19aWYocz09bnVsbClyZXR1cm4gbnVsbAp0PXMucHJvdG90eXBlCnI9cFswXQppZihyPT09
-IiEiKXtvPUgubCh0KQokLmpbcF09bwpPYmplY3QuZGVmaW5lUHJvcGVydHkoYSx2LmRpc3BhdGNoUHJv
-cGVydHlOYW1lLHt2YWx1ZTpvLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFi
-bGU6dHJ1ZX0pCnJldHVybiBvLml9aWYocj09PSJ+Iil7JC52W3BdPXQKcmV0dXJuIHR9aWYocj09PSIt
-Iil7cT1ILmwodCkKT2JqZWN0LmRlZmluZVByb3BlcnR5KE9iamVjdC5nZXRQcm90b3R5cGVPZihhKSx2
-LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpxLGVudW1lcmFibGU6ZmFsc2Usd3JpdGFibGU6dHJ1
-ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnJldHVybiBxLml9aWYocj09PSIrIilyZXR1cm4gSC5MYyhhLHQp
-CmlmKHI9PT0iKiIpdGhyb3cgSC5iKFAubihwKSkKaWYodi5sZWFmVGFnc1twXT09PXRydWUpe3E9SC5s
-KHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5kaXNwYXRj
-aFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmln
-dXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWVsc2UgcmV0dXJuIEguTGMoYSx0KX0sCkxjOmZ1bmN0aW9u
-KGEsYil7dmFyIHQ9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0
-LHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYix0LG51bGwsbnVsbCksZW51bWVyYWJs
-ZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApsOmZ1bmN0
-aW9uKGEpe3JldHVybiBKLlF1KGEsITEsbnVsbCwhIWEuJGlYail9LApWRjpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQ9Yi5wcm90b3R5cGUKaWYodi5sZWFmVGFnc1thXT09PXRydWUpcmV0dXJuIEgubCh0KQplbHNl
-IHJldHVybiBKLlF1KHQsYyxudWxsLG51bGwpfSwKTTpmdW5jdGlvbigpe2lmKCEwPT09JC5LKXJldHVy
-bgokLks9ITAKSC5EKCl9LApEOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbQokLmo9T2JqZWN0
-LmNyZWF0ZShudWxsKQokLnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmEoKQp0PXYuaW50ZXJjZXB0b3Jz
-QnlUYWcKcz1PYmplY3QuZ2V0T3duUHJvcGVydHlOYW1lcyh0KQppZih0eXBlb2Ygd2luZG93IT0idW5k
-ZWZpbmVkIil7d2luZG93CnI9ZnVuY3Rpb24oKXt9CmZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1tx
-XQpvPSQueDcuJDEocCkKaWYobyE9bnVsbCl7bj1ILlZGKHAsdFtwXSxvKQppZihuIT1udWxsKXtPYmpl
-Y3QuZGVmaW5lUHJvcGVydHkobyx2LmRpc3BhdGNoUHJvcGVydHlOYW1lLHt2YWx1ZTpuLGVudW1lcmFi
-bGU6ZmFsc2Usd3JpdGFibGU6dHJ1ZSxjb25maWd1cmFibGU6dHJ1ZX0pCnIucHJvdG90eXBlPW99fX19
-Zm9yKHE9MDtxPHMubGVuZ3RoOysrcSl7cD1zW3FdCmlmKC9eW0EtWmEtel9dLy50ZXN0KHApKXttPXRb
-cF0KdFsiISIrcF09bQp0WyJ+IitwXT1tCnRbIi0iK3BdPW0KdFsiKyIrcF09bQp0WyIqIitwXT1tfX19
-LAphOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49Qy5PNCgpCm49SC5GKEMuWXEsSC5GKEMuS1Us
-SC5GKEMuZlEsSC5GKEMuZlEsSC5GKEMuaTcsSC5GKEMueGksSC5GKEMuZGsoQy53YiksbikpKSkpKSkK
-aWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIhPSJ1bmRlZmluZWQiKXt0
-PWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIKaWYodHlwZW9mIHQ9PSJmdW5jdGlvbiIp
-dD1bdF0KaWYodC5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHM9MDtzPHQubGVuZ3RoOysrcyl7cj10W3Nd
-CmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKW49cihuKXx8bn19cT1uLmdldFRhZwpwPW4uZ2V0VW5rbm93
-blRhZwpvPW4ucHJvdG90eXBlRm9yVGFnCiQueT1uZXcgSC5yKHEpCiQudT1uZXcgSC5kQyhwKQokLng3
-PW5ldyBILndOKG8pfSwKRjpmdW5jdGlvbihhLGIpe3JldHVybiBhKGIpfHxifSwKdjQ6ZnVuY3Rpb24o
-YSxiLGMsZCxlLGYpe3ZhciB0PWI/Im0iOiIiLHM9Yz8iIjoiaSIscj1kPyJ1IjoiIixxPWU/InMiOiIi
-LHA9Zj8iZyI6IiIsbz1mdW5jdGlvbihnLGgpe3RyeXtyZXR1cm4gbmV3IFJlZ0V4cChnLGgpfWNhdGNo
-KG4pe3JldHVybiBufX0oYSx0K3MrcitxK3ApCmlmKG8gaW5zdGFuY2VvZiBSZWdFeHApcmV0dXJuIG8K
-dGhyb3cgSC5iKFAucnIoIklsbGVnYWwgUmVnRXhwIHBhdHRlcm4gKCIrU3RyaW5nKG8pKyIpIixhLG51
-bGwpKX0sCm0yOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZih0eXBlb2YgYj09InN0cmluZyIpcmV0dXJu
-IGEuaW5kZXhPZihiLGMpPj0wCmVsc2UgaWYoYiBpbnN0YW5jZW9mIEguVlIpe3Q9Qy54Qi5HKGEsYykK
-cmV0dXJuIGIuYi50ZXN0KHQpfWVsc2V7dD1KLkZMKGIsQy54Qi5HKGEsYykpCnJldHVybiF0LmdsMCh0
-KX19LApBNDpmdW5jdGlvbihhKXtpZihhLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnJlcGxhY2Uo
-L1wkL2csIiQkJCQiKQpyZXR1cm4gYX0sCmVBOmZ1bmN0aW9uKGEpe2lmKC9bW1xde30oKSorPy5cXF4k
-fF0vLnRlc3QoYSkpcmV0dXJuIGEucmVwbGFjZSgvW1tcXXt9KCkqKz8uXFxeJHxdL2csIlxcJCYiKQpy
-ZXR1cm4gYX0sCnlzOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILm5NKGEsYixjKQpyZXR1cm4gdH0sCm5N
-OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiPT09IiIpe2lmKGE9PT0iIilyZXR1cm4gYwp0
-PWEubGVuZ3RoCmZvcihzPWMscj0wO3I8dDsrK3Ipcz1zK2Fbcl0rYwpyZXR1cm4gcy5jaGFyQ29kZUF0
-KDApPT0wP3M6c31xPWEuaW5kZXhPZihiLDApCmlmKHE8MClyZXR1cm4gYQppZihhLmxlbmd0aDw1MDB8
-fGMuaW5kZXhPZigiJCIsMCk+PTApcmV0dXJuIGEuc3BsaXQoYikuam9pbihjKQpyZXR1cm4gYS5yZXBs
-YWNlKG5ldyBSZWdFeHAoSC5lQShiKSwnZycpLEguQTQoYykpfSwKUEQ6ZnVuY3Rpb24gUEQoYSxiKXt0
-aGlzLmE9YQp0aGlzLiR0aT1ifSwKV1U6ZnVuY3Rpb24gV1UoKXt9LApMUDpmdW5jdGlvbiBMUChhLGIs
-YyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uJHRpPWR9LApYUjpmdW5jdGlvbiBYUihh
-LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApMSTpmdW5jdGlvbiBMSShhLGIsYyxkLGUpe3ZhciBfPXRo
-aXMKXy5hPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy5mPWV9LApDajpmdW5jdGlvbiBDaihhLGIsYyl7dGhp
-cy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApmOTpmdW5jdGlvbiBmOShhLGIsYyxkLGUsZil7dmFyIF89
-dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sClcwOmZ1bmN0aW9uIFcwKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LAphejpmdW5jdGlvbiBheihhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
-PWIKdGhpcy5jPWN9LAp2VjpmdW5jdGlvbiB2VihhKXt0aGlzLmE9YX0sCmJxOmZ1bmN0aW9uIGJxKGEs
-Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApBbTpmdW5jdGlvbiBBbShhKXt0aGlzLmE9YX0sClhPOmZ1bmN0
-aW9uIFhPKGEpe3RoaXMuYT1hCnRoaXMuYj1udWxsfSwKVHA6ZnVuY3Rpb24gVHAoKXt9LApsYzpmdW5j
-dGlvbiBsYygpe30sCnp4OmZ1bmN0aW9uIHp4KCl7fSwKank6ZnVuY3Rpb24gankoYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCkVxOmZ1bmN0aW9uIEVxKGEpe3RoaXMuYT1h
-fSwKa1k6ZnVuY3Rpb24ga1koYSl7dGhpcy5hPWF9LApONTpmdW5jdGlvbiBONShhKXt2YXIgXz10aGlz
-Cl8uYT0wCl8uZj1fLmU9Xy5kPV8uYz1fLmI9bnVsbApfLnI9MApfLiR0aT1hfSwKZGI6ZnVuY3Rpb24g
-ZGIoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbH0sCmk1OmZ1bmN0aW9uIGk1
-KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCk42OmZ1bmN0aW9uIE42KGEsYixjKXt2YXIgXz10aGlz
-Cl8uYT1hCl8uYj1iCl8uZD1fLmM9bnVsbApfLiR0aT1jfSwKcjpmdW5jdGlvbiByKGEpe3RoaXMuYT1h
-fSwKZEM6ZnVuY3Rpb24gZEMoYSl7dGhpcy5hPWF9LAp3TjpmdW5jdGlvbiB3TihhKXt0aGlzLmE9YX0s
-ClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApF
-SzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktXOmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0
-aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9uIFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8u
-Yj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rpb24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0s
-Ck5GOmZ1bmN0aW9uIE5GKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0
-aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0s
-Cm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9
-LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8
-fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIoSC5hdShhLGIsYykpCnJldHVybiBifSwKZUg6ZnVu
-Y3Rpb24gZUgoKXt9LApMWjpmdW5jdGlvbiBMWigpe30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVu
-Y3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigpe30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVu
-Y3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigpe30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVu
-Y3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigpe30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVu
-Y3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigpe30sClpHOmZ1bmN0aW9uIFpHKCl7fSwKY3o6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdD1iLmMKcmV0dXJuIHQ9PW51bGw/Yi5jPUguQmMoYSxiLnosITApOnR9LAp4
-WjpmdW5jdGlvbihhLGIpe3ZhciB0PWIuYwpyZXR1cm4gdD09bnVsbD9iLmM9SC5RMihhLCJiOCIsW2Iu
-el0pOnR9LApRMTpmdW5jdGlvbihhKXt2YXIgdD1hLnkKaWYodD09PTZ8fHQ9PT03fHx0PT09OClyZXR1
-cm4gSC5RMShhLnopCnJldHVybiB0PT09MTF8fHQ9PT0xMn0sCm1EOmZ1bmN0aW9uKGEpe3JldHVybiBh
-LmN5fSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5cGVVbml2ZXJzZSxhLCExKX0sClBMOmZ1
-bmN0aW9uKGEsYixjLGEwKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPWIueQpz
-d2l0Y2goZCl7Y2FzZSA1OmNhc2UgMTpjYXNlIDI6Y2FzZSAzOmNhc2UgNDpyZXR1cm4gYgpjYXNlIDY6
-dD1iLnoKcz1ILlBMKGEsdCxjLGEwKQppZihzPT09dClyZXR1cm4gYgpyZXR1cm4gSC5TTyhhLHMsITAp
-CmNhc2UgNzp0PWIuegpzPUguUEwoYSx0LGMsYTApCmlmKHM9PT10KXJldHVybiBiCnJldHVybiBILkJj
-KGEscywhMCkKY2FzZSA4OnQ9Yi56CnM9SC5QTChhLHQsYyxhMCkKaWYocz09PXQpcmV0dXJuIGIKcmV0
-dXJuIEguTE4oYSxzLCEwKQpjYXNlIDk6cj1iLlEKcT1ILmJaKGEscixjLGEwKQppZihxPT09cilyZXR1
-cm4gYgpyZXR1cm4gSC5RMihhLGIueixxKQpjYXNlIDEwOnA9Yi56Cm89SC5QTChhLHAsYyxhMCkKbj1i
-LlEKbT1ILmJaKGEsbixjLGEwKQppZihvPT09cCYmbT09PW4pcmV0dXJuIGIKcmV0dXJuIEguYXAoYSxv
-LG0pCmNhc2UgMTE6bD1iLnoKaz1ILlBMKGEsbCxjLGEwKQpqPWIuUQppPUgucVQoYSxqLGMsYTApCmlm
-KGs9PT1sJiZpPT09ailyZXR1cm4gYgpyZXR1cm4gSC5OZihhLGssaSkKY2FzZSAxMjpoPWIuUQphMCs9
-aC5sZW5ndGgKZz1ILmJaKGEsaCxjLGEwKQpwPWIuegpvPUguUEwoYSxwLGMsYTApCmlmKGc9PT1oJiZv
-PT09cClyZXR1cm4gYgpyZXR1cm4gSC5EUyhhLG8sZywhMCkKY2FzZSAxMzpmPWIuegppZihmPGEwKXJl
-dHVybiBiCmU9Y1tmLWEwXQppZihlPT1udWxsKXJldHVybiBiCnJldHVybiBlCmRlZmF1bHQ6dGhyb3cg
-SC5iKFAuaFYoIkF0dGVtcHRlZCB0byBzdWJzdGl0dXRlIHVuZXhwZWN0ZWQgUlRJIGtpbmQgIitkKSl9
-fSwKYlo6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscD1iLmxlbmd0aCxvPVtdCmZvcih0PSEx
-LHM9MDtzPHA7KytzKXtyPWJbc10KcT1ILlBMKGEscixjLGQpCmlmKHEhPT1yKXQ9ITAKby5wdXNoKHEp
-fXJldHVybiB0P286Yn0sCnZPOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxLHAsbz1iLmxlbmd0
-aCxuPVtdCmZvcih0PSExLHM9MDtzPG87cys9Mil7cj1iW3NdCnE9YltzKzFdCnA9SC5QTChhLHEsYyxk
-KQppZihwIT09cSl0PSEwCm4ucHVzaChyKQpuLnB1c2gocCl9cmV0dXJuIHQ/bjpifSwKcVQ6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHQscz1iLmEscj1ILmJaKGEscyxjLGQpLHE9Yi5iLHA9SC5iWihhLHEsYyxk
-KSxvPWIuYyxuPUgudk8oYSxvLGMsZCkKaWYocj09PXMmJnA9PT1xJiZuPT09bylyZXR1cm4gYgp0PW5l
-dyBILkVUKCkKdC5hPXIKdC5iPXAKdC5jPW4KcmV0dXJuIHR9LApKUzpmdW5jdGlvbihhKXt2YXIgdD1h
-LiRTCmlmKHQhPW51bGwpe2lmKHR5cGVvZiB0PT0ibnVtYmVyIilyZXR1cm4gSC5CcCh0KQpyZXR1cm4g
-YS4kUygpfXJldHVybiBudWxsfSwKVWU6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihILlExKGIpKWlmKGEg
-aW5zdGFuY2VvZiBILlRwKXt0PUguSlMoYSkKaWYodCE9bnVsbClyZXR1cm4gdH1yZXR1cm4gSC5xKGEp
-fSwKcTpmdW5jdGlvbihhKXt2YXIgdAppZihhIGluc3RhbmNlb2YgUC5NaCl7dD1hLiR0aQpyZXR1cm4g
-dCE9bnVsbD90OkguVlUoYSl9aWYoQXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4g
-SC5WVShKLmlhKGEpKX0sCnQ2OmZ1bmN0aW9uKGEpe3ZhciB0PWFbdi5hcnJheVJ0aV0scz11LmIKaWYo
-dD09bnVsbClyZXR1cm4gcwppZih0LmNvbnN0cnVjdG9yIT09cy5jb25zdHJ1Y3RvcilyZXR1cm4gcwpy
-ZXR1cm4gdH0sCkxoOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJHRpCnJldHVybiB0IT1udWxsP3Q6SC5WVShh
-KX0sClZVOmZ1bmN0aW9uKGEpe3ZhciB0PWEuY29uc3RydWN0b3Iscz10LiRjY2FjaGUKaWYocyE9bnVs
-bClyZXR1cm4gcwpyZXR1cm4gSC5yOShhLHQpfSwKcjk6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hIGluc3Rh
-bmNlb2YgSC5UcD9hLl9fcHJvdG9fXy5fX3Byb3RvX18uY29uc3RydWN0b3I6YixzPUguYWkodi50eXBl
-VW5pdmVyc2UsdC5uYW1lKQpiLiRjY2FjaGU9cwpyZXR1cm4gc30sCkJwOmZ1bmN0aW9uKGEpe3ZhciB0
-LHM9YSxyPXYudHlwZXMscT1yW3NdCmlmKHR5cGVvZiBxPT0ic3RyaW5nIil7dD1ILkUodi50eXBlVW5p
-dmVyc2UscSwhMSkKcltzXT10CnJldHVybiB0fXJldHVybiBxfSwKSko6ZnVuY3Rpb24oYSl7dmFyIHQ9
-dGhpcyxzPUguWU8scj11LksKaWYodD09PXIpe3M9SC5rZQp0LmE9SC5UaX1lbHNlIGlmKEguQTgodCl8
-fHQ9PT1yKXtzPUguSXcKdC5hPUguaG59ZWxzZSBpZih0PT09dS5wKXM9SC5vawplbHNlIGlmKHQ9PT11
-LmdSKXM9SC5LSAplbHNlIGlmKHQ9PT11LmRpKXM9SC5LSAplbHNlIGlmKHQ9PT11Lk4pcz1ILk1NCmVs
-c2UgaWYodD09PXUueSlzPUguclEKZWxzZSBpZih0Lnk9PT05KXtyPXQuegppZih0LlEuZXZlcnkoSC5j
-Yykpe3Qucj0iJGkiK3IKcz1ILnQ0fX10LmI9cwpyZXR1cm4gdC5iKGEpfSwKWU86ZnVuY3Rpb24oYSl7
-dmFyIHQ9dGhpcwpyZXR1cm4gSC5XZSh2LnR5cGVVbml2ZXJzZSxILlVlKGEsdCksbnVsbCx0LG51bGwp
-fSwKdDQ6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPXQucgppZihhIGluc3RhbmNlb2YgUC5NaClyZXR1
-cm4hIWFbc10KcmV0dXJuISFKLmlhKGEpW3NdfSwKT3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcwppZihh
-PT1udWxsKXJldHVybiBhCmVsc2UgaWYodC5iKGEpKXJldHVybiBhCnRocm93IEguYihILlpjKEgucChh
-LEguVWUoYSx0KSxILkoodCxudWxsKSkpKX0sCkRoOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PW51bGwK
-aWYoSC5XZSh2LnR5cGVVbml2ZXJzZSxhLHQsYix0KSlyZXR1cm4gYQp0aHJvdyBILmIoSC5aYygiVGhl
-IHR5cGUgYXJndW1lbnQgJyIrSC5kKEguSihhLHQpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0
-eXBlIHZhcmlhYmxlIGJvdW5kICciK0guZChILkooYix0KSkrIicgb2YgdHlwZSB2YXJpYWJsZSAnIitj
-KyInIGluICciK0guZChkKSsiJy4iKSl9LApwOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1QLmgoYSkscz1I
-LkooYj09bnVsbD9ILnEoYSk6YixudWxsKQpyZXR1cm4gdCsiOiB0eXBlICciK0guZChzKSsiJyBpcyBu
-b3QgYSBzdWJ0eXBlIG9mIHR5cGUgJyIrSC5kKGMpKyInIn0sClpjOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgSC54KCJUeXBlRXJyb3I6ICIrYSl9LApCOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILngoIlR5
-cGVFcnJvcjogIitILnAoYSxudWxsLGIpKX0sCmtlOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKVGk6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIGF9LApJdzpmdW5jdGlvbihhKXtyZXR1cm4hMH0sCmhuOmZ1bmN0aW9uKGEp
-e3JldHVybiBhfSwKclE6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApFOTpmdW5jdGlv
-bihhKXtpZighMD09PWF8fCExPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEgu
-YihILkIoYSwiYm9vbCIpKX0sCmRqOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1
-cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILkIoYSwiZG91YmxlIikpfSwKb2s6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihhKT09PWF9LApXWTpm
-dW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9PT1hKXJldHVybiBh
-CmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJpbnQiKSl9LApLSDpmdW5jdGlvbihh
-KXtyZXR1cm4gdHlwZW9mIGE9PSJudW1iZXIifSwKdVU6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJu
-dW1iZXIiKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguQihhLCJudW0iKSl9
-LApNTTpmdW5jdGlvbihhKXtyZXR1cm4gdHlwZW9mIGE9PSJzdHJpbmcifSwKYzpmdW5jdGlvbihhKXtp
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIGEKaWYoYT09bnVsbClyZXR1cm4gYQp0aHJvdyBILmIo
-SC5CKGEsIlN0cmluZyIpKX0sCnc6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKZm9yKHQ9IiIscz0iIixy
-PTA7cjxhLmxlbmd0aDsrK3Iscz0iLCAiKXQrPUMueEIuaChzLEguSihhW3JdLGIpKQpyZXR1cm4gdH0s
-CmY6ZnVuY3Rpb24oYTEsYTIsYTMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQs
-YyxiLGEsYTA9IiwgIgppZihhMyE9bnVsbCl7dD1hMy5sZW5ndGgKaWYoYTI9PW51bGwpe2EyPUguVk0o
-W10sdS5zKQpzPW51bGx9ZWxzZSBzPWEyLmxlbmd0aApyPWEyLmxlbmd0aApmb3IocT10O3E+MDstLXEp
-Qy5ObS5pKGEyLCJUIisocitxKSkKZm9yKHA9dS5LLG89IjwiLG49IiIscT0wO3E8dDsrK3Esbj1hMCl7
-bys9bgptPWEyLmxlbmd0aApsPW0tMS1xCmlmKGw8MClyZXR1cm4gSC5rKGEyLGwpCm89Qy54Qi5oKG8s
-YTJbbF0pCms9YTNbcV0KaWYoIShILkE4KGspfHxrPT09cCkpbT0hKGs9PT1wKQplbHNlIG09ITEKaWYo
-bSlvKz1DLnhCLmgoIiBleHRlbmRzICIsSC5KKGssYTIpKX1vKz0iPiJ9ZWxzZXtvPSIiCnM9bnVsbH1w
-PWExLnoKaj1hMS5RCmk9ai5hCmg9aS5sZW5ndGgKZz1qLmIKZj1nLmxlbmd0aAplPWouYwpkPWUubGVu
-Z3RoCmM9SC5KKHAsYTIpCmZvcihiPSIiLGE9IiIscT0wO3E8aDsrK3EsYT1hMCliKz1DLnhCLmgoYSxI
-LkooaVtxXSxhMikpCmlmKGY+MCl7Yis9YSsiWyIKZm9yKGE9IiIscT0wO3E8ZjsrK3EsYT1hMCliKz1D
-LnhCLmgoYSxILkooZ1txXSxhMikpCmIrPSJdIn1pZihkPjApe2IrPWErInsiCmZvcihhPSIiLHE9MDtx
-PGQ7cSs9MixhPWEwKWIrPUMueEIuaChhLEguSihlW3ErMV0sYTIpKSsiICIrZVtxXQpiKz0ifSJ9aWYo
-cyE9bnVsbClhMi5sZW5ndGg9cwpyZXR1cm4gbysiKCIrYisiKSA9PiAiK0guZChjKX0sCko6ZnVuY3Rp
-b24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEueQppZihtPT09NSlyZXR1cm4iZXJhc2VkIgppZiht
-PT09MilyZXR1cm4iZHluYW1pYyIKaWYobT09PTMpcmV0dXJuInZvaWQiCmlmKG09PT0xKXJldHVybiJO
-ZXZlciIKaWYobT09PTQpcmV0dXJuImFueSIKaWYobT09PTYpe3Q9SC5KKGEueixiKQpyZXR1cm4gdH1p
-ZihtPT09Nyl7cz1hLnoKdD1ILkoocyxiKQpyPXMueQpyZXR1cm4gSi5tKHI9PT0xMXx8cj09PTEyP0Mu
-eEIuaCgiKCIsdCkrIikiOnQsIj8iKX1pZihtPT09OClyZXR1cm4iRnV0dXJlT3I8IitILmQoSC5KKGEu
-eixiKSkrIj4iCmlmKG09PT05KXtxPUguQyhhLnopCnA9YS5RCnJldHVybiBwLmxlbmd0aCE9PTA/cSso
-IjwiK0gudyhwLGIpKyI+Iik6cX1pZihtPT09MTEpcmV0dXJuIEguZihhLGIsbnVsbCkKaWYobT09PTEy
-KXJldHVybiBILmYoYS56LGIsYS5RKQppZihtPT09MTMpe289YS56Cm49Yi5sZW5ndGgKbz1uLTEtbwpp
-ZihvPDB8fG8+PW4pcmV0dXJuIEguayhiLG8pCnJldHVybiBiW29dfXJldHVybiI/In0sCkM6ZnVuY3Rp
-b24oYSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0ibWluaWZpZWQ6IithCnJl
-dHVybiB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7dHlwZW9mIHQ9PSJzdHJp
-bmciOyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1h
-LmVULG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiLCExKQplbHNlIGlmKHR5cGVvZiBuPT0i
-bnVtYmVyIil7dD1uCnM9SC5tWihhLDUsIiMiKQpyPVtdCmZvcihxPTA7cTx0OysrcSlyLnB1c2gocykK
-cD1ILlEyKGEsYixyKQpvW2JdPXAKcmV0dXJuIHB9ZWxzZSByZXR1cm4gbn0sCnhiOmZ1bmN0aW9uKGEs
-Yil7cmV0dXJuIEguSXgoYS50UixiKX0sCkZGOmZ1bmN0aW9uKGEsYil7cmV0dXJuIEguSXgoYS5lVCxi
-KX0sCkU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9YS5lQyxyPXMuZ2V0KGIpCmlmKHIhPW51bGwpcmV0
-dXJuIHIKdD1ILnooYSxudWxsLGIsYykKcy5zZXQoYix0KQpyZXR1cm4gdH0sCmNFOmZ1bmN0aW9uKGEs
-YixjKXt2YXIgdCxzLHI9Yi5jaAppZihyPT1udWxsKXI9Yi5jaD1uZXcgTWFwKCkKdD1yLmdldChjKQpp
-Zih0IT1udWxsKXJldHVybiB0CnM9SC56KGEsYixjLCEwKQpyLnNldChjLHMpCnJldHVybiBzfSwKdjU6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIuY3gKaWYocT09bnVsbClxPWIuY3g9bmV3IE1hcCgp
-CnQ9Yy5jeQpzPXEuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmFwKGEsYixjLnk9PT0xMD9j
-LlE6W2NdKQpxLnNldCh0LHIpCnJldHVybiByfSwKejpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdD1ILmko
-SC5vKGEsYixjLGQpKQppZih0IT1udWxsKXJldHVybiB0CnRocm93IEguYihQLm4oJ19Vbml2ZXJzZS5f
-cGFyc2VSZWNpcGUoIicrSC5kKGMpKyciKScpKX0sCkJEOmZ1bmN0aW9uKGEsYil7Yi5hPUguT3oKYi5i
-PUguSkoKcmV0dXJuIGJ9LAptWjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPWEuZUMuZ2V0KGMpCmlm
-KHIhPW51bGwpcmV0dXJuIHIKdD1uZXcgSC5KYyhudWxsLG51bGwpCnQueT1iCnQuY3k9YwpzPUguQkQo
-YSx0KQphLmVDLnNldChjLHMpCnJldHVybiBzfSwKU086ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5j
-eSsiKiIscj1hLmVDLmdldChzKQppZihyIT1udWxsKXJldHVybiByCnQ9SC5aNyhhLGIscyxjKQphLmVD
-LnNldChzLHQpCnJldHVybiB0fSwKWjc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihkKXt0PWIu
-eQppZihILkE4KGIpfHxiPT09dS5LfHxiPT09dS5QfHx0PT09N3x8dD09PTYpcmV0dXJuIGJ9cz1uZXcg
-SC5KYyhudWxsLG51bGwpCnMueT02CnMuej1iCnMuY3k9YwpyZXR1cm4gSC5CRChhLHMpfSwKQmM6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5jeSsiPyIscj1hLmVDLmdldChzKQppZihyIT1udWxsKXJldHVy
-biByCnQ9SC5sbChhLGIscyxjKQphLmVDLnNldChzLHQpCnJldHVybiB0fSwKbGw6ZnVuY3Rpb24oYSxi
-LGMsZCl7dmFyIHQscyxyLHEscAppZihkKXt0PWIueQppZighSC5BOChiKSlpZighKGI9PT11LlApKWlm
-KHQhPT03KXM9dD09PTgmJkgubFIoYi56KQplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAppZihz
-KXJldHVybiBiCmVsc2UgaWYodD09PTEpcmV0dXJuIHUuUAplbHNlIGlmKHQ9PT02KXtyPWIuegpxPXIu
-eQppZihxPT09MSlyZXR1cm4gdS5QCmVsc2UgaWYocT09PTgmJkgubFIoci56KSlyZXR1cm4gcgplbHNl
-IHJldHVybiBILmN6KGEsYil9fXA9bmV3IEguSmMobnVsbCxudWxsKQpwLnk9NwpwLno9YgpwLmN5PWMK
-cmV0dXJuIEguQkQoYSxwKX0sCkxOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWIuY3krIi8iLHI9YS5l
-Qy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PUguZVYoYSxiLHMsYykKYS5lQy5zZXQocyx0KQpy
-ZXR1cm4gdH0sCmVWOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMKaWYoZCl7dD1iLnkKaWYoSC5BOChi
-KXx8Yj09PXUuS3x8Yj09PXUuSylyZXR1cm4gYgplbHNlIGlmKHQ9PT0xKXJldHVybiBILlEyKGEsImI4
-IixbYl0pCmVsc2UgaWYoYj09PXUuUClyZXR1cm4gdS5hUX1zPW5ldyBILkpjKG51bGwsbnVsbCkKcy55
-PTgKcy56PWIKcy5jeT1jCnJldHVybiBILkJEKGEscyl9LApIYzpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
-cj0iIitiKyJeIixxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKdD1uZXcgSC5KYyhudWxs
-LG51bGwpCnQueT0xMwp0Lno9Ygp0LmN5PXIKcz1ILkJEKGEsdCkKYS5lQy5zZXQocixzKQpyZXR1cm4g
-c30sClV4OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8
-cTsrK3Iscz0iLCIpdCs9cythW3JdLmN5CnJldHVybiB0fSwKUzQ6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
-LHEscCxvPWEubGVuZ3RoCmZvcih0PSIiLHM9IiIscj0wO3I8bztyKz0yLHM9IiwiKXtxPWFbcl0KcD1h
-W3IrMV0uY3kKdCs9cytxKyI6IitwfXJldHVybiB0fSwKUTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cixxPWIKaWYoYy5sZW5ndGghPT0wKXErPSI8IitILlV4KGMpKyI+Igp0PWEuZUMuZ2V0KHEpCmlmKHQh
-PW51bGwpcmV0dXJuIHQKcz1uZXcgSC5KYyhudWxsLG51bGwpCnMueT05CnMuej1iCnMuUT1jCmlmKGMu
-bGVuZ3RoPjApcy5jPWNbMF0Kcy5jeT1xCnI9SC5CRChhLHMpCmEuZUMuc2V0KHEscikKcmV0dXJuIHJ9
-LAphcDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvCmlmKGIueT09PTEwKXt0PWIuegpzPWIu
-US5jb25jYXQoYyl9ZWxzZXtzPWMKdD1ifXI9dC5jeSsiOyIrKCI8IitILlV4KHMpKyI+IikKcT1hLmVD
-LmdldChyKQppZihxIT1udWxsKXJldHVybiBxCnA9bmV3IEguSmMobnVsbCxudWxsKQpwLnk9MTAKcC56
-PXQKcC5RPXMKcC5jeT1yCm89SC5CRChhLHApCmEuZUMuc2V0KHIsbykKcmV0dXJuIG99LApOZjpmdW5j
-dGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1iLmN5LG89Yy5hLG49by5sZW5ndGgsbT1jLmIsbD1tLmxl
-bmd0aCxrPWMuYyxqPWsubGVuZ3RoLGk9IigiK0guVXgobykKaWYobD4wKWkrPShuPjA/IiwiOiIiKSsi
-WyIrSC5VeChtKSsiXSIKaWYoaj4wKWkrPShuPjA/IiwiOiIiKSsieyIrSC5TNChrKSsifSIKdD1wKyhp
-KyIpIikKcz1hLmVDLmdldCh0KQppZihzIT1udWxsKXJldHVybiBzCnI9bmV3IEguSmMobnVsbCxudWxs
-KQpyLnk9MTEKci56PWIKci5RPWMKci5jeT10CnE9SC5CRChhLHIpCmEuZUMuc2V0KHQscSkKcmV0dXJu
-IHF9LApEUzpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzPWIuY3krIjwiK0guVXgoYykrIj4iLHI9YS5l
-Qy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PUguaHcoYSxiLGMscyxkKQphLmVDLnNldChzLHQp
-CnJldHVybiB0fSwKaHc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG8sbixtCmlmKGUp
-e3Q9Yy5sZW5ndGgKcz1uZXcgQXJyYXkodCkKZm9yKHI9MCxxPTA7cTx0OysrcSl7cD1jW3FdCmlmKHAu
-eT09PTEpe3NbcV09cDsrK3J9fWlmKHI+MCl7bz1ILlBMKGEsYixzLDApCm49SC5iWihhLGMscywwKQpy
-ZXR1cm4gSC5EUyhhLG8sbixjIT09bil9fW09bmV3IEguSmMobnVsbCxudWxsKQptLnk9MTIKbS56PWIK
-bS5RPWMKbS5jeT1kCnJldHVybiBILkJEKGEsbSl9LApvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybnt1
-OmEsZTpiLHI6YyxzOltdLHA6MCxuOmR9fSwKaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsayxqLGksaD1hLnIsZz1hLnMKZm9yKHQ9aC5sZW5ndGgscz0wO3M8dDspe3I9aC5jaGFyQ29kZUF0
-KHMpCmlmKHI+PTQ4JiZyPD01NylzPUguQWwocysxLHIsaCxnKQplbHNlIGlmKCgoKHJ8MzIpPj4+MCkt
-OTcmNjU1MzUpPDI2fHxyPT09OTV8fHI9PT0zNilzPUguUjgoYSxzLGgsZywhMSkKZWxzZSBpZihyPT09
-NDYpcz1ILlI4KGEscyxoLGcsITApCmVsc2V7KytzCnN3aXRjaChyKXtjYXNlIDQ0OmJyZWFrCmNhc2Ug
-NTg6YnJlYWsKY2FzZSA1OTpnLnB1c2goSC5LUShhLnUsYS5lLGcucG9wKCkpKQpicmVhawpjYXNlIDk0
-OmcucHVzaChILkhjKGEudSxnLnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpnLnB1c2goSC5tWihhLnUsNSwi
-IyIpKQpicmVhawpjYXNlIDY0OmcucHVzaChILm1aKGEudSwyLCJAIikpCmJyZWFrCmNhc2UgMTI2Omcu
-cHVzaChILm1aKGEudSwzLCJ+IikpCmJyZWFrCmNhc2UgNjA6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3Ro
-CmJyZWFrCmNhc2UgNjI6cT1hLnUKcD1nLnNwbGljZShhLnApCkguclQoYS51LGEuZSxwKQphLnA9Zy5w
-b3AoKQpvPWcucG9wKCkKaWYodHlwZW9mIG89PSJzdHJpbmciKWcucHVzaChILlEyKHEsbyxwKSkKZWxz
-ZXtuPUguS1EocSxhLmUsbykKc3dpdGNoKG4ueSl7Y2FzZSAxMTpnLnB1c2goSC5EUyhxLG4scCxhLm4p
-KQpicmVhawpkZWZhdWx0OmcucHVzaChILmFwKHEsbixwKSkKYnJlYWt9fWJyZWFrCmNhc2UgMzg6SC5J
-MyhhLGcpCmJyZWFrCmNhc2UgNDI6bT1hLnUKZy5wdXNoKEguU08obSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNjM6bT1hLnUKZy5wdXNoKEguQmMobSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNDc6bT1hLnUKZy5wdXNoKEguTE4obSxILktRKG0sYS5lLGcucG9wKCkp
-LGEubikpCmJyZWFrCmNhc2UgNDA6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3RoCmJyZWFrCmNhc2UgNDE6
-cT1hLnUKbD1uZXcgSC5FVCgpCms9cS5zRUEKaj1xLnNFQQpvPWcucG9wKCkKaWYodHlwZW9mIG89PSJu
-dW1iZXIiKXN3aXRjaChvKXtjYXNlLTE6az1nLnBvcCgpCmJyZWFrCmNhc2UtMjpqPWcucG9wKCkKYnJl
-YWsKZGVmYXVsdDpnLnB1c2gobykKYnJlYWt9ZWxzZSBnLnB1c2gobykKcD1nLnNwbGljZShhLnApCkgu
-clQoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpsLmE9cApsLmI9awpsLmM9agpnLnB1c2goSC5OZihxLEgu
-S1EocSxhLmUsZy5wb3AoKSksbCkpCmJyZWFrCmNhc2UgOTE6Zy5wdXNoKGEucCkKYS5wPWcubGVuZ3Ro
-CmJyZWFrCmNhc2UgOTM6cD1nLnNwbGljZShhLnApCkguclQoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpn
-LnB1c2gocCkKZy5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpnLnB1c2goYS5wKQphLnA9Zy5sZW5ndGgK
-YnJlYWsKY2FzZSAxMjU6cD1nLnNwbGljZShhLnApCkguV1MoYS51LGEuZSxwKQphLnA9Zy5wb3AoKQpn
-LnB1c2gocCkKZy5wdXNoKC0yKQpicmVhawpkZWZhdWx0OnRocm93IkJhZCBjaGFyYWN0ZXIgIityfX19
-aT1nLnBvcCgpCnJldHVybiBILktRKGEudSxhLmUsaSl9LApBbDpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
-dCxzLHI9Yi00OApmb3IodD1jLmxlbmd0aDthPHQ7KythKXtzPWMuY2hhckNvZGVBdChhKQppZighKHM+
-PTQ4JiZzPD01NykpYnJlYWsKcj1yKjEwKyhzLTQ4KX1kLnB1c2gocikKcmV0dXJuIGF9LApSODpmdW5j
-dGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbyxuPWIrMQpmb3IodD1jLmxlbmd0aDtuPHQ7Kytu
-KXtzPWMuY2hhckNvZGVBdChuKQppZihzPT09NDYpe2lmKGUpYnJlYWsKZT0hMH1lbHNle2lmKCEoKCgo
-c3wzMik+Pj4wKS05NyY2NTUzNSk8MjZ8fHM9PT05NXx8cz09PTM2KSlyPXM+PTQ4JiZzPD01NwplbHNl
-IHI9ITAKaWYoIXIpYnJlYWt9fXE9Yy5zdWJzdHJpbmcoYixuKQppZihlKXt0PWEudQpwPWEuZQppZihw
-Lnk9PT0xMClwPXAuegpvPUguUW8odCxwLnopW3FdCmlmKG89PW51bGwpSC52aCgnTm8gIicrcSsnIiBp
-biAiJytILm1EKHApKyciJykKZC5wdXNoKEguY0UodCxwLG8pKX1lbHNlIGQucHVzaChxKQpyZXR1cm4g
-bn0sCkkzOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5wb3AoKQppZigwPT09dCl7Yi5wdXNoKEgubVooYS51
-LDEsIjAmIikpCnJldHVybn1pZigxPT09dCl7Yi5wdXNoKEgubVooYS51LDQsIjEmIikpCnJldHVybn10
-aHJvdyBILmIoUC5oVigiVW5leHBlY3RlZCBleHRlbmRlZCBvcGVyYXRpb24gIitILmQodCkpKX0sCktR
-OmZ1bmN0aW9uKGEsYixjKXtpZih0eXBlb2YgYz09InN0cmluZyIpcmV0dXJuIEguUTIoYSxjLGEuc0VB
-KQplbHNlIGlmKHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4g
-Y30sCnJUOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWMubGVuZ3RoCmZvcih0PTA7dDxzOysrdCljW3Rd
-PUguS1EoYSxiLGNbdF0pfSwKV1M6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9
-MTt0PHM7dCs9MiljW3RdPUguS1EoYSxiLGNbdF0pfSwKVFY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
-cj1iLnkKaWYocj09PTEwKXtpZihjPT09MClyZXR1cm4gYi56CnQ9Yi5RCnM9dC5sZW5ndGgKaWYoYzw9
-cylyZXR1cm4gdFtjLTFdCmMtPXMKYj1iLnoKcj1iLnl9ZWxzZSBpZihjPT09MClyZXR1cm4gYgppZihy
-IT09OSl0aHJvdyBILmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJmYWNlIHR5cGUi
-KSkKdD1iLlEKaWYoYzw9dC5sZW5ndGgpcmV0dXJuIHRbYy0xXQp0aHJvdyBILmIoUC5oVigiQmFkIGlu
-ZGV4ICIrYysiIGZvciAiK2IuWigwKSkpfSwKV2U6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIs
-cSxwLG8sbixtLGwsawppZihiPT09ZClyZXR1cm4hMAppZihILkE4KGQpfHxkPT09dS5LKXJldHVybiEw
-CnQ9Yi55CmlmKHQ9PT00KXJldHVybiEwCmlmKEguQTgoYikpcmV0dXJuITEKaWYoYj09PXUuUClyZXR1
-cm4hMApzPXQ9PT0xMwppZihzKWlmKEguV2UoYSxjW2Iuel0sYyxkLGUpKXJldHVybiEwCnI9ZC55Cmlm
-KHQ9PT02KXJldHVybiBILldlKGEsYi56LGMsZCxlKQppZihyPT09Nil7cT1kLnoKcmV0dXJuIEguV2Uo
-YSxiLGMscSxlKX1pZih0PT09OCl7aWYoIUguV2UoYSxiLnosYyxkLGUpKXJldHVybiExCnJldHVybiBI
-LldlKGEsSC54WihhLGIpLGMsZCxlKX1pZih0PT09Nyl7cT1ILldlKGEsYi56LGMsZCxlKQpyZXR1cm4g
-cX1pZihyPT09OCl7aWYoSC5XZShhLGIsYyxkLnosZSkpcmV0dXJuITAKcmV0dXJuIEguV2UoYSxiLGMs
-SC54WihhLGQpLGUpfWlmKHI9PT03KXtxPUguV2UoYSxiLGMsZC56LGUpCnJldHVybiBxfWlmKHMpcmV0
-dXJuITEKcT10IT09MTEKaWYoKCFxfHx0PT09MTIpJiZkPT09dS5aKXJldHVybiEwCmlmKHI9PT0xMil7
-aWYoYj09PXUuZylyZXR1cm4hMAppZih0IT09MTIpcmV0dXJuITEKcD1iLlEKbz1kLlEKbj1wLmxlbmd0
-aAppZihuIT09by5sZW5ndGgpcmV0dXJuITEKYz1jPT1udWxsP3A6cC5jb25jYXQoYykKZT1lPT1udWxs
-P286by5jb25jYXQoZSkKZm9yKHE9dS5hdixtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQpxLmEobCkK
-cS5hKGspCmlmKCFILldlKGEsbCxjLGssZSl8fCFILldlKGEsayxlLGwsYykpcmV0dXJuITF9cmV0dXJu
-IEguYk8oYSxiLnosYyxkLnosZSl9aWYocj09PTExKXtpZihiPT09dS5nKXJldHVybiEwCmlmKHEpcmV0
-dXJuITEKcmV0dXJuIEguYk8oYSxiLGMsZCxlKX1pZih0PT09OSl7aWYociE9PTkpcmV0dXJuITEKcmV0
-dXJuIEgucEcoYSxiLGMsZCxlKX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEwLGExLGEyLGEzLGE0KXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixhCmlmKCFILldlKGEwLGExLnos
-YTIsYTMueixhNCkpcmV0dXJuITEKdD1hMS5RCnM9YTMuUQpyPXQuYQpxPXMuYQpwPXIubGVuZ3RoCm89
-cS5sZW5ndGgKaWYocD5vKXJldHVybiExCm49by1wCm09dC5iCmw9cy5iCms9bS5sZW5ndGgKaj1sLmxl
-bmd0aAppZihwK2s8bytqKXJldHVybiExCmZvcihpPTA7aTxwOysraSl7aD1yW2ldCmlmKCFILldlKGEw
-LHFbaV0sYTQsaCxhMikpcmV0dXJuITF9Zm9yKGk9MDtpPG47KytpKXtoPW1baV0KaWYoIUguV2UoYTAs
-cVtwK2ldLGE0LGgsYTIpKXJldHVybiExfWZvcihpPTA7aTxqOysraSl7aD1tW24raV0KaWYoIUguV2Uo
-YTAsbFtpXSxhNCxoLGEyKSlyZXR1cm4hMX1nPXQuYwpmPXMuYwplPWcubGVuZ3RoCmQ9Zi5sZW5ndGgK
-Zm9yKGk9MCxjPTA7YzxkO2MrPTIpe2I9ZltjXQpkb3tpZihpPj1lKXJldHVybiExCmE9Z1tpXQppKz0y
-fXdoaWxlKGE8YikKaWYoYjxhKXJldHVybiExCmg9Z1tpLTFdCmlmKCFILldlKGEwLGZbYysxXSxhNCxo
-LGEyKSlyZXR1cm4hMX1yZXR1cm4hMH0sCnBHOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEs
-cCxvLG4sbSxsPWIueixrPWQuegppZihsPT09ayl7dD1iLlEKcz1kLlEKcj10Lmxlbmd0aApmb3IocT0w
-O3E8cjsrK3Epe3A9dFtxXQpvPXNbcV0KaWYoIUguV2UoYSxwLGMsbyxlKSlyZXR1cm4hMX1yZXR1cm4h
-MH1pZihkPT09dS5LKXJldHVybiEwCm49SC5RbyhhLGwpCmlmKG49PW51bGwpcmV0dXJuITEKbT1uW2td
-CmlmKG09PW51bGwpcmV0dXJuITEKcj1tLmxlbmd0aApzPWQuUQpmb3IocT0wO3E8cjsrK3EpaWYoIUgu
-V2UoYSxILmNFKGEsYixtW3FdKSxjLHNbcV0sZSkpcmV0dXJuITEKcmV0dXJuITB9LApsUjpmdW5jdGlv
-bihhKXt2YXIgdCxzPWEueQppZighKGE9PT11LlApKWlmKCFILkE4KGEpKWlmKHMhPT03KWlmKCEocz09
-PTYmJkgubFIoYS56KSkpdD1zPT09OCYmSC5sUihhLnopCmVsc2UgdD0hMAplbHNlIHQ9ITAKZWxzZSB0
-PSEwCmVsc2UgdD0hMApyZXR1cm4gdH0sCmNjOmZ1bmN0aW9uKGEpe3JldHVybiBILkE4KGEpfHxhPT09
-dS5LfSwKQTg6ZnVuY3Rpb24oYSl7dmFyIHQscz1hLnkscj1zCmlmKHIhPT0yKWlmKHIhPT0zKWlmKHIh
-PT00KWlmKHIhPT01KXt0PXUuSwppZighKGE9PT10KSlzPXM9PT03JiZhLno9PT10CmVsc2Ugcz0hMH1l
-bHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMAplbHNlIHM9ITAKcmV0dXJuIHN9LApJeDpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMscj1PYmplY3Qua2V5cyhiKSxxPXIubGVuZ3RoCmZvcih0PTA7dDxxOysrdCl7
-cz1yW3RdCmFbc109YltzXX19LApKYzpmdW5jdGlvbiBKYyhhLGIpe3ZhciBfPXRoaXMKXy5hPWEKXy5i
-PWIKXy54PV8ucj1fLmM9bnVsbApfLnk9MApfLmN5PV8uY3g9Xy5jaD1fLlE9Xy56PW51bGx9LApFVDpm
-dW5jdGlvbiBFVCgpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlvbiB1OSgpe30s
-Cng6ZnVuY3Rpb24geChhKXt0aGlzLmE9YX0sClI5OmZ1bmN0aW9uKGEpe3JldHVybiB1LmQuYihhKXx8
-dS5CLmIoYSl8fHUuZHouYihhKXx8dS5JLmIoYSl8fHUuQS5iKGEpfHx1Lmc0LmIoYSl8fHUuZzIuYihh
-KX0sCkpnOmZ1bmN0aW9uKGEpe3JldHVybiB2Lm1hbmdsZWRHbG9iYWxOYW1lc1thXX19LEo9ewpRdTpm
-dW5jdGlvbihhLGIsYyxkKXtyZXR1cm57aTphLHA6YixlOmMseDpkfX0sCmtzOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxLHA9YVt2LmRpc3BhdGNoUHJvcGVydHlOYW1lXQppZihwPT1udWxsKWlmKCQuSz09bnVs
-bCl7SC5NKCkKcD1hW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCEx
-PT09dClyZXR1cm4gcC5pCmlmKCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihh
-KQppZih0PT09cylyZXR1cm4gcC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAubigiUmV0dXJuIGludGVy
-Y2VwdG9yIGZvciAiK0guZCh0KGEscCkpKSl9cj1hLmNvbnN0cnVjdG9yCnE9cj09bnVsbD9udWxsOnJb
-JC5BKCldCmlmKHEhPW51bGwpcmV0dXJuIHEKcT1ILkcoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0
-eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQpp
-Zih0PT1udWxsKXJldHVybiBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlm
-KHR5cGVvZiByPT0iZnVuY3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLkEoKSx7dmFsdWU6
-Qy52QixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1
-cm4gQy52Qn1yZXR1cm4gQy52Qn0sClFpOmZ1bmN0aW9uKGEsYil7aWYoYTwwfHxhPjQyOTQ5NjcyOTUp
-dGhyb3cgSC5iKFAuVEUoYSwwLDQyOTQ5NjcyOTUsImxlbmd0aCIsbnVsbCkpCnJldHVybiBKLnB5KG5l
-dyBBcnJheShhKSxiKX0sCnB5OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouRXAoSC5WTShhLGIuQygiamQ8
-MD4iKSkpfSwKRXA6ZnVuY3Rpb24oYSl7YS5maXhlZCRsZW5ndGg9QXJyYXkKcmV0dXJuIGF9LAp1bjpm
-dW5jdGlvbihhKXthLmZpeGVkJGxlbmd0aD1BcnJheQphLmltbXV0YWJsZSRsaXN0PUFycmF5CnJldHVy
-biBhfSwKR2E6ZnVuY3Rpb24oYSl7aWYoYTwyNTYpc3dpdGNoKGEpe2Nhc2UgOTpjYXNlIDEwOmNhc2Ug
-MTE6Y2FzZSAxMjpjYXNlIDEzOmNhc2UgMzI6Y2FzZSAxMzM6Y2FzZSAxNjA6cmV0dXJuITAKZGVmYXVs
-dDpyZXR1cm4hMX1zd2l0Y2goYSl7Y2FzZSA1NzYwOmNhc2UgODE5MjpjYXNlIDgxOTM6Y2FzZSA4MTk0
-OmNhc2UgODE5NTpjYXNlIDgxOTY6Y2FzZSA4MTk3OmNhc2UgODE5ODpjYXNlIDgxOTk6Y2FzZSA4MjAw
-OmNhc2UgODIwMTpjYXNlIDgyMDI6Y2FzZSA4MjMyOmNhc2UgODIzMzpjYXNlIDgyMzk6Y2FzZSA4Mjg3
-OmNhc2UgMTIyODg6Y2FzZSA2NTI3OTpyZXR1cm4hMApkZWZhdWx0OnJldHVybiExfX0sCm1tOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscwpmb3IodD1hLmxlbmd0aDtiPHQ7KXtzPUMueEIuVyhhLGIpCmlmKHMhPT0z
-MiYmcyE9PTEzJiYhSi5HYShzKSlicmVhazsrK2J9cmV0dXJuIGJ9LApjMTpmdW5jdGlvbihhLGIpe3Zh
-ciB0LHMKZm9yKDtiPjA7Yj10KXt0PWItMQpzPUMueEIubShhLHQpCmlmKHMhPT0zMiYmcyE9PTEzJiYh
-Si5HYShzKSlicmVha31yZXR1cm4gYn0sClJFOmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIGEK
-aWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5w
-cm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3Mo
-YSl9LApUSjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90
-eXBlCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbCly
-ZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlw
-ZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5
-cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApV
-NjpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlm
-KGE9PW51bGwpcmV0dXJuIGEKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkpcmV0dXJuIEouamQucHJvdG90
-eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEou
-YzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLk1oKXJldHVybiBhCnJldHVybiBK
-LmtzKGEpfSwKaWE6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiKXtpZihNYXRoLmZsb29y
-KGEpPT1hKXJldHVybiBKLmJVLnByb3RvdHlwZQpyZXR1cm4gSi5WQS5wcm90b3R5cGV9aWYodHlwZW9m
-IGE9PSJzdHJpbmciKXJldHVybiBKLkRyLnByb3RvdHlwZQppZihhPT1udWxsKXJldHVybiBKLllFLnBy
-b3RvdHlwZQppZih0eXBlb2YgYT09ImJvb2xlYW4iKXJldHVybiBKLnlFLnByb3RvdHlwZQppZihhLmNv
+IiEiKXtvPUguVmEodCkKJC5ud1twXT1vCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShhLHYuZGlzcGF0Y2hQ
+cm9wZXJ0eU5hbWUse3ZhbHVlOm8sZW51bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3Vy
+YWJsZTp0cnVlfSkKcmV0dXJuIG8uaX1pZihyPT09In4iKXskLnZ2W3BdPXQKcmV0dXJuIHR9aWYocj09
+PSItIil7cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2Yo
+YSksdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxl
+OnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWlmKHI9PT0iKyIpcmV0dXJuIEguTGMo
+YSx0KQppZihyPT09IioiKXRocm93IEguYihQLlNZKHApKQppZih2LmxlYWZUYWdzW3BdPT09dHJ1ZSl7
+cT1ILlZhKHQpCk9iamVjdC5kZWZpbmVQcm9wZXJ0eShPYmplY3QuZ2V0UHJvdG90eXBlT2YoYSksdi5k
+aXNwYXRjaFByb3BlcnR5TmFtZSx7dmFsdWU6cSxlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUs
+Y29uZmlndXJhYmxlOnRydWV9KQpyZXR1cm4gcS5pfWVsc2UgcmV0dXJuIEguTGMoYSx0KX0sCkxjOmZ1
+bmN0aW9uKGEsYil7dmFyIHQ9T2JqZWN0LmdldFByb3RvdHlwZU9mKGEpCk9iamVjdC5kZWZpbmVQcm9w
+ZXJ0eSh0LHYuZGlzcGF0Y2hQcm9wZXJ0eU5hbWUse3ZhbHVlOkouUXUoYix0LG51bGwsbnVsbCksZW51
+bWVyYWJsZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIGJ9LApW
+YTpmdW5jdGlvbihhKXtyZXR1cm4gSi5RdShhLCExLG51bGwsISFhLiRpWGopfSwKVkY6ZnVuY3Rpb24o
+YSxiLGMpe3ZhciB0PWIucHJvdG90eXBlCmlmKHYubGVhZlRhZ3NbYV09PT10cnVlKXJldHVybiBILlZh
+KHQpCmVsc2UgcmV0dXJuIEouUXUodCxjLG51bGwsbnVsbCl9LApYRDpmdW5jdGlvbigpe2lmKCEwPT09
+JC5CdilyZXR1cm4KJC5Cdj0hMApILloxKCl9LApaMTpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxu
+LG0KJC5udz1PYmplY3QuY3JlYXRlKG51bGwpCiQudnY9T2JqZWN0LmNyZWF0ZShudWxsKQpILmtPKCkK
+dD12LmludGVyY2VwdG9yc0J5VGFnCnM9T2JqZWN0LmdldE93blByb3BlcnR5TmFtZXModCkKaWYodHlw
+ZW9mIHdpbmRvdyE9InVuZGVmaW5lZCIpe3dpbmRvdwpyPWZ1bmN0aW9uKCl7fQpmb3IocT0wO3E8cy5s
+ZW5ndGg7KytxKXtwPXNbcV0Kbz0kLng3LiQxKHApCmlmKG8hPW51bGwpe249SC5WRihwLHRbcF0sbykK
+aWYobiE9bnVsbCl7T2JqZWN0LmRlZmluZVByb3BlcnR5KG8sdi5kaXNwYXRjaFByb3BlcnR5TmFtZSx7
+dmFsdWU6bixlbnVtZXJhYmxlOmZhbHNlLHdyaXRhYmxlOnRydWUsY29uZmlndXJhYmxlOnRydWV9KQpy
+LnByb3RvdHlwZT1vfX19fWZvcihxPTA7cTxzLmxlbmd0aDsrK3Epe3A9c1txXQppZigvXltBLVphLXpf
+XS8udGVzdChwKSl7bT10W3BdCnRbIiEiK3BdPW0KdFsifiIrcF09bQp0WyItIitwXT1tCnRbIisiK3Bd
+PW0KdFsiKiIrcF09bX19fSwKa086ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbj1DLllxKCkKbj1I
+LnVkKEMuS1UsSC51ZChDLmZRLEgudWQoQy5pNyxILnVkKEMuaTcsSC51ZChDLnhpLEgudWQoQy5kayxI
+LnVkKEMud2IoQy5PNCksbikpKSkpKSkKaWYodHlwZW9mIGRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJh
+bnNmb3JtZXIhPSJ1bmRlZmluZWQiKXt0PWRhcnROYXRpdmVEaXNwYXRjaEhvb2tzVHJhbnNmb3JtZXIK
+aWYodHlwZW9mIHQ9PSJmdW5jdGlvbiIpdD1bdF0KaWYodC5jb25zdHJ1Y3Rvcj09QXJyYXkpZm9yKHM9
+MDtzPHQubGVuZ3RoOysrcyl7cj10W3NdCmlmKHR5cGVvZiByPT0iZnVuY3Rpb24iKW49cihuKXx8bn19
+cT1uLmdldFRhZwpwPW4uZ2V0VW5rbm93blRhZwpvPW4ucHJvdG90eXBlRm9yVGFnCiQuTkY9bmV3IEgu
+ZEMocSkKJC5UWD1uZXcgSC53TihwKQokLng3PW5ldyBILlZYKG8pfSwKdWQ6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gYShiKXx8Yn0sCnY0OmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdD1iPyJtIjoiIixzPWM/
+IiI6ImkiLHI9ZD8idSI6IiIscT1lPyJzIjoiIixwPWY/ImciOiIiLG89ZnVuY3Rpb24oZyxoKXt0cnl7
+cmV0dXJuIG5ldyBSZWdFeHAoZyxoKX1jYXRjaChuKXtyZXR1cm4gbn19KGEsdCtzK3IrcStwKQppZihv
+IGluc3RhbmNlb2YgUmVnRXhwKXJldHVybiBvCnRocm93IEguYihQLnJyKCJJbGxlZ2FsIFJlZ0V4cCBw
+YXR0ZXJuICgiK1N0cmluZyhvKSsiKSIsYSxudWxsKSl9LAptMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXJldHVybiBhLmluZGV4T2YoYixjKT49MAplbHNlIGlmKGIgaW5z
+dGFuY2VvZiBILlZSKXt0PUMueEIuRyhhLGMpCnJldHVybiBiLmIudGVzdCh0KX1lbHNle3Q9Si5GTChi
+LEMueEIuRyhhLGMpKQpyZXR1cm4hdC5nbDAodCl9fSwKQTQ6ZnVuY3Rpb24oYSl7aWYoYS5pbmRleE9m
+KCIkIiwwKT49MClyZXR1cm4gYS5yZXBsYWNlKC9cJC9nLCIkJCQkIikKcmV0dXJuIGF9LAplQTpmdW5j
+dGlvbihhKXtpZigvW1tcXXt9KCkqKz8uXFxeJHxdLy50ZXN0KGEpKXJldHVybiBhLnJlcGxhY2UoL1tb
+XF17fSgpKis/LlxcXiR8XS9nLCJcXCQmIikKcmV0dXJuIGF9LAp5czpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9SC5uTShhLGIsYykKcmV0dXJuIHR9LApuTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKaWYo
+Yj09PSIiKXtpZihhPT09IiIpcmV0dXJuIGMKdD1hLmxlbmd0aApmb3Iocz1jLHI9MDtyPHQ7KytyKXM9
+cythW3JdK2MKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9cT1hLmluZGV4T2YoYiwwKQppZihx
+PDApcmV0dXJuIGEKaWYoYS5sZW5ndGg8NTAwfHxjLmluZGV4T2YoIiQiLDApPj0wKXJldHVybiBhLnNw
+bGl0KGIpLmpvaW4oYykKcmV0dXJuIGEucmVwbGFjZShuZXcgUmVnRXhwKEguZUEoYiksJ2cnKSxILkE0
+KGMpKX0sClBEOmZ1bmN0aW9uIFBEKGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCldVOmZ1bmN0aW9u
+IFdVKCl7fSwKTFA6ZnVuY3Rpb24gTFAoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9
+YwpfLiR0aT1kfSwKWFI6ZnVuY3Rpb24gWFIoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTEk6ZnVu
+Y3Rpb24gTEkoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uZj1l
+fSwKQ2o6ZnVuY3Rpb24gQ2ooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKZjk6ZnVu
+Y3Rpb24gZjkoYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5l
+PWUKXy5mPWZ9LApXMDpmdW5jdGlvbiBXMChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYXo6ZnVuY3Rp
+b24gYXooYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKdlY6ZnVuY3Rpb24gdlYoYSl7
+dGhpcy5hPWF9LApicTpmdW5jdGlvbiBicShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQW06ZnVuY3Rp
+b24gQW0oYSl7dGhpcy5hPWF9LApYTzpmdW5jdGlvbiBYTyhhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
+ClRwOmZ1bmN0aW9uIFRwKCl7fSwKbGM6ZnVuY3Rpb24gbGMoKXt9LAp6eDpmdW5jdGlvbiB6eCgpe30s
+CnJUOmZ1bmN0aW9uIHJUKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9
+LApFcTpmdW5jdGlvbiBFcShhKXt0aGlzLmE9YX0sCmtZOmZ1bmN0aW9uIGtZKGEpe3RoaXMuYT1hfSwK
+TjU6ZnVuY3Rpb24gTjUoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51bGwK
+Xy5yPTAKXy4kdGk9YX0sCmRiOmZ1bmN0aW9uIGRiKGEsYil7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
+LmQ9Xy5jPW51bGx9LAppNTpmdW5jdGlvbiBpNShhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApONjpm
+dW5jdGlvbiBONihhLGIsYyl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9
+Y30sCmRDOmZ1bmN0aW9uIGRDKGEpe3RoaXMuYT1hfSwKd046ZnVuY3Rpb24gd04oYSl7dGhpcy5hPWF9
+LApWWDpmdW5jdGlvbiBWWChhKXt0aGlzLmE9YX0sClZSOmZ1bmN0aW9uIFZSKGEsYil7dmFyIF89dGhp
+cwpfLmE9YQpfLmI9YgpfLmQ9Xy5jPW51bGx9LApFSzpmdW5jdGlvbiBFSyhhKXt0aGlzLmI9YX0sCktX
+OmZ1bmN0aW9uIEtXKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClBiOmZ1bmN0aW9u
+IFBiKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKdFE6ZnVuY3Rp
+b24gdFEoYSxiKXt0aGlzLmE9YQp0aGlzLmM9Yn0sCnVuOmZ1bmN0aW9uIHVuKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClNkOmZ1bmN0aW9uIFNkKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8uZD1udWxsfSwKWEY6ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApEUTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IEludDhBcnJheShhKX0sCm9kOmZ1bmN0aW9uKGEsYixjKXtpZihhPj4+MCE9
+PWF8fGE+PWMpdGhyb3cgSC5iKEguSFkoYixhKSl9LApyTTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYo
+IShhPj4+MCE9PWEpKXQ9Yj4+PjAhPT1ifHxhPmJ8fGI+YwplbHNlIHQ9ITAKaWYodCl0aHJvdyBILmIo
+SC5hdShhLGIsYykpCnJldHVybiBifSwKRVQ6ZnVuY3Rpb24gRVQoKXt9LApMWjpmdW5jdGlvbiBMWigp
+e30sCkRnOmZ1bmN0aW9uIERnKCl7fSwKUGc6ZnVuY3Rpb24gUGcoKXt9LAp4ajpmdW5jdGlvbiB4aigp
+e30sCmRFOmZ1bmN0aW9uIGRFKCl7fSwKWkE6ZnVuY3Rpb24gWkEoKXt9LAp3ZjpmdW5jdGlvbiB3Zigp
+e30sClBxOmZ1bmN0aW9uIFBxKCl7fSwKZUU6ZnVuY3Rpb24gZUUoKXt9LApWNjpmdW5jdGlvbiBWNigp
+e30sClJHOmZ1bmN0aW9uIFJHKCl7fSwKVlA6ZnVuY3Rpb24gVlAoKXt9LApXQjpmdW5jdGlvbiBXQigp
+e30sClpHOmZ1bmN0aW9uIFpHKCl7fSwKeFo6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmQKcmV0dXJuIHQ9
+PW51bGw/Yi5kPUguSihhLCJiOCIsW2IuUV0pOnR9LApRMTpmdW5jdGlvbihhKXt2YXIgdD1hLnoKaWYo
+dD09PTZ8fHQ9PT03fHx0PT09OClyZXR1cm4gSC5RMShhLlEpCnJldHVybiB0PT09MTF8fHQ9PT0xMn0s
+Cm1EOmZ1bmN0aW9uKGEpe3JldHVybiBhLmRifSwKTjA6ZnVuY3Rpb24oYSl7cmV0dXJuIEguRSh2LnR5
+cGVVbml2ZXJzZSxhKX0sCkpTOmZ1bmN0aW9uKGEpe3ZhciB0PWEuJFMKaWYodCE9bnVsbCl7aWYodHlw
+ZW9mIHQ9PSJudW1iZXIiKXJldHVybiBILkJwKHQpCnJldHVybiBhLiRTKCl9cmV0dXJuIG51bGx9LApV
+ZTpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKEguUTEoYikpaWYoYSBpbnN0YW5jZW9mIEguVHApe3Q9SC5K
+UyhhKQppZih0IT1udWxsKXJldHVybiB0fXJldHVybiBILnpLKGEpfSwKeks6ZnVuY3Rpb24oYSl7dmFy
+IHQKaWYoYSBpbnN0YW5jZW9mIFAuayl7dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9aWYo
+QXJyYXkuaXNBcnJheShhKSlyZXR1cm4gSC50NihhKQpyZXR1cm4gSC5WVShKLmlhKGEpKX0sCnQ2OmZ1
+bmN0aW9uKGEpe3ZhciB0PWEuJHRpLHM9dS5iCmlmKHQ9PW51bGwpcmV0dXJuIHMKaWYodC5jb25zdHJ1
+Y3RvciE9PXMuY29uc3RydWN0b3IpcmV0dXJuIHMKcmV0dXJuIHR9LApMaDpmdW5jdGlvbihhKXt2YXIg
+dD1hLiR0aQpyZXR1cm4gdCE9bnVsbD90OkguVlUoYSl9LApWVTpmdW5jdGlvbihhKXt2YXIgdD1hLmNv
+bnN0cnVjdG9yLHM9dC4kY2NhY2hlCmlmKHMhPW51bGwpcmV0dXJuIHMKcmV0dXJuIEgucjkoYSx0KX0s
+CnI5OmZ1bmN0aW9uKGEsYil7dmFyIHQ9YSBpbnN0YW5jZW9mIEguVHA/YS5fX3Byb3RvX18uX19wcm90
+b19fLmNvbnN0cnVjdG9yOmIscz1ILmFpKHYudHlwZVVuaXZlcnNlLHQubmFtZSkKYi4kY2NhY2hlPXMK
+cmV0dXJuIHN9LApCcDpmdW5jdGlvbihhKXt2YXIgdCxzPWEscj12LnR5cGVzLHE9cltzXQppZih0eXBl
+b2YgcT09InN0cmluZyIpe3Q9SC5FKHYudHlwZVVuaXZlcnNlLHEpCnJbc109dApyZXR1cm4gdH1yZXR1
+cm4gcX0sCkpKOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMueixxPUguWU8KaWYoSC5jYyhzKSl7
+cT1ILkl3CnMuYj1zLmE9SC5obn1lbHNlIGlmKHI9PT05KXt0PXMuZGIKaWYoIktOIj09PXQpcT1ILm9r
+CmVsc2UgaWYoIkNQIj09PXQpcT1ILktICmVsc2UgaWYoIkZLIj09PXQpcT1ILktICmVsc2UgaWYoInFV
+Ij09PXQpcT1ILk1NCmVsc2UgaWYoImEyIj09PXQpcT1ILmwKZWxzZXtyPXMuUQppZihzLmNoLmV2ZXJ5
+KEguY2MpKXtzLng9IiRpIityCnE9SC50NH19fXMuYz1xCnJldHVybiBzLmMoYSl9LApZTzpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzCnJldHVybiBILldlKHYudHlwZVVuaXZlcnNlLEguVWUoYSx0KSxudWxsLHQs
+bnVsbCl9LAp0NDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLngKaWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1
+cm4hIWFbdF0KcmV0dXJuISFKLmlhKGEpW3RdfSwKT3o6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVs
+bClyZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlE1KEguV0soYSxI
+LlVlKGEsdCksSC5kbSh0LG51bGwpKSkpfSwKQXY6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbCly
+ZXR1cm4gYQp0PXRoaXMKaWYodC5jKGEpKXJldHVybiBhCnRocm93IEguYihILlpjKEguV0soYSxILlVl
+KGEsdCksSC5kbSh0LG51bGwpKSkpfSwKRGg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9bnVsbAppZihI
+LldlKHYudHlwZVVuaXZlcnNlLGEsdCxiLHQpKXJldHVybiBhCnRocm93IEguYihILlpjKCJUaGUgdHlw
+ZSBhcmd1bWVudCAnIitILmQoSC5kbShhLHQpKSsiJyBpcyBub3QgYSBzdWJ0eXBlIG9mIHRoZSB0eXBl
+IHZhcmlhYmxlIGJvdW5kICciK0guZChILmRtKGIsdCkpKyInIG9mIHR5cGUgdmFyaWFibGUgJyIrYysi
+JyBpbiAnIitILmQoZCkrIicuIikpfSwKV0s6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAucChhKSxzPUgu
+ZG0oYj09bnVsbD9ILnpLKGEpOmIsbnVsbCkKcmV0dXJuIHQrIjogdHlwZSAnIitILmQocykrIicgaXMg
+bm90IGEgc3VidHlwZSBvZiB0eXBlICciK0guZChjKSsiJyJ9LApRNTpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IEguaHooIkNhc3RFcnJvcjogIithKX0sClB2OmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmh6
+KCJDYXN0RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKWmM6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBI
+LmlNKCJUeXBlRXJyb3I6ICIrYSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILmlNKCJUeXBl
+RXJyb3I6ICIrSC5XSyhhLG51bGwsYikpfSwKSXc6ZnVuY3Rpb24oYSl7cmV0dXJuITB9LApobjpmdW5j
+dGlvbihhKXtyZXR1cm4gYX0sCmw6ZnVuY3Rpb24oYSl7cmV0dXJuITA9PT1hfHwhMT09PWF9LApFOTpm
+dW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSlyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRo
+cm93IEguYihILlB2KGEsImJvb2wiKSl9LAp4ZDpmdW5jdGlvbihhKXtpZighMD09PWF8fCExPT09YSly
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiYm9vbCIpKX0sCmRqOmZ1
+bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBh
+CnRocm93IEguYihILlB2KGEsImRvdWJsZSIpKX0sCklnOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0i
+bnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiZG91Ymxl
+IikpfSwKb2s6ZnVuY3Rpb24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIiYmTWF0aC5mbG9vcihh
+KT09PWF9LApXWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09Im51bWJlciImJk1hdGguZmxvb3IoYSk9
+PT1hKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJuIGEKdGhyb3cgSC5iKEguUHYoYSwiaW50IikpfSwK
+U2M6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1iZXIiJiZNYXRoLmZsb29yKGEpPT09YSlyZXR1
+cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwiaW50IikpfSwKS0g6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHR5cGVvZiBhPT0ibnVtYmVyIn0sClZZOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBh
+PT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIm51
+bSIpKX0sCkROOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZihhPT1u
+dWxsKXJldHVybiBhCnRocm93IEguYihILnEoYSwibnVtIikpfSwKTU06ZnVuY3Rpb24oYSl7cmV0dXJu
+IHR5cGVvZiBhPT0ic3RyaW5nIn0sCmMwOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0ic3RyaW5nIily
+ZXR1cm4gYQppZihhPT1udWxsKXJldHVybiBhCnRocm93IEguYihILlB2KGEsIlN0cmluZyIpKX0sCnk6
+ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJzdHJpbmciKXJldHVybiBhCmlmKGE9PW51bGwpcmV0dXJu
+IGEKdGhyb3cgSC5iKEgucShhLCJTdHJpbmciKSl9LAppbzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpm
+b3IodD0iIixzPSIiLHI9MDtyPGEubGVuZ3RoOysrcixzPSIsICIpdCs9Qy54Qi5oKHMsSC5kbShhW3Jd
+LGIpKQpyZXR1cm4gdH0sCmJJOmZ1bmN0aW9uKGEwLGExLGEyKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
+ayxqLGksaCxnLGYsZSxkLGMsYixhPSIsICIKaWYoYTIhPW51bGwpe3Q9YTIubGVuZ3RoCmlmKGExPT1u
+dWxsKXthMT1ILlZNKFtdLHUucykKcz1udWxsfWVsc2Ugcz1hMS5sZW5ndGgKcj1hMS5sZW5ndGgKZm9y
+KHE9dDtxPjA7LS1xKUMuTm0uaShhMSwiVCIrKHIrcSkpCmZvcihwPSI8IixvPSIiLHE9MDtxPHQ7Kytx
+LG89YSl7cCs9bwpuPWExLmxlbmd0aAptPW4tMS1xCmlmKG08MClyZXR1cm4gSC5PSChhMSxtKQpwPUMu
+eEIuaChwLGExW21dKQpsPWEyW3FdCmlmKCFILmNjKGwpKXArPUMueEIuaCgiIGV4dGVuZHMgIixILmRt
+KGwsYTEpKX1wKz0iPiJ9ZWxzZXtwPSIiCnM9bnVsbH1uPWEwLlEKaz1hMC5jaApqPWsuYQppPWoubGVu
+Z3RoCmg9ay5iCmc9aC5sZW5ndGgKZj1rLmMKZT1mLmxlbmd0aApkPUguZG0obixhMSkKZm9yKGM9IiIs
+Yj0iIixxPTA7cTxpOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShqW3FdLGExKSkKaWYoZz4wKXtjKz1i
+KyJbIgpmb3IoYj0iIixxPTA7cTxnOysrcSxiPWEpYys9Qy54Qi5oKGIsSC5kbShoW3FdLGExKSkKYys9
+Il0ifWlmKGU+MCl7Yys9YisieyIKZm9yKGI9IiIscT0wO3E8ZTtxKz0yLGI9YSljKz1DLnhCLmgoYixI
+LmRtKGZbcSsxXSxhMSkpKyIgIitmW3FdCmMrPSJ9In1pZihzIT1udWxsKWExLmxlbmd0aD1zCnJldHVy
+biBwKyIoIitjKyIpID0+ICIrSC5kKGQpfSwKZG06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEu
+egppZihwPT09NSlyZXR1cm4iZXJhc2VkIgppZihwPT09MilyZXR1cm4iZHluYW1pYyIKaWYocD09PTMp
+cmV0dXJuInZvaWQiCmlmKHA9PT0xKXJldHVybiJOZXZlciIKaWYocD09PTQpcmV0dXJuImFueSIKaWYo
+cD09PTYpcmV0dXJuIEguZChILmRtKGEuUSxiKSkrIioiCmlmKHA9PT03KXJldHVybiBILmQoSC5kbShh
+LlEsYikpKyI/IgppZihwPT09OClyZXR1cm4iRnV0dXJlT3I8IitILmQoSC5kbShhLlEsYikpKyI+Igpp
+ZihwPT09OSl7dD1ILm8zKGEuUSkKcz1hLmNoCnJldHVybiBzLmxlbmd0aCE9PTA/dCsoIjwiK0guaW8o
+cyxiKSsiPiIpOnR9aWYocD09PTExKXJldHVybiBILmJJKGEsYixudWxsKQppZihwPT09MTIpcmV0dXJu
+IEguYkkoYS5RLGIsYS5jaCkKaWYocD09PTEzKXtyPWEuUQpxPWIubGVuZ3RoCnI9cS0xLXIKaWYocjww
+fHxyPj1xKXJldHVybiBILk9IKGIscikKcmV0dXJuIGJbcl19cmV0dXJuIj8ifSwKbzM6ZnVuY3Rpb24o
+YSl7dmFyIHQscz1ILkpnKGEpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD0ibWluaWZpZWQ6IithCnJldHVy
+biB0fSwKUW86ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLnRSW2JdCmZvcig7dHlwZW9mIHQ9PSJzdHJpbmci
+Oyl0PWEudFJbdF0KcmV0dXJuIHR9LAphaTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1hLmVU
+LG49b1tiXQppZihuPT1udWxsKXJldHVybiBILkUoYSxiKQplbHNlIGlmKHR5cGVvZiBuPT0ibnVtYmVy
+Iil7dD1uCnM9SC5tKGEsNSwiIyIpCnI9W10KZm9yKHE9MDtxPHQ7KytxKXIucHVzaChzKQpwPUguSihh
+LGIscikKb1tiXT1wCnJldHVybiBwfWVsc2UgcmV0dXJuIG59LAp4YjpmdW5jdGlvbihhLGIpe3JldHVy
+biBILkl4KGEudFIsYil9LApGRjpmdW5jdGlvbihhLGIpe3JldHVybiBILkl4KGEuZVQsYil9LApFOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz1hLmVDLHI9cy5nZXQoYikKaWYociE9bnVsbClyZXR1cm4gcgp0PUgu
+eihhLG51bGwsYikKcy5zZXQoYix0KQpyZXR1cm4gdH0sCmNFOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxz
+LHI9Yi5jeAppZihyPT1udWxsKXI9Yi5jeD1uZXcgTWFwKCkKdD1yLmdldChjKQppZih0IT1udWxsKXJl
+dHVybiB0CnM9SC56KGEsYixjKQpyLnNldChjLHMpCnJldHVybiBzfSwKdjU6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0LHMscixxPWIuY3kKaWYocT09bnVsbClxPWIuY3k9bmV3IE1hcCgpCnQ9Yy5kYgpzPXEuZ2V0
+KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1ILmEoYSxiLGMuej09PTEwP2MuY2g6W2NdKQpxLnNldCh0
+LHIpCnJldHVybiByfSwKejpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5pKEgubyhhLGIsYykpCnJldHVy
+biB0fSwKV0c6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmRiCmEuZUMuc2V0KHQsYikKYi5hPUguT3oKYi5i
+PUguQXYKYi5jPUguSkoKcmV0dXJuIGJ9LAptOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPWEuZUMuZ2V0
+KGMpCmlmKHMhPW51bGwpcmV0dXJuIHMKdD1uZXcgSC5KYyhudWxsLG51bGwsbnVsbCkKdC56PWIKdC5k
+Yj1jCnJldHVybiBILldHKGEsdCl9LAp2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHM9YS5lQy5nZXQo
+ZCkKaWYocyE9bnVsbClyZXR1cm4gcwp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxsKQp0Lno9Ygp0LlE9
+Ywp0LmRiPWQKcmV0dXJuIEguV0coYSx0KX0sCkg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPSIiK2IrIl4i
+LHI9YS5lQy5nZXQocykKaWYociE9bnVsbClyZXR1cm4gcgp0PW5ldyBILkpjKG51bGwsbnVsbCxudWxs
+KQp0Lno9MTMKdC5RPWIKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApVeDpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscT1hLmxlbmd0aApmb3IodD0iIixzPSIiLHI9MDtyPHE7KytyLHM9IiwiKXQrPXMrYVtyXS5k
+YgpyZXR1cm4gdH0sClM0OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbz1hLmxlbmd0aApmb3IodD0i
+IixzPSIiLHI9MDtyPG87cis9MixzPSIsIil7cT1hW3JdCnA9YVtyKzFdLmRiCnQrPXMrcSsiOiIrcH1y
+ZXR1cm4gdH0sCko6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj1iCmlmKGMubGVuZ3RoIT09MClyKz0i
+PCIrSC5VeChjKSsiPiIKdD1hLmVDLmdldChyKQppZih0IT1udWxsKXJldHVybiB0CnM9bmV3IEguSmMo
+bnVsbCxudWxsLG51bGwpCnMuej05CnMuUT1iCnMuY2g9YwppZihjLmxlbmd0aD4wKXMuZD1jWzBdCnMu
+ZGI9cgpyZXR1cm4gSC5XRyhhLHMpfSwKYTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscAppZihi
+Lno9PT0xMCl7dD1iLlEKcz1iLmNoLmNvbmNhdChjKX1lbHNle3M9Ywp0PWJ9cj10LmRiKyI7IisoIjwi
+K0guVXgocykrIj4iKQpxPWEuZUMuZ2V0KHIpCmlmKHEhPW51bGwpcmV0dXJuIHEKcD1uZXcgSC5KYyhu
+dWxsLG51bGwsbnVsbCkKcC56PTEwCnAuUT10CnAuY2g9cwpwLmRiPXIKcmV0dXJuIEguV0coYSxwKX0s
+CkM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxPWIuZGIscD1jLmEsbz1wLmxlbmd0aCxuPWMuYixt
+PW4ubGVuZ3RoLGw9Yy5jLGs9bC5sZW5ndGgsaj0iKCIrSC5VeChwKQppZihtPjApais9KG8+MD8iLCI6
+IiIpKyJbIitILlV4KG4pKyJdIgppZihrPjApais9KG8+MD8iLCI6IiIpKyJ7IitILlM0KGwpKyJ9Igp0
+PXErKGorIikiKQpzPWEuZUMuZ2V0KHQpCmlmKHMhPW51bGwpcmV0dXJuIHMKcj1uZXcgSC5KYyhudWxs
+LG51bGwsbnVsbCkKci56PTExCnIuUT1iCnIuY2g9YwpyLmRiPXQKcmV0dXJuIEguV0coYSxyKX0sCkQ6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yi5kYisiPCIrSC5VeChjKSsiPiIscj1hLmVDLmdldChzKQpp
+ZihyIT1udWxsKXJldHVybiByCnQ9bmV3IEguSmMobnVsbCxudWxsLG51bGwpCnQuej0xMgp0LlE9Ygp0
+LmNoPWMKdC5kYj1zCnJldHVybiBILldHKGEsdCl9LApvOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm57dTph
+LGU6YixyOmMsczpbXSxwOjB9fSwKaTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxq
+LGksaCxnPWEucixmPWEucwpmb3IodD1nLmxlbmd0aCxzPTA7czx0Oyl7cj1nLmNoYXJDb2RlQXQocykK
+aWYocj49NDgmJnI8PTU3KXM9SC5BKHMrMSxyLGcsZikKZWxzZSBpZigoKChyfDMyKT4+PjApLTk3JjY1
+NTM1KTwyNnx8cj09PTk1fHxyPT09MzYpcz1ILnQoYSxzLGcsZiwhMSkKZWxzZSBpZihyPT09NDYpcz1I
+LnQoYSxzLGcsZiwhMCkKZWxzZXsrK3MKc3dpdGNoKHIpe2Nhc2UgNDQ6YnJlYWsKY2FzZSA1ODpicmVh
+awpjYXNlIDU5OmYucHVzaChILksoYS51LGEuZSxmLnBvcCgpKSkKYnJlYWsKY2FzZSA5NDpmLnB1c2go
+SC5IKGEudSxmLnBvcCgpKSkKYnJlYWsKY2FzZSAzNTpmLnB1c2goSC5tKGEudSw1LCIjIikpCmJyZWFr
+CmNhc2UgNjQ6Zi5wdXNoKEgubShhLnUsMiwiQCIpKQpicmVhawpjYXNlIDEyNjpmLnB1c2goSC5tKGEu
+dSwzLCJ+IikpCmJyZWFrCmNhc2UgNjA6Zi5wdXNoKGEucCkKYS5wPWYubGVuZ3RoCmJyZWFrCmNhc2Ug
+NjI6cT1hLnUKcD1mLnNwbGljZShhLnApCkgucihhLnUsYS5lLHApCmEucD1mLnBvcCgpCm89Zi5wb3Ao
+KQppZih0eXBlb2Ygbz09InN0cmluZyIpZi5wdXNoKEguSihxLG8scCkpCmVsc2V7bj1ILksocSxhLmUs
+bykKc3dpdGNoKG4ueil7Y2FzZSAxMTpmLnB1c2goSC5EKHEsbixwKSkKYnJlYWsKZGVmYXVsdDpmLnB1
+c2goSC5hKHEsbixwKSkKYnJlYWt9fWJyZWFrCmNhc2UgMzg6SC5JKGEsZikKYnJlYWsKY2FzZSA0Mjpt
+PWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNixsLGwuZGIrIioiKSkKYnJlYWsK
+Y2FzZSA2MzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sNyxsLGwuZGIrIj8i
+KSkKYnJlYWsKY2FzZSA0NzptPWEudQpsPUguSyhtLGEuZSxmLnBvcCgpKQpmLnB1c2goSC52KG0sOCxs
+LGwuZGIrIi8iKSkKYnJlYWsKY2FzZSA0MDpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgKYnJlYWsKY2Fz
+ZSA0MTpxPWEudQprPW5ldyBILkcoKQpqPXEuc0VBCmk9cS5zRUEKbz1mLnBvcCgpCmlmKHR5cGVvZiBv
+PT0ibnVtYmVyIilzd2l0Y2gobyl7Y2FzZS0xOmo9Zi5wb3AoKQpicmVhawpjYXNlLTI6aT1mLnBvcCgp
+CmJyZWFrCmRlZmF1bHQ6Zi5wdXNoKG8pCmJyZWFrfWVsc2UgZi5wdXNoKG8pCnA9Zi5zcGxpY2UoYS5w
+KQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQprLmE9cAprLmI9agprLmM9aQpmLnB1c2goSC5DKHEs
+SC5LKHEsYS5lLGYucG9wKCkpLGspKQpicmVhawpjYXNlIDkxOmYucHVzaChhLnApCmEucD1mLmxlbmd0
+aApicmVhawpjYXNlIDkzOnA9Zi5zcGxpY2UoYS5wKQpILnIoYS51LGEuZSxwKQphLnA9Zi5wb3AoKQpm
+LnB1c2gocCkKZi5wdXNoKC0xKQpicmVhawpjYXNlIDEyMzpmLnB1c2goYS5wKQphLnA9Zi5sZW5ndGgK
+YnJlYWsKY2FzZSAxMjU6cD1mLnNwbGljZShhLnApCkguQihhLnUsYS5lLHApCmEucD1mLnBvcCgpCmYu
+cHVzaChwKQpmLnB1c2goLTIpCmJyZWFrCmRlZmF1bHQ6dGhyb3ciQmFkIGNoYXJhY3RlciAiK3J9fX1o
+PWYucG9wKCkKcmV0dXJuIEguSyhhLnUsYS5lLGgpfSwKQTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxz
+LHI9Yi00OApmb3IodD1jLmxlbmd0aDthPHQ7KythKXtzPWMuY2hhckNvZGVBdChhKQppZighKHM+PTQ4
+JiZzPD01NykpYnJlYWsKcj1yKjEwKyhzLTQ4KX1kLnB1c2gocikKcmV0dXJuIGF9LAp0OmZ1bmN0aW9u
+KGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG49YisxCmZvcih0PWMubGVuZ3RoO248dDsrK24pe3M9
+Yy5jaGFyQ29kZUF0KG4pCmlmKHM9PT00Nil7aWYoZSlicmVhawplPSEwfWVsc2V7aWYoISgoKChzfDMy
+KT4+PjApLTk3JjY1NTM1KTwyNnx8cz09PTk1fHxzPT09MzYpKXI9cz49NDgmJnM8PTU3CmVsc2Ugcj0h
+MAppZighcilicmVha319cT1jLnN1YnN0cmluZyhiLG4pCmlmKGUpe3Q9YS51CnA9YS5lCmlmKHAuej09
+PTEwKXA9cC5RCm89SC5Rbyh0LHAuUSlbcV0KaWYobz09bnVsbClILnZoKCdObyAiJytxKyciIGluICIn
+K0gubUQocCkrJyInKQpkLnB1c2goSC5jRSh0LHAsbykpfWVsc2UgZC5wdXNoKHEpCnJldHVybiBufSwK
+STpmdW5jdGlvbihhLGIpe3ZhciB0PWIucG9wKCkKaWYoMD09PXQpe2IucHVzaChILm0oYS51LDEsIjAm
+IikpCnJldHVybn1pZigxPT09dCl7Yi5wdXNoKEgubShhLnUsNCwiMSYiKSkKcmV0dXJufXRocm93IEgu
+YihQLmhWKCJVbmV4cGVjdGVkIGV4dGVuZGVkIG9wZXJhdGlvbiAiK0guZCh0KSkpfSwKSzpmdW5jdGlv
+bihhLGIsYyl7aWYodHlwZW9mIGM9PSJzdHJpbmciKXJldHVybiBILkooYSxjLGEuc0VBKQplbHNlIGlm
+KHR5cGVvZiBjPT0ibnVtYmVyIilyZXR1cm4gSC5UVihhLGIsYykKZWxzZSByZXR1cm4gY30sCnI6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MDt0PHM7Kyt0KWNbdF09SC5LKGEsYixj
+W3RdKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9Yy5sZW5ndGgKZm9yKHQ9MTt0PHM7dCs9Milj
+W3RdPUguSyhhLGIsY1t0XSl9LApUVjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyPWIuegppZihyPT09
+MTApe2lmKGM9PT0wKXJldHVybiBiLlEKdD1iLmNoCnM9dC5sZW5ndGgKaWYoYzw9cylyZXR1cm4gdFtj
+LTFdCmMtPXMKYj1iLlEKcj1iLnp9ZWxzZSBpZihjPT09MClyZXR1cm4gYgppZihyIT09OSl0aHJvdyBI
+LmIoUC5oVigiSW5kZXhlZCBiYXNlIG11c3QgYmUgYW4gaW50ZXJmYWNlIHR5cGUiKSkKdD1iLmNoCmlm
+KGM8PXQubGVuZ3RoKXJldHVybiB0W2MtMV0KdGhyb3cgSC5iKFAuaFYoIkJhZCBpbmRleCAiK2MrIiBm
+b3IgIitiLncoMCkpKX0sCldlOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscCxvLG4sbSxs
+LGsKaWYoYj09PWQpcmV0dXJuITAKaWYoSC5jYyhkKSlyZXR1cm4hMAp0PWIuegppZih0PT09NClyZXR1
+cm4hMAppZihILmNjKGIpKXJldHVybiExCmlmKGI9PT11LlApcmV0dXJuITAKcz10PT09MTMKaWYocylp
+ZihILldlKGEsY1tiLlFdLGMsZCxlKSlyZXR1cm4hMApyPWQuegppZih0PT09NilyZXR1cm4gSC5XZShh
+LGIuUSxjLGQsZSkKaWYocj09PTYpe3E9ZC5RCnJldHVybiBILldlKGEsYixjLHEsZSl9aWYodD09PTgp
+e2lmKCFILldlKGEsYi5RLGMsZCxlKSlyZXR1cm4hMQpyZXR1cm4gSC5XZShhLEgueFooYSxiKSxjLGQs
+ZSl9aWYodD09PTcpe3E9SC5XZShhLGIuUSxjLGQsZSkKcmV0dXJuIHF9aWYocj09PTgpe2lmKEguV2Uo
+YSxiLGMsZC5RLGUpKXJldHVybiEwCnJldHVybiBILldlKGEsYixjLEgueFooYSxkKSxlKX1pZihyPT09
+Nyl7cT1ILldlKGEsYixjLGQuUSxlKQpyZXR1cm4gcX1pZihzKXJldHVybiExCnE9dCE9PTExCmlmKCgh
+cXx8dD09PTEyKSYmZD09PXUuWilyZXR1cm4hMAppZihyPT09MTIpe2lmKGI9PT11LmcpcmV0dXJuITAK
+aWYodCE9PTEyKXJldHVybiExCnA9Yi5jaApvPWQuY2gKbj1wLmxlbmd0aAppZihuIT09by5sZW5ndGgp
+cmV0dXJuITEKZm9yKHE9dS5hdixtPTA7bTxuOysrbSl7bD1wW21dCms9b1ttXQpxLmIobCkKcS5iKGsp
+CmlmKCFILldlKGEsbCxjLGssZSl8fCFILldlKGEsayxlLGwsYykpcmV0dXJuITF9Yz1jPT1udWxsP3A6
+cC5jb25jYXQoYykKZT1lPT1udWxsP286by5jb25jYXQoZSkKcmV0dXJuIEguYk8oYSxiLlEsYyxkLlEs
+ZSl9aWYocj09PTExKXtpZihiPT09dS5nKXJldHVybiEwCmlmKHEpcmV0dXJuITEKcmV0dXJuIEguYk8o
+YSxiLGMsZCxlKX1pZih0PT09OSl7aWYociE9PTkpcmV0dXJuITEKcmV0dXJuIEgucEcoYSxiLGMsZCxl
+KX1yZXR1cm4hMX0sCmJPOmZ1bmN0aW9uKGEwLGExLGEyLGEzLGE0KXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGksaCxnLGYsZSxkLGMsYixhCmlmKCFILldlKGEwLGExLlEsYTIsYTMuUSxhNCkpcmV0dXJu
+ITEKdD1hMS5jaApzPWEzLmNoCnI9dC5hCnE9cy5hCnA9ci5sZW5ndGgKbz1xLmxlbmd0aAppZihwPm8p
+cmV0dXJuITEKbj1vLXAKbT10LmIKbD1zLmIKaz1tLmxlbmd0aApqPWwubGVuZ3RoCmlmKHArazxvK2op
+cmV0dXJuITEKZm9yKGk9MDtpPHA7KytpKXtoPXJbaV0KaWYoIUguV2UoYTAscVtpXSxhNCxoLGEyKSly
+ZXR1cm4hMX1mb3IoaT0wO2k8bjsrK2kpe2g9bVtpXQppZighSC5XZShhMCxxW3AraV0sYTQsaCxhMikp
+cmV0dXJuITF9Zm9yKGk9MDtpPGo7KytpKXtoPW1bbitpXQppZighSC5XZShhMCxsW2ldLGE0LGgsYTIp
+KXJldHVybiExfWc9dC5jCmY9cy5jCmU9Zy5sZW5ndGgKZD1mLmxlbmd0aApmb3IoaT0wLGM9MDtjPGQ7
+Yys9Mil7Yj1mW2NdCmRve2lmKGk+PWUpcmV0dXJuITEKYT1nW2ldCmkrPTJ9d2hpbGUoYTxiKQppZihi
+PGEpcmV0dXJuITEKaD1nW2ktMV0KaWYoIUguV2UoYTAsZltjKzFdLGE0LGgsYTIpKXJldHVybiExfXJl
+dHVybiEwfSwKcEc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9Yi5RLGs9
+ZC5RCmlmKGw9PT1rKXt0PWIuY2gKcz1kLmNoCnI9dC5sZW5ndGgKZm9yKHE9MDtxPHI7KytxKXtwPXRb
+cV0Kbz1zW3FdCmlmKCFILldlKGEscCxjLG8sZSkpcmV0dXJuITF9cmV0dXJuITB9bj1ILlFvKGEsbCkK
+aWYobj09bnVsbClyZXR1cm4hMQptPW5ba10KaWYobT09bnVsbClyZXR1cm4hMQpyPW0ubGVuZ3RoCnM9
+ZC5jaApmb3IocT0wO3E8cjsrK3EpaWYoIUguV2UoYSxILmNFKGEsYixtW3FdKSxjLHNbcV0sZSkpcmV0
+dXJuITEKcmV0dXJuITB9LApjYzpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PT11LkspcmV0dXJuITAK
+dD1hLnoKaWYodCE9PTIpaWYodCE9PTMpaWYodCE9PTQpaWYodCE9PTUpcz10PT09OCYmSC5jYyhhLlEp
+CmVsc2Ugcz0hMAplbHNlIHM9ITAKZWxzZSBzPSEwCmVsc2Ugcz0hMApyZXR1cm4gc30sCkl4OmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyPU9iamVjdC5rZXlzKGIpLHE9ci5sZW5ndGgKZm9yKHQ9MDt0PHE7Kyt0
+KXtzPXJbdF0KYVtzXT1iW3NdfX0sCkpjOmZ1bmN0aW9uIEpjKGEsYixjKXt2YXIgXz10aGlzCl8uYT1h
+Cl8uYj1iCl8uYz1jCl8ueT1fLng9Xy5kPW51bGwKXy56PTAKXy5kYj1fLmN5PV8uY3g9Xy5jaD1fLlE9
+bnVsbH0sCkc6ZnVuY3Rpb24gRygpe3RoaXMuYz10aGlzLmI9dGhpcy5hPW51bGx9LAp1OTpmdW5jdGlv
+biB1OSgpe30sCmh6OmZ1bmN0aW9uIGh6KGEpe3RoaXMuYT1hfSwKaU06ZnVuY3Rpb24gaU0oYSl7dGhp
+cy5hPWF9LApSOTpmdW5jdGlvbihhKXtyZXR1cm4gdS5kLmMoYSl8fHUuQi5jKGEpfHx1LmR6LmMoYSl8
+fHUuSS5jKGEpfHx1LkEuYyhhKXx8dS5nNC5jKGEpfHx1LmcyLmMoYSl9LApKZzpmdW5jdGlvbihhKXty
+ZXR1cm4gdi5tYW5nbGVkR2xvYmFsTmFtZXNbYV19fSxKPXsKUXU6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0
+dXJue2k6YSxwOmIsZTpjLHg6ZH19LAprczpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwPWFbdi5kaXNw
+YXRjaFByb3BlcnR5TmFtZV0KaWYocD09bnVsbClpZigkLkJ2PT1udWxsKXtILlhEKCkKcD1hW3YuZGlz
+cGF0Y2hQcm9wZXJ0eU5hbWVdfWlmKHAhPW51bGwpe3Q9cC5wCmlmKCExPT09dClyZXR1cm4gcC5pCmlm
+KCEwPT09dClyZXR1cm4gYQpzPU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT09cylyZXR1cm4g
+cC5pCmlmKHAuZT09PXMpdGhyb3cgSC5iKFAuU1koIlJldHVybiBpbnRlcmNlcHRvciBmb3IgIitILmQo
+dChhLHApKSkpfXI9YS5jb25zdHJ1Y3RvcgpxPXI9PW51bGw/bnVsbDpyWyQuVU4oKV0KaWYocSE9bnVs
+bClyZXR1cm4gcQpxPUgudzMoYSkKaWYocSE9bnVsbClyZXR1cm4gcQppZih0eXBlb2YgYT09ImZ1bmN0
+aW9uIilyZXR1cm4gQy5ERwp0PU9iamVjdC5nZXRQcm90b3R5cGVPZihhKQppZih0PT1udWxsKXJldHVy
+biBDLlpRCmlmKHQ9PT1PYmplY3QucHJvdG90eXBlKXJldHVybiBDLlpRCmlmKHR5cGVvZiByPT0iZnVu
+Y3Rpb24iKXtPYmplY3QuZGVmaW5lUHJvcGVydHkociwkLlVOKCkse3ZhbHVlOkMudkIsZW51bWVyYWJs
+ZTpmYWxzZSx3cml0YWJsZTp0cnVlLGNvbmZpZ3VyYWJsZTp0cnVlfSkKcmV0dXJuIEMudkJ9cmV0dXJu
+IEMudkJ9LApRaTpmdW5jdGlvbihhLGIpe2lmKGE8MHx8YT40Mjk0OTY3Mjk1KXRocm93IEguYihQLlRF
+KGEsMCw0Mjk0OTY3Mjk1LCJsZW5ndGgiLG51bGwpKQpyZXR1cm4gSi5weShuZXcgQXJyYXkoYSksYil9
+LApweTpmdW5jdGlvbihhLGIpe3JldHVybiBKLkVwKEguVk0oYSxiLkMoImpkPDA+IikpKX0sCkVwOmZ1
+bmN0aW9uKGEpe2EuZml4ZWQkbGVuZ3RoPUFycmF5CnJldHVybiBhfSwKekM6ZnVuY3Rpb24oYSl7YS5m
+aXhlZCRsZW5ndGg9QXJyYXkKYS5pbW11dGFibGUkbGlzdD1BcnJheQpyZXR1cm4gYX0sCkdhOmZ1bmN0
+aW9uKGEpe2lmKGE8MjU2KXN3aXRjaChhKXtjYXNlIDk6Y2FzZSAxMDpjYXNlIDExOmNhc2UgMTI6Y2Fz
+ZSAxMzpjYXNlIDMyOmNhc2UgMTMzOmNhc2UgMTYwOnJldHVybiEwCmRlZmF1bHQ6cmV0dXJuITF9c3dp
+dGNoKGEpe2Nhc2UgNTc2MDpjYXNlIDgxOTI6Y2FzZSA4MTkzOmNhc2UgODE5NDpjYXNlIDgxOTU6Y2Fz
+ZSA4MTk2OmNhc2UgODE5NzpjYXNlIDgxOTg6Y2FzZSA4MTk5OmNhc2UgODIwMDpjYXNlIDgyMDE6Y2Fz
+ZSA4MjAyOmNhc2UgODIzMjpjYXNlIDgyMzM6Y2FzZSA4MjM5OmNhc2UgODI4NzpjYXNlIDEyMjg4OmNh
+c2UgNjUyNzk6cmV0dXJuITAKZGVmYXVsdDpyZXR1cm4hMX19LAptbTpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKZm9yKHQ9YS5sZW5ndGg7Yjx0Oyl7cz1DLnhCLlcoYSxiKQppZihzIT09MzImJnMhPT0xMyYmIUou
+R2EocykpYnJlYWs7KytifXJldHVybiBifSwKYzE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmZvcig7Yj4w
+O2I9dCl7dD1iLTEKcz1DLnhCLm0oYSx0KQppZihzIT09MzImJnMhPT0xMyYmIUouR2EocykpYnJlYWt9
+cmV0dXJuIGJ9LApSRTpmdW5jdGlvbihhKXtpZihhPT1udWxsKXJldHVybiBhCmlmKHR5cGVvZiBhIT0i
+b2JqZWN0Iil7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVy
+biBhfWlmKGEgaW5zdGFuY2VvZiBQLmspcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApUSjpmdW5jdGlv
+bihhKXtpZih0eXBlb2YgYT09Im51bWJlciIpcmV0dXJuIEoucUkucHJvdG90eXBlCmlmKHR5cGVvZiBh
+PT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNv
 bnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3Qi
 KXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYo
-YSBpbnN0YW5jZW9mIFAuTWgpcmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtp
-Zih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJu
-IGEKaWYoIShhIGluc3RhbmNlb2YgUC5NaCkpcmV0dXJuIEoua2QucHJvdG90eXBlCnJldHVybiBhfSwK
-dzE6ZnVuY3Rpb24oYSl7aWYoYT09bnVsbClyZXR1cm4gYQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSly
-ZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEhPSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1
-bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuTWgp
-cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApBYzpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5aKGEp
-fSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApDaTpmdW5j
-dGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAoYSl9LApGTDpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZ
-KGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVybiBKLncxKGEpLkUoYSxiKX0sCkdyOmZ1
-bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0sCkg6ZnVuY3Rpb24oYSl7cmV0dXJuIEouVTYo
-YSkuZ0EoYSl9LApJVDpmdW5jdGlvbihhKXtyZXR1cm4gSi53MShhKS5na3ooYSl9LApKeTpmdW5jdGlv
-bihhLGIpe3JldHVybiBKLmlhKGEpLmU3KGEsYil9LApLVjpmdW5jdGlvbihhLGIpe3JldHVybiBKLnJZ
-KGEpLkcoYSxiKX0sCkx0OmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLndnKGEpfSwKTTE6ZnVuY3Rp
-b24oYSxiLGMpe3JldHVybiBKLncxKGEpLkUyKGEsYixjKX0sCk11OmZ1bmN0aW9uKGEsYil7cmV0dXJu
-IEouUkUoYSkuc1AoYSxiKX0sClF6OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkuVyhhLGIpfSwK
-Uk06ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKXJldHVybiBiPT1udWxsCmlmKHR5cGVvZiBhIT0ib2Jq
-ZWN0IilyZXR1cm4gYiE9bnVsbCYmYT09PWIKcmV0dXJuIEouaWEoYSkuRE4oYSxiKX0sClQwOmZ1bmN0
-aW9uKGEpe3JldHVybiBKLnJZKGEpLmJTKGEpfSwKYTY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShh
-KS5tKGEsYil9LApiVDpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5ENChhKX0sCmNIOmZ1bmN0aW9u
-KGEpe3JldHVybiBKLnJZKGEpLmhjKGEpfSwKZFI6ZnVuY3Rpb24oYSl7cmV0dXJuIEouUkUoYSkuZ1Ao
-YSl9LApkWjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gSi5SRShhKS5PbihhLGIsYyxkKX0sCmRnOmZ1
-bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLnJZKGEpLmk3KGEsYixjLGQpfSwKZGg6ZnVuY3Rpb24oYSl7
-cmV0dXJuIEouUkUoYSkuRkYoYSl9LApoZjpmdW5jdGlvbihhKXtyZXR1cm4gSi5pYShhKS5naU8oYSl9
-LAppZzpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nUWcoYSl9LApsNTpmdW5jdGlvbihhLGIpe3Jl
-dHVybiBKLlJFKGEpLnNoZihhLGIpfSwKbGQ6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBKLnJZKGEpLk5q
-KGEsYixjKX0sCm06ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYT09Im51bWJlciImJnR5cGVvZiBiPT0i
-bnVtYmVyIilyZXR1cm4gYStiCnJldHVybiBKLlRKKGEpLmgoYSxiKX0sCnEwOmZ1bmN0aW9uKGEsYixj
-KXtyZXR1cm4gSi5yWShhKS5RaShhLGIsYyl9LApxRjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5n
-VmwoYSl9LAp0SDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouUkUoYSkucGsoYSxiLGMpfSwKeDk6ZnVu
-Y3Rpb24oYSxiKXtpZih0eXBlb2YgYj09PSJudW1iZXIiKWlmKGEuY29uc3RydWN0b3I9PUFycmF5fHx0
-eXBlb2YgYT09InN0cmluZyJ8fEgud1YoYSxhW3YuZGlzcGF0Y2hQcm9wZXJ0eU5hbWVdKSlpZihiPj4+
-MD09PWImJmI8YS5sZW5ndGgpcmV0dXJuIGFbYl0KcmV0dXJuIEouVTYoYSkucShhLGIpfSwKemw6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gSi5VNihhKS50ZyhhLGIpfSwKdkI6ZnVuY3Rpb24gdkIoKXt9LAp5RTpm
-dW5jdGlvbiB5RSgpe30sCllFOmZ1bmN0aW9uIFlFKCl7fSwKTUY6ZnVuY3Rpb24gTUYoKXt9LAppQzpm
-dW5jdGlvbiBpQygpe30sCmtkOmZ1bmN0aW9uIGtkKCl7fSwKYzU6ZnVuY3Rpb24gYzUoKXt9LApqZDpm
-dW5jdGlvbiBqZChhKXt0aGlzLiR0aT1hfSwKUG86ZnVuY3Rpb24gUG8oYSl7dGhpcy4kdGk9YX0sCm0x
-OmZ1bmN0aW9uIG0xKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0wCl8uZD1udWxsCl8u
-JHRpPWN9LApxSTpmdW5jdGlvbiBxSSgpe30sCmJVOmZ1bmN0aW9uIGJVKCl7fSwKVkE6ZnVuY3Rpb24g
-VkEoKXt9LApEcjpmdW5jdGlvbiBEcigpe319LFA9ewpPajpmdW5jdGlvbigpe3ZhciB0LHMscj17fQpp
-ZihzZWxmLnNjaGVkdWxlSW1tZWRpYXRlIT1udWxsKXJldHVybiBQLkVYKCkKaWYoc2VsZi5NdXRhdGlv
-bk9ic2VydmVyIT1udWxsJiZzZWxmLmRvY3VtZW50IT1udWxsKXt0PXNlbGYuZG9jdW1lbnQuY3JlYXRl
-RWxlbWVudCgiZGl2IikKcz1zZWxmLmRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpyLmE9bnVs
-bApuZXcgc2VsZi5NdXRhdGlvbk9ic2VydmVyKEgudFIobmV3IFAudGgociksMSkpLm9ic2VydmUodCx7
-Y2hpbGRMaXN0OnRydWV9KQpyZXR1cm4gbmV3IFAuaGEocix0LHMpfWVsc2UgaWYoc2VsZi5zZXRJbW1l
-ZGlhdGUhPW51bGwpcmV0dXJuIFAueXQoKQpyZXR1cm4gUC5xVygpfSwKWlY6ZnVuY3Rpb24oYSl7c2Vs
-Zi5zY2hlZHVsZUltbWVkaWF0ZShILnRSKG5ldyBQLlZzKHUuTS5hKGEpKSwwKSl9LApvQTpmdW5jdGlv
-bihhKXtzZWxmLnNldEltbWVkaWF0ZShILnRSKG5ldyBQLkZ0KHUuTS5hKGEpKSwwKSl9LApCejpmdW5j
-dGlvbihhKXt1Lk0uYShhKQpQLlFOKDAsYSl9LApRTjpmdW5jdGlvbihhLGIpe3ZhciB0PW5ldyBQLlcz
-KCkKdC5DWShhLGIpCnJldHVybiB0fSwKRlg6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLmloKG5ldyBQ
-LnZzKCQuWDMsYS5DKCJ2czwwPiIpKSxhLkMoImloPDA+IikpfSwKREk6ZnVuY3Rpb24oYSxiKXthLiQy
-KDAsbnVsbCkKYi5iPSEwCnJldHVybiBiLmF9LApqUTpmdW5jdGlvbihhLGIpe1AuSmUoYSxiKX0sCnlD
-OmZ1bmN0aW9uKGEsYil7Yi5hTSgwLGEpfSwKZjM6ZnVuY3Rpb24oYSxiKXtiLncwKEguUnUoYSksSC50
-cyhhKSl9LApKZTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1uZXcgUC5XTShiKSxxPW5ldyBQLlNYKGIp
-CmlmKGEgaW5zdGFuY2VvZiBQLnZzKWEuUWQocixxLHUueikKZWxzZXt0PXUuegppZih1LmMuYihhKSlh
-LlNxKHIscSx0KQplbHNle3M9bmV3IFAudnMoJC5YMyx1Ll8pCnMuYT00CnMuYz1hCnMuUWQocixxLHQp
-fX19LApsejpmdW5jdGlvbihhKXt2YXIgdD1mdW5jdGlvbihiLGMpe3JldHVybiBmdW5jdGlvbihkLGUp
-e3doaWxlKHRydWUpdHJ5e2IoZCxlKQpicmVha31jYXRjaChzKXtlPXMKZD1jfX19KGEsMSkKcmV0dXJu
-ICQuWDMuTGoobmV3IFAuR3ModCksdS5QLHUucCx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBQLkZ5KGEsMSl9LApUaDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBQLkZ5KGEsMyl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygi
-cTQ8MD4iKSl9LAprMzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShuZXcgUC5w
-VihiKSxuZXcgUC5VNyhiKSx1LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5yYihuZXcg
-UC52cihiLHQscykpfX0sCkE5OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztzPWEuYSxz
-PT09MjspYT10LmEoYS5jKQppZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHIp
-fWVsc2V7cj11LnguYShiLmMpCmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpmb3IodD11
-Lm4scz11Lngscj11LmM7ITA7KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtvPXQuYShj
-LmMpClAuTDIoZSxlLGMuYixvLmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9bil7Yi5h
-PW51bGwKUC5IWihkLmEsYil9Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtrPWIuYwpr
-PShrJjEpIT09MHx8KGsmMTUpPT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYocCl7aT1j
-LmI9PT1qCmk9IShpfHxpKX1lbHNlIGk9ITEKaWYoaSl7dC5hKG0pClAuTDIoZSxlLGMuYixtLmEsbS5i
-KQpyZXR1cm59aD0kLlgzCmlmKGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYxNSk9PT04
-KW5ldyBQLlJUKGQscSxiLHApLiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAucnEocSxi
-LG0pLiQwKCl9ZWxzZSBpZigoYyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9bnVsbCkk
-LlgzPWgKYz1xLmIKaWYoci5iKGMpKXtpZihjLmE+PTQpe2c9cy5hKGsuYykKay5jPW51bGwKYj1rLk44
-KGcpCmsuYT1jLmEKay5jPWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1cm59fWY9
-Yi5iCmc9cy5hKGYuYykKZi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtmLiR0aS5j
-LmEobCkKZi5hPTQKZi5jPWx9ZWxzZXt0LmEobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0sClZIOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKaWYodS5hZy5iKGEpKXJldHVybiBiLkxqKGEsdS56LHUuSyx1LmwpCnQ9
-dS5iSQppZih0LmIoYSkpcmV0dXJuIHQuYShhKQp0aHJvdyBILmIoUC5MMyhhLCJvbkVycm9yIiwiRXJy
-b3IgaGFuZGxlciBtdXN0IGFjY2VwdCBvbmUgT2JqZWN0IG9yIG9uZSBPYmplY3QgYW5kIGEgU3RhY2tU
-cmFjZSBhcyBhcmd1bWVudHMsIGFuZCByZXR1cm4gYSBhIHZhbGlkIHJlc3VsdCIpKX0sCnB1OmZ1bmN0
-aW9uKCl7dmFyIHQscwpmb3IoO3Q9JC5TNix0IT1udWxsOyl7JC5tZz1udWxsCnM9dC5iCiQuUzY9cwpp
-ZihzPT1udWxsKSQuazg9bnVsbAp0LmEuJDAoKX19LAplTjpmdW5jdGlvbigpeyQuVUQ9ITAKdHJ5e1Au
-cHUoKX1maW5hbGx5eyQubWc9bnVsbAokLlVEPSExCmlmKCQuUzYhPW51bGwpJC51dCgpLiQxKFAuVjko
-KSl9fSwKZVc6ZnVuY3Rpb24oYSl7dmFyIHQ9bmV3IFAuT00oYSkKaWYoJC5TNj09bnVsbCl7JC5TNj0k
-Lms4PXQKaWYoISQuVUQpJC51dCgpLiQxKFAuVjkoKSl9ZWxzZSAkLms4PSQuazguYj10fSwKclI6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyPSQuUzYKaWYocj09bnVsbCl7UC5lVyhhKQokLm1nPSQuazgKcmV0dXJu
-fXQ9bmV3IFAuT00oYSkKcz0kLm1nCmlmKHM9PW51bGwpe3QuYj1yCiQuUzY9JC5tZz10fWVsc2V7dC5i
-PXMuYgokLm1nPXMuYj10CmlmKHQuYj09bnVsbCkkLms4PXR9fSwKcmI6ZnVuY3Rpb24oYSl7dmFyIHQ9
-bnVsbCxzPSQuWDMKaWYoQy5OVT09PXMpe1AuVGsodCx0LEMuTlUsYSkKcmV0dXJufVAuVGsodCx0LHMs
-dS5NLmEocy5HWShhKSkpfSwKUXc6ZnVuY3Rpb24oYSxiKXtpZihhPT1udWxsKUgudmgoUC5FZSgic3Ry
-ZWFtIikpCnJldHVybiBuZXcgUC54SShiLkMoInhJPDA+IikpfSwKVGw6ZnVuY3Rpb24oYSxiKXt2YXIg
-dD1iPT1udWxsP1AudjAoYSk6YgpQLlVJKGEsImVycm9yIix1LkspCnJldHVybiBuZXcgUC5PSChhLHQp
-fSwKdjA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5XLmIoYSkpe3Q9YS5nSUkoKQppZih0IT1udWxsKXJl
-dHVybiB0fXJldHVybiBDLnBkfSwKTDI6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD17fQp0LmE9ZAp0
-LmI9ZQppZihkPT1udWxsKXt0LmE9bmV3IFAuQVQoITEsbnVsbCwiZXJyb3IiLCJNdXN0IG5vdCBiZSBu
-dWxsIikKdC5iPVAuWmIoKX1QLnJSKG5ldyBQLnBLKHQpKX0sClQ4OmZ1bmN0aW9uKGEsYixjLGQsZSl7
-dmFyIHQscz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQwKCkKJC5YMz1jCnQ9cwp0cnl7cz1kLiQwKCkK
-cmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKeXY6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQs
-cz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQxKGUpCiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMShlKQpyZXR1
-cm4gc31maW5hbGx5eyQuWDM9dH19LApReDpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSl7dmFyIHQs
-cz0kLlgzCmlmKHM9PT1jKXJldHVybiBkLiQyKGUsZikKJC5YMz1jCnQ9cwp0cnl7cz1kLiQyKGUsZikK
-cmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKVGs6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQKdS5NLmEo
-ZCkKdD1DLk5VIT09YwppZih0KWQ9ISghdHx8ITEpP2MuR1koZCk6Yy5SVChkLHUuSCkKUC5lVyhkKX0s
-CnRoOmZ1bmN0aW9uIHRoKGEpe3RoaXMuYT1hfSwKaGE6ZnVuY3Rpb24gaGEoYSxiLGMpe3RoaXMuYT1h
-CnRoaXMuYj1iCnRoaXMuYz1jfSwKVnM6ZnVuY3Rpb24gVnMoYSl7dGhpcy5hPWF9LApGdDpmdW5jdGlv
-biBGdChhKXt0aGlzLmE9YX0sClczOmZ1bmN0aW9uIFczKCl7fSwKeUg6ZnVuY3Rpb24geUgoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sCmloOmZ1bmN0aW9uIGloKGEsYil7dGhpcy5hPWEKdGhpcy5iPSExCnRo
-aXMuJHRpPWJ9LApXTTpmdW5jdGlvbiBXTShhKXt0aGlzLmE9YX0sClNYOmZ1bmN0aW9uIFNYKGEpe3Ro
-aXMuYT1hfSwKR3M6ZnVuY3Rpb24gR3MoYSl7dGhpcy5hPWF9LApGeTpmdW5jdGlvbiBGeShhLGIpe3Ro
-aXMuYT1hCnRoaXMuYj1ifSwKR1Y6ZnVuY3Rpb24gR1YoYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uZD1f
-LmM9Xy5iPW51bGwKXy4kdGk9Yn0sCnE0OmZ1bmN0aW9uIHE0KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9
-Yn0sCmI4OmZ1bmN0aW9uIGI4KCl7fSwKUGY6ZnVuY3Rpb24gUGYoKXt9LApaZjpmdW5jdGlvbiBaZihh
-LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApGZTpmdW5jdGlvbiBGZShhLGIsYyxkLGUpe3ZhciBfPXRo
-aXMKXy5hPW51bGwKXy5iPWEKXy5jPWIKXy5kPWMKXy5lPWQKXy4kdGk9ZX0sCnZzOmZ1bmN0aW9uIHZz
-KGEsYil7dmFyIF89dGhpcwpfLmE9MApfLmI9YQpfLmM9bnVsbApfLiR0aT1ifSwKZGE6ZnVuY3Rpb24g
-ZGEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCm9ROmZ1bmN0aW9uIG9RKGEsYil7dGhpcy5hPWEKdGhp
-cy5iPWJ9LApwVjpmdW5jdGlvbiBwVihhKXt0aGlzLmE9YX0sClU3OmZ1bmN0aW9uIFU3KGEpe3RoaXMu
-YT1hfSwKdnI6ZnVuY3Rpb24gdnIoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKckg6
-ZnVuY3Rpb24gckgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktGOmZ1bmN0aW9uIEtGKGEsYil7dGhp
-cy5hPWEKdGhpcy5iPWJ9LApaTDpmdW5jdGlvbiBaTChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApSVDpmdW5jdGlvbiBSVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
-Cl8uZD1kfSwKalo6ZnVuY3Rpb24galooYSl7dGhpcy5hPWF9LApycTpmdW5jdGlvbiBycShhLGIsYyl7
-dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApSVzpmdW5jdGlvbiBSVyhhLGIsYyl7dGhpcy5hPWEK
-dGhpcy5iPWIKdGhpcy5jPWN9LApPTTpmdW5jdGlvbiBPTShhKXt0aGlzLmE9YQp0aGlzLmI9bnVsbH0s
-CnFoOmZ1bmN0aW9uIHFoKCl7fSwKQjU6ZnVuY3Rpb24gQjUoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
-CnVPOmZ1bmN0aW9uIHVPKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApNTzpmdW5jdGlvbiBNTygpe30s
-CmtUOmZ1bmN0aW9uIGtUKCl7fSwKeEk6ZnVuY3Rpb24geEkoYSl7dGhpcy4kdGk9YX0sCk9IOmZ1bmN0
-aW9uIE9IKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAptMDpmdW5jdGlvbiBtMCgpe30sCnBLOmZ1bmN0
-aW9uIHBLKGEpe3RoaXMuYT1hfSwKSmk6ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIs
-Yyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1h
-CnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24gT1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1j
-fSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+Iiku
-YShILkI3KGEsbmV3IEguTjUoYi5DKCJAPDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVu
-Y3Rpb24oYSxiKXtyZXR1cm4gbmV3IEguTjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0s
-CkxzOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24o
-KXt2YXIgdD1PYmplY3QuY3JlYXRlKG51bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+Il09dApkZWxl
-dGUgdFsiPG5vbi1pZGVudGlmaWVyLWtleT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJsbTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwKRVA6ZnVuY3Rp
-b24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4u
-LikiCnJldHVybiBiKyIuLi4iK2N9dD1ILlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIo
-YSx0KX1maW5hbGx5e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3Ao
-KX1zPVAudmcoYix1LlIuYSh0KSwiLCAiKStjCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfSwK
-V0U6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5oQihhKSlyZXR1cm4gYisiLi4uIitjCnQ9bmV3
-IFAuUm4oYikKQy5ObS5pKCQueGcsYSkKdHJ5e3M9dApzLmE9UC52ZyhzLmEsYSwiLCAiKX1maW5hbGx5
-e2lmKDA+PSQueGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX10LmErPWMKcz10
-LmEKcmV0dXJuIHMuY2hhckNvZGVBdCgwKT09MD9zOnN9LApoQjpmdW5jdGlvbihhKXt2YXIgdCxzCmZv
-cih0PSQueGcubGVuZ3RoLHM9MDtzPHQ7KytzKWlmKGE9PT0kLnhnW3NdKXJldHVybiEwCnJldHVybiEx
-fSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtPWEuZ2t6KGEpLGw9MCxrPTAKd2hp
-bGUoITApe2lmKCEobDw4MHx8azwzKSlicmVhawppZighbS5GKCkpcmV0dXJuCnQ9SC5kKG0uZ2woKSkK
-Qy5ObS5pKGIsdCkKbCs9dC5sZW5ndGgrMjsrK2t9aWYoIW0uRigpKXtpZihrPD01KXJldHVybgppZigw
-Pj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4g
-SC5rKGIsLTEpCnI9Yi5wb3AoKX1lbHNle3E9bS5nbCgpOysrawppZighbS5GKCkpe2lmKGs8PTQpe0Mu
-Tm0uaShiLEguZChxKSkKcmV0dXJufXM9SC5kKHEpCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILmsoYiwt
-MSkKcj1iLnBvcCgpCmwrPXMubGVuZ3RoKzJ9ZWxzZXtwPW0uZ2woKTsrK2sKZm9yKDttLkYoKTtxPXAs
-cD1vKXtvPW0uZ2woKTsrK2sKaWYoaz4xMDApe3doaWxlKCEwKXtpZighKGw+NzUmJms+MykpYnJlYWsK
-aWYoMD49Yi5sZW5ndGgpcmV0dXJuIEguayhiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyOy0ta31DLk5t
-LmkoYiwiLi4uIikKcmV0dXJufX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0aCtyLmxlbmd0aCs0
-fX1pZihrPmIubGVuZ3RoKzIpe2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGlsZSghMCl7aWYoIShs
-PjgwJiZiLmxlbmd0aD4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5rKGIsLTEpCmwtPWIu
-cG9wKCkubGVuZ3RoKzIKaWYobj09bnVsbCl7bCs9NQpuPSIuLi4ifX1pZihuIT1udWxsKUMuTm0uaShi
-LG4pCkMuTm0uaShiLHIpCkMuTm0uaShiLHMpfSwKdE06ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9UC5M
-cyhiKQpmb3IodD1hLmxlbmd0aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8fCgwLEgubGspKGEp
-LCsrcylyLmkoMCxiLmEoYVtzXSkpCnJldHVybiByfSwKbk86ZnVuY3Rpb24oYSl7dmFyIHQscz17fQpp
-ZihQLmhCKGEpKXJldHVybiJ7Li4ufSIKdD1uZXcgUC5SbigiIikKdHJ5e0MuTm0uaSgkLnhnLGEpCnQu
-YSs9InsiCnMuYT0hMAphLksoMCxuZXcgUC5yYShzLHQpKQp0LmErPSJ9In1maW5hbGx5e2lmKDA+PSQu
-eGcubGVuZ3RoKXJldHVybiBILmsoJC54ZywtMSkKJC54Zy5wb3AoKX1zPXQuYQpyZXR1cm4gcy5jaGFy
-Q29kZUF0KDApPT0wP3M6c30sCmI2OmZ1bmN0aW9uIGI2KGEpe3ZhciBfPXRoaXMKXy5hPTAKXy5mPV8u
-ZT1fLmQ9Xy5jPV8uYj1udWxsCl8ucj0wCl8uJHRpPWF9LApibjpmdW5jdGlvbiBibihhKXt0aGlzLmE9
-YQp0aGlzLmM9dGhpcy5iPW51bGx9LApsbTpmdW5jdGlvbiBsbShhLGIsYyl7dmFyIF89dGhpcwpfLmE9
-YQpfLmI9YgpfLmQ9Xy5jPW51bGwKXy4kdGk9Y30sCm1XOmZ1bmN0aW9uIG1XKCl7fSwKdXk6ZnVuY3Rp
-b24gdXkoKXt9LApsRDpmdW5jdGlvbiBsRCgpe30sCmlsOmZ1bmN0aW9uIGlsKCl7fSwKcmE6ZnVuY3Rp
-b24gcmEoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCllrOmZ1bmN0aW9uIFlrKCl7fSwKeVE6ZnVuY3Rp
-b24geVEoYSl7dGhpcy5hPWF9LApLUDpmdW5jdGlvbiBLUCgpe30sClBuOmZ1bmN0aW9uIFBuKCl7fSwK
-R2o6ZnVuY3Rpb24gR2ooYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKTWE6ZnVuY3Rpb24gTWEoKXt9
-LApWajpmdW5jdGlvbiBWaigpe30sClh2OmZ1bmN0aW9uIFh2KCl7fSwKblk6ZnVuY3Rpb24gblkoKXt9
-LApUQzpmdW5jdGlvbiBUQygpe30sClJVOmZ1bmN0aW9uIFJVKCl7fSwKQlM6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscQppZih0eXBlb2YgYSE9InN0cmluZyIpdGhyb3cgSC5iKEguSShhKSkKdD1udWxsCnRy
-eXt0PUpTT04ucGFyc2UoYSl9Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJpbmcocyksbnVsbCxu
-dWxsKQp0aHJvdyBILmIocSl9cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHQK
-aWYoYT09bnVsbClyZXR1cm4gbnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGEKaWYoT2Jq
-ZWN0LmdldFByb3RvdHlwZU9mKGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBuZXcgUC51dyhhLE9i
-amVjdC5jcmVhdGUobnVsbCkpCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1QLlFlKGFbdF0pCnJl
-dHVybiBhfSwKa3k6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0
-dXJuIFAuUlAoITEsYixjLGQpCnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
-cyxyPSQudEwoKQppZihyPT1udWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYmITApcmV0dXJuIFAu
-T1EocixiKQpzPWIubGVuZ3RoCmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0dXJuIFAuT1Eocixi
-KQpyZXR1cm4gUC5PUShyLGIuc3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihhLGIpe2lmKFAuQWoo
-YikpcmV0dXJuIG51bGwKcmV0dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0
-cnl7dD1hLmRlY29kZShiKQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVybiBudWxsfSwKQWo6
-ZnVuY3Rpb24oYSl7dmFyIHQscz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClpZihhW3RdPT09MjM3
-KWlmKChhW3QrMV0mMjI0KT09PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCldJOmZ1bmN0aW9uKCl7dmFy
-IHQscwp0cnl7dD1uZXcgVGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNh
-dGNoKHMpe0guUnUocyl9cmV0dXJuIG51bGx9LApjUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyCmZv
-cih0PUouVTYoYSkscz1iO3M8YzsrK3Mpe3I9dC5xKGEscykKaWYodHlwZW9mIHIhPT0ibnVtYmVyIily
-ZXR1cm4gci56TSgpCmlmKChyJjEyNykhPT1yKXJldHVybiBzLWJ9cmV0dXJuIGMtYn0sCnhNOmZ1bmN0
-aW9uKGEsYixjLGQsZSxmKXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlk
-IGJhc2U2NCBwYWRkaW5nLCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMg
-IitmLGEsYykpCmlmKGQrZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcs
-ICc9JyBub3QgYXQgdGhlIGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJh
-c2U2NCBwYWRkaW5nLCBtb3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0
-aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0
-KCl9LAp1WDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1uZXcgUC5SbigiIikscj1uZXcgUC50dShzLFtd
-LFAuQ3koKSkKci5pVShhKQp0PXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnV3OmZ1
-bmN0aW9uIHV3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBp
-OChhKXt0aGlzLmE9YX0sCkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpm
-dW5jdGlvbiBVaygpe30sCndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpm
-dW5jdGlvbiBVZChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlz
-LmE9YQp0aGlzLmI9Yn0sCmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5i
-PWF9LApNeDpmdW5jdGlvbiBNeChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVu
-Y3Rpb24gdGkoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlz
-LmM9YQp0aGlzLmE9Ygp0aGlzLmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMo
-KXt9LApSdzpmdW5jdGlvbiBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEp
-e3RoaXMuYT1hfSwKYno6ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0h
-MApfLmY9Xy5lPV8uZD0wfSwKUUE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguSHAoYSxjKQppZih0IT1u
-dWxsKXJldHVybiB0CmlmKGIhPW51bGwpcmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5iKFAucnIoYSxudWxs
-LG51bGwpKX0sCm9zOmZ1bmN0aW9uKGEpe2lmKGEgaW5zdGFuY2VvZiBILlRwKXJldHVybiBhLlooMCkK
-cmV0dXJuIkluc3RhbmNlIG9mICciK0guZChILmxoKGEpKSsiJyJ9LApPODpmdW5jdGlvbihhLGIsYyl7
-dmFyIHQscz1KLlFpKGEsYykKaWYoYSE9PTAmJiEwKWZvcih0PTA7dDxzLmxlbmd0aDsrK3QpQy5ObS5Z
-KHMsdCxiKQpyZXR1cm4gc30sCkNIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJq
-ZDwwPiIpKQpmb3IodD1KLklUKGEpO3QuRigpOylDLk5tLmkocyxjLmEodC5nbCgpKSkKaWYoYilyZXR1
-cm4gcwpyZXR1cm4gYy5DKCJ6TTwwPiIpLmEoSi5FcChzKSl9LApBRjpmdW5jdGlvbihhLGIpe3JldHVy
-biBiLkMoInpNPDA+IikuYShKLnVuKFAuQ0goYSwhMSxiKSkpfSwKSE06ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0CmlmKEFycmF5LmlzQXJyYXkoYSkpe3UudC5hKGEpCnQ9YS5sZW5ndGgKYz1QLmpCKGIsYyx0KQpy
-ZXR1cm4gSC5lVChiPjB8fGM8dD9DLk5tLkQ2KGEsYixjKTphKX1pZih1LmJtLmIoYSkpcmV0dXJuIEgu
-ZncoYSxiLFAuakIoYixjLGEubGVuZ3RoKSkKcmV0dXJuIFAuYncoYSxiLGMpfSwKT286ZnVuY3Rpb24o
-YSl7cmV0dXJuIEguTHcoYSl9LApidzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD1udWxsCmlm
-KGI8MCl0aHJvdyBILmIoUC5URShiLDAsSi5IKGEpLHAscCkpCnQ9Yz09bnVsbAppZighdCYmYzxiKXRo
-cm93IEguYihQLlRFKGMsYixKLkgoYSkscCxwKSkKcz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZigh
-cy5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHIscCxwKSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVz
-aChzLmdsKCkpCmVsc2UgZm9yKHI9YjtyPGM7KytyKXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxi
-LHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9cmV0dXJuIEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1
-cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAsITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2
-YXIgdD1KLklUKGIpCmlmKCF0LkYoKSlyZXR1cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0
-LmdsKCkpCndoaWxlKHQuRigpKX1lbHNle2ErPUguZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0gu
-ZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEs
-YixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIgdD1ILk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0
-KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNlJyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rp
-b24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG49IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhN
-KXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0ic3RyaW5nIilILnZoKEguSShiKSkKdD10LnRlc3QoYil9
-ZWxzZSB0PSExCmlmKHQpcmV0dXJuIGIKSC5MaChjKS5DKCJVay5TIikuYShiKQpzPWMuZ1pFKCkuV0oo
-YikKZm9yKHQ9cy5sZW5ndGgscj0wLHE9IiI7cjx0Oysrcil7cD1zW3JdCmlmKHA8MTI4KXtvPXA+Pj40
-CmlmKG8+PTgpcmV0dXJuIEguayhhLG8pCm89KGFbb10mMTw8KHAmMTUpKSE9PTB9ZWxzZSBvPSExCmlm
-KG8pcSs9SC5MdyhwKQplbHNlIHE9ZCYmcD09PTMyP3ErIisiOnErIiUiK25bcD4+PjQmMTVdK25bcCYx
-NV19cmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApaYjpmdW5jdGlvbigpe3ZhciB0LHMKaWYo
-SC5vVCgkLnA2KCkpKXJldHVybiBILnRzKG5ldyBFcnJvcigpKQp0cnl7dGhyb3cgSC5iKCIiKX1jYXRj
-aChzKXtILlJ1KHMpCnQ9SC50cyhzKQpyZXR1cm4gdH19LApHcTpmdW5jdGlvbihhKXt2YXIgdD1NYXRo
-LmFicyhhKSxzPWE8MD8iLSI6IiIKaWYodD49MTAwMClyZXR1cm4iIithCmlmKHQ+PTEwMClyZXR1cm4g
-cysiMCIrdAppZih0Pj0xMClyZXR1cm4gcysiMDAiK3QKcmV0dXJuIHMrIjAwMCIrdH0sClZ4OmZ1bmN0
-aW9uKGEpe2lmKGE+PTEwMClyZXR1cm4iIithCmlmKGE+PTEwKXJldHVybiIwIithCnJldHVybiIwMCIr
-YX0sCmgwOmZ1bmN0aW9uKGEpe2lmKGE+PTEwKXJldHVybiIiK2EKcmV0dXJuIjAiK2F9LApoOmZ1bmN0
-aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyInx8SC5yUShhKXx8bnVsbD09YSlyZXR1cm4gSi5BYyhh
-KQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJuIEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLm9z
-KGEpfSwKaFY6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkM2KGEpfSwKeFk6ZnVuY3Rpb24oYSl7cmV0
-dXJuIG5ldyBQLkFUKCExLG51bGwsbnVsbCxhKX0sCkwzOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3
-IFAuQVQoITAsYSxiLGMpfSwKRWU6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkFUKCExLG51bGwsYSwi
-TXVzdCBub3QgYmUgbnVsbCIpfSwKVUk6ZnVuY3Rpb24oYSxiLGMpe2lmKGE9PW51bGwpdGhyb3cgSC5i
-KFAuRWUoYikpCnJldHVybiBhfSwKTzc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuYkoobnVsbCxu
-dWxsLCEwLGEsYiwiVmFsdWUgbm90IGluIHJhbmdlIil9LApURTpmdW5jdGlvbihhLGIsYyxkLGUpe3Jl
-dHVybiBuZXcgUC5iSihiLGMsITAsYSxkLCJJbnZhbGlkIHZhbHVlIil9LAp3QTpmdW5jdGlvbihhLGIs
-YyxkKXtpZihhPGJ8fGE+Yyl0aHJvdyBILmIoUC5URShhLGIsYyxkLG51bGwpKQpyZXR1cm4gYX0sCmpC
-OmZ1bmN0aW9uKGEsYixjKXtpZigwPmF8fGE+Yyl0aHJvdyBILmIoUC5URShhLDAsYywic3RhcnQiLG51
-bGwpKQppZihiIT1udWxsKXtpZihhPmJ8fGI+Yyl0aHJvdyBILmIoUC5URShiLGEsYywiZW5kIixudWxs
-KSkKcmV0dXJuIGJ9cmV0dXJuIGN9LAprMTpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhIT09Im51bWJl
-ciIpcmV0dXJuIGEuSigpCmlmKGE8MCl0aHJvdyBILmIoUC5URShhLDAsbnVsbCxiLG51bGwpKQpyZXR1
-cm4gYX0sCnQ6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdD1ILldZKGU9PW51bGw/Si5IKGIpOmUpCnJl
-dHVybiBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApMNDpmdW5jdGlvbihh
-KXtyZXR1cm4gbmV3IFAudWIoYSl9LApuOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5kcyhhKX0sClBW
-OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5saihhKX0sCmE0OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcg
-UC5VVihhKX0sCnJyOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gbmV3IFAuYUUoYSxiLGMpfSwKZEg6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHQscz1ILlZNKFtdLGQuQygiamQ8MD4iKSkKQy5ObS5zQShzLGEpCmZv
-cih0PTA7dDxhOysrdClDLk5tLlkocyx0LGIuJDEodCkpCnJldHVybiBzfSwKaEs6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGU9bnVsbCxkPWEubGVuZ3RoCmlmKGQ+PTUp
-e3Q9KChKLlF6KGEsNCleNTgpKjN8Qy54Qi5XKGEsMCleMTAwfEMueEIuVyhhLDEpXjk3fEMueEIuVyhh
-LDIpXjExNnxDLnhCLlcoYSwzKV45Nyk+Pj4wCmlmKHQ9PT0wKXJldHVybiBQLktEKGQ8ZD9DLnhCLk5q
-KGEsMCxkKTphLDUsZSkuZ2xSKCkKZWxzZSBpZih0PT09MzIpcmV0dXJuIFAuS0QoQy54Qi5OaihhLDUs
-ZCksMCxlKS5nbFIoKX1zPW5ldyBBcnJheSg4KQpzLmZpeGVkJGxlbmd0aD1BcnJheQpyPUguVk0ocyx1
-LnQpCkMuTm0uWShyLDAsMCkKQy5ObS5ZKHIsMSwtMSkKQy5ObS5ZKHIsMiwtMSkKQy5ObS5ZKHIsNywt
-MSkKQy5ObS5ZKHIsMywwKQpDLk5tLlkociw0LDApCkMuTm0uWShyLDUsZCkKQy5ObS5ZKHIsNixkKQpp
-ZihQLlVCKGEsMCxkLDAscik+PTE0KUMuTm0uWShyLDcsZCkKcT1yWzFdCmlmKHR5cGVvZiBxIT09Im51
-bWJlciIpcmV0dXJuIHEudEIoKQppZihxPj0wKWlmKFAuVUIoYSwwLHEsMjAscik9PT0yMClyWzddPXEK
-cz1yWzJdCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuaCgpCnA9cysxCm89clszXQpuPXJb
-NF0KbT1yWzVdCmw9cls2XQppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZih0eXBl
-b2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCmlmKGw8bSltPWwKaWYodHlwZW9mIG4hPT0ibnVt
-YmVyIilyZXR1cm4gbi5KKCkKaWYobjxwKW49bQplbHNlIGlmKG48PXEpbj1xKzEKaWYodHlwZW9mIG8h
-PT0ibnVtYmVyIilyZXR1cm4gby5KKCkKaWYobzxwKW89bgpzPXJbN10KaWYodHlwZW9mIHMhPT0ibnVt
-YmVyIilyZXR1cm4gcy5KKCkKaz1zPDAKaWYoaylpZihwPnErMyl7aj1lCms9ITF9ZWxzZXtzPW8+MApp
-ZihzJiZvKzE9PT1uKXtqPWUKaz0hMX1lbHNle2lmKCEobTxkJiZtPT09bisyJiZKLnEwKGEsIi4uIixu
-KSkpaT1tPm4rMiYmSi5xMChhLCIvLi4iLG0tMykKZWxzZSBpPSEwCmlmKGkpe2o9ZQprPSExfWVsc2V7
-aWYocT09PTQpaWYoSi5xMChhLCJmaWxlIiwwKSl7aWYocDw9MCl7aWYoIUMueEIuUWkoYSwiLyIsbikp
-e2g9ImZpbGU6Ly8vIgp0PTN9ZWxzZXtoPSJmaWxlOi8vIgp0PTJ9YT1oK0MueEIuTmooYSxuLGQpCnEt
-PTAKcz10LTAKbSs9cwpsKz1zCmQ9YS5sZW5ndGgKcD03Cm89NwpuPTd9ZWxzZSBpZihuPT09bSl7Zz1t
-KzE7KytsCmE9Qy54Qi5pNyhhLG4sbSwiLyIpOysrZAptPWd9aj0iZmlsZSJ9ZWxzZSBpZihDLnhCLlFp
-KGEsImh0dHAiLDApKXtpZihzJiZvKzM9PT1uJiZDLnhCLlFpKGEsIjgwIixvKzEpKXtmPW4tMwptLT0z
-CmwtPTMKYT1DLnhCLmk3KGEsbyxuLCIiKQpkLT0zCm49Zn1qPSJodHRwIn1lbHNlIGo9ZQplbHNlIGlm
-KHE9PT01JiZKLnEwKGEsImh0dHBzIiwwKSl7aWYocyYmbys0PT09biYmSi5xMChhLCI0NDMiLG8rMSkp
-e2Y9bi00Cm0tPTQKbC09NAphPUouZGcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9Imh0dHBzIn1lbHNlIGo9
-ZQprPSEwfX19ZWxzZSBqPWUKaWYoayl7cz1hLmxlbmd0aAppZihkPHMpe2E9Si5sZChhLDAsZCkKcS09
-MApwLT0wCm8tPTAKbi09MAptLT0wCmwtPTB9cmV0dXJuIG5ldyBQLlVmKGEscSxwLG8sbixtLGwsail9
-cmV0dXJuIFAuanYoYSwwLGQscSxwLG8sbixtLGwsail9LApNdDpmdW5jdGlvbihhKXtILmMoYSkKcmV0
-dXJuIFAua3UoYSwwLGEubGVuZ3RoLEMueE0sITEpfSwKV1g6ZnVuY3Rpb24oYSl7dmFyIHQ9dS5OCnJl
-dHVybiBDLk5tLk4wKEguVk0oYS5zcGxpdCgiJiIpLHUucyksUC5GbCh0LHQpLG5ldyBQLm4xKEMueE0p
-LHUuZil9LApIaDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsLGw9IklQdjQg
-YWRkcmVzcyBzaG91bGQgY29udGFpbiBleGFjdGx5IDQgcGFydHMiLGs9ImVhY2ggcGFydCBtdXN0IGJl
-IGluIHRoZSByYW5nZSAwLi4yNTUiLGo9bmV3IFAuY1MoYSksaT1uZXcgVWludDhBcnJheSg0KQpmb3Io
-dD1pLmxlbmd0aCxzPWIscj1zLHE9MDtzPGM7KytzKXtwPUMueEIubShhLHMpCmlmKHAhPT00Nil7aWYo
-KHBeNDgpPjkpai4kMigiaW52YWxpZCBjaGFyYWN0ZXIiLHMpfWVsc2V7aWYocT09PTMpai4kMihsLHMp
-Cm89UC5RQShDLnhCLk5qKGEscixzKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8u
-b3MoKQppZihvPjI1NSlqLiQyKGsscikKbj1xKzEKaWYocT49dClyZXR1cm4gSC5rKGkscSkKaVtxXT1v
-CnI9cysxCnE9bn19aWYocSE9PTMpai4kMihsLGMpCm89UC5RQShDLnhCLk5qKGEscixjKSxtLG0pCmlm
-KHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlqLiQyKGsscikKaWYocT49
-dClyZXR1cm4gSC5rKGkscSkKaVtxXT1vCnJldHVybiBpfSwKZWc6ZnVuY3Rpb24oYSxiLGEwKXt2YXIg
-dCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkPW5ldyBQLlZDKGEpLGM9bmV3IFAuSlQoZCxh
-KQppZihhLmxlbmd0aDwyKWQuJDEoImFkZHJlc3MgaXMgdG9vIHNob3J0IikKdD1ILlZNKFtdLHUudCkK
-Zm9yKHM9YixyPXMscT0hMSxwPSExO3M8YTA7KytzKXtvPUMueEIubShhLHMpCmlmKG89PT01OCl7aWYo
-cz09PWIpeysrcwppZihDLnhCLm0oYSxzKSE9PTU4KWQuJDIoImludmFsaWQgc3RhcnQgY29sb24uIixz
-KQpyPXN9aWYocz09PXIpe2lmKHEpZC4kMigib25seSBvbmUgd2lsZGNhcmQgYDo6YCBpcyBhbGxvd2Vk
-IixzKQpDLk5tLmkodCwtMSkKcT0hMH1lbHNlIEMuTm0uaSh0LGMuJDIocixzKSkKcj1zKzF9ZWxzZSBp
-ZihvPT09NDYpcD0hMH1pZih0Lmxlbmd0aD09PTApZC4kMSgidG9vIGZldyBwYXJ0cyIpCm49cj09PWEw
-Cm09Qy5ObS5ncloodCkKaWYobiYmbSE9PS0xKWQuJDIoImV4cGVjdGVkIGEgcGFydCBhZnRlciBsYXN0
-IGA6YCIsYTApCmlmKCFuKWlmKCFwKUMuTm0uaSh0LGMuJDIocixhMCkpCmVsc2V7bD1QLkhoKGEscixh
-MCkKQy5ObS5pKHQsKGxbMF08PDh8bFsxXSk+Pj4wKQpDLk5tLmkodCwobFsyXTw8OHxsWzNdKT4+PjAp
-fWlmKHEpe2lmKHQubGVuZ3RoPjcpZC4kMSgiYW4gYWRkcmVzcyB3aXRoIGEgd2lsZGNhcmQgbXVzdCBo
-YXZlIGxlc3MgdGhhbiA3IHBhcnRzIil9ZWxzZSBpZih0Lmxlbmd0aCE9PTgpZC4kMSgiYW4gYWRkcmVz
-cyB3aXRob3V0IGEgd2lsZGNhcmQgbXVzdCBjb250YWluIGV4YWN0bHkgOCBwYXJ0cyIpCms9bmV3IFVp
-bnQ4QXJyYXkoMTYpCmZvcihtPXQubGVuZ3RoLGo9ay5sZW5ndGgsaT05LW0scz0wLGg9MDtzPG07Kytz
-KXtnPXRbc10KaWYoZz09PS0xKWZvcihmPTA7ZjxpOysrZil7aWYoaDwwfHxoPj1qKXJldHVybiBILmso
-ayxoKQprW2hdPTAKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5rKGssZSkKa1tlXT0wCmgrPTJ9ZWxzZXtl
-PUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguayhrLGgpCmtbaF09ZQplPWgrMQppZihl
-Pj1qKXJldHVybiBILmsoayxlKQprW2VdPWcmMjU1CmgrPTJ9fXJldHVybiBrfSwKanY6ZnVuY3Rpb24o
-YSxiLGMsZCxlLGYsZyxoLGksail7dmFyIHQscyxyLHEscCxvLG4sbT1udWxsCmlmKGo9PW51bGwpaWYo
-ZD5iKWo9UC5QaShhLGIsZCkKZWxzZXtpZihkPT09YilQLlIzKGEsYiwiSW52YWxpZCBlbXB0eSBzY2hl
-bWUiKQpqPSIifWlmKGU+Yil7dD1kKzMKcz10PGU/UC56UihhLHQsZS0xKToiIgpyPVAuT2UoYSxlLGYs
-ITEpCmlmKHR5cGVvZiBmIT09Im51bWJlciIpcmV0dXJuIGYuaCgpCnE9ZisxCmlmKHR5cGVvZiBnIT09
-Im51bWJlciIpcmV0dXJuIEgucFkoZykKcD1xPGc/UC53QihQLlFBKEoubGQoYSxxLGcpLG5ldyBQLmUx
-KGEsZiksbSksaik6bX1lbHNle3A9bQpyPXAKcz0iIn1vPVAua2EoYSxnLGgsbSxqLHIhPW51bGwpCmlm
-KHR5cGVvZiBoIT09Im51bWJlciIpcmV0dXJuIGguSigpCm49aDxpP1AubGUoYSxoKzEsaSxtKTptCnJl
-dHVybiBuZXcgUC5EbihqLHMscixwLG8sbixpPGM/UC50RyhhLGkrMSxjKTptKX0sCktMOmZ1bmN0aW9u
-KGEsYixjLGQsZSxmLGcpe3ZhciB0LHMscixxLHAsbwpmPVAuUGkoZiwwLGY9PW51bGw/MDpmLmxlbmd0
-aCkKZz1QLnpSKGcsMCxnPT1udWxsPzA6Zy5sZW5ndGgpCmE9UC5PZShhLDAsYT09bnVsbD8wOmEubGVu
-Z3RoLCExKQp0PVAubGUobnVsbCwwLDAsZSkKcz1QLnRHKG51bGwsMCwwKQpkPVAud0IoZCxmKQpyPWY9
-PT0iZmlsZSIKaWYoYT09bnVsbClxPWcubGVuZ3RoIT09MHx8ZCE9bnVsbHx8cgplbHNlIHE9ITEKaWYo
-cSlhPSIiCnE9YT09bnVsbApwPSFxCmI9UC5rYShiLDAsYj09bnVsbD8wOmIubGVuZ3RoLGMsZixwKQpv
-PWYubGVuZ3RoPT09MAppZihvJiZxJiYhQy54Qi5uKGIsIi8iKSliPVAud0YoYiwhb3x8cCkKZWxzZSBi
-PVAueGUoYikKcmV0dXJuIG5ldyBQLkRuKGYsZyxxJiZDLnhCLm4oYiwiLy8iKT8iIjphLGQsYix0LHMp
-fSwKd0s6ZnVuY3Rpb24oYSl7aWYoYT09PSJodHRwIilyZXR1cm4gODAKaWYoYT09PSJodHRwcyIpcmV0
-dXJuIDQ0MwpyZXR1cm4gMH0sClIzOmZ1bmN0aW9uKGEsYixjKXt0aHJvdyBILmIoUC5ycihjLGEsYikp
-fSwKWGQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpPW51bGwsaD1i
-Lmxlbmd0aAppZihoIT09MCl7cj0wCndoaWxlKCEwKXtpZighKHI8aCkpe3Q9IiIKcz0wCmJyZWFrfWlm
-KEMueEIuVyhiLHIpPT09NjQpe3Q9Qy54Qi5OaihiLDAscikKcz1yKzEKYnJlYWt9KytyfWlmKHM8aCYm
-Qy54Qi5XKGIscyk9PT05MSl7Zm9yKHE9cyxwPS0xO3E8aDsrK3Epe289Qy54Qi5XKGIscSkKaWYobz09
-PTM3JiZwPDApe249Qy54Qi5RaShiLCIyNSIscSsxKT9xKzI6cQpwPXEKcT1ufWVsc2UgaWYobz09PTkz
-KWJyZWFrfWlmKHE9PT1oKXRocm93IEguYihQLnJyKCJJbnZhbGlkIElQdjYgaG9zdCBlbnRyeS4iLGIs
-cykpCm09cDwwP3E6cApQLmVnKGIscysxLG0pOysrcQppZihxIT09aCYmQy54Qi5XKGIscSkhPT01OCl0
-aHJvdyBILmIoUC5ycigiSW52YWxpZCBlbmQgb2YgYXV0aG9yaXR5IixiLHEpKX1lbHNlIHE9cwp3aGls
-ZSghMCl7aWYoIShxPGgpKXtsPWkKYnJlYWt9aWYoQy54Qi5XKGIscSk9PT01OCl7az1DLnhCLkcoYixx
-KzEpCmw9ay5sZW5ndGghPT0wP1AuUUEoayxpLGkpOmkKYnJlYWt9KytxfWo9Qy54Qi5OaihiLHMscSl9
-ZWxzZXtsPWkKaj1sCnQ9IiJ9cmV0dXJuIFAuS0woaixpLEguVk0oYy5zcGxpdCgiLyIpLHUucyksbCxk
-LGEsdCl9LAprRTpmdW5jdGlvbihhLGIpe0MuTm0uSyhhLG5ldyBQLk5ZKCExKSl9LApITjpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyCmZvcih0PUgucUMoYSxjLG51bGwsSC50NihhKS5jKSx0PW5ldyBILmE3
-KHQsdC5nQSh0KSx0LiR0aS5DKCJhNzxhTC5FPiIpKTt0LkYoKTspe3M9dC5kCnI9UC5udSgnWyIqLzo8
-Pj9cXFxcfF0nKQpzLnRvU3RyaW5nCmlmKEgubTIocyxyLDApKXt0PVAuTDQoIklsbGVnYWwgY2hhcmFj
-dGVyIGluIHBhdGg6ICIrcykKdGhyb3cgSC5iKHQpfX19LApyZzpmdW5jdGlvbihhLGIpe3ZhciB0Cmlm
-KCEoNjU8PWEmJmE8PTkwKSl0PTk3PD1hJiZhPD0xMjIKZWxzZSB0PSEwCmlmKHQpcmV0dXJuCnQ9UC5M
-NCgiSWxsZWdhbCBkcml2ZSBsZXR0ZXIgIitQLk9vKGEpKQp0aHJvdyBILmIodCl9LAp3QjpmdW5jdGlv
-bihhLGIpe2lmKGEhPW51bGwmJmE9PT1QLndLKGIpKXJldHVybiBudWxsCnJldHVybiBhfSwKT2U6ZnVu
-Y3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxvCmlmKGE9PW51bGwpcmV0dXJuIG51bGwKaWYoYj09
-PWMpcmV0dXJuIiIKaWYoQy54Qi5tKGEsYik9PT05MSl7aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1
-cm4gYy5ITigpCnQ9Yy0xCmlmKEMueEIubShhLHQpIT09OTMpUC5SMyhhLGIsIk1pc3NpbmcgZW5kIGBd
-YCB0byBtYXRjaCBgW2AgaW4gaG9zdCIpCnM9YisxCnI9UC50byhhLHMsdCkKaWYodHlwZW9mIHIhPT0i
-bnVtYmVyIilyZXR1cm4gci5KKCkKaWYocjx0KXtxPXIrMQpwPVAuT0EoYSxDLnhCLlFpKGEsIjI1Iixx
-KT9yKzM6cSx0LCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLHMscikKcmV0dXJuIEMueEIuTmooYSxiLHIp
-LnRvTG93ZXJDYXNlKCkrcCsiXSJ9aWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQpv
-PWIKZm9yKDtvPGM7KytvKWlmKEMueEIubShhLG8pPT09NTgpe3I9Qy54Qi5YVShhLCIlIixiKQppZigh
-KHI+PWImJnI8Yykpcj1jCmlmKHI8Yyl7cT1yKzEKcD1QLk9BKGEsQy54Qi5RaShhLCIyNSIscSk/cisz
-OnEsYywiJTI1Iil9ZWxzZSBwPSIiClAuZWcoYSxiLHIpCnJldHVybiJbIitDLnhCLk5qKGEsYixyKStw
-KyJdIn1yZXR1cm4gUC5PTChhLGIsYyl9LAp0bzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscz1DLnhCLlhV
-KGEsIiUiLGIpCmlmKHM+PWIpe2lmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1z
-PGN9ZWxzZSB0PSExCnJldHVybiB0P3M6Y30sCk9BOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixx
-LHAsbyxuLG0sbCxrPWQhPT0iIj9uZXcgUC5SbihkKTpudWxsCmlmKHR5cGVvZiBjIT09Im51bWJlciIp
-cmV0dXJuIEgucFkoYykKdD1iCnM9dApyPSEwCmZvcig7dDxjOyl7cT1DLnhCLm0oYSx0KQppZihxPT09
-Mzcpe3A9UC5ydihhLHQsITApCm89cD09bnVsbAppZihvJiZyKXt0Kz0zCmNvbnRpbnVlfWlmKGs9PW51
-bGwpaz1uZXcgUC5SbigiIikKbj1rLmErPUMueEIuTmooYSxzLHQpCmlmKG8pcD1DLnhCLk5qKGEsdCx0
-KzMpCmVsc2UgaWYocD09PSIlIilQLlIzKGEsdCwiWm9uZUlEIHNob3VsZCBub3QgY29udGFpbiAlIGFu
-eW1vcmUiKQprLmE9bitwCnQrPTMKcz10CnI9ITB9ZWxzZXtpZihxPDEyNyl7bz1xPj4+NAppZihvPj04
-KXJldHVybiBILmsoQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihv
-KXtpZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKaWYoczx0KXtrLmEr
-PUMueEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0NTEyKT09PTU1Mjk2JiZ0KzE8
-Yyl7bT1DLnhCLm0oYSx0KzEpCmlmKChtJjY0NTEyKT09PTU2MzIwKXtxPTY1NTM2fChxJjEwMjMpPDwx
-MHxtJjEwMjMKbD0yfWVsc2UgbD0xfWVsc2UgbD0xCmlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5h
-Kz1DLnhCLk5qKGEscyx0KQprLmErPVAuelgocSkKdCs9bApzPXR9fX1pZihrPT1udWxsKXJldHVybiBD
-LnhCLk5qKGEsYixjKQppZihzPGMpay5hKz1DLnhCLk5qKGEscyxjKQpvPWsuYQpyZXR1cm4gby5jaGFy
-Q29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGws
-ayxqCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKdD1iCnM9dApyPW51bGwKcT0h
-MApmb3IoO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYocD09PTM3KXtvPVAucnYoYSx0LCEwKQpuPW89PW51
-bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5O
-aihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNhc2UoKTptCmlmKG4pe289Qy54Qi5OaihhLHQsdCsz
-KQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUiCms9MX1lbHNlIGs9MwpyLmE9bCtvCnQrPWsKcz10
-CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVybiBILmsoQy5lYSxuKQpuPShD
-LmVhW25dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbj0hMQppZihuKXtpZihxJiY2NTw9cCYmOTA+PXApe2lm
-KHI9PW51bGwpcj1uZXcgUC5SbigiIikKaWYoczx0KXtyLmErPUMueEIuTmooYSxzLHQpCnM9dH1xPSEx
-fSsrdH1lbHNle2lmKHA8PTkzKXtuPXA+Pj40CmlmKG4+PTgpcmV0dXJuIEguayhDLmFrLG4pCm49KEMu
-YWtbbl0mMTw8KHAmMTUpKSE9PTB9ZWxzZSBuPSExCmlmKG4pUC5SMyhhLHQsIkludmFsaWQgY2hhcmFj
-dGVyIikKZWxzZXtpZigocCY2NDUxMik9PT01NTI5NiYmdCsxPGMpe2o9Qy54Qi5tKGEsdCsxKQppZigo
-aiY2NDUxMik9PT01NjMyMCl7cD02NTUzNnwocCYxMDIzKTw8MTB8aiYxMDIzCms9Mn1lbHNlIGs9MX1l
-bHNlIGs9MQppZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKci5hKz0hcT9t
-LnRvTG93ZXJDYXNlKCk6bQpyLmErPVAuelgocCkKdCs9awpzPXR9fX19aWYocj09bnVsbClyZXR1cm4g
-Qy54Qi5OaihhLGIsYykKaWYoczxjKXttPUMueEIuTmooYSxzLGMpCnIuYSs9IXE/bS50b0xvd2VyQ2Fz
-ZSgpOm19bj1yLmEKcmV0dXJuIG4uY2hhckNvZGVBdCgwKT09MD9uOm59LApQaTpmdW5jdGlvbihhLGIs
-Yyl7dmFyIHQscyxyLHEKaWYoYj09PWMpcmV0dXJuIiIKaWYoIVAuRXQoSi5yWShhKS5XKGEsYikpKVAu
-UjMoYSxiLCJTY2hlbWUgbm90IHN0YXJ0aW5nIHdpdGggYWxwaGFiZXRpYyBjaGFyYWN0ZXIiKQpmb3Io
-dD1iLHM9ITE7dDxjOysrdCl7cj1DLnhCLlcoYSx0KQppZihyPDEyOCl7cT1yPj4+NAppZihxPj04KXJl
-dHVybiBILmsoQy5tSyxxKQpxPShDLm1LW3FdJjE8PChyJjE1KSkhPT0wfWVsc2UgcT0hMQppZighcSlQ
-LlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikKaWYoNjU8PXImJnI8PTkwKXM9ITB9YT1D
-LnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dlckNhc2UoKTphKX0sCllhOmZ1bmN0aW9u
-KGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0iZmlsZSIpcmV0dXJuImZpbGUiCmlm
-KGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNrYWdlIilyZXR1cm4icGFja2FnZSIK
-cmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVsbClyZXR1cm4iIgpyZXR1cm4gUC5Q
-SShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQsZSxmKXt2YXIgdCxzPWU9PT0iZmls
-ZSIscj1zfHxmLHE9YT09bnVsbAppZihxJiZkPT1udWxsKXJldHVybiBzPyIvIjoiIgpxPSFxCmlmKHEm
-JmQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQgcGF0aFNlZ21lbnRzIHNwZWNpZmll
-ZCIpKQppZihxKXQ9UC5QSShhLGIsYyxDLldkLCEwKQplbHNle2QudG9TdHJpbmcKcT1ILnQ2KGQpCnQ9
-bmV3IEgubEooZCxxLkMoInFVKDEpIikuYShuZXcgUC5SWigpKSxxLkMoImxKPDEscVU+IikpLkgoMCwi
-LyIpfWlmKHQubGVuZ3RoPT09MCl7aWYocylyZXR1cm4iLyJ9ZWxzZSBpZihyJiYhQy54Qi5uKHQsIi8i
-KSl0PSIvIit0CnJldHVybiBQLkpyKHQsZSxmKX0sCkpyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1iLmxl
-bmd0aD09PTAKaWYodCYmIWMmJiFDLnhCLm4oYSwiLyIpKXJldHVybiBQLndGKGEsIXR8fGMpCnJldHVy
-biBQLnhlKGEpfSwKbGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscz17fQppZihhIT1udWxsKXtpZihk
-IT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHF1ZXJ5IGFuZCBxdWVyeVBhcmFtZXRlcnMgc3BlY2lm
-aWVkIikpCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfWlmKGQ9PW51bGwpcmV0dXJuIG51bGwKdD1u
-ZXcgUC5SbigiIikKcy5hPSIiCmQuSygwLG5ldyBQLnk1KG5ldyBQLk1FKHMsdCkpKQpzPXQuYQpyZXR1
-cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCnRHOmZ1bmN0aW9uKGEsYixjKXtpZihhPT1udWxsKXJl
-dHVybiBudWxsCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfSwKcnY6ZnVuY3Rpb24oYSxiLGMpe3Zh
-ciB0LHMscixxLHAsbz1iKzIKaWYobz49YS5sZW5ndGgpcmV0dXJuIiUiCnQ9Qy54Qi5tKGEsYisxKQpz
-PUMueEIubShhLG8pCnI9SC5vbyh0KQpxPUgub28ocykKaWYocjwwfHxxPDApcmV0dXJuIiUiCnA9ciox
-NitxCmlmKHA8MTI3KXtvPUMuam4ud0cocCw0KQppZihvPj04KXJldHVybiBILmsoQy5GMyxvKQpvPShD
-LkYzW29dJjE8PChwJjE1KSkhPT0wfWVsc2Ugbz0hMQppZihvKXJldHVybiBILkx3KGMmJjY1PD1wJiY5
-MD49cD8ocHwzMik+Pj4wOnApCmlmKHQ+PTk3fHxzPj05NylyZXR1cm4gQy54Qi5OaihhLGIsYiszKS50
-b1VwcGVyQ2FzZSgpCnJldHVybiBudWxsfSwKelg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49
-IjAxMjM0NTY3ODlBQkNERUYiCmlmKGE8MTI4KXt0PW5ldyBBcnJheSgzKQp0LmZpeGVkJGxlbmd0aD1B
-cnJheQpzPUguVk0odCx1LnQpCkMuTm0uWShzLDAsMzcpCkMuTm0uWShzLDEsQy54Qi5XKG4sYT4+PjQp
-KQpDLk5tLlkocywyLEMueEIuVyhuLGEmMTUpKX1lbHNle2lmKGE+MjA0NylpZihhPjY1NTM1KXtyPTI0
-MApxPTR9ZWxzZXtyPTIyNApxPTN9ZWxzZXtyPTE5MgpxPTJ9dD1uZXcgQXJyYXkoMypxKQp0LmZpeGVk
-JGxlbmd0aD1BcnJheQpzPUguVk0odCx1LnQpCmZvcihwPTA7LS1xLHE+PTA7cj0xMjgpe289Qy5qbi5i
-ZihhLDYqcSkmNjN8cgpDLk5tLlkocyxwLDM3KQpDLk5tLlkocyxwKzEsQy54Qi5XKG4sbz4+PjQpKQpD
-Lk5tLlkocyxwKzIsQy54Qi5XKG4sbyYxNSkpCnArPTN9fXJldHVybiBQLkhNKHMsMCxudWxsKX0sClBJ
-OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQ9UC5VbChhLGIsYyxkLGUpCnJldHVybiB0PT1udWxsP0Mu
-eEIuTmooYSxiLGMpOnR9LApVbDpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz1udWxs
-LG49IWUsbT1iLGw9bSxrPW8Kd2hpbGUoITApe2lmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
-SigpCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykKaWYoIShtPGMpKWJyZWFrCmMk
-MDp7dD1DLnhCLm0oYSxtKQppZih0PDEyNyl7cz10Pj4+NAppZihzPj04KXJldHVybiBILmsoZCxzKQpz
-PShkW3NdJjE8PCh0JjE1KSkhPT0wfWVsc2Ugcz0hMQppZihzKSsrbQplbHNle2lmKHQ9PT0zNyl7cj1Q
-LnJ2KGEsbSwhMSkKaWYocj09bnVsbCl7bSs9MwpicmVhayBjJDB9aWYoIiUiPT09cil7cj0iJTI1Igpx
-PTF9ZWxzZSBxPTN9ZWxzZXtpZihuKWlmKHQ8PTkzKXtzPXQ+Pj40CmlmKHM+PTgpcmV0dXJuIEguayhD
-LmFrLHMpCnM9KEMuYWtbc10mMTw8KHQmMTUpKSE9PTB9ZWxzZSBzPSExCmVsc2Ugcz0hMQppZihzKXtQ
-LlIzKGEsbSwiSW52YWxpZCBjaGFyYWN0ZXIiKQpxPW8Kcj1xfWVsc2V7aWYoKHQmNjQ1MTIpPT09NTUy
-OTYpe3M9bSsxCmlmKHM8Yyl7cD1DLnhCLm0oYSxzKQppZigocCY2NDUxMik9PT01NjMyMCl7dD02NTUz
-NnwodCYxMDIzKTw8MTB8cCYxMDIzCnE9Mn1lbHNlIHE9MX1lbHNlIHE9MX1lbHNlIHE9MQpyPVAuelgo
-dCl9fWlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEsbCxtKQprLmErPUguZChy
-KQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCm0rPXEKbD1tfX19aWYoaz09bnVs
-bClyZXR1cm4gbwppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJldHVybiBsLkooKQppZihsPGMpay5hKz1D
-LnhCLk5qKGEsbCxjKQpuPWsuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246bn0sCnlCOmZ1bmN0
-aW9uKGEpe2lmKEMueEIubihhLCIuIikpcmV0dXJuITAKcmV0dXJuIEMueEIuT1koYSwiLy4iKSE9PS0x
-fSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KaWYoIVAueUIoYSkpcmV0dXJuIGEKdD1I
-LlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5sZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7
-bz1zW3BdCmlmKEouUk0obywiLi4iKSl7bj10Lmxlbmd0aAppZihuIT09MCl7aWYoMD49bilyZXR1cm4g
-SC5rKHQsLTEpCnQucG9wKCkKaWYodC5sZW5ndGg9PT0wKUMuTm0uaSh0LCIiKX1xPSEwfWVsc2UgaWYo
-Ii4iPT09bylxPSEwCmVsc2V7Qy5ObS5pKHQsbykKcT0hMX19aWYocSlDLk5tLmkodCwiIikKcmV0dXJu
-IEMuTm0uSCh0LCIvIil9LAp3RjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwppZighUC55Qihh
-KSlyZXR1cm4hYj9QLkMxKGEpOmEKdD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5s
-ZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKCIuLiI9PT1vKWlmKHQubGVuZ3RoIT09MCYm
-Qy5ObS5ncloodCkhPT0iLi4iKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkK
-cT0hMH1lbHNle0MuTm0uaSh0LCIuLiIpCnE9ITF9ZWxzZSBpZigiLiI9PT1vKXE9ITAKZWxzZXtDLk5t
-LmkodCxvKQpxPSExfX1zPXQubGVuZ3RoCmlmKHMhPT0wKWlmKHM9PT0xKXtpZigwPj1zKXJldHVybiBI
-LmsodCwwKQpzPXRbMF0ubGVuZ3RoPT09MH1lbHNlIHM9ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4v
-IgppZihxfHxDLk5tLmdyWih0KT09PSIuLiIpQy5ObS5pKHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0
-aClyZXR1cm4gSC5rKHQsMCkKQy5ObS5ZKHQsMCxQLkMxKHRbMF0pKX1yZXR1cm4gQy5ObS5IKHQsIi8i
-KX0sCkMxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPWEubGVuZ3RoCmlmKHE+PTImJlAuRXQoSi5Reihh
-LDApKSlmb3IodD0xO3Q8cTsrK3Qpe3M9Qy54Qi5XKGEsdCkKaWYocz09PTU4KXJldHVybiBDLnhCLk5q
-KGEsMCx0KSsiJTNBIitDLnhCLkcoYSx0KzEpCmlmKHM8PTEyNyl7cj1zPj4+NAppZihyPj04KXJldHVy
-biBILmsoQy5tSyxyKQpyPShDLm1LW3JdJjE8PChzJjE1KSk9PT0wfWVsc2Ugcj0hMAppZihyKWJyZWFr
-fXJldHVybiBhfSwKbW46ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9YS5nRmooKSxwPXEubGVuZ3RoCmlm
-KHA+MCYmSi5IKHFbMF0pPT09MiYmSi5hNihxWzBdLDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguayhx
-LDApClAucmcoSi5hNihxWzBdLDApLCExKQpQLkhOKHEsITEsMSkKdD0hMH1lbHNle1AuSE4ocSwhMSww
-KQp0PSExfXM9YS5ndFQoKSYmIXQ/IlxcIjoiIgppZihhLmdjaigpKXtyPWEuZ0pmKGEpCmlmKHIubGVu
-Z3RoIT09MClzPXMrIlxcIityKyJcXCJ9cz1QLnZnKHMscSwiXFwiKQpwPXQmJnA9PT0xP3MrIlxcIjpz
-CnJldHVybiBwLmNoYXJDb2RlQXQoMCk9PTA/cDpwfSwKSWg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIK
-Zm9yKHQ9MCxzPTA7czwyOysrcyl7cj1DLnhCLlcoYSxiK3MpCmlmKDQ4PD1yJiZyPD01Nyl0PXQqMTYr
-ci00OAplbHNle3J8PTMyCmlmKDk3PD1yJiZyPD0xMDIpdD10KjE2K3ItODcKZWxzZSB0aHJvdyBILmIo
-UC54WSgiSW52YWxpZCBVUkwgZW5jb2RpbmciKSl9fXJldHVybiB0fSwKa3U6ZnVuY3Rpb24oYSxiLGMs
-ZCxlKXt2YXIgdCxzLHIscSxwPUouclkoYSksbz1iCndoaWxlKCEwKXtpZighKG88Yykpe3Q9ITAKYnJl
-YWt9cz1wLlcoYSxvKQppZihzPD0xMjcpaWYocyE9PTM3KXI9ZSYmcz09PTQzCmVsc2Ugcj0hMAplbHNl
-IHI9ITAKaWYocil7dD0hMQpicmVha30rK299aWYodCl7aWYoQy54TSE9PWQpcj0hMQplbHNlIHI9ITAK
-aWYocilyZXR1cm4gcC5OaihhLGIsYykKZWxzZSBxPW5ldyBILnFqKHAuTmooYSxiLGMpKX1lbHNle3E9
-SC5WTShbXSx1LnQpCmZvcihvPWI7bzxjOysrbyl7cz1wLlcoYSxvKQppZihzPjEyNyl0aHJvdyBILmIo
-UC54WSgiSWxsZWdhbCBwZXJjZW50IGVuY29kaW5nIGluIFVSSSIpKQppZihzPT09Mzcpe2lmKG8rMz5h
-Lmxlbmd0aCl0aHJvdyBILmIoUC54WSgiVHJ1bmNhdGVkIFVSSSIpKQpDLk5tLmkocSxQLkloKGEsbysx
-KSkKbys9Mn1lbHNlIGlmKGUmJnM9PT00MylDLk5tLmkocSwzMikKZWxzZSBDLk5tLmkocSxzKX19dS5M
-LmEocSkKcmV0dXJuIG5ldyBQLkdZKCExKS5XSihxKX0sCkV0OmZ1bmN0aW9uKGEpe3ZhciB0PWF8MzIK
-cmV0dXJuIDk3PD10JiZ0PD0xMjJ9LApLRDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4s
-bSxsPSJJbnZhbGlkIE1JTUUgdHlwZSIsaz1ILlZNKFtiLTFdLHUudCkKZm9yKHQ9YS5sZW5ndGgscz1i
-LHI9LTEscT1udWxsO3M8dDsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTQ0fHxxPT09NTkpYnJlYWsK
-aWYocT09PTQ3KXtpZihyPDApe3I9cwpjb250aW51ZX10aHJvdyBILmIoUC5ycihsLGEscykpfX1pZihy
-PDAmJnM+Yil0aHJvdyBILmIoUC5ycihsLGEscykpCmZvcig7cSE9PTQ0Oyl7Qy5ObS5pKGsscyk7Kytz
-CmZvcihwPS0xO3M8dDsrK3Mpe3E9Qy54Qi5XKGEscykKaWYocT09PTYxKXtpZihwPDApcD1zfWVsc2Ug
-aWYocT09PTU5fHxxPT09NDQpYnJlYWt9aWYocD49MClDLk5tLmkoayxwKQplbHNle289Qy5ObS5ncloo
-aykKaWYocSE9PTQ0fHxzIT09bys3fHwhQy54Qi5RaShhLCJiYXNlNjQiLG8rMSkpdGhyb3cgSC5iKFAu
-cnIoIkV4cGVjdGluZyAnPSciLGEscykpCmJyZWFrfX1DLk5tLmkoayxzKQpuPXMrMQppZigoay5sZW5n
-dGgmMSk9PT0xKWE9Qy5oOS55cihhLG4sdCkKZWxzZXttPVAuVWwoYSxuLHQsQy5WQywhMCkKaWYobSE9
-bnVsbClhPUMueEIuaTcoYSxuLHQsbSl9cmV0dXJuIG5ldyBQLlBFKGEsayxjKX0sCktOOmZ1bmN0aW9u
-KCl7dmFyIHQ9IjAxMjM0NTY3ODlBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWmFiY2RlZmdoaWprbG1u
-b3BxcnN0dXZ3eHl6LS5ffiEkJicoKSorLDs9IixzPSIuIixyPSI6IixxPSIvIixwPSI/IixvPSIjIixu
-PXUuZ2MsbT1QLmRIKDIyLG5ldyBQLnEzKCksITAsbiksbD1uZXcgUC55SShtKSxrPW5ldyBQLmM2KCks
-aj1uZXcgUC5xZCgpLGk9bi5hKGwuJDIoMCwyMjUpKQprLiQzKGksdCwxKQprLiQzKGkscywxNCkKay4k
-MyhpLHIsMzQpCmsuJDMoaSxxLDMpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
-KDE0LDIyNSkpCmsuJDMoaSx0LDEpCmsuJDMoaSxzLDE1KQprLiQzKGksciwzNCkKay4kMyhpLHEsMjM0
-KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxNSwyMjUpKQprLiQzKGksdCwx
-KQprLiQzKGksIiUiLDIyNSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4k
-MyhpLG8sMjA1KQppPW4uYShsLiQyKDEsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLHIsMzQpCmsuJDMo
-aSxxLDEwKQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigyLDIzNSkpCmsuJDMo
-aSx0LDEzOSkKay4kMyhpLHEsMTMxKQprLiQzKGkscywxNDYpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8s
-MjA1KQppPW4uYShsLiQyKDMsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDY4KQprLiQzKGkscywx
-OCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNCwyMjkpKQprLiQzKGksdCw1
-KQpqLiQzKGksIkFaIiwyMjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2OCkKay4kMyhpLCJbIiwy
-MzIpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNSwy
-MjkpKQprLiQzKGksdCw1KQpqLiQzKGksIkFaIiwyMjkpCmsuJDMoaSxyLDEwMikKay4kMyhpLCJAIiw2
-OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMig2LDIz
-MSkpCmouJDMoaSwiMTkiLDcpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcy
-KQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoNywyMzEpKQpqLiQzKGksIjA5Iiw3KQprLiQzKGksIkAi
-LDY4KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQprLiQzKG4uYShsLiQy
-KDgsOCkpLCJdIiw1KQppPW4uYShsLiQyKDksMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxzLDE2KQpr
-LiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDE2LDIzNSkp
-CmsuJDMoaSx0LDExKQprLiQzKGkscywxNykKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMo
-aSxvLDIwNSkKaT1uLmEobC4kMigxNywyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEsOSkKay4kMyhp
-LHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5hKGwuJDIoMTAsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMo
-aSxzLDE4KQprLiQzKGkscSwyMzQpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQy
-KDE4LDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOSkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwx
-NzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxOSwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHEs
-MjM0KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmEobC4kMigxMSwyMzUpKQprLiQzKGks
-dCwxMSkKay4kMyhpLHEsMTApCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEy
-LDIzNikpCmsuJDMoaSx0LDEyKQprLiQzKGkscCwxMikKay4kMyhpLG8sMjA1KQppPW4uYShsLiQyKDEz
-LDIzNykpCmsuJDMoaSx0LDEzKQprLiQzKGkscCwxMykKai4kMyhuLmEobC4kMigyMCwyNDUpKSwiYXoi
-LDIxKQpsPW4uYShsLiQyKDIxLDI0NSkpCmouJDMobCwiYXoiLDIxKQpqLiQzKGwsIjA5IiwyMSkKay4k
-MyhsLCIrLS4iLDIxKQpyZXR1cm4gbX0sClVCOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEs
-cCxvPSQudlooKQpmb3IodD1KLnJZKGEpLHM9YjtzPGM7KytzKXtpZihkPDB8fGQ+PW8ubGVuZ3RoKXJl
-dHVybiBILmsobyxkKQpyPW9bZF0KcT10LlcoYSxzKV45NgppZihxPjk1KXE9MzEKaWYocT49ci5sZW5n
-dGgpcmV0dXJuIEguayhyLHEpCnA9cltxXQpkPXAmMzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9
-LApXRjpmdW5jdGlvbiBXRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9
-LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9
-LApYUzpmdW5jdGlvbiBYUygpe30sCkM2OmZ1bmN0aW9uIEM2KGEpe3RoaXMuYT1hfSwKTEs6ZnVuY3Rp
-b24gTEsoKXt9LApBVDpmdW5jdGlvbiBBVChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8u
-Yz1jCl8uZD1kfSwKYko6ZnVuY3Rpb24gYkooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5lPWEKXy5m
-PWIKXy5hPWMKXy5iPWQKXy5jPWUKXy5kPWZ9LAplWTpmdW5jdGlvbiBlWShhLGIsYyxkLGUpe3ZhciBf
-PXRoaXMKXy5mPWEKXy5hPWIKXy5iPWMKXy5jPWQKXy5kPWV9LAptcDpmdW5jdGlvbiBtcChhLGIsYyxk
-KXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKdWI6ZnVuY3Rpb24gdWIoYSl7dGhp
-cy5hPWF9LApkczpmdW5jdGlvbiBkcyhhKXt0aGlzLmE9YX0sCmxqOmZ1bmN0aW9uIGxqKGEpe3RoaXMu
-YT1hfSwKVVY6ZnVuY3Rpb24gVVYoYSl7dGhpcy5hPWF9LAprNTpmdW5jdGlvbiBrNSgpe30sCktZOmZ1
-bmN0aW9uIEtZKCl7fSwKdDc6ZnVuY3Rpb24gdDcoYSl7dGhpcy5hPWF9LApDRDpmdW5jdGlvbiBDRChh
-KXt0aGlzLmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9
-Y30sCkVIOmZ1bmN0aW9uIEVIKCl7fSwKSWY6ZnVuY3Rpb24gSWYoKXt9LApjWDpmdW5jdGlvbiBjWCgp
-e30sCkFuOmZ1bmN0aW9uIEFuKCl7fSwKek06ZnVuY3Rpb24gek0oKXt9LApaMDpmdW5jdGlvbiBaMCgp
-e30sCk4zOmZ1bmN0aW9uIE4zKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6
-ZnVuY3Rpb24gYzgoKXt9LApsZjpmdW5jdGlvbiBsZigpe30sCk1oOmZ1bmN0aW9uIE1oKCl7fSwKT2Q6
-ZnVuY3Rpb24gT2QoKXt9LAppYjpmdW5jdGlvbiBpYigpe30sCnh1OmZ1bmN0aW9uIHh1KCl7fSwKR3o6
-ZnVuY3Rpb24gR3ooKXt9LApaZDpmdW5jdGlvbiBaZCgpe30sCnFVOmZ1bmN0aW9uIHFVKCl7fSwKUm46
-ZnVuY3Rpb24gUm4oYSl7dGhpcy5hPWF9LApHRDpmdW5jdGlvbiBHRCgpe30sCm4xOmZ1bmN0aW9uIG4x
-KGEpe3RoaXMuYT1hfSwKY1M6ZnVuY3Rpb24gY1MoYSl7dGhpcy5hPWF9LApWQzpmdW5jdGlvbiBWQyhh
-KXt0aGlzLmE9YX0sCkpUOmZ1bmN0aW9uIEpUKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApEbjpmdW5j
-dGlvbiBEbihhLGIsYyxkLGUsZixnKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8u
-ZT1lCl8uZj1mCl8ucj1nCl8uUT1fLno9Xy55PV8ueD1udWxsfSwKZTE6ZnVuY3Rpb24gZTEoYSxiKXt0
-aGlzLmE9YQp0aGlzLmI9Yn0sCk5ZOmZ1bmN0aW9uIE5ZKGEpe3RoaXMuYT1hfSwKUlo6ZnVuY3Rpb24g
-UlooKXt9LApNRTpmdW5jdGlvbiBNRShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKeTU6ZnVuY3Rpb24g
-eTUoYSl7dGhpcy5hPWF9LApQRTpmdW5jdGlvbiBQRShhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
-cy5jPWN9LApxMzpmdW5jdGlvbiBxMygpe30sCnlJOmZ1bmN0aW9uIHlJKGEpe3RoaXMuYT1hfSwKYzY6
-ZnVuY3Rpb24gYzYoKXt9LApxZDpmdW5jdGlvbiBxZCgpe30sClVmOmZ1bmN0aW9uIFVmKGEsYixjLGQs
-ZSxmLGcsaCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9
-ZwpfLng9aApfLnk9bnVsbH0sCnFlOmZ1bmN0aW9uIHFlKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMK
-Xy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQKXy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51
-bGx9LAppSjpmdW5jdGlvbiBpSigpe30sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5i
-PWJ9LApUYTpmdW5jdGlvbiBUYShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQmY6ZnVuY3Rpb24gQmYo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkFzOmZ1bmN0aW9uIEFzKCl7fSwKR0U6ZnVuY3Rpb24gR0Uo
-YSl7dGhpcy5hPWF9LApONzpmdW5jdGlvbiBONyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKdVE6ZnVu
-Y3Rpb24gdVEoKXt9LApoRjpmdW5jdGlvbiBoRigpe30sClI0OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
-LHMscgpILkU5KGIpCnUuai5hKGQpCmlmKEgub1QoYikpe3Q9W2NdCkMuTm0uRlYodCxkKQpkPXR9cz11
-LnoKcj1QLkNIKEouTTEoZCxQLncwKCkscyksITAscykKdS5aLmEoYSkKcmV0dXJuIFAud1koSC5Fayhh
-LHIsbnVsbCkpfSwKRG06ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnRyeXtpZihPYmplY3QuaXNFeHRlbnNp
-YmxlKGEpJiYhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGEsYikpe09iamVjdC5k
-ZWZpbmVQcm9wZXJ0eShhLGIse3ZhbHVlOmN9KQpyZXR1cm4hMH19Y2F0Y2godCl7SC5SdSh0KX1yZXR1
-cm4hMX0sCk9tOmZ1bmN0aW9uKGEsYil7aWYoT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5j
-YWxsKGEsYikpcmV0dXJuIGFbYl0KcmV0dXJuIG51bGx9LAp3WTpmdW5jdGlvbihhKXtpZihhPT1udWxs
-fHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBhPT0ibnVtYmVyInx8SC5yUShhKSlyZXR1cm4gYQpp
-ZihhIGluc3RhbmNlb2YgUC5FNClyZXR1cm4gYS5hCmlmKEguUjkoYSkpcmV0dXJuIGEKaWYodS51LmIo
-YSkpcmV0dXJuIGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIEgubzIoYSkKaWYodS5aLmIoYSkp
-cmV0dXJuIFAuaEUoYSwiJGRhcnRfanNGdW5jdGlvbiIsbmV3IFAuUEMoKSkKcmV0dXJuIFAuaEUoYSwi
-XyRkYXJ0X2pzT2JqZWN0IixuZXcgUC5tdCgkLmtJKCkpKX0sCmhFOmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dD1QLk9tKGEsYikKaWYodD09bnVsbCl7dD1jLiQxKGEpClAuRG0oYSxiLHQpfXJldHVybiB0fSwKTDc6
-ZnVuY3Rpb24oYSl7dmFyIHQscwppZihhPT1udWxsfHx0eXBlb2YgYT09InN0cmluZyJ8fHR5cGVvZiBh
-PT0ibnVtYmVyInx8dHlwZW9mIGE9PSJib29sZWFuIilyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2Vv
-ZiBPYmplY3QmJkguUjkoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgT2JqZWN0JiZ1LnUu
-YihhKSlyZXR1cm4gYQplbHNlIGlmKGEgaW5zdGFuY2VvZiBEYXRlKXt0PUguV1koYS5nZXRUaW1lKCkp
-CmlmKE1hdGguYWJzKHQpPD04NjRlMTMpcz0hMQplbHNlIHM9ITAKaWYocylILnZoKFAueFkoIkRhdGVU
-aW1lIGlzIG91dHNpZGUgdmFsaWQgcmFuZ2U6ICIrdCkpClAuVUkoITEsImlzVXRjIix1LnkpCnJldHVy
-biBuZXcgUC5pUCh0LCExKX1lbHNlIGlmKGEuY29uc3RydWN0b3I9PT0kLmtJKCkpcmV0dXJuIGEubwpl
-bHNlIHJldHVybiBQLk5EKGEpfSwKTkQ6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJmdW5jdGlvbiIp
-cmV0dXJuIFAuaVEoYSwkLndRKCksbmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVy
-biBQLmlRKGEsJC5DcigpLG5ldyBQLlFTKCkpCnJldHVybiBQLmlRKGEsJC5DcigpLG5ldyBQLm5wKCkp
-fSwKaVE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFu
-Y2VvZiBPYmplY3QpKXt0PWMuJDEoYSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQ
-Qygpe30sCm10OmZ1bmN0aW9uIG10KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpm
-dW5jdGlvbiBRUygpe30sCm5wOmZ1bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5h
-PWF9LApyNzpmdW5jdGlvbiByNyhhKXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5h
-PWEKdGhpcy4kdGk9Yn0sCmNvOmZ1bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpm
-dW5jdGlvbiBLZShhKXt0aGlzLmE9YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYo
-KXt9fSxXPXsKeDM6ZnVuY3Rpb24oKXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4g
-ZG9jdW1lbnR9LApKNjpmdW5jdGlvbihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikK
-aWYoYSE9bnVsbCl0LmhyZWY9YQpyZXR1cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1
-bWVudC5ib2R5LHM9KHQmJkMuUlkpLnI2KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEgu
-VTUobmV3IFcuZTcocyksdC5DKCJhMihsRC5FKSIpLmEobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIp
-KQpyZXR1cm4gdS5oLmEodC5ncjgodCkpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50
-IHRhZyB1bmF2YWlsYWJsZSIKdHJ5e3Q9Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmci
-KXI9dC5nbnMoYSl9Y2F0Y2gocyl7SC5SdShzKX1yZXR1cm4gcn0sCkMwOmZ1bmN0aW9uKGEsYil7YT01
-MzY4NzA5MTEmYStiCmE9NTM2ODcwOTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0s
-CnJFOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxk
-KSxzPTUzNjg3MDkxMSZ0KygoNjcxMDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTEx
-JnMrKCgxNjM4MyZzKTw8MTUpfSwKVE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QK
-Zm9yKHQ9Yi5sZW5ndGgscz0wO3M8Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mp
-ci5hZGQoYltzXSl9LApKRTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyks
-dS5CKQppZih0IT1udWxsJiYhMClKLmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEs
-ZS5DKCJ4QzwwPiIpKX0sClR3OmZ1bmN0aW9uKGEpe3ZhciB0PVcuSjYobnVsbCkscz13aW5kb3cubG9j
-YXRpb24KdD1uZXcgVy5KUShuZXcgVy5tayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKcUQ6ZnVuY3Rp
-b24oYSxiLGMsZCl7dS5oLmEoYSkKSC5jKGIpCkguYyhjKQp1Lk8uYShkKQpyZXR1cm4hMH0sClFXOmZ1
-bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscgp1LmguYShhKQpILmMoYikKSC5jKGMpCnQ9dS5PLmEoZCku
-YQpzPXQuYQpzLmhyZWY9YwpyPXMuaG9zdG5hbWUKdD10LmIKaWYoIShyPT10Lmhvc3RuYW1lJiZzLnBv
-cnQ9PXQucG9ydCYmcy5wcm90b2NvbD09dC5wcm90b2NvbCkpaWYocj09PSIiKWlmKHMucG9ydD09PSIi
-KXt0PXMucHJvdG9jb2wKdD10PT09IjoifHx0PT09IiJ9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9
-ITAKcmV0dXJuIHR9LApCbDpmdW5jdGlvbigpe3ZhciB0PXUuTixzPVAudE0oQy5ReCx0KSxyPXUuZEcu
-YShuZXcgVy5JQSgpKSxxPUguVk0oWyJURU1QTEFURSJdLHUucykKdD1uZXcgVy5jdChzLFAuTHModCks
-UC5Mcyh0KSxQLkxzKHQpLG51bGwpCnQuQ1kobnVsbCxuZXcgSC5sSihDLlF4LHIsdS5kdikscSxudWxs
-KQpyZXR1cm4gdH0sClB2OmZ1bmN0aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFcu
-UDEoYSl9LApxYzpmdW5jdGlvbihhKXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0
-TWVzc2FnZSIgaW4gYSl7dD1XLlAxKGEpCmlmKHUuci5iKHQpKXJldHVybiB0CnJldHVybiBudWxsfWVs
-c2UgcmV0dXJuIHUuci5hKGEpfSwKUDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdS5j
-aS5hKGEpCmVsc2UgcmV0dXJuIG5ldyBXLmRXKGEpfSwKSEg6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRv
-dy5sb2NhdGlvbilyZXR1cm4gYQplbHNlIHJldHVybiBuZXcgVy5GYigpfSwKYUY6ZnVuY3Rpb24oYSxi
-KXt2YXIgdD0kLlgzCmlmKHQ9PT1DLk5VKXJldHVybiBhCnJldHVybiB0LlB5KGEsYil9LApxRTpmdW5j
-dGlvbiBxRSgpe30sCkdoOmZ1bmN0aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlkoKXt9LApuQjpmdW5j
-dGlvbiBuQigpe30sCkF6OmZ1bmN0aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAoKXt9LApueDpmdW5j
-dGlvbiBueCgpe30sCm9KOmZ1bmN0aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQoKXt9LApRRjpmdW5j
-dGlvbiBRRigpe30sCk5oOmZ1bmN0aW9uIE5oKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9LApuNzpmdW5j
-dGlvbiBuNygpe30sCnd6OmZ1bmN0aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmN2OmZ1
-bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVuY3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgpe30sCkQwOmZ1
-bmN0aW9uIEQwKCl7fSwKaEg6ZnVuY3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgpe30sCmJyOmZ1
-bmN0aW9uIGJyKCl7fSwKVmI6ZnVuY3Rpb24gVmIoKXt9LApmSjpmdW5jdGlvbiBmSigpe30sCndhOmZ1
-bmN0aW9uIHdhKCl7fSwKU2c6ZnVuY3Rpb24gU2coKXt9LAp1ODpmdW5jdGlvbiB1OCgpe30sCk9LOmZ1
-bmN0aW9uIE9LKCl7fSwKZTc6ZnVuY3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgp
-e30sCkJIOmZ1bmN0aW9uIEJIKCl7fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5jdGlvbiBldygp
-e30sCmxwOmZ1bmN0aW9uIGxwKCl7fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJdigp
-e30sCldQOmZ1bmN0aW9uIFdQKCl7fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5jdGlvbiB3Nigp
-e30sCks1OmZ1bmN0aW9uIEs1KCl7fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5jdGlvbiBDUSgp
-e30sCnc0OmZ1bmN0aW9uIHc0KCl7fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5jdGlvbiBjZigp
-e30sCmk3OmZ1bmN0aW9uIGk3KGEpe3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5hPWF9
-LApLUzpmdW5jdGlvbiBLUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMoYSxi
-KXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVuY3Rp
-b24gRmsoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7dmFy
-IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUoYSxiLGMsZCl7
-dmFyIF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxiLGMs
-ZCxlKXt2YXIgXz10aGlzCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5jdGlv
-biB2TihhKXt0aGlzLmE9YX0sCkpROmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rpb24g
-R20oKXt9LAp2RDpmdW5jdGlvbiB2RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3RoaXMu
-YT1hfSwKRWc6ZnVuY3Rpb24gRWcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKbTY6
-ZnVuY3Rpb24gbTYoKXt9LApFbzpmdW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwKY3Q6
-ZnVuY3Rpb24gY3QoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1kCl8u
-ZD1lfSwKSUE6ZnVuY3Rpb24gSUEoKXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9uIFc5
-KGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwKZFc6
-ZnVuY3Rpb24gZFcoYSl7dGhpcy5hPWF9LApGYjpmdW5jdGlvbiBGYigpe30sCmtGOmZ1bmN0aW9uIGtG
-KCl7fSwKbWs6ZnVuY3Rpb24gbWsoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktvOmZ1bmN0aW9uIEtv
-KGEpe3RoaXMuYT1hCnRoaXMuYj0hMX0sCmZtOmZ1bmN0aW9uIGZtKGEpe3RoaXMuYT1hfSwKTGU6ZnVu
-Y3Rpb24gTGUoKXt9LApLNzpmdW5jdGlvbiBLNygpe30sCnJCOmZ1bmN0aW9uIHJCKCl7fSwKWFc6ZnVu
-Y3Rpb24gWFcoKXt9LApvYTpmdW5jdGlvbiBvYSgpe319LE09ewpPWDpmdW5jdGlvbihhKXtzd2l0Y2go
-YSl7Y2FzZSBDLkFkOnJldHVybiJBZGQgLyo/Ki8gaGludCIKY2FzZSBDLm5lOnJldHVybiJBZGQgLyoh
-Ki8gaGludCIKY2FzZSBDLndWOnJldHVybiJSZW1vdmUgLyo/Ki8gaGludCIKY2FzZSBDLmZSOnJldHVy
-biJSZW1vdmUgLyohKi8gaGludCIKY2FzZSBDLm15OnJldHVybiJDaGFuZ2UgdG8gLyo/Ki8gaGludCIK
-Y2FzZSBDLnJ4OnJldHVybiJDaGFuZ2UgdG8gLyohKi8gaGludCJ9cmV0dXJuIG51bGx9LApINzpmdW5j
-dGlvbiBINyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWUY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIs
-cSxwLG8sbgpmb3IodD1iLmxlbmd0aCxzPTE7czx0Oysrcyl7aWYoYltzXT09bnVsbHx8YltzLTFdIT1u
-dWxsKWNvbnRpbnVlCmZvcig7dD49MTt0PXIpe3I9dC0xCmlmKGJbcl0hPW51bGwpYnJlYWt9cT1uZXcg
-UC5SbigiIikKcD1hKyIoIgpxLmE9cApvPUgucUMoYiwwLHQsSC50NihiKS5jKQpuPW8uJHRpCm49cCtu
-ZXcgSC5sSihvLG4uQygicVUoYUwuRSkiKS5hKG5ldyBNLk5vKCkpLG4uQygibEo8YUwuRSxxVT4iKSku
-SCgwLCIsICIpCnEuYT1uCnEuYT1uKygiKTogcGFydCAiKyhzLTEpKyIgd2FzIG51bGwsIGJ1dCBwYXJ0
-ICIrcysiIHdhcyBub3QuIikKdGhyb3cgSC5iKFAueFkocS5aKDApKSl9fSwKbEk6ZnVuY3Rpb24gbEko
-YSl7dGhpcy5hPWF9LApNaTpmdW5jdGlvbiBNaSgpe30sCnE3OmZ1bmN0aW9uIHE3KCl7fSwKTm86ZnVu
-Y3Rpb24gTm8oKXt9fSxVPXsKbno6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5XWShhLnEoMCwibm9kZUlkIikp
-CnJldHVybiBuZXcgVS5MTChDLk5tLkh0KEMucmssbmV3IFUuTUQoYSkpLHQpfSwKTEw6ZnVuY3Rpb24g
-TEwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1EOmZ1bmN0aW9uIE1EKGEpe3RoaXMuYT1hfSwKamY6
-ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKaWYoYT09bnVsbCl0PW51bGwKZWxzZXt0PUguVk0oW10sdS5m
-QSkKZm9yKHM9Si5JVCh1LlIuYShhKSk7cy5GKCk7KXtyPXMuZ2woKQpxPUouVTYocikKQy5ObS5pKHQs
-bmV3IFUuU2UoSC5jKHEucShyLCJkZXNjcmlwdGlvbiIpKSxILmMocS5xKHIsImhyZWYiKSkpKX19cmV0
-dXJuIHR9LApOZDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKGE9PW51bGwpdD1udWxsCmVsc2V7dD1ILlZN
-KFtdLHUuaGgpCmZvcihzPUouSVQodS5SLmEoYSkpO3MuRigpOylDLk5tLmkodCxVLkpqKHMuZ2woKSkp
-fXJldHVybiB0fSwKSmo6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5VNihhKSxzPUguYyh0LnEoYSwiZGVzY3Jp
-cHRpb24iKSkscj1ILlZNKFtdLHUuYUopCmZvcih0PUouSVQodS5SLmEodC5xKGEsImVudHJpZXMiKSkp
-O3QuRigpOylDLk5tLmkocixVLlJqKHQuZ2woKSkpCnJldHVybiBuZXcgVS55RChzLHIpfSwKUmo6ZnVu
-Y3Rpb24oYSl7dmFyIHQscz1KLlU2KGEpLHI9SC5jKHMucShhLCJkZXNjcmlwdGlvbiIpKSxxPUguYyhz
-LnEoYSwiZnVuY3Rpb24iKSkscD1zLnEoYSwibGluayIpCmlmKHA9PW51bGwpcD1udWxsCmVsc2V7dD1K
-LlU2KHApCnA9bmV3IFUuTWwoSC5jKHQucShwLCJocmVmIikpLEguV1kodC5xKHAsImxpbmUiKSksSC5j
-KHQucShwLCJwYXRoIikpKX1zPXUuai5hKHMucShhLCJoaW50QWN0aW9ucyIpKQpzPXM9PW51bGw/bnVs
-bDpKLk0xKHMsbmV3IFUuYU4oKSx1LkUpCnM9cz09bnVsbD9udWxsOnMuYnIoMCkKcmV0dXJuIG5ldyBV
-LndiKHIscSxwLHM9PW51bGw/Qy5kbjpzKX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIg
-Xz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2Uo
-YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCk1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlz
-LmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3Yjpm
-dW5jdGlvbiB3YihhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46
-ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5jdGlvbiBiMCgpe319LEI9ewpZZjpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIscSxwLG8sbixtLGw9SC5jKGEucSgwLCJyZWdpb25zIikpLGs9SC5jKGEucSgwLCJuYXZpZ2F0
-aW9uQ29udGVudCIpKSxqPUguYyhhLnEoMCwic291cmNlQ29kZSIpKSxpPVAuRmwodS5OLHUuZjQpCmZv
-cih0PXUuUy5hKGEucSgwLCJlZGl0cyIpKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCkscz11LlIscj11Lmdp
-O3QuRigpOyl7cT10LmdsKCkKcD1xLmEKbz1ILlZNKFtdLHIpCmZvcihxPUouSVQocy5hKHEuYikpO3Eu
-RigpOyl7bj1xLmdsKCkKbT1KLlU2KG4pCkMuTm0uaShvLG5ldyBCLmo4KEguV1kobS5xKG4sImxpbmUi
-KSksSC5jKG0ucShuLCJleHBsYW5hdGlvbiIpKSxILldZKG0ucShuLCJvZmZzZXQiKSkpKX1pLlkoMCxw
-LG8pfXJldHVybiBuZXcgQi5xcChsLGssaixpKX0sCmo4OmZ1bmN0aW9uIGo4KGEsYixjKXt0aGlzLmE9
-YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnFwOmZ1bmN0aW9uIHFwKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
-PWEKXy5iPWIKXy5jPWMKXy5kPWR9LApmdjpmdW5jdGlvbiBmdigpe30sCk9TOmZ1bmN0aW9uKGEpe3Zh
-ciB0CmlmKCEoYT49NjUmJmE8PTkwKSl0PWE+PTk3JiZhPD0xMjIKZWxzZSB0PSEwCnJldHVybiB0fSwK
-WXU6ZnVuY3Rpb24oYSxiKXt2YXIgdD1hLmxlbmd0aCxzPWIrMgppZih0PHMpcmV0dXJuITEKaWYoIUIu
-T1MoQy54Qi5tKGEsYikpKXJldHVybiExCmlmKEMueEIubShhLGIrMSkhPT01OClyZXR1cm4hMQppZih0
-PT09cylyZXR1cm4hMApyZXR1cm4gQy54Qi5tKGEscyk9PT00N319LFQ9e21ROmZ1bmN0aW9uIG1RKCl7
-fX0sTD17CklxOmZ1bmN0aW9uKCl7Qy5CWi5CKGRvY3VtZW50LCJET01Db250ZW50TG9hZGVkIixuZXcg
-TC5lKCkpCkMub2wuQih3aW5kb3csInBvcHN0YXRlIixuZXcgTC5MKCkpfSwKa3o6ZnVuY3Rpb24oYSl7
-dmFyIHQscz11LmguYShhLnBhcmVudE5vZGUpLnF1ZXJ5U2VsZWN0b3IoIjpzY29wZSA+IHVsIikscj1z
-LnN0eWxlLHE9IiIrQy5DRC56UShzLm9mZnNldEhlaWdodCkqMisicHgiCnIubWF4SGVpZ2h0PXEKcj1K
-LnFGKGEpCnE9ci4kdGkKdD1xLkMoIn4oMSkiKS5hKG5ldyBMLld4KHMsYSkpCnUuTS5hKG51bGwpClcu
-SkUoci5hLHIuYix0LCExLHEuYyl9LAp5WDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz0icXVl
-cnlTZWxlY3RvckFsbCIsbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKGEpLG09dS5oCm4udG9TdHJpbmcK
-SC5EaChtLG0sIlQiLG8pCnQ9dS5UCnM9bmV3IFcud3oobi5xdWVyeVNlbGVjdG9yQWxsKCIubmF2LWxp
-bmsiKSx0KQpzLksocyxuZXcgTC5BTyhiKSkKSC5EaChtLG0sIlQiLG8pCnI9bmV3IFcud3oobi5xdWVy
-eVNlbGVjdG9yQWxsKCIucmVnaW9uIiksdCkKaWYoci5nQShyKSE9PTApe3E9bi5xdWVyeVNlbGVjdG9y
-KCJ0YWJsZVtkYXRhLXBhdGhdIikKcS50b1N0cmluZwpyLksocixuZXcgTC5IbyhxLmdldEF0dHJpYnV0
-ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHEpKS5PKCJwYXRoIikpKSl9SC5EaChtLG0sIlQiLG8p
-CnA9bmV3IFcud3oobi5xdWVyeVNlbGVjdG9yQWxsKCIuYWRkLWhpbnQtbGluayIpLHQpCnAuSyhwLG5l
-dyBMLklDKCkpfSwKUTY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PW5ldyBYTUxIdHRwUmVxdWVzdCgpCkMu
-RHQuZW8odCwiR0VUIixMLlE0KGEsYiksITApCnQuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBl
-IiwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHQsbnVsbCxjKX0s
-CnR5OmZ1bmN0aW9uKGEsYil7dmFyIHQ9bmV3IFhNTEh0dHBSZXF1ZXN0KCkscz11Lk4KQy5EdC5lbyh0
-LCJQT1NUIixMLlE0KGEsUC5GbChzLHMpKSwhMCkKdC5zZXRSZXF1ZXN0SGVhZGVyKCJDb250ZW50LVR5
-cGUiLCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PVVURi04IikKcmV0dXJuIEwuTFUodCxiLHUuUyl9
-LApMVTpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEwuVGcoYSxiLGMsYyl9LApUZzpmdW5jdGlvbihhLGIs
-YyxkKXt2YXIgdD0wLHM9UC5GWChkKSxyLHE9MixwLG89W10sbixtLGwsayxqLGksaCxnCnZhciAkYXN5
-bmMkTFU9UC5seihmdW5jdGlvbihlLGYpe2lmKGU9PT0xKXtwPWYKdD1xfXdoaWxlKHRydWUpc3dpdGNo
-KHQpe2Nhc2UgMDpqPW5ldyBQLlpmKG5ldyBQLnZzKCQuWDMsdS5hbyksdS5iaikKaT11LmFuCmg9aS5h
-KG5ldyBMLmZDKGosYSkpCnUuTS5hKG51bGwpCm09dS5GClcuSkUoYSwibG9hZCIsaCwhMSxtKQpXLkpF
-KGEsImVycm9yIixpLmEoai5nWUooKSksITEsbSkKYS5zZW5kKGI9PW51bGw/bnVsbDpDLkN0Lk9CKGIs
-bnVsbCkpCnE9NAp0PTcKcmV0dXJuIFAualEoai5hLCRhc3luYyRMVSkKY2FzZSA3OnE9Mgp0PTYKYnJl
-YWsKY2FzZSA0OnE9MwpnPXAKSC5SdShnKQpuPUgudHMoZykKaT1QLlRsKCJFcnJvciByZWFjaGluZyBt
-aWdyYXRpb24gcHJldmlldyBzZXJ2ZXIuIixuKQp0aHJvdyBILmIoaSkKdD02CmJyZWFrCmNhc2UgMzp0
-PTIKYnJlYWsKY2FzZSA2Oms9Qy5DdC5wVygwLGEucmVzcG9uc2VUZXh0LG51bGwpCmlmKGEuc3RhdHVz
-PT09MjAwKXtyPWMuYShrKQp0PTEKYnJlYWt9ZWxzZSB0aHJvdyBILmIoaykKY2FzZSAxOnJldHVybiBQ
-LnlDKHIscykKY2FzZSAyOnJldHVybiBQLmYzKHAscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJExVLHMp
-fSwKYUs6ZnVuY3Rpb24oYSl7dmFyIHQ9UC5oSyhhKS5naFkoKS5xKDAsImxpbmUiKQpyZXR1cm4gdD09
-bnVsbD9udWxsOkguSHAodCxudWxsKX0sCkc2OmZ1bmN0aW9uKGEpe3ZhciB0PVAuaEsoYSkuZ2hZKCku
-cSgwLCJvZmZzZXQiKQpyZXR1cm4gdD09bnVsbD9udWxsOkguSHAodCxudWxsKX0sCmk2OmZ1bmN0aW9u
-KGEpe3JldHVybiBMLm5XKHUuVi5hKGEpKX0sCm5XOmZ1bmN0aW9uKGEpe3ZhciB0PTAscz1QLkZYKHUu
-eikscj0xLHEscD1bXSxvLG4sbSxsLGsKdmFyICRhc3luYyRpNj1QLmx6KGZ1bmN0aW9uKGIsYyl7aWYo
-Yj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOmw9dS5oLmEoVy5xYyhhLmN1
-cnJlbnRUYXJnZXQpKS5nZXRBdHRyaWJ1dGUoImhyZWYiKQphLnByZXZlbnREZWZhdWx0KCkKcj0zCnQ9
-NgpyZXR1cm4gUC5qUShMLnR5KGwsbnVsbCksJGFzeW5jJGk2KQpjYXNlIDY6dS5hXy5hKEouR3IoVy5Q
-dihkb2N1bWVudC5kZWZhdWx0VmlldykpKS5yZWxvYWQoKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIK
-az1xCm89SC5SdShrKQpuPUgudHMoaykKTC5DMigiQ291bGQgbm90IGFkZC9yZW1vdmUgaGludCIsbyxu
-KQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNl
-IDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkaTYscyl9LApDMjpmdW5jdGlv
-bihhLGIsYyl7dmFyIHQscyxyPSJleGNlcHRpb24iLHE9InN0YWNrVHJhY2UiLHA9dS5TLmIoYikmJkou
-Uk0oYi5xKDAsInN1Y2Nlc3MiKSwhMSkmJkgub1QoYi54NChyKSkmJkgub1QoYi54NChxKSksbz1KLmlh
-KGIpCmlmKHApe3Q9SC5jKG8ucShiLHIpKQpjPW8ucShiLHEpfWVsc2UgdD1vLlooYikKcD1kb2N1bWVu
-dApzPXAucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKQpzLnF1ZXJ5U2VsZWN0b3IoImgyIikuaW5u
-ZXJUZXh0PWEKcy5xdWVyeVNlbGVjdG9yKCJwIikuaW5uZXJUZXh0PXQKcy5xdWVyeVNlbGVjdG9yKCJw
-cmUiKS5pbm5lclRleHQ9Si5BYyhjKQpvPXUuTgp1LmJxLmEocy5xdWVyeVNlbGVjdG9yKCJhLmJvdHRv
-bSIpKS5ocmVmPVAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFuZy9zZGsvaXNzdWVzL25l
-dyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0aCBOTkJEIG1pZ3JhdGlv
-biB0b29sOiAiK2EsImxhYmVscyIsImFyZWEtYW5hbHl6ZXIsYW5hbHl6ZXItbm5iZC1taWdyYXRpb24s
-dHlwZS1idWciLCJib2R5IixhKyJcblxuRXJyb3I6ICIrSC5kKHQpKyJcblxuUGxlYXNlIGZpbGwgaW4g
-dGhlIGZvbGxvd2luZzpcblxuKipOYW1lIG9mIHBhY2thZ2UgYmVpbmcgbWlncmF0ZWQgKGlmIHB1Ymxp
-YykqKjpcbioqV2hhdCBJIHdhcyBkb2luZyB3aGVuIHRoaXMgaXNzdWUgb2NjdXJyZWQqKjpcbioqSXMg
-aXQgcG9zc2libGUgdG8gd29yayBhcm91bmQgdGhpcyBpc3N1ZSoqOlxuKipIYXMgdGhpcyBpc3N1ZSBo
-YXBwZW5lZCBiZWZvcmUsIGFuZCBpZiBzbywgaG93IG9mdGVuKio6XG4qKkRhcnQgU0RLIHZlcnNpb24q
-KjogIitILmQocC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkrIlxuKipB
-ZGRpdGlvbmFsIGRldGFpbHMqKjpcblxuVGhhbmtzIGZvciBmaWxpbmchXG5cblN0YWNrdHJhY2U6IF9h
-dXRvIHBvcHVsYXRlZCBieSBtaWdyYXRpb24gcHJldmlldyB0b29sLl9cblxuYGBgXG4iK0guZChjKSsi
-XG5gYGBcbiJdLG8sbykpLlooMCkKbz1zLnN0eWxlCm8uZGlzcGxheT0iaW5pdGlhbCIKcD1hKyI6ICIr
-SC5kKGIpCndpbmRvdwppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUu
-ZXJyb3IocCkKd2luZG93CnA9SC5kKGMpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5k
-b3cuY29uc29sZS5lcnJvcihwKX0sCnQyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwPXt9LG89
-dS5oLmEoVy5xYyhhLmN1cnJlbnRUYXJnZXQpKQphLnByZXZlbnREZWZhdWx0KCkKdD1wLmE9by5nZXRB
-dHRyaWJ1dGUoImhyZWYiKQpzPUouemwodCwiPyIpP3AuYT1DLnhCLk5qKHQsMCxDLnhCLk9ZKHQsIj8i
-KSk6dApyPUwuRzYodCkKcT1MLmFLKHQpCmlmKHIhPW51bGwpTC5hZihzLHIscSxiLG5ldyBMLm5UKHAs
-cixxKSkKZWxzZSBMLmFmKHMsbnVsbCxudWxsLGIsbmV3IEwuQloocCkpfSwKdlU6ZnVuY3Rpb24oKXt2
-YXIgdD1kb2N1bWVudCxzPXUuaApILkRoKHMscywiVCIsInF1ZXJ5U2VsZWN0b3JBbGwiKQp0PW5ldyBX
-Lnd6KHQucXVlcnlTZWxlY3RvckFsbCgiLmNvZGUiKSx1LlQpCnQuSyh0LG5ldyBMLkdIKCkpfSwKaFg6
-ZnVuY3Rpb24oYSxiLGMpe3JldHVybiBMLll3KGEsYixjKX0sCll3OmZ1bmN0aW9uKGEsYixjKXt2YXIg
-dD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrLGosaSxoCnZhciAkYXN5bmMkaFg9UC5s
-eihmdW5jdGlvbihkLGUpe2lmKGQ9PT0xKXtxPWUKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2Ug
-MDpyPTMKaz11Lk4KdD02CnJldHVybiBQLmpRKEwuUTYoYSxQLkVGKFsicmVnaW9uIiwicmVnaW9uIiwi
-b2Zmc2V0IixILmQoYildLGssayksdS5TKSwkYXN5bmMkaFgpCmNhc2UgNjpvPWUKaz1vCmo9Si5VNihr
-KQpuPW5ldyBVLmQyKFUuamYoai5xKGssImVkaXRzIikpLEguYyhqLnEoaywiZXhwbGFuYXRpb24iKSks
-SC5XWShqLnEoaywibGluZSIpKSxILmMoai5xKGssImRpc3BsYXlQYXRoIikpLEguYyhqLnEoaywidXJp
-UGF0aCIpKSxVLk5kKGoucShrLCJ0cmFjZXMiKSkpCkwuVDEobikKTC5GcihhLGIsYykKTC55WCgiLmVk
-aXQtcGFuZWwgLnBhbmVsLWNvbnRlbnQiLCExKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIKaD1xCm09
-SC5SdShoKQpsPUgudHMoaCkKTC5DMigiQ291bGQgbm90IGxvYWQgZWRpdCBkZXRhaWxzIixtLGwpCnQ9
-NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpy
-ZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRoWCxzKX0sCkc3OmZ1bmN0aW9uKGEs
-YixjLGQsZSl7cmV0dXJuIEwuTDUoYSxiLGMsZCxlKX0sCkw1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFy
-IHQ9MCxzPVAuRlgodS56KSxyLHE9MixwLG89W10sbixtLGwsayxqLGksaAp2YXIgJGFzeW5jJEc3PVAu
-bHooZnVuY3Rpb24oZixnKXtpZihmPT09MSl7cD1nCnQ9cX13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNl
-IDA6aWYoIUouclkoYSkuVGMoYSwiLmRhcnQiKSl7TC5CRShhLG5ldyBCLnFwKCIiLCIiLCIiLEMuQ00p
-LGQpCkwuQlgoYSxudWxsKQppZihlIT1udWxsKWUuJDAoKQp0PTEKYnJlYWt9cT00Cmo9dS5OCnQ9Nwpy
-ZXR1cm4gUC5qUShMLlE2KGEsUC5FRihbImlubGluZSIsInRydWUiXSxqLGopLHUuUyksJGFzeW5jJEc3
-KQpjYXNlIDc6bj1nCkwuQkUoYSxCLllmKG4pLGQpCkwuZkcoYixjKQptPUMueEIudGcoYSwiPyIpP0Mu
-eEIuTmooYSwwLEMueEIuT1koYSwiPyIpKTphCkwuQlgobSxiKQppZihlIT1udWxsKWUuJDAoKQpxPTIK
-dD02CmJyZWFrCmNhc2UgNDpxPTMKaD1wCmw9SC5SdShoKQprPUgudHMoaCkKTC5DMigiQ291bGQgbm90
-IGxvYWQgZGFydCBmaWxlICIrYSxsLGspCnQ9NgpicmVhawpjYXNlIDM6dD0yCmJyZWFrCmNhc2UgNjpj
-YXNlIDE6cmV0dXJuIFAueUMocixzKQpjYXNlIDI6cmV0dXJuIFAuZjMocCxzKX19KQpyZXR1cm4gUC5E
-SSgkYXN5bmMkRzcscyl9LApHZTpmdW5jdGlvbigpe3ZhciB0PTAscz1QLkZYKHUueikscj0xLHEscD1b
-XSxvLG4sbSxsLGssaixpCnZhciAkYXN5bmMkR2U9UC5seihmdW5jdGlvbihhLGIpe2lmKGE9PT0xKXtx
-PWIKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpqPSIvX3ByZXZpZXcvbmF2aWdhdGlvblRy
-ZWUuanNvbiIKcj0zCnQ9NgpyZXR1cm4gUC5qUShMLlE2KGosQy5XTyx1LmV3KSwkYXN5bmMkR2UpCmNh
-c2UgNjpvPWIKbj1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIubmF2LXRyZWUiKQpKLmw1KG4sIiIpCkwu
-dFgobixMLm1LKG8pKQpyPTEKdD01CmJyZWFrCmNhc2UgMzpyPTIKaT1xCm09SC5SdShpKQpsPUgudHMo
-aSkKTC5DMigiQ291bGQgbm90IGxvYWQgbmF2aWdhdGlvbiB0cmVlIixtLGwpCnQ9NQpicmVhawpjYXNl
-IDI6dD0xCmJyZWFrCmNhc2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhx
-LHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRHZSxzKX0sCnFPOmZ1bmN0aW9uKGEpe3ZhciB0LHM9YS5n
-ZXRCb3VuZGluZ0NsaWVudFJlY3QoKSxyPUMuQ0QuelEoJC5maSgpLm9mZnNldEhlaWdodCkscT13aW5k
-b3cuaW5uZXJIZWlnaHQscD1DLkNELnpRKCQuRFcoKS5vZmZzZXRIZWlnaHQpCmlmKHR5cGVvZiBxIT09
-Im51bWJlciIpcmV0dXJuIHEuSE4oKQp0PXMuYm90dG9tCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0
-dXJuIHQub3MoKQppZih0PnEtKHArMTQpKUouZGgoYSkKZWxzZXtxPXMudG9wCmlmKHR5cGVvZiBxIT09
-Im51bWJlciIpcmV0dXJuIHEuSigpCmlmKHE8cisxNClKLmRoKGEpfX0sCmZHOmZ1bmN0aW9uKGEsYil7
-dmFyIHQscyxyCmlmKGEhPW51bGwpe3Q9ZG9jdW1lbnQKcz10LmdldEVsZW1lbnRCeUlkKCJvIitILmQo
-YSkpCnI9dC5xdWVyeVNlbGVjdG9yKCIubGluZS0iK0guZChiKSkKaWYocyE9bnVsbCl7TC5xTyhzKQpK
-LmRSKHMpLmkoMCwidGFyZ2V0Iil9ZWxzZSBpZihyIT1udWxsKUwucU8oci5wYXJlbnRFbGVtZW50KQpp
-ZihyIT1udWxsKUouZFIodS5oLmEoci5wYXJlbnROb2RlKSkuaSgwLCJoaWdobGlnaHQiKX1lbHNlIEwu
-cU8oJC5EOSgpKX0sCmFmOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUwuRzYod2luZG93Lmxv
-Y2F0aW9uLmhyZWYpLHE9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKaWYociE9bnVsbCl7dD1kb2N1
-bWVudC5nZXRFbGVtZW50QnlJZCgibyIrSC5kKHIpKQppZih0IT1udWxsKUouZFIodCkuUigwLCJ0YXJn
-ZXQiKX1pZihxIT1udWxsKXtzPWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5saW5lLSIrSC5kKHEpKQpp
-ZihzIT1udWxsKUouZFIocy5wYXJlbnRFbGVtZW50KS5SKDAsImhpZ2hsaWdodCIpfWlmKGE9PXdpbmRv
-dy5sb2NhdGlvbi5wYXRobmFtZSl7TC5mRyhiLGMpCmUuJDAoKX1lbHNlIEwuRzcoYSxiLGMsZCxlKX0s
-ClE0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPVAuaEsoYSkscT11Lk4KcT1QLkZsKHEscSkKZm9yKHQ9
-ci5naFkoKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCk7dC5GKCk7KXtzPXQuZ2woKQpxLlkoMCxzLmEscy5i
-KX1mb3IodD1iLmdQdShiKSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10LmdsKCkKcS5ZKDAscy5hLHMuYil9
-cS5ZKDAsImF1dGhUb2tlbiIsJC5VRSgpKQpyZXR1cm4gci5ubSgwLHEpLlooMCl9LApUMTpmdW5jdGlv
-bihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsaz0kLmhMKCkKSi5sNShrLCIiKQppZihhPT1udWxsKXt0
-PWRvY3VtZW50LmNyZWF0ZUVsZW1lbnQoInAiKQp0LnRleHRDb250ZW50PSJTZWUgZGV0YWlscyBhYm91
-dCBhIHByb3Bvc2VkIGVkaXQuIgpDLkx0LnNQKHQsSC5WTShbInBsYWNlaG9sZGVyIl0sdS5zKSkKay5h
-cHBlbmRDaGlsZCh0KQpDLkx0LkZGKHQpCnJldHVybn1zPWEuZApyPSQublUoKQpxPXIuemYocykKcD1h
-LmIKbz1kb2N1bWVudApuPXIuSFAocyxKLlQwKG8ucXVlcnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29u
-dGVudCkpCm09YS5jCmw9by5jcmVhdGVFbGVtZW50KCJwIikKay5hcHBlbmRDaGlsZChsKQpsLmFwcGVu
-ZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHApKyIgYXQgIikpCnI9dS5OCnI9Vy5KNihMLlE0KGEu
-ZSxQLkVGKFsibGluZSIsSi5BYyhtKV0scixyKSkpCnIuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9k
-ZShILmQobikrIjoiK0guZChtKSsiLiIpKQpsLmFwcGVuZENoaWxkKHIpCkouZGgobCkKTC5DQyhhLGss
-cSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGos
-aSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9ZG9jdW1lbnQKcz10LmNyZWF0
-ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9k
-ZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShiKSxnPWcuZ2t6KGcpLHQ9dS5R
-LHI9dC5DKCJ+KDEpIikscT11Lk0sdD10LmM7Zy5GKCk7KXtwPWcuZ2woKQpvPWRvY3VtZW50CnM9by5j
-cmVhdGVFbGVtZW50KCJwIikKbj0kLnlQKCkKbi5hcHBlbmRDaGlsZChzKQpzLmFwcGVuZENoaWxkKG8u
-Y3JlYXRlVGV4dE5vZGUoSC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0ZUVsZW1lbnQoInVsIikKbi5hcHBl
-bmRDaGlsZChtKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXtuPXAuZ2woKQpsPW8uY3JlYXRlRWxlbWVu
-dCgibGkiKQptLmFwcGVuZENoaWxkKGwpCkouZFIobCkuaSgwLCJlZGl0IikKaz1vLmNyZWF0ZUVsZW1l
-bnQoImEiKQpsLmFwcGVuZENoaWxkKGspCmsuY2xhc3NMaXN0LmFkZCgiZWRpdC1saW5rIikKaj1uLmMK
-aT1ILmQoaikKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygib2Zm
-c2V0IiksaSkKaD1uLmEKaT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcg
-Vy5pNyhrKSkuTygibGluZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5jcmVhdGVUZXh0Tm9kZSgibGluZSAi
-K0guZChoKSkpCmk9ci5hKG5ldyBMLkVFKGosaCxhKSkKcS5hKG51bGwpClcuSkUoaywiY2xpY2siLGks
-ITEsdCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKCI6ICIrSC5kKG4uYikpKX19aWYoYylM
-LlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13aW5kb3cubG9jYXRpb24scT1Q
-LmhLKChyJiZDLkV4KS5nRHIocikrSC5kKGEpKQpyPXUuTgpyPVAuRmwocixyKQppZihiIT1udWxsKXIu
-WSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbClyLlkoMCwibGluZSIsSC5kKGMpKQpyLlkoMCwi
-YXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhpc3RvcnkKdD11LnoKcz1xLloo
-MCkKci50b1N0cmluZwpyLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSkuUHYoUC5GbCh0LHQpKSwiIixz
-KX0sCkVuOmZ1bmN0aW9uKGEpe3ZhciB0PUoubShkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucm9vdCIp
-LnRleHRDb250ZW50LCIvIikKaWYoQy54Qi5uKGEsdCkpcmV0dXJuIEMueEIuRyhhLHQubGVuZ3RoKQpl
-bHNlIHJldHVybiBhfSwKQlg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9e30Kci5hPWEKYT1MLkVuKGEp
-CnIuYT1hCiQuRDkoKS50ZXh0Q29udGVudD1hCnQ9ZG9jdW1lbnQKcz11LmgKSC5EaChzLHMsIlQiLCJx
-dWVyeVNlbGVjdG9yQWxsIikKdD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JBbGwoIi5uYXYtcGFuZWwg
-Lm5hdi1saW5rIiksdS5UKQp0LksodCxuZXcgTC5WUyhyKSl9LApCRTpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQ9Ii5yZWdpb25zIixzPWRvY3VtZW50LHI9cy5xdWVyeVNlbGVjdG9yKHQpLHE9cy5xdWVyeVNlbGVj
-dG9yKCIuY29kZSIpCkoudEgocixiLmEsJC5LRygpKQpKLnRIKHEsYi5iLCQuS0coKSkKTC5MSChhLGIu
-ZCxjKQpMLnZVKCkKTC55WCgiLmNvZGUiLCEwKQpMLnlYKHQsITApfSwKdFg6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnPWRvY3VtZW50LGY9Zy5jcmVhdGVFbGVtZW50KCJ1
-bCIpCmEuYXBwZW5kQ2hpbGQoZikKZm9yKHQ9Yi5sZW5ndGgscz11Lk0scj0wO3I8Yi5sZW5ndGg7Yi5s
-ZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Ipe3E9YltyXQpwPWcuY3JlYXRlRWxlbWVudCgibGkiKQpm
-LmFwcGVuZENoaWxkKHApCm89Si5SRShwKQppZihxLmE9PT1DLlkyKXtvLmdQKHApLmkoMCwiZGlyIikK
-bj1nLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKG4pCm89Si5SRShuKQpvLmdQKG4p
-LmkoMCwiYXJyb3ciKQpvLnNoZihuLCImI3gyNUJDOyIpCm09Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikK
-cC5hcHBlbmRDaGlsZChtKQpKLmw1KG0sIiYjeDFGNEMxOyIpCnAuYXBwZW5kQ2hpbGQoZy5jcmVhdGVU
-ZXh0Tm9kZShxLmIpKQpMLnRYKHAscS5jKQpMLmt6KG4pfWVsc2V7by5zaGYocCwiJiN4MUY0QzQ7IikK
-bD1nLmNyZWF0ZUVsZW1lbnQoImEiKQpwLmFwcGVuZENoaWxkKGwpCm89Si5SRShsKQpvLmdQKGwpLmko
-MCwibmF2LWxpbmsiKQpsLnNldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGwpKS5P
-KCJuYW1lIikscS5kKQpsLnNldEF0dHJpYnV0ZSgiaHJlZiIscS5lKQpsLmFwcGVuZENoaWxkKGcuY3Jl
-YXRlVGV4dE5vZGUocS5iKSkKbz1vLmdWbChsKQprPW8uJHRpCmo9ay5DKCJ+KDEpIikuYShuZXcgTC5U
-RCgpKQpzLmEobnVsbCkKVy5KRShvLmEsby5iLGosITEsay5jKQppPXEuZgppZih0eXBlb2YgaSE9PSJu
-dW1iZXIiKXJldHVybiBpLm9zKCkKaWYoaT4wKXtoPWcuY3JlYXRlRWxlbWVudCgic3BhbiIpCnAuYXBw
-ZW5kQ2hpbGQoaCkKSi5kUihoKS5pKDAsImVkaXQtY291bnQiKQpvPSIiK2krIiAiCmlmKGk9PT0xKWs9
-ImVkaXQiCmVsc2Ugaz0iZWRpdHMiCmguc2V0QXR0cmlidXRlKCJ0aXRsZSIsbytrKQpoLmFwcGVuZENo
-aWxkKGcuY3JlYXRlVGV4dE5vZGUoQy5qbi5aKGkpKSl9fX19LApGejpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxLHAsbyxuLG0sbCxrLGosaT1hLmEKaWYoaT09bnVsbClyZXR1cm4KdD1kb2N1bWVudApzPXQu
-Y3JlYXRlRWxlbWVudCgicCIpCnI9Yi5hcHBlbmRDaGlsZChzKQpzPXQuY3JlYXRlRWxlbWVudCgic3Bh
-biIpCnE9dS5zCkouTXUocyxILlZNKFsidHlwZS1kZXNjcmlwdGlvbiJdLHEpKQpzLmFwcGVuZENoaWxk
-KHQuY3JlYXRlVGV4dE5vZGUoIkFjdGlvbnMiKSkKci5hcHBlbmRDaGlsZChzKQpyLmFwcGVuZENoaWxk
-KHQuY3JlYXRlVGV4dE5vZGUoIjoiKSkKcD10LmNyZWF0ZUVsZW1lbnQoInAiKQpiLmFwcGVuZENoaWxk
-KHApCmZvcihzPWkubGVuZ3RoLG89dS5YLG49MDtuPGkubGVuZ3RoO2kubGVuZ3RoPT09c3x8KDAsSC5s
-aykoaSksKytuKXttPWlbbl0KbD10LmNyZWF0ZUVsZW1lbnQoImEiKQpwLmFwcGVuZENoaWxkKGwpCmwu
-YXBwZW5kQ2hpbGQodC5jcmVhdGVUZXh0Tm9kZShtLmEpKQpsLnNldEF0dHJpYnV0ZSgiaHJlZiIsbS5i
-KQprPW8uYShILlZNKFsiYWRkLWhpbnQtbGluayIsImJlZm9yZS1hcHBseSIsImJ1dHRvbiJdLHEpKQpq
-PUouZFIobCkKai5WMSgwKQpqLkZWKDAsayl9fSwKQ0M6ZnVuY3Rpb24oYTgsYTksYjApe3ZhciB0LHMs
-cixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiLGEsYTAsYTEsYTIsYTMsYTQsYTUsYTYsYTcK
-Zm9yKHQ9YTguZixzPXQubGVuZ3RoLHI9dS5zLHE9dS5YLHA9dS5RLG89cC5DKCJ+KDEpIiksbj11Lk0s
-cD1wLmMsbT0wO208dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK20pe2w9dFttXQpr
-PWRvY3VtZW50Cmo9ay5jcmVhdGVFbGVtZW50KCJwIikKaT1xLmEoSC5WTShbInRyYWNlIl0scikpCmg9
-Si5kUihqKQpoLlYxKDApCmguRlYoMCxpKQpnPWE5LmFwcGVuZENoaWxkKGopCmo9ay5jcmVhdGVFbGVt
-ZW50KCJzcGFuIikKaT1xLmEoSC5WTShbInR5cGUtZGVzY3JpcHRpb24iXSxyKSkKaD1KLmRSKGopCmgu
-VjEoMCkKaC5GVigwLGkpCmouYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZShsLmEpKQpnLmFwcGVu
-ZENoaWxkKGopCmcuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiOiIpKQpqPWsuY3JlYXRlRWxl
-bWVudCgidWwiKQppPXEuYShILlZNKFsidHJhY2UiXSxyKSkKaD1KLmRSKGopCmguVjEoMCkKaC5GVigw
-LGkpCmY9Zy5hcHBlbmRDaGlsZChqKQpmb3Ioaj1sLmIsaT1qLmxlbmd0aCxlPTA7ZTxqLmxlbmd0aDtq
-Lmxlbmd0aD09PWl8fCgwLEgubGspKGopLCsrZSl7ZD1qW2VdCmM9ay5jcmVhdGVFbGVtZW50KCJsaSIp
-CmYuYXBwZW5kQ2hpbGQoYykKYj1rLmNyZWF0ZUVsZW1lbnQoInNwYW4iKQphPXEuYShILlZNKFsiZnVu
-Y3Rpb24iXSxyKSkKaD1KLmRSKGIpCmguVjEoMCkKaC5GVigwLGEpCmE9ZC5iCkwua0QoYixhPT1udWxs
-PyJ1bmtub3duIjphKQpjLmFwcGVuZENoaWxkKGIpCmEwPWQuYwppZihhMCE9bnVsbCl7Yy5hcHBlbmRD
-aGlsZChrLmNyZWF0ZVRleHROb2RlKCIgKCIpKQphMT1hMC5iCmEyPWsuY3JlYXRlRWxlbWVudCgiYSIp
-CmEyLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4dE5vZGUoSC5kKGEwLmMpKyI6IitILmQoYTEpKSkKYTIu
-c2V0QXR0cmlidXRlKCJocmVmIixhMC5hKQphMi5jbGFzc0xpc3QuYWRkKCJuYXYtbGluayIpCmMuYXBw
-ZW5kQ2hpbGQoYTIpCmMuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiKSIpKX1jLmFwcGVuZENo
-aWxkKGsuY3JlYXRlVGV4dE5vZGUoIjogIikpCmI9ZC5hCkwua0QoYyxiPT1udWxsPyJ1bmtub3duIjpi
-KQpiPWQuZAppZihiLmxlbmd0aCE9PTApe2E9ay5jcmVhdGVFbGVtZW50KCJwIikKYTM9cS5hKEguVk0o
-WyJkcmF3ZXIiLCJiZWZvcmUtYXBwbHkiXSxyKSkKaD1KLmRSKGEpCmguVjEoMCkKaC5GVigwLGEzKQph
-ND1jLmFwcGVuZENoaWxkKGEpCmZvcihhPWIubGVuZ3RoLGE1PTA7YTU8Yi5sZW5ndGg7Yi5sZW5ndGg9
-PT1hfHwoMCxILmxrKShiKSwrK2E1KXthNj1iW2E1XQphMz1rLmNyZWF0ZUVsZW1lbnQoImJ1dHRvbiIp
-CmE3PW8uYShuZXcgTC5BUyhhNixhMCkpCm4uYShudWxsKQpXLkpFKGEzLCJjbGljayIsYTcsITEscCkK
-YTMuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZShNLk9YKGE2LmEpKSkKYTQuYXBwZW5kQ2hpbGQo
-YTMpfX19fX0sCmtEOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPUguVk0oYi5zcGxpdCgiLiIpLHUucyks
-cT1DLk5tLmd0SChyKSxwPWRvY3VtZW50CmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9kZShxKSkK
-Zm9yKHE9SC5xQyhyLDEsbnVsbCx1Lk4pLHE9bmV3IEguYTcocSxxLmdBKHEpLHEuJHRpLkMoImE3PGFM
-LkU+IikpLHQ9Si5SRShhKTtxLkYoKTspe3M9cS5kCnQubnooYSwiYmVmb3JlZW5kIiwiJiM4MjAzOy4i
-LG51bGwsbnVsbCkKYS5hcHBlbmRDaGlsZChwLmNyZWF0ZVRleHROb2RlKHMpKX19LAplOmZ1bmN0aW9u
-IGUoKXt9LApWVzpmdW5jdGlvbiBWVyhhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApv
-WjpmdW5jdGlvbiBvWigpe30sCmpyOmZ1bmN0aW9uIGpyKCl7fSwKcWw6ZnVuY3Rpb24gcWwoKXt9LAp5
-ODpmdW5jdGlvbiB5OCgpe30sCkhpOmZ1bmN0aW9uIEhpKCl7fSwKQlQ6ZnVuY3Rpb24gQlQoKXt9LApM
-OmZ1bmN0aW9uIEwoKXt9LApXeDpmdW5jdGlvbiBXeChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQU86
-ZnVuY3Rpb24gQU8oYSl7dGhpcy5hPWF9LApkTjpmdW5jdGlvbiBkTihhKXt0aGlzLmE9YX0sCkhvOmZ1
-bmN0aW9uIEhvKGEpe3RoaXMuYT1hfSwKeHo6ZnVuY3Rpb24geHooYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCklDOmZ1bmN0aW9uIElDKCl7fSwKZkM6ZnVuY3Rpb24gZkMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9
-Yn0sCm5UOmZ1bmN0aW9uIG5UKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkJaOmZ1
-bmN0aW9uIEJaKGEpe3RoaXMuYT1hfSwKR0g6ZnVuY3Rpb24gR0goKXt9LApFRTpmdW5jdGlvbiBFRShh
-LGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9LApRTDpmdW5jdGlvbiBRTChhLGIpe3RoaXMu
-YT1hCnRoaXMuYj1ifSwKVlM6ZnVuY3Rpb24gVlMoYSl7dGhpcy5hPWF9LApURDpmdW5jdGlvbiBURCgp
-e30sCkFTOmZ1bmN0aW9uIEFTKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApYQTpmdW5jdGlvbiBYQSgp
-e30sCm1LOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuPUguVk0oW10sdS5maCkKZm9yKHQ9Si5J
-VCh1LlIuYShhKSk7dC5GKCk7KXtzPXQuZ2woKQpyPUouVTYocykKcT1MLnAyKEguYyhyLnEocywidHlw
-ZSIpKSkKcD1ILmMoci5xKHMsIm5hbWUiKSkKbz1yLnEocywic3VidHJlZSIpCm89bz09bnVsbD9udWxs
-OkwubUsobykKQy5ObS5pKG4sbmV3IEwuWloocSxwLG8sSC5jKHIucShzLCJwYXRoIikpLEguYyhyLnEo
-cywiaHJlZiIpKSxILldZKHIucShzLCJlZGl0Q291bnQiKSkpKX1yZXR1cm4gbn0sClZEOmZ1bmN0aW9u
-KGEpe3ZhciB0LHMscj1ILlZNKFtdLHUuSikKZm9yKHQ9YS5sZW5ndGgscz0wO3M8YS5sZW5ndGg7YS5s
-ZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3MpQy5ObS5pKHIsYVtzXS5MdCgpKQpyZXR1cm4gcn0sCnAy
-OmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlImRpcmVjdG9yeSI6cmV0dXJuIEMuWTIKY2FzZSJmaWxl
-IjpyZXR1cm4gQy5yZgpkZWZhdWx0OnRocm93IEguYihQLlBWKCJVbnJlY29nbml6ZWQgbmF2aWdhdGlv
-biB0cmVlIG5vZGUgdHlwZTogIitILmQoYSkpKX19LAp2eTpmdW5jdGlvbihhKXtzd2l0Y2goYSl7Y2Fz
-ZSBDLlkyOnJldHVybiJkaXJlY3RvcnkiCmNhc2UgQy5yZjpyZXR1cm4iZmlsZSJ9dGhyb3cgSC5iKFAu
-UFYoIlVucmVjb2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK2EuWigwKSkpfSwKWlo6
-ZnVuY3Rpb24gWlooYSxiLGMsZCxlLGYpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQK
-Xy5lPWUKXy5mPWZ9LApPOTpmdW5jdGlvbiBPOShhKXt0aGlzLmI9YX0sCklWOmZ1bmN0aW9uIElWKGEs
-YixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxYPXsKQ0w6ZnVuY3Rpb24o
-YSxiKXt2YXIgdCxzLHIscSxwLG89Yi54WihhKQpiLmhLKGEpCmlmKG8hPW51bGwpYT1KLktWKGEsby5s
-ZW5ndGgpCnQ9dS5zCnM9SC5WTShbXSx0KQpyPUguVk0oW10sdCkKdD1hLmxlbmd0aAppZih0IT09MCYm
-Yi5yNChDLnhCLlcoYSwwKSkpe2lmKDA+PXQpcmV0dXJuIEguayhhLDApCkMuTm0uaShyLGFbMF0pCnE9
-MX1lbHNle0MuTm0uaShyLCIiKQpxPTB9Zm9yKHA9cTtwPHQ7KytwKWlmKGIucjQoQy54Qi5XKGEscCkp
-KXtDLk5tLmkocyxDLnhCLk5qKGEscSxwKSkKQy5ObS5pKHIsYVtwXSkKcT1wKzF9aWYocTx0KXtDLk5t
-LmkocyxDLnhCLkcoYSxxKSkKQy5ObS5pKHIsIiIpfXJldHVybiBuZXcgWC5XRChiLG8scyxyKX0sCldE
-OmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5kPWMKXy5lPWR9LApx
-UjpmdW5jdGlvbiBxUihhKXt0aGlzLmE9YX0sCkk3OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgWC5kdihh
-KX0sCmR2OmZ1bmN0aW9uIGR2KGEpe3RoaXMuYT1hfX0sTz17ClJoOmZ1bmN0aW9uKCl7dmFyIHQscz1u
-dWxsCmlmKFAudW8oKS5nRmkoKSE9PSJmaWxlIilyZXR1cm4gJC5FYigpCnQ9UC51bygpCmlmKCFDLnhC
-LlRjKHQuZ0lpKHQpLCIvIikpcmV0dXJuICQuRWIoKQppZihQLktMKHMsImEvYiIscyxzLHMscyxzKS50
-NCgpPT09ImFcXGIiKXJldHVybiAkLktrKCkKcmV0dXJuICQuYkQoKX0sCnpMOmZ1bmN0aW9uIHpMKCl7
-fX0sRT17T0Y6ZnVuY3Rpb24gT0YoYSxiLGMpe3RoaXMuZD1hCnRoaXMuZT1iCnRoaXMuZj1jfX0sRj17
-cnU6ZnVuY3Rpb24gcnUoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9YwpfLnI9ZH19
-LEQ9ewpSWDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9bnVsbAp0cnl7cD1QLnVvKCl9Y2F0Y2godCl7
-aWYodS5nOC5iKEguUnUodCkpKXtzPSQuRmYKaWYocyE9bnVsbClyZXR1cm4gcwp0aHJvdyB0fWVsc2Ug
-dGhyb3cgdH1pZihKLlJNKHAsJC5JNikpcmV0dXJuICQuRmYKJC5JNj1wCmlmKCQuSGsoKT09JC5FYigp
-KXM9JC5GZj1wLlpJKCIuIikuWigwKQplbHNle3I9cC50NCgpCnE9ci5sZW5ndGgtMQpzPSQuRmY9cT09
-PTA/cjpDLnhCLk5qKHIsMCxxKX1yZXR1cm4gc319CnZhciB3PVtDLEgsSixQLFcsTSxVLEIsVCxMLFgs
-TyxFLEYsRF0KaHVua0hlbHBlcnMuc2V0RnVuY3Rpb25OYW1lc0lmTmVjZXNzYXJ5KHcpCnZhciAkPXt9
-CkguRksucHJvdG90eXBlPXt9CkoudkIucHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-YT09PWJ9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIEguZVEoYSl9LApaOmZ1bmN0aW9uKGEpe3JldHVy
-biJJbnN0YW5jZSBvZiAnIitILmQoSC5saChhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYShi
-KQp0aHJvdyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlw
-ZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
-YT81MTkwMTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIG51bGw9PWJ9LApaOmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5jdGlvbihh
-KXtyZXR1cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYShiKSl9LAok
-aWM4OjF9CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKWjpmdW5jdGlv
-bihhKXtyZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3Rv
-dHlwZT17fQpKLmM1LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLndRKCldCmlmKHQ9
-PW51bGwpcmV0dXJuIHRoaXMudChhKQpyZXR1cm4iSmF2YVNjcmlwdCBmdW5jdGlvbiBmb3IgIitILmQo
-Si5BYyh0KSl9LAokUzpmdW5jdGlvbigpe3JldHVybntmdW5jOjEsb3B0OlssLCwsLCwsLCwsLCwsLCws
-XX19LAokaUVIOjF9CkouamQucHJvdG90eXBlPXsKaTpmdW5jdGlvbihhLGIpe0gudDYoYSkuYy5hKGIp
-CmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGQiKSkKYS5wdXNoKGIpfSwKVzQ6ZnVuY3Rp
-b24oYSxiKXt2YXIgdAppZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgicmVtb3ZlQXQiKSkKdD1h
-Lmxlbmd0aAppZihiPj10KXRocm93IEguYihQLk83KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEp
-WzBdfSwKVUc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYShjKQpp
-ZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShi
-LDAsdCwiaW5kZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEu
-bGVuZ3RoLGEsYikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRs
-ZW5ndGgpSC52aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5I
-WShhLC0xKSkKcmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygi
-Y1g8MT4iKS5hKGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9
-Si5JVChiKTt0LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2
-KGEpLkMoIn4oMSkiKS5hKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10pCmlm
-KGEubGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
-PUgudDYoYSkKcmV0dXJuIG5ldyBILmxKKGEsdC5LcShjKS5DKCIxKDIpIikuYShiKSx0LkMoIkA8MT4i
-KS5LcShjKS5DKCJsSjwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9bmV3IEFycmF5KGEu
-bGVuZ3RoKQpzLmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMuWShz
-LHQsSC5kKGFbdF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
-cyxyCmQuYShiKQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmEoYykKdD1hLmxlbmd0aApmb3Iocz1i
-LHI9MDtyPHQ7KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQo
-YSkpfXJldHVybiBzfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89SC50NihhKQpvLkMo
-ImEyKDEpIikuYShiKQpvLkMoIjEoKSIpLmEobnVsbCkKdD1hLmxlbmd0aApmb3Iocz1udWxsLHI9ITEs
-cT0wO3E8dDsrK3Epe3A9YVtxXQppZihILm9UKGIuJDEocCkpKXtpZihyKXRocm93IEguYihILmRVKCkp
-CnM9cApyPSEwfWlmKHQhPT1hLmxlbmd0aCl0aHJvdyBILmIoUC5hNChhKSl9aWYocilyZXR1cm4gcwp0
-aHJvdyBILmIoSC5XcCgpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVy
-biBILmsoYSxiKQpyZXR1cm4gYVtiXX0sCkQ2OmZ1bmN0aW9uKGEsYixjKXtpZihiPDB8fGI+YS5sZW5n
-dGgpdGhyb3cgSC5iKFAuVEUoYiwwLGEubGVuZ3RoLCJzdGFydCIsbnVsbCkpCmlmKGM8Ynx8Yz5hLmxl
-bmd0aCl0aHJvdyBILmIoUC5URShjLGIsYS5sZW5ndGgsImVuZCIsbnVsbCkpCmlmKGI9PT1jKXJldHVy
-biBILlZNKFtdLEgudDYoYSkpCnJldHVybiBILlZNKGEuc2xpY2UoYixjKSxILnQ2KGEpKX0sCmd0SDpm
-dW5jdGlvbihhKXtpZihhLmxlbmd0aD4wKXJldHVybiBhWzBdCnRocm93IEguYihILldwKCkpfSwKZ3Ja
-OmZ1bmN0aW9uKGEpe3ZhciB0PWEubGVuZ3RoCmlmKHQ+MClyZXR1cm4gYVt0LTFdCnRocm93IEguYihI
-LldwKCkpfSwKWVc6ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzLHI9SC50NihhKQpyLkMoImNYPDE+
-IikuYShkKQppZighIWEuaW1tdXRhYmxlJGxpc3QpSC52aChQLkw0KCJzZXRSYW5nZSIpKQpQLmpCKGIs
-YyxhLmxlbmd0aCkKdD1jLWIKaWYodD09PTApcmV0dXJuClAuazEoZSwic2tpcENvdW50IikKci5DKCJ6
-TTwxPiIpLmEoZCkKcj1KLlU2KGQpCmlmKGUrdD5yLmdBKGQpKXRocm93IEguYihILmFyKCkpCmlmKGU8
-Yilmb3Iocz10LTE7cz49MDstLXMpYVtiK3NdPXIucShkLGUrcykKZWxzZSBmb3Iocz0wO3M8dDsrK3Mp
-YVtiK3NdPXIucShkLGUrcyl9LAp2ZzpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gdGhpcy5ZVyhhLGIs
-YyxkLDApfSwKVnI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgudDYoYSkuQygiYTIoMSkiKS5hKGIpCnQ9
-YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtpZihILm9UKGIuJDEoYVtzXSkpKXJldHVybiEwCmlmKGEu
-bGVuZ3RoIT09dCl0aHJvdyBILmIoUC5hNChhKSl9cmV0dXJuITF9LAp0ZzpmdW5jdGlvbihhLGIpe3Zh
-ciB0CmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpaWYoSi5STShhW3RdLGIpKXJldHVybiEwCnJldHVybiEx
-fSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aD09PTB9LApnb3I6ZnVuY3Rpb24oYSl7cmV0
-dXJuIGEubGVuZ3RoIT09MH0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuV0UoYSwiWyIsIl0iKX0sCmdr
-ejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEoubTEoYSxhLmxlbmd0aCxILnQ2KGEpLkMoIm0xPDE+Iikp
-fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEu
-bGVuZ3RofSwKc0E6ZnVuY3Rpb24oYSxiKXtpZighIWEuZml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgic2V0
-IGxlbmd0aCIpKQppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLG51bGwsIm5ld0xlbmd0aCIsbnVsbCkp
-CmEubGVuZ3RoPWJ9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQppZihiPj1hLmxlbmd0aHx8YjwwKXRo
-cm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC50NihhKS5j
-LmEoYykKaWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgiaW5kZXhlZCBzZXQiKSkKaWYoYj49
-YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIoSC5IWShhLGIpKQphW2JdPWN9LAokaWJROjEsCiRpY1g6MSwK
-JGl6TToxfQpKLlBvLnByb3RvdHlwZT17fQpKLm0xLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0
-dXJuIHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1yLmxlbmd0aAppZihz
-LmIhPT1xKXRocm93IEguYihILmxrKHIpKQp0PXMuYwppZih0Pj1xKXtzLnNNKG51bGwpCnJldHVybiEx
-fXMuc00oclt0XSk7KytzLmMKcmV0dXJuITB9LApzTTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGku
-Yy5hKGEpfSwKJGlBbjoxfQpKLnFJLnByb3RvdHlwZT17Cnl1OmZ1bmN0aW9uKGEpe3ZhciB0CmlmKGE+
-PS0yMTQ3NDgzNjQ4JiZhPD0yMTQ3NDgzNjQ3KXJldHVybiBhfDAKaWYoaXNGaW5pdGUoYSkpe3Q9YTww
-P01hdGguY2VpbChhKTpNYXRoLmZsb29yKGEpCnJldHVybiB0KzB9dGhyb3cgSC5iKFAuTDQoIiIrYSsi
-LnRvSW50KCkiKSl9LAp6UTpmdW5jdGlvbihhKXtpZihhPjApe2lmKGEhPT0xLzApcmV0dXJuIE1hdGgu
-cm91bmQoYSl9ZWxzZSBpZihhPi0xLzApcmV0dXJuIDAtTWF0aC5yb3VuZCgwLWEpCnRocm93IEguYihQ
-Lkw0KCIiK2ErIi5yb3VuZCgpIikpfSwKV1o6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQppZihiPDJ8
-fGI+MzYpdGhyb3cgSC5iKFAuVEUoYiwyLDM2LCJyYWRpeCIsbnVsbCkpCnQ9YS50b1N0cmluZyhiKQpp
-ZihDLnhCLm0odCx0Lmxlbmd0aC0xKSE9PTQxKXJldHVybiB0CnM9L14oW1xkYS16XSspKD86XC4oW1xk
-YS16XSspKT9cKGVcKyhcZCspXCkkLy5leGVjKHQpCmlmKHM9PW51bGwpSC52aChQLkw0KCJVbmV4cGVj
-dGVkIHRvU3RyaW5nIHJlc3VsdDogIit0KSkKcj1zLmxlbmd0aAppZigxPj1yKXJldHVybiBILmsocywx
-KQp0PXNbMV0KaWYoMz49cilyZXR1cm4gSC5rKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7
-dCs9cgpxLT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sClo6ZnVuY3Rpb24oYSl7aWYo
-YT09PTAmJjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkK
-cz1NYXRoLmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9y
-OnIvdApyZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODEx
-NzY1MjF8MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09
-MClyZXR1cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCti
-fSwKd0c6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/
-MzE6Ygp0PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5i
-KEguSShiKSkKcmV0dXJuIHRoaXMucDMoYSxiKX0sCnAzOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGI+MzE/
-MDphPj4+Yn0sCiRpQ1A6MSwKJGlsZjoxfQpKLmJVLnByb3RvdHlwZT17JGlJZjoxfQpKLlZBLnByb3Rv
-dHlwZT17fQpKLkRyLnByb3RvdHlwZT17Cm06ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgu
-SFkoYSxiKSkKaWYoYj49YS5sZW5ndGgpSC52aChILkhZKGEsYikpCnJldHVybiBhLmNoYXJDb2RlQXQo
-Yil9LApXOmZ1bmN0aW9uKGEsYil7aWYoYj49YS5sZW5ndGgpdGhyb3cgSC5iKEguSFkoYSxiKSkKcmV0
-dXJuIGEuY2hhckNvZGVBdChiKX0sCmRkOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBILk5GKGIsYSww
-KX0sCmg6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYiE9InN0cmluZyIpdGhyb3cgSC5iKFAuTDMoYixu
-dWxsLG51bGwpKQpyZXR1cm4gYStifSwKVGM6ZnVuY3Rpb24oYSxiKXt2YXIgdD1iLmxlbmd0aCxzPWEu
-bGVuZ3RoCmlmKHQ+cylyZXR1cm4hMQpyZXR1cm4gYj09PXRoaXMuRyhhLHMtdCl9LAppNzpmdW5jdGlv
-bihhLGIsYyxkKXt2YXIgdCxzCmM9UC5qQihiLGMsYS5sZW5ndGgpCnQ9YS5zdWJzdHJpbmcoMCxiKQpz
-PWEuc3Vic3RyaW5nKGMpCnJldHVybiB0K2Qrc30sClFpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZigh
-SC5vayhjKSlILnZoKEguSShjKSkKaWYodHlwZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gYy5KKCkKaWYo
-YzwwfHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWMr
-Yi5sZW5ndGgKaWYodD5hLmxlbmd0aClyZXR1cm4hMQpyZXR1cm4gYj09PWEuc3Vic3RyaW5nKGMsdCl9
-LApuOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUWkoYSxiLDApfSwKTmo6ZnVuY3Rpb24oYSxiLGMp
-e2lmKCFILm9rKGIpKUgudmgoSC5JKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIh
-PT0ibnVtYmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLk83KGIsbnVsbCkpCmlmKGI+
-Yyl0aHJvdyBILmIoUC5PNyhiLG51bGwpKQppZihjPmEubGVuZ3RoKXRocm93IEguYihQLk83KGMsbnVs
-bCkpCnJldHVybiBhLnN1YnN0cmluZyhiLGMpfSwKRzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLk5q
-KGEsYixudWxsKX0sCmhjOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRvTG93ZXJDYXNlKCl9LApiUzpmdW5j
-dGlvbihhKXt2YXIgdCxzLHIscT1hLnRyaW0oKSxwPXEubGVuZ3RoCmlmKHA9PT0wKXJldHVybiBxCmlm
-KHRoaXMuVyhxLDApPT09MTMzKXt0PUoubW0ocSwxKQppZih0PT09cClyZXR1cm4iIn1lbHNlIHQ9MApz
-PXAtMQpyPXRoaXMubShxLHMpPT09MTMzP0ouYzEocSxzKTpwCmlmKHQ9PT0wJiZyPT09cClyZXR1cm4g
-cQpyZXR1cm4gcS5zdWJzdHJpbmcodCxyKX0sCkl4OmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZigwPj1i
-KXJldHVybiIiCmlmKGI9PT0xfHxhLmxlbmd0aD09PTApcmV0dXJuIGEKaWYoYiE9PWI+Pj4wKXRocm93
-IEguYihDLkVxKQpmb3IodD1hLHM9IiI7ITA7KXtpZigoYiYxKT09PTEpcz10K3MKYj1iPj4+MQppZihi
-PT09MClicmVhawp0Kz10fXJldHVybiBzfSwKWFU6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CmlmKGM8MHx8
-Yz5hLmxlbmd0aCl0aHJvdyBILmIoUC5URShjLDAsYS5sZW5ndGgsbnVsbCxudWxsKSkKdD1hLmluZGV4
-T2YoYixjKQpyZXR1cm4gdH0sCk9ZOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuWFUoYSxiLDApfSwK
-UGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoYz09bnVsbCljPWEubGVuZ3RoCmVsc2UgaWYoYzww
-fHxjPmEubGVuZ3RoKXRocm93IEguYihQLlRFKGMsMCxhLmxlbmd0aCxudWxsLG51bGwpKQp0PWIubGVu
-Z3RoCnM9YS5sZW5ndGgKaWYoYyt0PnMpYz1zLXQKcmV0dXJuIGEubGFzdEluZGV4T2YoYixjKX0sCmNu
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuUGsoYSxiLG51bGwpfSwKSXM6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0PWEubGVuZ3RoCmlmKGM+dCl0aHJvdyBILmIoUC5URShjLDAsdCxudWxsLG51bGwpKQpyZXR1
-cm4gSC5tMihhLGIsYyl9LAp0ZzpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLklzKGEsYiwwKX0sClo6
-ZnVuY3Rpb24oYSl7cmV0dXJuIGF9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEubGVu
-Z3RoLHM9MCxyPTA7cjx0Oysrcil7cz01MzY4NzA5MTEmcythLmNoYXJDb2RlQXQocikKcz01MzY4NzA5
-MTEmcysoKDUyNDI4NyZzKTw8MTApCnNePXM+PjZ9cz01MzY4NzA5MTEmcysoKDY3MTA4ODYzJnMpPDwz
-KQpzXj1zPj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwKZ0E6ZnVuY3Rpb24o
-YSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guV1koYikKaWYoYj49YS5sZW5ndGh8
-fCExKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWou
-cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIEMueEIubSh0aGlzLmEsSC5XWShiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFM
-LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQu
-Z0EodCksSC5MaCh0KS5DKCJhNzxhTC5FPiIpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5n
-QSh0aGlzKT09PTB9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYo
-Yi5sZW5ndGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0Eo
-cSkpdGhyb3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxy
-KSkKaWYocCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9
-PTA/czpzfWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEu
-Z0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYShi
-KSl9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEgubEoodGhp
-cyx0LktxKGMpLkMoIjEoYUwuRSkiKS5hKGIpLHQuQygiQDxhTC5FPiIpLktxKGMpLkMoImxKPDEsMj4i
-KSl9LAp0dDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPUguVk0oW10sSC5MaChzKS5DKCJqZDxh
-TC5FPiIpKQpDLk5tLnNBKHIscy5nQShzKSkKZm9yKHQ9MDt0PHMuZ0Eocyk7Kyt0KUMuTm0uWShyLHQs
-cy5FKDAsdCkpCnJldHVybiByfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpI
-Lm5ILnByb3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSCh0aGlzLmEpLHM9dGhpcy5jCmlm
-KHM9PW51bGx8fHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBczpmdW5jdGlvbigpe3ZhciB0PUouSCh0
-aGlzLmEpLHM9dGhpcy5iCmlmKHM+dClyZXR1cm4gdApyZXR1cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHM9Si5IKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMuYwppZih0PT1u
-dWxsfHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5ITigpCnJl
-dHVybiB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKStiCmlmKGI+PTAp
-e3Q9cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9cj49dH1lbHNl
-IHQ9ITAKaWYodCl0aHJvdyBILmIoUC50KGIscywiaW5kZXgiLG51bGwsbnVsbCkpCnJldHVybiBKLkdB
-KHMuYSxyKX19CkguYTcucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpm
-dW5jdGlvbigpe3ZhciB0LHM9dGhpcyxyPXMuYSxxPUouVTYocikscD1xLmdBKHIpCmlmKHMuYiE9PXAp
-dGhyb3cgSC5iKFAuYTQocikpCnQ9cy5jCmlmKHQ+PXApe3Muc0kobnVsbCkKcmV0dXJuITF9cy5zSShx
-LkUocix0KSk7KytzLmMKcmV0dXJuITB9LApzSTpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuYy5h
-KGEpfSwKJGlBbjoxfQpILmkxLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD1ILkxoKHRo
-aXMpCnJldHVybiBuZXcgSC5NSChKLklUKHRoaXMuYSksdGhpcy5iLHQuQygiQDwxPiIpLktxKHQuUVsx
-XSkuQygiTUg8MSwyPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5hKX19CkgueHku
+YSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sClU2OmZ1bmN0aW9uKGEpe2lm
+KHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4g
+YQppZihhLmNvbnN0cnVjdG9yPT1BcnJheSlyZXR1cm4gSi5qZC5wcm90b3R5cGUKaWYodHlwZW9mIGEh
+PSJvYmplY3QiKXtpZih0eXBlb2YgYT09ImZ1bmN0aW9uIilyZXR1cm4gSi5jNS5wcm90b3R5cGUKcmV0
+dXJuIGF9aWYoYSBpbnN0YW5jZW9mIFAuaylyZXR1cm4gYQpyZXR1cm4gSi5rcyhhKX0sCmlhOmZ1bmN0
+aW9uKGEpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIil7aWYoTWF0aC5mbG9vcihhKT09YSlyZXR1cm4gSi5i
+VS5wcm90b3R5cGUKcmV0dXJuIEouVkEucHJvdG90eXBlfWlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1
+cm4gSi5Eci5wcm90b3R5cGUKaWYoYT09bnVsbClyZXR1cm4gSi5ZRS5wcm90b3R5cGUKaWYodHlwZW9m
+IGE9PSJib29sZWFuIilyZXR1cm4gSi55RS5wcm90b3R5cGUKaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXkp
+cmV0dXJuIEouamQucHJvdG90eXBlCmlmKHR5cGVvZiBhIT0ib2JqZWN0Iil7aWYodHlwZW9mIGE9PSJm
+dW5jdGlvbiIpcmV0dXJuIEouYzUucHJvdG90eXBlCnJldHVybiBhfWlmKGEgaW5zdGFuY2VvZiBQLmsp
+cmV0dXJuIGEKcmV0dXJuIEoua3MoYSl9LApyWTpmdW5jdGlvbihhKXtpZih0eXBlb2YgYT09InN0cmlu
+ZyIpcmV0dXJuIEouRHIucHJvdG90eXBlCmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoIShhIGluc3RhbmNl
+b2YgUC5rKSlyZXR1cm4gSi5rZC5wcm90b3R5cGUKcmV0dXJuIGF9LAp3MTpmdW5jdGlvbihhKXtpZihh
+PT1udWxsKXJldHVybiBhCmlmKGEuY29uc3RydWN0b3I9PUFycmF5KXJldHVybiBKLmpkLnByb3RvdHlw
+ZQppZih0eXBlb2YgYSE9Im9iamVjdCIpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBKLmM1
+LnByb3RvdHlwZQpyZXR1cm4gYX1pZihhIGluc3RhbmNlb2YgUC5rKXJldHVybiBhCnJldHVybiBKLmtz
+KGEpfSwKQ006ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouUkUoYSkuZHUoYSxiLGMsZCl9LApGTDpm
+dW5jdGlvbihhLGIpe3JldHVybiBKLnJZKGEpLmRkKGEsYil9LApHQTpmdW5jdGlvbihhLGIpe3JldHVy
+biBKLncxKGEpLkUoYSxiKX0sCkdyOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdtVyhhKX0sCkht
+OmZ1bmN0aW9uKGEpe3JldHVybiBKLlU2KGEpLmdBKGEpfSwKSVQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+dzEoYSkuZ2t6KGEpfSwKSnk6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5pYShhKS5lNyhhLGIpfSwKS1Y6
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gSi5yWShhKS5HKGEsYil9LApMdDpmdW5jdGlvbihhKXtyZXR1cm4g
+Si5SRShhKS53ZyhhKX0sCk0xOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi53MShhKS5FMihhLGIsYyl9
+LApNdTpmdW5jdGlvbihhLGIpe3JldHVybiBKLlJFKGEpLnNQKGEsYil9LApRejpmdW5jdGlvbihhLGIp
+e3JldHVybiBKLnJZKGEpLlcoYSxiKX0sClJNOmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClyZXR1cm4g
+Yj09bnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGIhPW51bGwmJmE9PT1iCnJldHVybiBK
+LmlhKGEpLkROKGEsYil9LApUMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5yWShhKS5iUyhhKX0sCmE2OmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIEouclkoYSkubShhLGIpfSwKYlQ6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+UkUoYSkuRDQoYSl9LApiYjpmdW5jdGlvbihhLGIpe2lmKHR5cGVvZiBhPT0ibnVtYmVyIiYmdHlwZW9m
+IGI9PSJudW1iZXIiKXJldHVybiBhK2IKcmV0dXJuIEouVEooYSkuaChhLGIpfSwKY0g6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEouclkoYSkuaGMoYSl9LApkUjpmdW5jdGlvbihhKXtyZXR1cm4gSi5SRShhKS5nUChh
+KX0sCmRaOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBKLlJFKGEpLk9uKGEsYixjLGQpfSwKZGc6ZnVu
+Y3Rpb24oYSxiLGMsZCl7cmV0dXJuIEouclkoYSkuaTcoYSxiLGMsZCl9LApkaDpmdW5jdGlvbihhKXty
+ZXR1cm4gSi5SRShhKS5GRihhKX0sCmhmOmZ1bmN0aW9uKGEpe3JldHVybiBKLmlhKGEpLmdpTyhhKX0s
+CmlnOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEpLmdRZyhhKX0sCmo6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouaWEoYSkudyhhKX0sCmw1OmZ1bmN0aW9uKGEsYil7cmV0dXJuIEouUkUoYSkuc2hmKGEsYil9LAps
+ZDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEouclkoYSkuTmooYSxiLGMpfSwKcTA6ZnVuY3Rpb24oYSxi
+LGMpe3JldHVybiBKLnJZKGEpLlFpKGEsYixjKX0sCnFGOmZ1bmN0aW9uKGEpe3JldHVybiBKLlJFKGEp
+LmdWbChhKX0sCnRIOmZ1bmN0aW9uKGEsYixjKXtyZXR1cm4gSi5SRShhKS5wayhhLGIsYyl9LAp1VTpm
+dW5jdGlvbihhKXtyZXR1cm4gSi5VNihhKS5nbDAoYSl9LAp3MjpmdW5jdGlvbihhLGIpe2lmKHR5cGVv
+ZiBiPT09Im51bWJlciIpaWYoYS5jb25zdHJ1Y3Rvcj09QXJyYXl8fHR5cGVvZiBhPT0ic3RyaW5nInx8
+SC53VihhLGFbdi5kaXNwYXRjaFByb3BlcnR5TmFtZV0pKWlmKGI+Pj4wPT09YiYmYjxhLmxlbmd0aCly
+ZXR1cm4gYVtiXQpyZXR1cm4gSi5VNihhKS5xKGEsYil9LAp6bDpmdW5jdGlvbihhLGIpe3JldHVybiBK
+LlU2KGEpLnRnKGEsYil9LAp2QjpmdW5jdGlvbiB2Qigpe30sCnlFOmZ1bmN0aW9uIHlFKCl7fSwKWUU6
+ZnVuY3Rpb24gWUUoKXt9LApNRjpmdW5jdGlvbiBNRigpe30sCmlDOmZ1bmN0aW9uIGlDKCl7fSwKa2Q6
+ZnVuY3Rpb24ga2QoKXt9LApjNTpmdW5jdGlvbiBjNSgpe30sCmpkOmZ1bmN0aW9uIGpkKGEpe3RoaXMu
+JHRpPWF9LApQbzpmdW5jdGlvbiBQbyhhKXt0aGlzLiR0aT1hfSwKbTE6ZnVuY3Rpb24gbTEoYSxiLGMp
+e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPTAKXy5kPW51bGwKXy4kdGk9Y30sCnFJOmZ1bmN0aW9u
+IHFJKCl7fSwKYlU6ZnVuY3Rpb24gYlUoKXt9LApWQTpmdW5jdGlvbiBWQSgpe30sCkRyOmZ1bmN0aW9u
+IERyKCl7fX0sUD17Ck9qOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXt9CmlmKHNlbGYuc2NoZWR1bGVJbW1l
+ZGlhdGUhPW51bGwpcmV0dXJuIFAuRVgoKQppZihzZWxmLk11dGF0aW9uT2JzZXJ2ZXIhPW51bGwmJnNl
+bGYuZG9jdW1lbnQhPW51bGwpe3Q9c2VsZi5kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJkaXYiKQpzPXNl
+bGYuZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgic3BhbiIpCnIuYT1udWxsCm5ldyBzZWxmLk11dGF0aW9u
+T2JzZXJ2ZXIoSC50UihuZXcgUC50aChyKSwxKSkub2JzZXJ2ZSh0LHtjaGlsZExpc3Q6dHJ1ZX0pCnJl
+dHVybiBuZXcgUC5oYShyLHQscyl9ZWxzZSBpZihzZWxmLnNldEltbWVkaWF0ZSE9bnVsbClyZXR1cm4g
+UC55dCgpCnJldHVybiBQLnFXKCl9LApaVjpmdW5jdGlvbihhKXtzZWxmLnNjaGVkdWxlSW1tZWRpYXRl
+KEgudFIobmV3IFAuVnModS5NLmIoYSkpLDApKX0sCm9BOmZ1bmN0aW9uKGEpe3NlbGYuc2V0SW1tZWRp
+YXRlKEgudFIobmV3IFAuRnQodS5NLmIoYSkpLDApKX0sCkJ6OmZ1bmN0aW9uKGEpe3UuTS5iKGEpClAu
+UU4oMCxhKX0sClFOOmZ1bmN0aW9uKGEsYil7dmFyIHQ9bmV3IFAuVzMoKQp0LkNZKGEsYikKcmV0dXJu
+IHR9LApGWDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuaWgobmV3IFAudnMoJC5YMyxhLkMoInZzPDA+
+IikpLGEuQygiaWg8MD4iKSl9LApESTpmdW5jdGlvbihhLGIpe2EuJDIoMCxudWxsKQpiLmI9ITAKcmV0
+dXJuIGIuYX0sCmpROmZ1bmN0aW9uKGEsYil7UC5KZShhLGIpfSwKeUM6ZnVuY3Rpb24oYSxiKXtiLmFN
+KDAsYSl9LApmMzpmdW5jdGlvbihhLGIpe2IudzAoSC5SdShhKSxILnRzKGEpKX0sCkplOmZ1bmN0aW9u
+KGEsYil7dmFyIHQscyxyPW5ldyBQLldNKGIpLHE9bmV3IFAuU1goYikKaWYoYSBpbnN0YW5jZW9mIFAu
+dnMpYS5RZChyLHEsdS56KQplbHNle3Q9dS56CmlmKHUuYy5jKGEpKWEuU3EocixxLHQpCmVsc2V7cz1u
+ZXcgUC52cygkLlgzLHUuXykKcy5hPTQKcy5jPWEKcy5RZChyLG51bGwsdCl9fX0sCmx6OmZ1bmN0aW9u
+KGEpe3ZhciB0PWZ1bmN0aW9uKGIsYyl7cmV0dXJuIGZ1bmN0aW9uKGQsZSl7d2hpbGUodHJ1ZSl0cnl7
+YihkLGUpCmJyZWFrfWNhdGNoKHMpe2U9cwpkPWN9fX0oYSwxKQpyZXR1cm4gJC5YMy5MaihuZXcgUC5H
+cyh0KSx1LlAsdS5lZyx1LnopfSwKR1E6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEsMSl9LApU
+aDpmdW5jdGlvbigpe3JldHVybiBDLndRfSwKWW06ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLkZ5KGEs
+Myl9LApsMDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5xNChhLGIuQygicTQ8MD4iKSl9LAprMzpm
+dW5jdGlvbihhLGIpe3ZhciB0LHMscgpiLmE9MQp0cnl7YS5TcShuZXcgUC5wVihiKSxuZXcgUC5VNyhi
+KSx1LlApfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5yYihuZXcgUC52cihiLHQscykpfX0s
+CkE5OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PXUuXztzPWEuYSxzPT09MjspYT10LmIoYS5j
+KQppZihzPj00KXtyPWIuYWgoKQpiLmE9YS5hCmIuYz1hLmMKUC5IWihiLHIpfWVsc2V7cj11LnguYihi
+LmMpCmIuYT0yCmIuYz1hCmEualEocil9fSwKSFo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8s
+bixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9e30sYz1kLmE9YQpmb3IodD11Lm4scz11Lngscj11LmM7
+ITA7KXtxPXt9CnA9Yy5hPT09OAppZihiPT1udWxsKXtpZihwKXtvPXQuYihjLmMpClAuTDIoZSxlLGMu
+YixvLmEsby5iKX1yZXR1cm59Zm9yKDtuPWIuYSxuIT1udWxsO2I9bil7Yi5hPW51bGwKUC5IWihkLmEs
+Yil9Yz1kLmEKbT1jLmMKcS5hPXAKcS5iPW0KbD0hcAppZihsKXtrPWIuYwprPShrJjEpIT09MHx8KGsm
+MTUpPT09OH1lbHNlIGs9ITAKaWYoayl7az1iLmIKaj1rLmIKaWYocCl7aT1jLmI9PT1qCmk9IShpfHxp
+KX1lbHNlIGk9ITEKaWYoaSl7dC5iKG0pClAuTDIoZSxlLGMuYixtLmEsbS5iKQpyZXR1cm59aD0kLlgz
+CmlmKGghPT1qKSQuWDM9agplbHNlIGg9ZQpjPWIuYwppZigoYyYxNSk9PT04KW5ldyBQLlJUKGQscSxi
+LHApLiQwKCkKZWxzZSBpZihsKXtpZigoYyYxKSE9PTApbmV3IFAucnEocSxiLG0pLiQwKCl9ZWxzZSBp
+ZigoYyYyKSE9PTApbmV3IFAuUlcoZCxxLGIpLiQwKCkKaWYoaCE9bnVsbCkkLlgzPWgKYz1xLmIKaWYo
+ci5jKGMpKXtpZihjLmE+PTQpe2c9cy5iKGsuYykKay5jPW51bGwKYj1rLk44KGcpCmsuYT1jLmEKay5j
+PWMuYwpkLmE9Ywpjb250aW51ZX1lbHNlIFAuQTkoYyxrKQpyZXR1cm59fWY9Yi5iCmc9cy5iKGYuYykK
+Zi5jPW51bGwKYj1mLk44KGcpCmM9cS5hCmw9cS5iCmlmKCFjKXtmLiR0aS5kLmIobCkKZi5hPTQKZi5j
+PWx9ZWxzZXt0LmIobCkKZi5hPTgKZi5jPWx9ZC5hPWYKYz1mfX0sClZIOmZ1bmN0aW9uKGEsYil7dmFy
+IHQKaWYodS5FLmMoYSkpcmV0dXJuIGIuTGooYSx1LnosdS5LLHUubCkKdD11LncKaWYodC5jKGEpKXJl
+dHVybiB0LmIoYSkKdGhyb3cgSC5iKFAuTDMoYSwib25FcnJvciIsIkVycm9yIGhhbmRsZXIgbXVzdCBh
+Y2NlcHQgb25lIE9iamVjdCBvciBvbmUgT2JqZWN0IGFuZCBhIFN0YWNrVHJhY2UgYXMgYXJndW1lbnRz
+LCBhbmQgcmV0dXJuIGEgYSB2YWxpZCByZXN1bHQiKSl9LApwdTpmdW5jdGlvbigpe3ZhciB0LHMKZm9y
+KDt0PSQuUzYsdCE9bnVsbDspeyQubWc9bnVsbApzPXQuYgokLlM2PXMKaWYocz09bnVsbCkkLms4PW51
+bGwKdC5hLiQwKCl9fSwKZU46ZnVuY3Rpb24oKXskLlVEPSEwCnRyeXtQLnB1KCl9ZmluYWxseXskLm1n
+PW51bGwKJC5VRD0hMQppZigkLlM2IT1udWxsKSQudXQoKS4kMShQLlVJKCkpfX0sCmVXOmZ1bmN0aW9u
+KGEpe3ZhciB0PW5ldyBQLk9NKGEpCmlmKCQuUzY9PW51bGwpeyQuUzY9JC5rOD10CmlmKCEkLlVEKSQu
+dXQoKS4kMShQLlVJKCkpfWVsc2UgJC5rOD0kLms4LmI9dH0sCnJSOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cj0kLlM2CmlmKHI9PW51bGwpe1AuZVcoYSkKJC5tZz0kLms4CnJldHVybn10PW5ldyBQLk9NKGEpCnM9
+JC5tZwppZihzPT1udWxsKXt0LmI9cgokLlM2PSQubWc9dH1lbHNle3QuYj1zLmIKJC5tZz1zLmI9dApp
+Zih0LmI9PW51bGwpJC5rOD10fX0sCnJiOmZ1bmN0aW9uKGEpe3ZhciB0PW51bGwscz0kLlgzCmlmKEMu
+TlU9PT1zKXtQLlRrKHQsdCxDLk5VLGEpCnJldHVybn1QLlRrKHQsdCxzLHUuTS5iKHMuR1koYSkpKX0s
+ClF3OmZ1bmN0aW9uKGEsYil7aWYoYT09bnVsbClILnZoKFAuRWUoInN0cmVhbSIpKQpyZXR1cm4gbmV3
+IFAueEkoYi5DKCJ4STwwPiIpKX0sClRsOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG5ldyBQLkN3KGEsYil9
+LApMMjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PXt9CnQuYT1kClAuclIobmV3IFAucEsodCxlKSl9
+LApUODpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMCgp
+CiQuWDM9Ywp0PXMKdHJ5e3M9ZC4kMCgpCnJldHVybiBzfWZpbmFsbHl7JC5YMz10fX0sCnl2OmZ1bmN0
+aW9uKGEsYixjLGQsZSxmLGcpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMShlKQokLlgz
+PWMKdD1zCnRyeXtzPWQuJDEoZSkKcmV0dXJuIHN9ZmluYWxseXskLlgzPXR9fSwKUXg6ZnVuY3Rpb24o
+YSxiLGMsZCxlLGYsZyxoLGkpe3ZhciB0LHM9JC5YMwppZihzPT09YylyZXR1cm4gZC4kMihlLGYpCiQu
+WDM9Ywp0PXMKdHJ5e3M9ZC4kMihlLGYpCnJldHVybiBzfWZpbmFsbHl7JC5YMz10fX0sClRrOmZ1bmN0
+aW9uKGEsYixjLGQpe3ZhciB0CnUuTS5iKGQpCnQ9Qy5OVSE9PWMKaWYodClkPSEoIXR8fCExKT9jLkdZ
+KGQpOmMuUlQoZCx1LkgpClAuZVcoZCl9LAp0aDpmdW5jdGlvbiB0aChhKXt0aGlzLmE9YX0sCmhhOmZ1
+bmN0aW9uIGhhKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sClZzOmZ1bmN0aW9uIFZz
+KGEpe3RoaXMuYT1hfSwKRnQ6ZnVuY3Rpb24gRnQoYSl7dGhpcy5hPWF9LApXMzpmdW5jdGlvbiBXMygp
+e30sCnlIOmZ1bmN0aW9uIHlIKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAppaDpmdW5jdGlvbiBpaChh
+LGIpe3RoaXMuYT1hCnRoaXMuYj0hMQp0aGlzLiR0aT1ifSwKV006ZnVuY3Rpb24gV00oYSl7dGhpcy5h
+PWF9LApTWDpmdW5jdGlvbiBTWChhKXt0aGlzLmE9YX0sCkdzOmZ1bmN0aW9uIEdzKGEpe3RoaXMuYT1h
+fSwKRnk6ZnVuY3Rpb24gRnkoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkdWOmZ1bmN0aW9uIEdWKGEs
+Yil7dmFyIF89dGhpcwpfLmE9YQpfLmQ9Xy5jPV8uYj1udWxsCl8uJHRpPWJ9LApxNDpmdW5jdGlvbiBx
+NChhLGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApiODpmdW5jdGlvbiBiOCgpe30sClBmOmZ1bmN0aW9u
+IFBmKCl7fSwKWmY6ZnVuY3Rpb24gWmYoYSxiKXt0aGlzLmE9YQp0aGlzLiR0aT1ifSwKRmU6ZnVuY3Rp
+b24gRmUoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYT1udWxsCl8uYj1hCl8uYz1iCl8uZD1jCl8uZT1k
+Cl8uJHRpPWV9LAp2czpmdW5jdGlvbiB2cyhhLGIpe3ZhciBfPXRoaXMKXy5hPTAKXy5iPWEKXy5jPW51
+bGwKXy4kdGk9Yn0sCmRhOmZ1bmN0aW9uIGRhKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApvUTpmdW5j
+dGlvbiBvUShhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKcFY6ZnVuY3Rpb24gcFYoYSl7dGhpcy5hPWF9
+LApVNzpmdW5jdGlvbiBVNyhhKXt0aGlzLmE9YX0sCnZyOmZ1bmN0aW9uIHZyKGEsYixjKXt0aGlzLmE9
+YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnJIOmZ1bmN0aW9uIHJIKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LApLRjpmdW5jdGlvbiBLRihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKWkw6ZnVuY3Rpb24gWkwoYSxi
+LGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUlQ6ZnVuY3Rpb24gUlQoYSxiLGMsZCl7dmFy
+IF89dGhpcwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZH0sCmpaOmZ1bmN0aW9uIGpaKGEpe3RoaXMuYT1h
+fSwKcnE6ZnVuY3Rpb24gcnEoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUlc6ZnVu
+Y3Rpb24gUlcoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKT006ZnVuY3Rpb24gT00o
+YSl7dGhpcy5hPWEKdGhpcy5iPW51bGx9LApxaDpmdW5jdGlvbiBxaCgpe30sCkI1OmZ1bmN0aW9uIEI1
+KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1TzpmdW5jdGlvbiB1TyhhLGIpe3RoaXMuYT1hCnRoaXMu
+Yj1ifSwKTU86ZnVuY3Rpb24gTU8oKXt9LAprVDpmdW5jdGlvbiBrVCgpe30sCnhJOmZ1bmN0aW9uIHhJ
+KGEpe3RoaXMuJHRpPWF9LApDdzpmdW5jdGlvbiBDdyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKbTA6
+ZnVuY3Rpb24gbTAoKXt9LApwSzpmdW5jdGlvbiBwSyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKSmk6
+ZnVuY3Rpb24gSmkoKXt9LApoajpmdW5jdGlvbiBoaihhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhp
+cy5jPWN9LApWcDpmdW5jdGlvbiBWcChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKT1I6ZnVuY3Rpb24g
+T1IoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKRUY6ZnVuY3Rpb24oYSxiLGMpe3Jl
+dHVybiBiLkMoIkA8MD4iKS5LcShjKS5DKCJGbzwxLDI+IikuYihILkI3KGEsbmV3IEguTjUoYi5DKCJA
+PDA+IikuS3EoYykuQygiTjU8MSwyPiIpKSkpfSwKRmw6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IEgu
+TjUoYS5DKCJAPDA+IikuS3EoYikuQygiTjU8MSwyPiIpKX0sCkxzOmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgUC5iNihhLkMoImI2PDA+IikpfSwKVDI6ZnVuY3Rpb24oKXt2YXIgdD1PYmplY3QuY3JlYXRlKG51
+bGwpCnRbIjxub24taWRlbnRpZmllci1rZXk+Il09dApkZWxldGUgdFsiPG5vbi1pZGVudGlmaWVyLWtl
+eT4iXQpyZXR1cm4gdH0sCnJqOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1uZXcgUC5sbShhLGIsYy5DKCJs
+bTwwPiIpKQp0LmM9YS5lCnJldHVybiB0fSwKRVA6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKaWYoUC5o
+QihhKSl7aWYoYj09PSIoIiYmYz09PSIpIilyZXR1cm4iKC4uLikiCnJldHVybiBiKyIuLi4iK2N9dD1I
+LlZNKFtdLHUucykKQy5ObS5pKCQueGcsYSkKdHJ5e1AuVnIoYSx0KX1maW5hbGx5e2lmKDA+PSQueGcu
+bGVuZ3RoKXJldHVybiBILk9IKCQueGcsLTEpCiQueGcucG9wKCl9cz1QLnZnKGIsdS5SLmIodCksIiwg
+IikrYwpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCldFOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dCxzCmlmKFAuaEIoYSkpcmV0dXJuIGIrIi4uLiIrYwp0PW5ldyBQLlJuKGIpCkMuTm0uaSgkLnhnLGEp
+CnRyeXtzPXQKcy5hPVAudmcocy5hLGEsIiwgIil9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1
+cm4gSC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXQuYSs9YwpzPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0
+KDApPT0wP3M6c30sCmhCOmZ1bmN0aW9uKGEpe3ZhciB0LHMKZm9yKHQ9JC54Zy5sZW5ndGgscz0wO3M8
+dDsrK3MpaWYoYT09PSQueGdbc10pcmV0dXJuITAKcmV0dXJuITF9LApWcjpmdW5jdGlvbihhLGIpe3Zh
+ciB0LHMscixxLHAsbyxuLG09YS5na3ooYSksbD0wLGs9MAp3aGlsZSghMCl7aWYoIShsPDgwfHxrPDMp
+KWJyZWFrCmlmKCFtLkYoKSlyZXR1cm4KdD1ILmQobS5nbCgpKQpDLk5tLmkoYix0KQpsKz10Lmxlbmd0
+aCsyOysra31pZighbS5GKCkpe2lmKGs8PTUpcmV0dXJuCmlmKDA+PWIubGVuZ3RoKXJldHVybiBILk9I
+KGIsLTEpCnM9Yi5wb3AoKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCl9
+ZWxzZXtxPW0uZ2woKTsrK2sKaWYoIW0uRigpKXtpZihrPD00KXtDLk5tLmkoYixILmQocSkpCnJldHVy
+bn1zPUguZChxKQppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpyPWIucG9wKCkKbCs9cy5s
+ZW5ndGgrMn1lbHNle3A9bS5nbCgpOysrawpmb3IoO20uRigpO3E9cCxwPW8pe289bS5nbCgpOysrawpp
+ZihrPjEwMCl7d2hpbGUoITApe2lmKCEobD43NSYmaz4zKSlicmVhawppZigwPj1iLmxlbmd0aClyZXR1
+cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyOy0ta31DLk5tLmkoYiwiLi4uIikKcmV0dXJu
+fX1yPUguZChxKQpzPUguZChwKQpsKz1zLmxlbmd0aCtyLmxlbmd0aCs0fX1pZihrPmIubGVuZ3RoKzIp
+e2wrPTUKbj0iLi4uIn1lbHNlIG49bnVsbAp3aGlsZSghMCl7aWYoIShsPjgwJiZiLmxlbmd0aD4zKSli
+cmVhawppZigwPj1iLmxlbmd0aClyZXR1cm4gSC5PSChiLC0xKQpsLT1iLnBvcCgpLmxlbmd0aCsyCmlm
+KG49PW51bGwpe2wrPTUKbj0iLi4uIn19aWYobiE9bnVsbClDLk5tLmkoYixuKQpDLk5tLmkoYixyKQpD
+Lk5tLmkoYixzKX0sCnRNOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPVAuTHMoYikKZm9yKHQ9YS5sZW5n
+dGgscz0wO3M8YS5sZW5ndGg7YS5sZW5ndGg9PT10fHwoMCxILmxrKShhKSwrK3Mpci5pKDAsYi5iKGFb
+c10pKQpyZXR1cm4gcn0sCm5POmZ1bmN0aW9uKGEpe3ZhciB0LHM9e30KaWYoUC5oQihhKSlyZXR1cm4i
+ey4uLn0iCnQ9bmV3IFAuUm4oIiIpCnRyeXtDLk5tLmkoJC54ZyxhKQp0LmErPSJ7IgpzLmE9ITAKYS5L
+KDAsbmV3IFAucmEocyx0KSkKdC5hKz0ifSJ9ZmluYWxseXtpZigwPj0kLnhnLmxlbmd0aClyZXR1cm4g
+SC5PSCgkLnhnLC0xKQokLnhnLnBvcCgpfXM9dC5hCnJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
+fSwKYjY6ZnVuY3Rpb24gYjYoYSl7dmFyIF89dGhpcwpfLmE9MApfLmY9Xy5lPV8uZD1fLmM9Xy5iPW51
+bGwKXy5yPTAKXy4kdGk9YX0sCmJuOmZ1bmN0aW9uIGJuKGEpe3RoaXMuYT1hCnRoaXMuYz10aGlzLmI9
+bnVsbH0sCmxtOmZ1bmN0aW9uIGxtKGEsYixjKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uZD1fLmM9
+bnVsbApfLiR0aT1jfSwKbVc6ZnVuY3Rpb24gbVcoKXt9LAp1eTpmdW5jdGlvbiB1eSgpe30sCmxEOmZ1
+bmN0aW9uIGxEKCl7fSwKaWw6ZnVuY3Rpb24gaWwoKXt9LApyYTpmdW5jdGlvbiByYShhLGIpe3RoaXMu
+YT1hCnRoaXMuYj1ifSwKWWs6ZnVuY3Rpb24gWWsoKXt9LAp5UTpmdW5jdGlvbiB5UShhKXt0aGlzLmE9
+YX0sCktQOmZ1bmN0aW9uIEtQKCl7fSwKUG46ZnVuY3Rpb24gUG4oKXt9LApHajpmdW5jdGlvbiBHaihh
+LGIpe3RoaXMuYT1hCnRoaXMuJHRpPWJ9LApsZjpmdW5jdGlvbiBsZigpe30sClZqOmZ1bmN0aW9uIFZq
+KCl7fSwKWHY6ZnVuY3Rpb24gWHYoKXt9LApuWTpmdW5jdGlvbiBuWSgpe30sClRDOmZ1bmN0aW9uIFRD
+KCl7fSwKUlU6ZnVuY3Rpb24gUlUoKXt9LApCUzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxCmlmKHR5
+cGVvZiBhIT0ic3RyaW5nIil0aHJvdyBILmIoSC50TChhKSkKdD1udWxsCnRyeXt0PUpTT04ucGFyc2Uo
+YSl9Y2F0Y2gocil7cz1ILlJ1KHIpCnE9UC5ycihTdHJpbmcocyksbnVsbCxudWxsKQp0aHJvdyBILmIo
+cSl9cT1QLlFlKHQpCnJldHVybiBxfSwKUWU6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoYT09bnVsbClyZXR1
+cm4gbnVsbAppZih0eXBlb2YgYSE9Im9iamVjdCIpcmV0dXJuIGEKaWYoT2JqZWN0LmdldFByb3RvdHlw
+ZU9mKGEpIT09QXJyYXkucHJvdG90eXBlKXJldHVybiBuZXcgUC51dyhhLE9iamVjdC5jcmVhdGUobnVs
+bCkpCmZvcih0PTA7dDxhLmxlbmd0aDsrK3QpYVt0XT1QLlFlKGFbdF0pCnJldHVybiBhfSwKa3k6ZnVu
+Y3Rpb24oYSxiLGMsZCl7aWYoYiBpbnN0YW5jZW9mIFVpbnQ4QXJyYXkpcmV0dXJuIFAuUlAoITEsYixj
+LGQpCnJldHVybiBudWxsfSwKUlA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyPSQucmYoKQppZihy
+PT1udWxsKXJldHVybiBudWxsCnQ9MD09PWMKaWYodCYmITApcmV0dXJuIFAuT1EocixiKQpzPWIubGVu
+Z3RoCmQ9UC5qQihjLGQscykKaWYodCYmZD09PXMpcmV0dXJuIFAuT1EocixiKQpyZXR1cm4gUC5PUShy
+LGIuc3ViYXJyYXkoYyxkKSl9LApPUTpmdW5jdGlvbihhLGIpe2lmKFAuQmUoYikpcmV0dXJuIG51bGwK
+cmV0dXJuIFAuSmgoYSxiKX0sCkpoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0cnl7dD1hLmRlY29kZShi
+KQpyZXR1cm4gdH1jYXRjaChzKXtILlJ1KHMpfXJldHVybiBudWxsfSwKQmU6ZnVuY3Rpb24oYSl7dmFy
+IHQscz1hLmxlbmd0aC0yCmZvcih0PTA7dDxzOysrdClpZihhW3RdPT09MjM3KWlmKChhW3QrMV0mMjI0
+KT09PTE2MClyZXR1cm4hMApyZXR1cm4hMX0sCldJOmZ1bmN0aW9uKCl7dmFyIHQscwp0cnl7dD1uZXcg
+VGV4dERlY29kZXIoInV0Zi04Iix7ZmF0YWw6dHJ1ZX0pCnJldHVybiB0fWNhdGNoKHMpe0guUnUocyl9
+cmV0dXJuIG51bGx9LApjUDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyCmZvcih0PUouVTYoYSkscz1i
+O3M8YzsrK3Mpe3I9dC5xKGEscykKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci56TSgpCmlm
+KChyJjEyNykhPT1yKXJldHVybiBzLWJ9cmV0dXJuIGMtYn0sCnhNOmZ1bmN0aW9uKGEsYixjLGQsZSxm
+KXtpZihDLmpuLnpZKGYsNCkhPT0wKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5n
+LCBwYWRkZWQgbGVuZ3RoIG11c3QgYmUgbXVsdGlwbGUgb2YgZm91ciwgaXMgIitmLGEsYykpCmlmKGQr
+ZSE9PWYpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgYmFzZTY0IHBhZGRpbmcsICc9JyBub3QgYXQgdGhl
+IGVuZCIsYSxiKSkKaWYoZT4yKXRocm93IEguYihQLnJyKCJJbnZhbGlkIGJhc2U2NCBwYWRkaW5nLCBt
+b3JlIHRoYW4gdHdvICc9JyBjaGFyYWN0ZXJzIixhLGIpKX0sCkd5OmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gbmV3IFAuVWQoYSxiKX0sCk5DOmZ1bmN0aW9uKGEpe3JldHVybiBhLkx0KCl9LAp1WDpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscz1uZXcgUC5SbigiIikscj1uZXcgUC50dShzLFtdLFAuQ3koKSkKci5pVShh
+KQp0PXMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH0sCnV3OmZ1bmN0aW9uIHV3KGEsYil7
+dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPW51bGx9LAppODpmdW5jdGlvbiBpOChhKXt0aGlzLmE9YX0s
+CkNWOmZ1bmN0aW9uIENWKCl7fSwKVTg6ZnVuY3Rpb24gVTgoKXt9LApVazpmdW5jdGlvbiBVaygpe30s
+CndJOmZ1bmN0aW9uIHdJKCl7fSwKWmk6ZnVuY3Rpb24gWmkoKXt9LApVZDpmdW5jdGlvbiBVZChhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKSzg6ZnVuY3Rpb24gSzgoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+CmJ5OmZ1bmN0aW9uIGJ5KCl7fSwKb2o6ZnVuY3Rpb24gb2ooYSl7dGhpcy5iPWF9LApNeDpmdW5jdGlv
+biBNeChhKXt0aGlzLmE9YX0sClNoOmZ1bmN0aW9uIFNoKCl7fSwKdGk6ZnVuY3Rpb24gdGkoYSxiKXt0
+aGlzLmE9YQp0aGlzLmI9Yn0sCnR1OmZ1bmN0aW9uIHR1KGEsYixjKXt0aGlzLmM9YQp0aGlzLmE9Ygp0
+aGlzLmI9Y30sCnU1OmZ1bmN0aW9uIHU1KCl7fSwKRTM6ZnVuY3Rpb24gRTMoKXt9LApSdzpmdW5jdGlv
+biBSdyhhKXt0aGlzLmI9MAp0aGlzLmM9YX0sCkdZOmZ1bmN0aW9uIEdZKGEpe3RoaXMuYT1hfSwKYno6
+ZnVuY3Rpb24gYnooYSxiKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz0hMApfLmY9Xy5lPV8uZD0w
+fSwKUUE6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguSHAoYSxjKQppZih0IT1udWxsKXJldHVybiB0Cmlm
+KGIhPW51bGwpcmV0dXJuIGIuJDEoYSkKdGhyb3cgSC5iKFAucnIoYSxudWxsLG51bGwpKX0sCkY6ZnVu
+Y3Rpb24oYSl7aWYoYSBpbnN0YW5jZW9mIEguVHApcmV0dXJuIGEudygwKQpyZXR1cm4iSW5zdGFuY2Ug
+b2YgJyIrSC5kKEguTShhKSkrIicifSwKTzg6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZihjKXQ9
+SC5WTShuZXcgQXJyYXkoYSksZC5DKCJqZDwwPiIpKQplbHNlIHQ9Si5RaShhLGQpCmlmKGEhPT0wJiYh
+MClmb3Iocz0wO3M8dC5sZW5ndGg7KytzKUMuTm0uWSh0LHMsYikKcmV0dXJuIHR9LApDSDpmdW5jdGlv
+bihhLGIsYyl7dmFyIHQscz1ILlZNKFtdLGMuQygiamQ8MD4iKSkKZm9yKHQ9Si5JVChhKTt0LkYoKTsp
+Qy5ObS5pKHMsYy5iKHQuZ2woKSkpCmlmKGIpcmV0dXJuIHMKcmV0dXJuIGMuQygiek08MD4iKS5iKEou
+RXAocykpfSwKQUY6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gYi5DKCJ6TTwwPiIpLmIoSi56QyhQLkNIKGEs
+ITEsYikpKX0sCkhNOmZ1bmN0aW9uKGEsYixjKXt2YXIgdAppZihBcnJheS5pc0FycmF5KGEpKXt1LnQu
+YihhKQp0PWEubGVuZ3RoCmM9UC5qQihiLGMsdCkKcmV0dXJuIEguZVQoYj4wfHxjPHQ/Qy5ObS5ENihh
+LGIsYyk6YSl9aWYodS5ibS5jKGEpKXJldHVybiBILmZ3KGEsYixQLmpCKGIsYyxhLmxlbmd0aCkpCnJl
+dHVybiBQLmJ3KGEsYixjKX0sCk9vOmZ1bmN0aW9uKGEpe3JldHVybiBILkx3KGEpfSwKYnc6ZnVuY3Rp
+b24oYSxiLGMpe3ZhciB0LHMscixxLHA9bnVsbAppZihiPDApdGhyb3cgSC5iKFAuVEUoYiwwLEouSG0o
+YSkscCxwKSkKdD1jPT1udWxsCmlmKCF0JiZjPGIpdGhyb3cgSC5iKFAuVEUoYyxiLEouSG0oYSkscCxw
+KSkKcz1KLklUKGEpCmZvcihyPTA7cjxiOysrcilpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYiwwLHIs
+cCxwKSkKcT1bXQppZih0KWZvcig7cy5GKCk7KXEucHVzaChzLmdsKCkpCmVsc2UgZm9yKHI9YjtyPGM7
+KytyKXtpZighcy5GKCkpdGhyb3cgSC5iKFAuVEUoYyxiLHIscCxwKSkKcS5wdXNoKHMuZ2woKSl9cmV0
+dXJuIEguZVQocSl9LApudTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEguVlIoYSxILnY0KGEsITEsITAs
+ITEsITEsITEpKX0sCnZnOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1KLklUKGIpCmlmKCF0LkYoKSlyZXR1
+cm4gYQppZihjLmxlbmd0aD09PTApe2RvIGErPUguZCh0LmdsKCkpCndoaWxlKHQuRigpKX1lbHNle2Er
+PUguZCh0LmdsKCkpCmZvcig7dC5GKCk7KWE9YStjK0guZCh0LmdsKCkpfXJldHVybiBhfSwKbHI6ZnVu
+Y3Rpb24oYSxiLGMsZCl7cmV0dXJuIG5ldyBQLm1wKGEsYixjLGQpfSwKdW86ZnVuY3Rpb24oKXt2YXIg
+dD1ILk0wKCkKaWYodCE9bnVsbClyZXR1cm4gUC5oSyh0KQp0aHJvdyBILmIoUC5MNCgiJ1VyaS5iYXNl
+JyBpcyBub3Qgc3VwcG9ydGVkIikpfSwKZVA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyLHEscCxv
+LG49IjAxMjM0NTY3ODlBQkNERUYiCmlmKGM9PT1DLnhNKXt0PSQuejQoKS5iCmlmKHR5cGVvZiBiIT0i
+c3RyaW5nIilILnZoKEgudEwoYikpCnQ9dC50ZXN0KGIpfWVsc2UgdD0hMQppZih0KXJldHVybiBiCkgu
+TGgoYykuQygiVWsuUyIpLmIoYikKcz1jLmdaRSgpLldKKGIpCmZvcih0PXMubGVuZ3RoLHI9MCxxPSIi
+O3I8dDsrK3Ipe3A9c1tyXQppZihwPDEyOCl7bz1wPj4+NAppZihvPj04KXJldHVybiBILk9IKGEsbykK
+bz0oYVtvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKaWYobylxKz1ILkx3KHApCmVsc2UgcT1kJiZw
+PT09MzI/cSsiKyI6cSsiJSIrbltwPj4+NCYxNV0rbltwJjE1XX1yZXR1cm4gcS5jaGFyQ29kZUF0KDAp
+PT0wP3E6cX0sCkdxOmZ1bmN0aW9uKGEpe3ZhciB0PU1hdGguYWJzKGEpLHM9YTwwPyItIjoiIgppZih0
+Pj0xMDAwKXJldHVybiIiK2EKaWYodD49MTAwKXJldHVybiBzKyIwIit0CmlmKHQ+PTEwKXJldHVybiBz
+KyIwMCIrdApyZXR1cm4gcysiMDAwIit0fSwKVng6ZnVuY3Rpb24oYSl7aWYoYT49MTAwKXJldHVybiIi
+K2EKaWYoYT49MTApcmV0dXJuIjAiK2EKcmV0dXJuIjAwIithfSwKaDA6ZnVuY3Rpb24oYSl7aWYoYT49
+MTApcmV0dXJuIiIrYQpyZXR1cm4iMCIrYX0sCnA6ZnVuY3Rpb24oYSl7aWYodHlwZW9mIGE9PSJudW1i
+ZXIifHxILmwoYSl8fG51bGw9PWEpcmV0dXJuIEouaihhKQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0
+dXJuIEpTT04uc3RyaW5naWZ5KGEpCnJldHVybiBQLkYoYSl9LApoVjpmdW5jdGlvbihhKXtyZXR1cm4g
+bmV3IFAuQzYoYSl9LAp4WTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudSghMSxudWxsLG51bGwsYSl9
+LApMMzpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLnUoITAsYSxiLGMpfSwKRWU6ZnVuY3Rpb24o
+YSl7cmV0dXJuIG5ldyBQLnUoITEsbnVsbCxhLCJNdXN0IG5vdCBiZSBudWxsIil9LAp4OmZ1bmN0aW9u
+KGEsYil7cmV0dXJuIG5ldyBQLmJKKG51bGwsbnVsbCwhMCxhLGIsIlZhbHVlIG5vdCBpbiByYW5nZSIp
+fSwKVEU6ZnVuY3Rpb24oYSxiLGMsZCxlKXtyZXR1cm4gbmV3IFAuYkooYixjLCEwLGEsZCwiSW52YWxp
+ZCB2YWx1ZSIpfSwKd0E6ZnVuY3Rpb24oYSxiLGMsZCl7aWYoYTxifHxhPmMpdGhyb3cgSC5iKFAuVEUo
+YSxiLGMsZCxudWxsKSl9LApqQjpmdW5jdGlvbihhLGIsYyl7aWYoMD5hfHxhPmMpdGhyb3cgSC5iKFAu
+VEUoYSwwLGMsInN0YXJ0IixudWxsKSkKaWYoYiE9bnVsbCl7aWYoYT5ifHxiPmMpdGhyb3cgSC5iKFAu
+VEUoYixhLGMsImVuZCIsbnVsbCkpCnJldHVybiBifXJldHVybiBjfSwKazE6ZnVuY3Rpb24oYSxiKXtp
+Zih0eXBlb2YgYSE9PSJudW1iZXIiKXJldHVybiBhLkooKQppZihhPDApdGhyb3cgSC5iKFAuVEUoYSww
+LG51bGwsYixudWxsKSl9LApDZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PUguU2MoZT09bnVsbD9K
+LkhtKGIpOmUpCnJldHVybiBuZXcgUC5lWSh0LCEwLGEsYywiSW5kZXggb3V0IG9mIHJhbmdlIil9LApM
+NDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAudWIoYSl9LApTWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3
+IFAuZHMoYSl9LApQVjpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAubGooYSl9LAphNDpmdW5jdGlvbihh
+KXtyZXR1cm4gbmV3IFAuVVYoYSl9LApycjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIG5ldyBQLmFFKGEs
+YixjKX0sCmRIOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzPUguVk0oW10sYy5DKCJqZDwwPiIpKQpDLk5t
+LnNBKHMsYSkKZm9yKHQ9MDt0PGE7Kyt0KUMuTm0uWShzLHQsYi4kMSh0KSkKcmV0dXJuIHN9LApoSzpm
+dW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1udWxsLGQ9YS5sZW5n
+dGgKaWYoZD49NSl7dD0oKEouUXooYSw0KV41OCkqM3xDLnhCLlcoYSwwKV4xMDB8Qy54Qi5XKGEsMSle
+OTd8Qy54Qi5XKGEsMileMTE2fEMueEIuVyhhLDMpXjk3KT4+PjAKaWYodD09PTApcmV0dXJuIFAuS0Qo
+ZDxkP0MueEIuTmooYSwwLGQpOmEsNSxlKS5nbFIoKQplbHNlIGlmKHQ9PT0zMilyZXR1cm4gUC5LRChD
+LnhCLk5qKGEsNSxkKSwwLGUpLmdsUigpfXM9bmV3IEFycmF5KDgpCnMuZml4ZWQkbGVuZ3RoPUFycmF5
+CnI9SC5WTShzLHUudCkKQy5ObS5ZKHIsMCwwKQpDLk5tLlkociwxLC0xKQpDLk5tLlkociwyLC0xKQpD
+Lk5tLlkociw3LC0xKQpDLk5tLlkociwzLDApCkMuTm0uWShyLDQsMCkKQy5ObS5ZKHIsNSxkKQpDLk5t
+Llkociw2LGQpCmlmKFAuVUIoYSwwLGQsMCxyKT49MTQpQy5ObS5ZKHIsNyxkKQpxPXJbMV0KaWYodHlw
+ZW9mIHEhPT0ibnVtYmVyIilyZXR1cm4gcS50QigpCmlmKHE+PTApaWYoUC5VQihhLDAscSwyMCxyKT09
+PTIwKXJbN109cQpzPXJbMl0KaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5oKCkKcD1zKzEK
+bz1yWzNdCm49cls0XQptPXJbNV0KbD1yWzZdCmlmKHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwu
+SigpCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIEgucFkobSkKaWYobDxtKW09bAppZih0eXBl
+b2YgbiE9PSJudW1iZXIiKXJldHVybiBuLkooKQppZihuPHApbj1tCmVsc2UgaWYobjw9cSluPXErMQpp
+Zih0eXBlb2YgbyE9PSJudW1iZXIiKXJldHVybiBvLkooKQppZihvPHApbz1uCnM9cls3XQppZih0eXBl
+b2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkooKQprPXM8MAppZihrKWlmKHA+cSszKXtqPWUKaz0hMX1l
+bHNle3M9bz4wCmlmKHMmJm8rMT09PW4pe2o9ZQprPSExfWVsc2V7aWYoIShtPGQmJm09PT1uKzImJkou
+cTAoYSwiLi4iLG4pKSlpPW0+bisyJiZKLnEwKGEsIi8uLiIsbS0zKQplbHNlIGk9ITAKaWYoaSl7aj1l
+Cms9ITF9ZWxzZXtpZihxPT09NClpZihKLnEwKGEsImZpbGUiLDApKXtpZihwPD0wKXtpZighQy54Qi5R
+aShhLCIvIixuKSl7aD0iZmlsZTovLy8iCnQ9M31lbHNle2g9ImZpbGU6Ly8iCnQ9Mn1hPWgrQy54Qi5O
+aihhLG4sZCkKcS09MApzPXQtMAptKz1zCmwrPXMKZD1hLmxlbmd0aApwPTcKbz03Cm49N31lbHNlIGlm
+KG49PT1tKXtnPW0rMTsrK2wKYT1DLnhCLmk3KGEsbixtLCIvIik7KytkCm09Z31qPSJmaWxlIn1lbHNl
+IGlmKEMueEIuUWkoYSwiaHR0cCIsMCkpe2lmKHMmJm8rMz09PW4mJkMueEIuUWkoYSwiODAiLG8rMSkp
+e2Y9bi0zCm0tPTMKbC09MwphPUMueEIuaTcoYSxvLG4sIiIpCmQtPTMKbj1mfWo9Imh0dHAifWVsc2Ug
+aj1lCmVsc2UgaWYocT09PTUmJkoucTAoYSwiaHR0cHMiLDApKXtpZihzJiZvKzQ9PT1uJiZKLnEwKGEs
+IjQ0MyIsbysxKSl7Zj1uLTQKbS09NApsLT00CmE9Si5kZyhhLG8sbiwiIikKZC09MwpuPWZ9aj0iaHR0
+cHMifWVsc2Ugaj1lCms9ITB9fX1lbHNlIGo9ZQppZihrKXtzPWEubGVuZ3RoCmlmKGQ8cyl7YT1KLmxk
+KGEsMCxkKQpxLT0wCnAtPTAKby09MApuLT0wCm0tPTAKbC09MH1yZXR1cm4gbmV3IFAuVWYoYSxxLHAs
+byxuLG0sbCxqKX1yZXR1cm4gUC5qdihhLDAsZCxxLHAsbyxuLG0sbCxqKX0sCk10OmZ1bmN0aW9uKGEp
+e0gueShhKQpyZXR1cm4gUC5rdShhLDAsYS5sZW5ndGgsQy54TSwhMSl9LApXWDpmdW5jdGlvbihhKXt2
+YXIgdD11Lk4KcmV0dXJuIEMuTm0uTjAoSC5WTShhLnNwbGl0KCImIiksdS5zKSxQLkZsKHQsdCksbmV3
+IFAubjEoQy54TSksdS5mKX0sCkhoOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtPW51
+bGwsbD0iSVB2NCBhZGRyZXNzIHNob3VsZCBjb250YWluIGV4YWN0bHkgNCBwYXJ0cyIsaz0iZWFjaCBw
+YXJ0IG11c3QgYmUgaW4gdGhlIHJhbmdlIDAuLjI1NSIsaj1uZXcgUC5jUyhhKSxpPW5ldyBVaW50OEFy
+cmF5KDQpCmZvcih0PWkubGVuZ3RoLHM9YixyPXMscT0wO3M8YzsrK3Mpe3A9Qy54Qi5tKGEscykKaWYo
+cCE9PTQ2KXtpZigocF40OCk+OSlqLiQyKCJpbnZhbGlkIGNoYXJhY3RlciIscyl9ZWxzZXtpZihxPT09
+MylqLiQyKGwscykKbz1QLlFBKEMueEIuTmooYSxyLHMpLG0sbSkKaWYodHlwZW9mIG8hPT0ibnVtYmVy
+IilyZXR1cm4gby5vcygpCmlmKG8+MjU1KWouJDIoayxyKQpuPXErMQppZihxPj10KXJldHVybiBILk9I
+KGkscSkKaVtxXT1vCnI9cysxCnE9bn19aWYocSE9PTMpai4kMihsLGMpCm89UC5RQShDLnhCLk5qKGEs
+cixjKSxtLG0pCmlmKHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8ub3MoKQppZihvPjI1NSlqLiQy
+KGsscikKaWYocT49dClyZXR1cm4gSC5PSChpLHEpCmlbcV09bwpyZXR1cm4gaX0sCmVnOmZ1bmN0aW9u
+KGEsYixhMCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZyxmLGUsZD1uZXcgUC5WQyhhKSxj
+PW5ldyBQLkpUKGQsYSkKaWYoYS5sZW5ndGg8MilkLiQxKCJhZGRyZXNzIGlzIHRvbyBzaG9ydCIpCnQ9
+SC5WTShbXSx1LnQpCmZvcihzPWIscj1zLHE9ITEscD0hMTtzPGEwOysrcyl7bz1DLnhCLm0oYSxzKQpp
+ZihvPT09NTgpe2lmKHM9PT1iKXsrK3MKaWYoQy54Qi5tKGEscykhPT01OClkLiQyKCJpbnZhbGlkIHN0
+YXJ0IGNvbG9uLiIscykKcj1zfWlmKHM9PT1yKXtpZihxKWQuJDIoIm9ubHkgb25lIHdpbGRjYXJkIGA6
+OmAgaXMgYWxsb3dlZCIscykKQy5ObS5pKHQsLTEpCnE9ITB9ZWxzZSBDLk5tLmkodCxjLiQyKHIscykp
+CnI9cysxfWVsc2UgaWYobz09PTQ2KXA9ITB9aWYodC5sZW5ndGg9PT0wKWQuJDEoInRvbyBmZXcgcGFy
+dHMiKQpuPXI9PT1hMAptPUMuTm0uZ3JaKHQpCmlmKG4mJm0hPT0tMSlkLiQyKCJleHBlY3RlZCBhIHBh
+cnQgYWZ0ZXIgbGFzdCBgOmAiLGEwKQppZighbilpZighcClDLk5tLmkodCxjLiQyKHIsYTApKQplbHNl
+e2w9UC5IaChhLHIsYTApCkMuTm0uaSh0LChsWzBdPDw4fGxbMV0pPj4+MCkKQy5ObS5pKHQsKGxbMl08
+PDh8bFszXSk+Pj4wKX1pZihxKXtpZih0Lmxlbmd0aD43KWQuJDEoImFuIGFkZHJlc3Mgd2l0aCBhIHdp
+bGRjYXJkIG11c3QgaGF2ZSBsZXNzIHRoYW4gNyBwYXJ0cyIpfWVsc2UgaWYodC5sZW5ndGghPT04KWQu
+JDEoImFuIGFkZHJlc3Mgd2l0aG91dCBhIHdpbGRjYXJkIG11c3QgY29udGFpbiBleGFjdGx5IDggcGFy
+dHMiKQprPW5ldyBVaW50OEFycmF5KDE2KQpmb3IobT10Lmxlbmd0aCxqPWsubGVuZ3RoLGk9OS1tLHM9
+MCxoPTA7czxtOysrcyl7Zz10W3NdCmlmKGc9PT0tMSlmb3IoZj0wO2Y8aTsrK2Ype2lmKGg8MHx8aD49
+ailyZXR1cm4gSC5PSChrLGgpCmtbaF09MAplPWgrMQppZihlPj1qKXJldHVybiBILk9IKGssZSkKa1tl
+XT0wCmgrPTJ9ZWxzZXtlPUMuam4ud0coZyw4KQppZihoPDB8fGg+PWopcmV0dXJuIEguT0goayxoKQpr
+W2hdPWUKZT1oKzEKaWYoZT49ailyZXR1cm4gSC5PSChrLGUpCmtbZV09ZyYyNTUKaCs9Mn19cmV0dXJu
+IGt9LApqdjpmdW5jdGlvbihhLGIsYyxkLGUsZixnLGgsaSxqKXt2YXIgdCxzLHIscSxwLG8sbixtPW51
+bGwKaWYoaj09bnVsbClpZihkPmIpaj1QLlBpKGEsYixkKQplbHNle2lmKGQ9PT1iKVAuUjMoYSxiLCJJ
+bnZhbGlkIGVtcHR5IHNjaGVtZSIpCmo9IiJ9aWYoZT5iKXt0PWQrMwpzPXQ8ZT9QLnpSKGEsdCxlLTEp
+OiIiCnI9UC5PZShhLGUsZiwhMSkKaWYodHlwZW9mIGYhPT0ibnVtYmVyIilyZXR1cm4gZi5oKCkKcT1m
+KzEKaWYodHlwZW9mIGchPT0ibnVtYmVyIilyZXR1cm4gSC5wWShnKQpwPXE8Zz9QLndCKFAuUUEoSi5s
+ZChhLHEsZyksbmV3IFAuZTEoYSxmKSxtKSxqKTptfWVsc2V7cD1tCnI9cApzPSIifW89UC5rYShhLGcs
+aCxtLGosciE9bnVsbCkKaWYodHlwZW9mIGghPT0ibnVtYmVyIilyZXR1cm4gaC5KKCkKbj1oPGk/UC5s
+ZShhLGgrMSxpLG0pOm0KcmV0dXJuIG5ldyBQLkRuKGoscyxyLHAsbyxuLGk8Yz9QLnRHKGEsaSsxLGMp
+Om0pfSwKS0w6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyl7dmFyIHQscyxyLHEscCxvCmY9UC5QaShmLDAs
+Zj09bnVsbD8wOmYubGVuZ3RoKQpnPVAuelIoZywwLGc9PW51bGw/MDpnLmxlbmd0aCkKYT1QLk9lKGEs
+MCxhPT1udWxsPzA6YS5sZW5ndGgsITEpCnQ9UC5sZShudWxsLDAsMCxlKQpzPVAudEcobnVsbCwwLDAp
+CmQ9UC53QihkLGYpCnI9Zj09PSJmaWxlIgppZihhPT1udWxsKXE9Zy5sZW5ndGghPT0wfHxkIT1udWxs
+fHxyCmVsc2UgcT0hMQppZihxKWE9IiIKcT1hPT1udWxsCnA9IXEKYj1QLmthKGIsMCxiPT1udWxsPzA6
+Yi5sZW5ndGgsYyxmLHApCm89Zi5sZW5ndGg9PT0wCmlmKG8mJnEmJiFDLnhCLm4oYiwiLyIpKWI9UC53
+RihiLCFvfHxwKQplbHNlIGI9UC54ZShiKQpyZXR1cm4gbmV3IFAuRG4oZixnLHEmJkMueEIubihiLCIv
+LyIpPyIiOmEsZCxiLHQscyl9LAp3SzpmdW5jdGlvbihhKXtpZihhPT09Imh0dHAiKXJldHVybiA4MApp
+ZihhPT09Imh0dHBzIilyZXR1cm4gNDQzCnJldHVybiAwfSwKUjM6ZnVuY3Rpb24oYSxiLGMpe3Rocm93
+IEguYihQLnJyKGMsYSxiKSl9LApYZDpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGwsayxqLGk9bnVsbCxoPWIubGVuZ3RoCmlmKGghPT0wKXtyPTAKd2hpbGUoITApe2lmKCEocjxoKSl7
+dD0iIgpzPTAKYnJlYWt9aWYoQy54Qi5XKGIscik9PT02NCl7dD1DLnhCLk5qKGIsMCxyKQpzPXIrMQpi
+cmVha30rK3J9aWYoczxoJiZDLnhCLlcoYixzKT09PTkxKXtmb3IocT1zLHA9LTE7cTxoOysrcSl7bz1D
+LnhCLlcoYixxKQppZihvPT09MzcmJnA8MCl7bj1DLnhCLlFpKGIsIjI1IixxKzEpP3ErMjpxCnA9cQpx
+PW59ZWxzZSBpZihvPT09OTMpYnJlYWt9aWYocT09PWgpdGhyb3cgSC5iKFAucnIoIkludmFsaWQgSVB2
+NiBob3N0IGVudHJ5LiIsYixzKSkKbT1wPDA/cTpwClAuZWcoYixzKzEsbSk7KytxCmlmKHEhPT1oJiZD
+LnhCLlcoYixxKSE9PTU4KXRocm93IEguYihQLnJyKCJJbnZhbGlkIGVuZCBvZiBhdXRob3JpdHkiLGIs
+cSkpfWVsc2UgcT1zCndoaWxlKCEwKXtpZighKHE8aCkpe2w9aQpicmVha31pZihDLnhCLlcoYixxKT09
+PTU4KXtrPUMueEIuRyhiLHErMSkKbD1rLmxlbmd0aCE9PTA/UC5RQShrLGksaSk6aQpicmVha30rK3F9
+aj1DLnhCLk5qKGIscyxxKX1lbHNle2w9aQpqPWwKdD0iIn1yZXR1cm4gUC5LTChqLGksSC5WTShjLnNw
+bGl0KCIvIiksdS5zKSxsLGQsYSx0KX0sCmtFOmZ1bmN0aW9uKGEsYil7Qy5ObS5LKGEsbmV3IFAuTlko
+ITEpKX0sCkhOOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIKZm9yKHQ9SC5xQyhhLGMsbnVsbCxILnQ2
+KGEpLmQpLHQ9bmV3IEguYTcodCx0LmdBKHQpLHQuJHRpLkMoImE3PGFMLkU+IikpO3QuRigpOyl7cz10
+LmQKcj1QLm51KCdbIiovOjw+P1xcXFx8XScpCnMudG9TdHJpbmcKaWYoSC5tMihzLHIsMCkpe3Q9UC5M
+NCgiSWxsZWdhbCBjaGFyYWN0ZXIgaW4gcGF0aDogIitzKQp0aHJvdyBILmIodCl9fX0sCnJnOmZ1bmN0
+aW9uKGEsYil7dmFyIHQKaWYoISg2NTw9YSYmYTw9OTApKXQ9OTc8PWEmJmE8PTEyMgplbHNlIHQ9ITAK
+aWYodClyZXR1cm4KdD1QLkw0KCJJbGxlZ2FsIGRyaXZlIGxldHRlciAiK1AuT28oYSkpCnRocm93IEgu
+Yih0KX0sCndCOmZ1bmN0aW9uKGEsYil7aWYoYSE9bnVsbCYmYT09PVAud0soYikpcmV0dXJuIG51bGwK
+cmV0dXJuIGF9LApPZTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYoYT09bnVsbCly
+ZXR1cm4gbnVsbAppZihiPT09YylyZXR1cm4iIgppZihDLnhCLm0oYSxiKT09PTkxKXtpZih0eXBlb2Yg
+YyE9PSJudW1iZXIiKXJldHVybiBjLkhOKCkKdD1jLTEKaWYoQy54Qi5tKGEsdCkhPT05MylQLlIzKGEs
+YiwiTWlzc2luZyBlbmQgYF1gIHRvIG1hdGNoIGBbYCBpbiBob3N0IikKcz1iKzEKcj1QLnRvKGEscyx0
+KQppZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLkooKQppZihyPHQpe3E9cisxCnA9UC5PQShh
+LEMueEIuUWkoYSwiMjUiLHEpP3IrMzpxLHQsIiUyNSIpfWVsc2UgcD0iIgpQLmVnKGEscyxyKQpyZXR1
+cm4gQy54Qi5OaihhLGIscikudG9Mb3dlckNhc2UoKStwKyJdIn1pZih0eXBlb2YgYyE9PSJudW1iZXIi
+KXJldHVybiBILnBZKGMpCm89Ygpmb3IoO288YzsrK28paWYoQy54Qi5tKGEsbyk9PT01OCl7cj1DLnhC
+LlhVKGEsIiUiLGIpCmlmKCEocj49YiYmcjxjKSlyPWMKaWYocjxjKXtxPXIrMQpwPVAuT0EoYSxDLnhC
+LlFpKGEsIjI1IixxKT9yKzM6cSxjLCIlMjUiKX1lbHNlIHA9IiIKUC5lZyhhLGIscikKcmV0dXJuIlsi
+K0MueEIuTmooYSxiLHIpK3ArIl0ifXJldHVybiBQLk9MKGEsYixjKX0sCnRvOmZ1bmN0aW9uKGEsYixj
+KXt2YXIgdCxzPUMueEIuWFUoYSwiJSIsYikKaWYocz49Yil7aWYodHlwZW9mIGMhPT0ibnVtYmVyIily
+ZXR1cm4gSC5wWShjKQp0PXM8Y31lbHNlIHQ9ITEKcmV0dXJuIHQ/czpjfSwKT0E6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9ZCE9PSIiP25ldyBQLlJuKGQpOm51bGwKaWYodHlw
+ZW9mIGMhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShjKQp0PWIKcz10CnI9ITAKZm9yKDt0PGM7KXtxPUMu
+eEIubShhLHQpCmlmKHE9PT0zNyl7cD1QLnJ2KGEsdCwhMCkKbz1wPT1udWxsCmlmKG8mJnIpe3QrPTMK
+Y29udGludWV9aWYoaz09bnVsbClrPW5ldyBQLlJuKCIiKQpuPWsuYSs9Qy54Qi5OaihhLHMsdCkKaWYo
+bylwPUMueEIuTmooYSx0LHQrMykKZWxzZSBpZihwPT09IiUiKVAuUjMoYSx0LCJab25lSUQgc2hvdWxk
+IG5vdCBjb250YWluICUgYW55bW9yZSIpCmsuYT1uK3AKdCs9MwpzPXQKcj0hMH1lbHNle2lmKHE8MTI3
+KXtvPXE+Pj40CmlmKG8+PTgpcmV0dXJuIEguT0goQy5GMyxvKQpvPShDLkYzW29dJjE8PChxJjE1KSkh
+PT0wfWVsc2Ugbz0hMQppZihvKXtpZihyJiY2NTw9cSYmOTA+PXEpe2lmKGs9PW51bGwpaz1uZXcgUC5S
+bigiIikKaWYoczx0KXtrLmErPUMueEIuTmooYSxzLHQpCnM9dH1yPSExfSsrdH1lbHNle2lmKChxJjY0
+NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7bT1DLnhCLm0oYSx0KzEpCmlmKChtJjY0NTEyKT09PTU2MzIwKXtx
+PTY1NTM2fChxJjEwMjMpPDwxMHxtJjEwMjMKbD0yfWVsc2UgbD0xfWVsc2UgbD0xCmlmKGs9PW51bGwp
+az1uZXcgUC5SbigiIikKay5hKz1DLnhCLk5qKGEscyx0KQprLmErPVAuelgocSkKdCs9bApzPXR9fX1p
+ZihrPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpay5hKz1DLnhCLk5qKGEscyxjKQpv
+PWsuYQpyZXR1cm4gby5jaGFyQ29kZUF0KDApPT0wP286b30sCk9MOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dCxzLHIscSxwLG8sbixtLGwsayxqCmlmKHR5cGVvZiBjIT09Im51bWJlciIpcmV0dXJuIEgucFkoYykK
+dD1iCnM9dApyPW51bGwKcT0hMApmb3IoO3Q8Yzspe3A9Qy54Qi5tKGEsdCkKaWYocD09PTM3KXtvPVAu
+cnYoYSx0LCEwKQpuPW89PW51bGwKaWYobiYmcSl7dCs9Mwpjb250aW51ZX1pZihyPT1udWxsKXI9bmV3
+IFAuUm4oIiIpCm09Qy54Qi5OaihhLHMsdCkKbD1yLmErPSFxP20udG9Mb3dlckNhc2UoKTptCmlmKG4p
+e289Qy54Qi5OaihhLHQsdCszKQprPTN9ZWxzZSBpZihvPT09IiUiKXtvPSIlMjUiCms9MX1lbHNlIGs9
+MwpyLmE9bCtvCnQrPWsKcz10CnE9ITB9ZWxzZXtpZihwPDEyNyl7bj1wPj4+NAppZihuPj04KXJldHVy
+biBILk9IKEMuZWEsbikKbj0oQy5lYVtuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobil7aWYo
+cSYmNjU8PXAmJjkwPj1wKXtpZihyPT1udWxsKXI9bmV3IFAuUm4oIiIpCmlmKHM8dCl7ci5hKz1DLnhC
+Lk5qKGEscyx0KQpzPXR9cT0hMX0rK3R9ZWxzZXtpZihwPD05Myl7bj1wPj4+NAppZihuPj04KXJldHVy
+biBILk9IKEMuYWssbikKbj0oQy5ha1tuXSYxPDwocCYxNSkpIT09MH1lbHNlIG49ITEKaWYobilQLlIz
+KGEsdCwiSW52YWxpZCBjaGFyYWN0ZXIiKQplbHNle2lmKChwJjY0NTEyKT09PTU1Mjk2JiZ0KzE8Yyl7
+aj1DLnhCLm0oYSx0KzEpCmlmKChqJjY0NTEyKT09PTU2MzIwKXtwPTY1NTM2fChwJjEwMjMpPDwxMHxq
+JjEwMjMKaz0yfWVsc2Ugaz0xfWVsc2Ugaz0xCmlmKHI9PW51bGwpcj1uZXcgUC5SbigiIikKbT1DLnhC
+Lk5qKGEscyx0KQpyLmErPSFxP20udG9Mb3dlckNhc2UoKTptCnIuYSs9UC56WChwKQp0Kz1rCnM9dH19
+fX1pZihyPT1udWxsKXJldHVybiBDLnhCLk5qKGEsYixjKQppZihzPGMpe209Qy54Qi5OaihhLHMsYykK
+ci5hKz0hcT9tLnRvTG93ZXJDYXNlKCk6bX1uPXIuYQpyZXR1cm4gbi5jaGFyQ29kZUF0KDApPT0wP246
+bn0sClBpOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscQppZihiPT09YylyZXR1cm4iIgppZighUC5F
+dChKLnJZKGEpLlcoYSxiKSkpUC5SMyhhLGIsIlNjaGVtZSBub3Qgc3RhcnRpbmcgd2l0aCBhbHBoYWJl
+dGljIGNoYXJhY3RlciIpCmZvcih0PWIscz0hMTt0PGM7Kyt0KXtyPUMueEIuVyhhLHQpCmlmKHI8MTI4
+KXtxPXI+Pj40CmlmKHE+PTgpcmV0dXJuIEguT0goQy5tSyxxKQpxPShDLm1LW3FdJjE8PChyJjE1KSkh
+PT0wfWVsc2UgcT0hMQppZighcSlQLlIzKGEsdCwiSWxsZWdhbCBzY2hlbWUgY2hhcmFjdGVyIikKaWYo
+NjU8PXImJnI8PTkwKXM9ITB9YT1DLnhCLk5qKGEsYixjKQpyZXR1cm4gUC5ZYShzP2EudG9Mb3dlckNh
+c2UoKTphKX0sCllhOmZ1bmN0aW9uKGEpe2lmKGE9PT0iaHR0cCIpcmV0dXJuImh0dHAiCmlmKGE9PT0i
+ZmlsZSIpcmV0dXJuImZpbGUiCmlmKGE9PT0iaHR0cHMiKXJldHVybiJodHRwcyIKaWYoYT09PSJwYWNr
+YWdlIilyZXR1cm4icGFja2FnZSIKcmV0dXJuIGF9LAp6UjpmdW5jdGlvbihhLGIsYyl7aWYoYT09bnVs
+bClyZXR1cm4iIgpyZXR1cm4gUC5QSShhLGIsYyxDLnRvLCExKX0sCmthOmZ1bmN0aW9uKGEsYixjLGQs
+ZSxmKXt2YXIgdCxzPWU9PT0iZmlsZSIscj1zfHxmLHE9YT09bnVsbAppZihxJiZkPT1udWxsKXJldHVy
+biBzPyIvIjoiIgpxPSFxCmlmKHEmJmQhPW51bGwpdGhyb3cgSC5iKFAueFkoIkJvdGggcGF0aCBhbmQg
+cGF0aFNlZ21lbnRzIHNwZWNpZmllZCIpKQppZihxKXQ9UC5QSShhLGIsYyxDLldkLCEwKQplbHNle2Qu
+dG9TdHJpbmcKcT1ILnQ2KGQpCnQ9bmV3IEguQTgoZCxxLkMoInFVKDEpIikuYihuZXcgUC5SWigpKSxx
+LkMoIkE4PDEscVU+IikpLkgoMCwiLyIpfWlmKHQubGVuZ3RoPT09MCl7aWYocylyZXR1cm4iLyJ9ZWxz
+ZSBpZihyJiYhQy54Qi5uKHQsIi8iKSl0PSIvIit0CnJldHVybiBQLkpyKHQsZSxmKX0sCkpyOmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdD1iLmxlbmd0aD09PTAKaWYodCYmIWMmJiFDLnhCLm4oYSwiLyIpKXJldHVy
+biBQLndGKGEsIXR8fGMpCnJldHVybiBQLnhlKGEpfSwKbGU6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQs
+cz17fQppZihhIT1udWxsKXtpZihkIT1udWxsKXRocm93IEguYihQLnhZKCJCb3RoIHF1ZXJ5IGFuZCBx
+dWVyeVBhcmFtZXRlcnMgc3BlY2lmaWVkIikpCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfWlmKGQ9
+PW51bGwpcmV0dXJuIG51bGwKdD1uZXcgUC5SbigiIikKcy5hPSIiCmQuSygwLG5ldyBQLnk1KG5ldyBQ
+Lk1FKHMsdCkpKQpzPXQuYQpyZXR1cm4gcy5jaGFyQ29kZUF0KDApPT0wP3M6c30sCnRHOmZ1bmN0aW9u
+KGEsYixjKXtpZihhPT1udWxsKXJldHVybiBudWxsCnJldHVybiBQLlBJKGEsYixjLEMuVkMsITApfSwK
+cnY6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbz1iKzIKaWYobz49YS5sZW5ndGgpcmV0dXJu
+IiUiCnQ9Qy54Qi5tKGEsYisxKQpzPUMueEIubShhLG8pCnI9SC5vbyh0KQpxPUgub28ocykKaWYocjww
+fHxxPDApcmV0dXJuIiUiCnA9cioxNitxCmlmKHA8MTI3KXtvPUMuam4ud0cocCw0KQppZihvPj04KXJl
+dHVybiBILk9IKEMuRjMsbykKbz0oQy5GM1tvXSYxPDwocCYxNSkpIT09MH1lbHNlIG89ITEKaWYobyly
+ZXR1cm4gSC5MdyhjJiY2NTw9cCYmOTA+PXA/KHB8MzIpPj4+MDpwKQppZih0Pj05N3x8cz49OTcpcmV0
+dXJuIEMueEIuTmooYSxiLGIrMykudG9VcHBlckNhc2UoKQpyZXR1cm4gbnVsbH0sCnpYOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscixxLHAsbyxuPSIwMTIzNDU2Nzg5QUJDREVGIgppZihhPDEyOCl7dD1uZXcgQXJy
+YXkoMykKdC5maXhlZCRsZW5ndGg9QXJyYXkKcz1ILlZNKHQsdS50KQpDLk5tLlkocywwLDM3KQpDLk5t
+LlkocywxLEMueEIuVyhuLGE+Pj40KSkKQy5ObS5ZKHMsMixDLnhCLlcobixhJjE1KSl9ZWxzZXtpZihh
+PjIwNDcpaWYoYT42NTUzNSl7cj0yNDAKcT00fWVsc2V7cj0yMjQKcT0zfWVsc2V7cj0xOTIKcT0yfXQ9
+bmV3IEFycmF5KDMqcSkKdC5maXhlZCRsZW5ndGg9QXJyYXkKcz1ILlZNKHQsdS50KQpmb3IocD0wOy0t
+cSxxPj0wO3I9MTI4KXtvPUMuam4uYmYoYSw2KnEpJjYzfHIKQy5ObS5ZKHMscCwzNykKQy5ObS5ZKHMs
+cCsxLEMueEIuVyhuLG8+Pj40KSkKQy5ObS5ZKHMscCsyLEMueEIuVyhuLG8mMTUpKQpwKz0zfX1yZXR1
+cm4gUC5ITShzLDAsbnVsbCl9LApQSTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PVAuVWwoYSxiLGMs
+ZCxlKQpyZXR1cm4gdD09bnVsbD9DLnhCLk5qKGEsYixjKTp0fSwKVWw6ZnVuY3Rpb24oYSxiLGMsZCxl
+KXt2YXIgdCxzLHIscSxwLG89bnVsbCxuPSFlLG09YixsPW0saz1vCndoaWxlKCEwKXtpZih0eXBlb2Yg
+bSE9PSJudW1iZXIiKXJldHVybiBtLkooKQppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBILnBZ
+KGMpCmlmKCEobTxjKSlicmVhawpjJDA6e3Q9Qy54Qi5tKGEsbSkKaWYodDwxMjcpe3M9dD4+PjQKaWYo
+cz49OClyZXR1cm4gSC5PSChkLHMpCnM9KGRbc10mMTw8KHQmMTUpKSE9PTB9ZWxzZSBzPSExCmlmKHMp
+KyttCmVsc2V7aWYodD09PTM3KXtyPVAucnYoYSxtLCExKQppZihyPT1udWxsKXttKz0zCmJyZWFrIGMk
+MH1pZigiJSI9PT1yKXtyPSIlMjUiCnE9MX1lbHNlIHE9M31lbHNle2lmKG4paWYodDw9OTMpe3M9dD4+
+PjQKaWYocz49OClyZXR1cm4gSC5PSChDLmFrLHMpCnM9KEMuYWtbc10mMTw8KHQmMTUpKSE9PTB9ZWxz
+ZSBzPSExCmVsc2Ugcz0hMQppZihzKXtQLlIzKGEsbSwiSW52YWxpZCBjaGFyYWN0ZXIiKQpxPW8Kcj1x
+fWVsc2V7aWYoKHQmNjQ1MTIpPT09NTUyOTYpe3M9bSsxCmlmKHM8Yyl7cD1DLnhCLm0oYSxzKQppZigo
+cCY2NDUxMik9PT01NjMyMCl7dD02NTUzNnwodCYxMDIzKTw8MTB8cCYxMDIzCnE9Mn1lbHNlIHE9MX1l
+bHNlIHE9MX1lbHNlIHE9MQpyPVAuelgodCl9fWlmKGs9PW51bGwpaz1uZXcgUC5SbigiIikKay5hKz1D
+LnhCLk5qKGEsbCxtKQprLmErPUguZChyKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZ
+KHEpCm0rPXEKbD1tfX19aWYoaz09bnVsbClyZXR1cm4gbwppZih0eXBlb2YgbCE9PSJudW1iZXIiKXJl
+dHVybiBsLkooKQppZihsPGMpay5hKz1DLnhCLk5qKGEsbCxjKQpuPWsuYQpyZXR1cm4gbi5jaGFyQ29k
+ZUF0KDApPT0wP246bn0sCnlCOmZ1bmN0aW9uKGEpe2lmKEMueEIubihhLCIuIikpcmV0dXJuITAKcmV0
+dXJuIEMueEIuT1koYSwiLy4iKSE9PS0xfSwKeGU6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4K
+aWYoIVAueUIoYSkpcmV0dXJuIGEKdD1ILlZNKFtdLHUucykKZm9yKHM9YS5zcGxpdCgiLyIpLHI9cy5s
+ZW5ndGgscT0hMSxwPTA7cDxyOysrcCl7bz1zW3BdCmlmKEouUk0obywiLi4iKSl7bj10Lmxlbmd0aApp
+ZihuIT09MCl7aWYoMD49bilyZXR1cm4gSC5PSCh0LC0xKQp0LnBvcCgpCmlmKHQubGVuZ3RoPT09MClD
+Lk5tLmkodCwiIil9cT0hMH1lbHNlIGlmKCIuIj09PW8pcT0hMAplbHNle0MuTm0uaSh0LG8pCnE9ITF9
+fWlmKHEpQy5ObS5pKHQsIiIpCnJldHVybiBDLk5tLkgodCwiLyIpfSwKd0Y6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIscSxwLG8KaWYoIVAueUIoYSkpcmV0dXJuIWI/UC5DMShhKTphCnQ9SC5WTShbXSx1LnMp
+CmZvcihzPWEuc3BsaXQoIi8iKSxyPXMubGVuZ3RoLHE9ITEscD0wO3A8cjsrK3Ape289c1twXQppZigi
+Li4iPT09bylpZih0Lmxlbmd0aCE9PTAmJkMuTm0uZ3JaKHQpIT09Ii4uIil7aWYoMD49dC5sZW5ndGgp
+cmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQpxPSEwfWVsc2V7Qy5ObS5pKHQsIi4uIikKcT0hMX1lbHNl
+IGlmKCIuIj09PW8pcT0hMAplbHNle0MuTm0uaSh0LG8pCnE9ITF9fXM9dC5sZW5ndGgKaWYocyE9PTAp
+aWYocz09PTEpe2lmKDA+PXMpcmV0dXJuIEguT0godCwwKQpzPXRbMF0ubGVuZ3RoPT09MH1lbHNlIHM9
+ITEKZWxzZSBzPSEwCmlmKHMpcmV0dXJuIi4vIgppZihxfHxDLk5tLmdyWih0KT09PSIuLiIpQy5ObS5p
+KHQsIiIpCmlmKCFiKXtpZigwPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LDApCkMuTm0uWSh0LDAsUC5D
+MSh0WzBdKSl9cmV0dXJuIEMuTm0uSCh0LCIvIil9LApDMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT1h
+Lmxlbmd0aAppZihxPj0yJiZQLkV0KEouUXooYSwwKSkpZm9yKHQ9MTt0PHE7Kyt0KXtzPUMueEIuVyhh
+LHQpCmlmKHM9PT01OClyZXR1cm4gQy54Qi5OaihhLDAsdCkrIiUzQSIrQy54Qi5HKGEsdCsxKQppZihz
+PD0xMjcpe3I9cz4+PjQKaWYocj49OClyZXR1cm4gSC5PSChDLm1LLHIpCnI9KEMubUtbcl0mMTw8KHMm
+MTUpKT09PTB9ZWxzZSByPSEwCmlmKHIpYnJlYWt9cmV0dXJuIGF9LAptbjpmdW5jdGlvbihhKXt2YXIg
+dCxzLHIscT1hLmdGaigpLHA9cS5sZW5ndGgKaWYocD4wJiZKLkhtKHFbMF0pPT09MiYmSi5hNihxWzBd
+LDEpPT09NTgpe2lmKDA+PXApcmV0dXJuIEguT0gocSwwKQpQLnJnKEouYTYocVswXSwwKSwhMSkKUC5I
+TihxLCExLDEpCnQ9ITB9ZWxzZXtQLkhOKHEsITEsMCkKdD0hMX1zPWEuZ3RUKCkmJiF0PyJcXCI6IiIK
+aWYoYS5nY2ooKSl7cj1hLmdKZihhKQppZihyLmxlbmd0aCE9PTApcz1zKyJcXCIrcisiXFwifXM9UC52
+ZyhzLHEsIlxcIikKcD10JiZwPT09MT9zKyJcXCI6cwpyZXR1cm4gcC5jaGFyQ29kZUF0KDApPT0wP3A6
+cH0sCkloOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCmZvcih0PTAscz0wO3M8MjsrK3Mpe3I9Qy54Qi5X
+KGEsYitzKQppZig0ODw9ciYmcjw9NTcpdD10KjE2K3ItNDgKZWxzZXtyfD0zMgppZig5Nzw9ciYmcjw9
+MTAyKXQ9dCoxNityLTg3CmVsc2UgdGhyb3cgSC5iKFAueFkoIkludmFsaWQgVVJMIGVuY29kaW5nIikp
+fX1yZXR1cm4gdH0sCmt1OmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyLHEscD1KLnJZKGEpLG89
+Ygp3aGlsZSghMCl7aWYoIShvPGMpKXt0PSEwCmJyZWFrfXM9cC5XKGEsbykKaWYoczw9MTI3KWlmKHMh
+PT0zNylyPWUmJnM9PT00MwplbHNlIHI9ITAKZWxzZSByPSEwCmlmKHIpe3Q9ITEKYnJlYWt9KytvfWlm
+KHQpe2lmKEMueE0hPT1kKXI9ITEKZWxzZSByPSEwCmlmKHIpcmV0dXJuIHAuTmooYSxiLGMpCmVsc2Ug
+cT1uZXcgSC5xaihwLk5qKGEsYixjKSl9ZWxzZXtxPUguVk0oW10sdS50KQpmb3Iobz1iO288YzsrK28p
+e3M9cC5XKGEsbykKaWYocz4xMjcpdGhyb3cgSC5iKFAueFkoIklsbGVnYWwgcGVyY2VudCBlbmNvZGlu
+ZyBpbiBVUkkiKSkKaWYocz09PTM3KXtpZihvKzM+YS5sZW5ndGgpdGhyb3cgSC5iKFAueFkoIlRydW5j
+YXRlZCBVUkkiKSkKQy5ObS5pKHEsUC5JaChhLG8rMSkpCm8rPTJ9ZWxzZSBpZihlJiZzPT09NDMpQy5O
+bS5pKHEsMzIpCmVsc2UgQy5ObS5pKHEscyl9fXUuTC5iKHEpCnJldHVybiBuZXcgUC5HWSghMSkuV0oo
+cSl9LApFdDpmdW5jdGlvbihhKXt2YXIgdD1hfDMyCnJldHVybiA5Nzw9dCYmdDw9MTIyfSwKS0Q6ZnVu
+Y3Rpb24oYSxiLGMpe3ZhciB0LHMscixxLHAsbyxuLG0sbD0iSW52YWxpZCBNSU1FIHR5cGUiLGs9SC5W
+TShbYi0xXSx1LnQpCmZvcih0PWEubGVuZ3RoLHM9YixyPS0xLHE9bnVsbDtzPHQ7KytzKXtxPUMueEIu
+VyhhLHMpCmlmKHE9PT00NHx8cT09PTU5KWJyZWFrCmlmKHE9PT00Nyl7aWYocjwwKXtyPXMKY29udGlu
+dWV9dGhyb3cgSC5iKFAucnIobCxhLHMpKX19aWYocjwwJiZzPmIpdGhyb3cgSC5iKFAucnIobCxhLHMp
+KQpmb3IoO3EhPT00NDspe0MuTm0uaShrLHMpOysrcwpmb3IocD0tMTtzPHQ7KytzKXtxPUMueEIuVyhh
+LHMpCmlmKHE9PT02MSl7aWYocDwwKXA9c31lbHNlIGlmKHE9PT01OXx8cT09PTQ0KWJyZWFrfWlmKHA+
+PTApQy5ObS5pKGsscCkKZWxzZXtvPUMuTm0uZ3JaKGspCmlmKHEhPT00NHx8cyE9PW8rN3x8IUMueEIu
+UWkoYSwiYmFzZTY0IixvKzEpKXRocm93IEguYihQLnJyKCJFeHBlY3RpbmcgJz0nIixhLHMpKQpicmVh
+a319Qy5ObS5pKGsscykKbj1zKzEKaWYoKGsubGVuZ3RoJjEpPT09MSlhPUMuaDkueXIoYSxuLHQpCmVs
+c2V7bT1QLlVsKGEsbix0LEMuVkMsITApCmlmKG0hPW51bGwpYT1DLnhCLmk3KGEsbix0LG0pfXJldHVy
+biBuZXcgUC5QRShhLGssYyl9LAp1eDpmdW5jdGlvbigpe3ZhciB0PSIwMTIzNDU2Nzg5QUJDREVGR0hJ
+SktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ei0uX34hJCYnKCkqKyw7PSIs
+cz0iLiIscj0iOiIscT0iLyIscD0iPyIsbz0iIyIsbj11LmdjLG09UC5kSCgyMixuZXcgUC5xMygpLG4p
+LGw9bmV3IFAueUkobSksaz1uZXcgUC5jNigpLGo9bmV3IFAucWQoKSxpPW4uYihsLiQyKDAsMjI1KSkK
+ay4kMyhpLHQsMSkKay4kMyhpLHMsMTQpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwzKQprLiQzKGkscCwx
+NzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxNCwyMjUpKQprLiQzKGksdCwxKQprLiQzKGkscywx
+NSkKay4kMyhpLHIsMzQpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9
+bi5iKGwuJDIoMTUsMjI1KSkKay4kMyhpLHQsMSkKay4kMyhpLCIlIiwyMjUpCmsuJDMoaSxyLDM0KQpr
+LiQzKGkscSw5KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxLDIyNSkpCmsu
+JDMoaSx0LDEpCmsuJDMoaSxyLDM0KQprLiQzKGkscSwxMCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywy
+MDUpCmk9bi5iKGwuJDIoMiwyMzUpKQprLiQzKGksdCwxMzkpCmsuJDMoaSxxLDEzMSkKay4kMyhpLHMs
+MTQ2KQprLiQzKGkscCwxNzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigzLDIzNSkpCmsuJDMoaSx0
+LDExKQprLiQzKGkscSw2OCkKay4kMyhpLHMsMTgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQpp
+PW4uYihsLiQyKDQsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIsMjI5KQprLiQzKGksciwxMDIp
+CmsuJDMoaSwiQCIsNjgpCmsuJDMoaSwiWyIsMjMyKQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikK
+ay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDUsMjI5KSkKay4kMyhpLHQsNSkKai4kMyhpLCJBWiIsMjI5
+KQprLiQzKGksciwxMDIpCmsuJDMoaSwiQCIsNjgpCmsuJDMoaSxxLDEzOCkKay4kMyhpLHAsMTcyKQpr
+LiQzKGksbywyMDUpCmk9bi5iKGwuJDIoNiwyMzEpKQpqLiQzKGksIjE5Iiw3KQprLiQzKGksIkAiLDY4
+KQprLiQzKGkscSwxMzgpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQyKDcsMjMx
+KSkKai4kMyhpLCIwOSIsNykKay4kMyhpLCJAIiw2OCkKay4kMyhpLHEsMTM4KQprLiQzKGkscCwxNzIp
+CmsuJDMoaSxvLDIwNSkKay4kMyhuLmIobC4kMig4LDgpKSwiXSIsNSkKaT1uLmIobC4kMig5LDIzNSkp
+CmsuJDMoaSx0LDExKQprLiQzKGkscywxNikKay4kMyhpLHEsMjM0KQprLiQzKGkscCwxNzIpCmsuJDMo
+aSxvLDIwNSkKaT1uLmIobC4kMigxNiwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMsMTcpCmsuJDMo
+aSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTcsMjM1KSkKay4k
+MyhpLHQsMTEpCmsuJDMoaSxxLDkpCmsuJDMoaSxwLDE3MikKay4kMyhpLG8sMjA1KQppPW4uYihsLiQy
+KDEwLDIzNSkpCmsuJDMoaSx0LDExKQprLiQzKGkscywxOCkKay4kMyhpLHEsMjM0KQprLiQzKGkscCwx
+NzIpCmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxOCwyMzUpKQprLiQzKGksdCwxMSkKay4kMyhpLHMs
+MTkpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUpCmk9bi5iKGwuJDIoMTks
+MjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDIzNCkKay4kMyhpLHAsMTcyKQprLiQzKGksbywyMDUp
+Cmk9bi5iKGwuJDIoMTEsMjM1KSkKay4kMyhpLHQsMTEpCmsuJDMoaSxxLDEwKQprLiQzKGkscCwxNzIp
+CmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMiwyMzYpKQprLiQzKGksdCwxMikKay4kMyhpLHAsMTIp
+CmsuJDMoaSxvLDIwNSkKaT1uLmIobC4kMigxMywyMzcpKQprLiQzKGksdCwxMykKay4kMyhpLHAsMTMp
+CmouJDMobi5iKGwuJDIoMjAsMjQ1KSksImF6IiwyMSkKbD1uLmIobC4kMigyMSwyNDUpKQpqLiQzKGws
+ImF6IiwyMSkKai4kMyhsLCIwOSIsMjEpCmsuJDMobCwiKy0uIiwyMSkKcmV0dXJuIG19LApVQjpmdW5j
+dGlvbihhLGIsYyxkLGUpe3ZhciB0LHMscixxLHAsbz0kLnZaKCkKZm9yKHQ9Si5yWShhKSxzPWI7czxj
+Oysrcyl7aWYoZDwwfHxkPj1vLmxlbmd0aClyZXR1cm4gSC5PSChvLGQpCnI9b1tkXQpxPXQuVyhhLHMp
+Xjk2CmlmKHE+OTUpcT0zMQppZihxPj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLHEpCnA9cltxXQpkPXAm
+MzEKQy5ObS5ZKGUscD4+PjUscyl9cmV0dXJuIGR9LApXRjpmdW5jdGlvbiBXRihhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKYTI6ZnVuY3Rpb24gYTIoKXt9LAppUDpmdW5jdGlvbiBpUChhLGIpe3RoaXMuYT1h
+CnRoaXMuYj1ifSwKQ1A6ZnVuY3Rpb24gQ1AoKXt9LApYUzpmdW5jdGlvbiBYUygpe30sCkM2OmZ1bmN0
+aW9uIEM2KGEpe3RoaXMuYT1hfSwKbjpmdW5jdGlvbiBuKCl7fSwKdTpmdW5jdGlvbiB1KGEsYixjLGQp
+e3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWR9LApiSjpmdW5jdGlvbiBiSihhLGIsYyxk
+LGUsZil7dmFyIF89dGhpcwpfLmU9YQpfLmY9YgpfLmE9YwpfLmI9ZApfLmM9ZQpfLmQ9Zn0sCmVZOmZ1
+bmN0aW9uIGVZKGEsYixjLGQsZSl7dmFyIF89dGhpcwpfLmY9YQpfLmE9YgpfLmI9YwpfLmM9ZApfLmQ9
+ZX0sCm1wOmZ1bmN0aW9uIG1wKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5k
+PWR9LAp1YjpmdW5jdGlvbiB1YihhKXt0aGlzLmE9YX0sCmRzOmZ1bmN0aW9uIGRzKGEpe3RoaXMuYT1h
+fSwKbGo6ZnVuY3Rpb24gbGooYSl7dGhpcy5hPWF9LApVVjpmdW5jdGlvbiBVVihhKXt0aGlzLmE9YX0s
+Cms1OmZ1bmN0aW9uIGs1KCl7fSwKS1k6ZnVuY3Rpb24gS1koKXt9LApjOmZ1bmN0aW9uIGMoYSl7dGhp
+cy5hPWF9LApDRDpmdW5jdGlvbiBDRChhKXt0aGlzLmE9YX0sCmFFOmZ1bmN0aW9uIGFFKGEsYixjKXt0
+aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCkVIOmZ1bmN0aW9uIEVIKCl7fSwKS046ZnVuY3Rpb24g
+S04oKXt9LApjWDpmdW5jdGlvbiBjWCgpe30sCkFuOmZ1bmN0aW9uIEFuKCl7fSwKek06ZnVuY3Rpb24g
+ek0oKXt9LApaMDpmdW5jdGlvbiBaMCgpe30sCk4zOmZ1bmN0aW9uIE4zKGEsYixjKXt0aGlzLmE9YQp0
+aGlzLmI9Ygp0aGlzLiR0aT1jfSwKYzg6ZnVuY3Rpb24gYzgoKXt9LApGSzpmdW5jdGlvbiBGSygpe30s
+Cms6ZnVuY3Rpb24gaygpe30sCk9kOmZ1bmN0aW9uIE9kKCl7fSwKaWI6ZnVuY3Rpb24gaWIoKXt9LAp4
+dTpmdW5jdGlvbiB4dSgpe30sCkd6OmZ1bmN0aW9uIEd6KCl7fSwKcVU6ZnVuY3Rpb24gcVUoKXt9LApS
+bjpmdW5jdGlvbiBSbihhKXt0aGlzLmE9YX0sCkdEOmZ1bmN0aW9uIEdEKCl7fSwKbjE6ZnVuY3Rpb24g
+bjEoYSl7dGhpcy5hPWF9LApjUzpmdW5jdGlvbiBjUyhhKXt0aGlzLmE9YX0sClZDOmZ1bmN0aW9uIFZD
+KGEpe3RoaXMuYT1hfSwKSlQ6ZnVuY3Rpb24gSlQoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCkRuOmZ1
+bmN0aW9uIERuKGEsYixjLGQsZSxmLGcpe3ZhciBfPXRoaXMKXy5hPWEKXy5iPWIKXy5jPWMKXy5kPWQK
+Xy5lPWUKXy5mPWYKXy5yPWcKXy5RPV8uej1fLnk9Xy54PW51bGx9LAplMTpmdW5jdGlvbiBlMShhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKTlk6ZnVuY3Rpb24gTlkoYSl7dGhpcy5hPWF9LApSWjpmdW5jdGlv
+biBSWigpe30sCk1FOmZ1bmN0aW9uIE1FKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp5NTpmdW5jdGlv
+biB5NShhKXt0aGlzLmE9YX0sClBFOmZ1bmN0aW9uIFBFKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0
+aGlzLmM9Y30sCnEzOmZ1bmN0aW9uIHEzKCl7fSwKeUk6ZnVuY3Rpb24geUkoYSl7dGhpcy5hPWF9LApj
+NjpmdW5jdGlvbiBjNigpe30sCnFkOmZ1bmN0aW9uIHFkKCl7fSwKVWY6ZnVuY3Rpb24gVWYoYSxiLGMs
+ZCxlLGYsZyxoKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kCl8uZT1lCl8uZj1mCl8u
+cj1nCl8ueD1oCl8ueT1udWxsfSwKcWU6ZnVuY3Rpb24gcWUoYSxiLGMsZCxlLGYsZyl7dmFyIF89dGhp
+cwpfLmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9ZgpfLnI9ZwpfLlE9Xy56PV8ueT1fLng9
+bnVsbH0sCmlKOmZ1bmN0aW9uIGlKKCl7fSwKbFI6ZnVuY3Rpb24gbFIoYSxiKXt0aGlzLmE9YQp0aGlz
+LmI9Yn0sCmpnOmZ1bmN0aW9uIGpnKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LApCZjpmdW5jdGlvbiBC
+ZihhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKQXM6ZnVuY3Rpb24gQXMoKXt9LApHRTpmdW5jdGlvbiBH
+RShhKXt0aGlzLmE9YX0sCk43OmZ1bmN0aW9uIE43KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp1UTpm
+dW5jdGlvbiB1USgpe30sCmhGOmZ1bmN0aW9uIGhGKCl7fSwKUjQ6ZnVuY3Rpb24oYSxiLGMsZCl7dmFy
+IHQscyxyCkgueGQoYikKdS5qLmIoZCkKaWYoSC5vVChiKSl7dD1bY10KQy5ObS5GVih0LGQpCmQ9dH1z
+PXUuegpyPVAuQ0goSi5NMShkLFAudzAoKSxzKSwhMCxzKQp1LlouYihhKQpyZXR1cm4gUC53WShILkVr
+KGEscixudWxsKSl9LApEbTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdHJ5e2lmKE9iamVjdC5pc0V4dGVu
+c2libGUoYSkmJiFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoYSxiKSl7T2JqZWN0
+LmRlZmluZVByb3BlcnR5KGEsYix7dmFsdWU6Y30pCnJldHVybiEwfX1jYXRjaCh0KXtILlJ1KHQpfXJl
+dHVybiExfSwKT206ZnVuY3Rpb24oYSxiKXtpZihPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5
+LmNhbGwoYSxiKSlyZXR1cm4gYVtiXQpyZXR1cm4gbnVsbH0sCndZOmZ1bmN0aW9uKGEpe2lmKGE9PW51
+bGx8fHR5cGVvZiBhPT0ic3RyaW5nInx8dHlwZW9mIGE9PSJudW1iZXIifHxILmwoYSkpcmV0dXJuIGEK
+aWYoYSBpbnN0YW5jZW9mIFAuRTQpcmV0dXJuIGEuYQppZihILlI5KGEpKXJldHVybiBhCmlmKHUudS5j
+KGEpKXJldHVybiBhCmlmKGEgaW5zdGFuY2VvZiBQLmlQKXJldHVybiBILm8yKGEpCmlmKHUuWi5jKGEp
+KXJldHVybiBQLmhFKGEsIiRkYXJ0X2pzRnVuY3Rpb24iLG5ldyBQLlBDKCkpCnJldHVybiBQLmhFKGEs
+Il8kZGFydF9qc09iamVjdCIsbmV3IFAubXQoJC5rSSgpKSl9LApoRTpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9UC5PbShhLGIpCmlmKHQ9PW51bGwpe3Q9Yy4kMShhKQpQLkRtKGEsYix0KX1yZXR1cm4gdH0sCkw3
+OmZ1bmN0aW9uKGEpe3ZhciB0LHMKaWYoYT09bnVsbHx8dHlwZW9mIGE9PSJzdHJpbmcifHx0eXBlb2Yg
+YT09Im51bWJlciJ8fHR5cGVvZiBhPT0iYm9vbGVhbiIpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNl
+b2YgT2JqZWN0JiZILlI5KGEpKXJldHVybiBhCmVsc2UgaWYoYSBpbnN0YW5jZW9mIE9iamVjdCYmdS51
+LmMoYSkpcmV0dXJuIGEKZWxzZSBpZihhIGluc3RhbmNlb2YgRGF0ZSl7dD1ILlNjKGEuZ2V0VGltZSgp
+KQppZihNYXRoLmFicyh0KTw9ODY0ZTEzKXM9ITEKZWxzZSBzPSEwCmlmKHMpSC52aChQLnhZKCJEYXRl
+VGltZSBpcyBvdXRzaWRlIHZhbGlkIHJhbmdlOiAiK3QpKQpyZXR1cm4gbmV3IFAuaVAodCwhMSl9ZWxz
+ZSBpZihhLmNvbnN0cnVjdG9yPT09JC5rSSgpKXJldHVybiBhLm8KZWxzZSByZXR1cm4gUC5ORChhKX0s
+Ck5EOmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhPT0iZnVuY3Rpb24iKXJldHVybiBQLmlRKGEsJC53KCks
+bmV3IFAuTnooKSkKaWYoYSBpbnN0YW5jZW9mIEFycmF5KXJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQ
+LlFTKCkpCnJldHVybiBQLmlRKGEsJC5SOCgpLG5ldyBQLm5wKCkpfSwKaVE6ZnVuY3Rpb24oYSxiLGMp
+e3ZhciB0PVAuT20oYSxiKQppZih0PT1udWxsfHwhKGEgaW5zdGFuY2VvZiBPYmplY3QpKXt0PWMuJDEo
+YSkKUC5EbShhLGIsdCl9cmV0dXJuIHR9LApQQzpmdW5jdGlvbiBQQygpe30sCm10OmZ1bmN0aW9uIG10
+KGEpe3RoaXMuYT1hfSwKTno6ZnVuY3Rpb24gTnooKXt9LApRUzpmdW5jdGlvbiBRUygpe30sCm5wOmZ1
+bmN0aW9uIG5wKCl7fSwKRTQ6ZnVuY3Rpb24gRTQoYSl7dGhpcy5hPWF9LApyNzpmdW5jdGlvbiByNyhh
+KXt0aGlzLmE9YX0sClR6OmZ1bmN0aW9uIFR6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmNvOmZ1
+bmN0aW9uIGNvKCl7fSwKbmQ6ZnVuY3Rpb24gbmQoKXt9LApLZTpmdW5jdGlvbiBLZShhKXt0aGlzLmE9
+YX0sCmQ1OmZ1bmN0aW9uIGQ1KCl7fSwKbjY6ZnVuY3Rpb24gbjYoKXt9fSxXPXsKeDM6ZnVuY3Rpb24o
+KXtyZXR1cm4gd2luZG93fSwKWnI6ZnVuY3Rpb24oKXtyZXR1cm4gZG9jdW1lbnR9LApKNjpmdW5jdGlv
+bihhKXt2YXIgdD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJhIikKaWYoYSE9bnVsbCl0LmhyZWY9YQpy
+ZXR1cm4gdH0sClU5OmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1kb2N1bWVudC5ib2R5LHM9KHQmJkMuUlkp
+LnI2KHQsYSxiLGMpCnMudG9TdHJpbmcKdD11LmFjCnQ9bmV3IEguVTUobmV3IFcuZTcocyksdC5DKCJh
+MihsRC5FKSIpLmIobmV3IFcuQ3YoKSksdC5DKCJVNTxsRC5FPiIpKQpyZXR1cm4gdS5oLmIodC5ncjgo
+dCkpfSwKclM6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPSJlbGVtZW50IHRhZyB1bmF2YWlsYWJsZSIKdHJ5
+e3Q9Si5SRShhKQppZih0eXBlb2YgdC5nbnMoYSk9PSJzdHJpbmciKXI9dC5nbnMoYSl9Y2F0Y2gocyl7
+SC5SdShzKX1yZXR1cm4gcn0sCkMwOmZ1bmN0aW9uKGEsYil7YT01MzY4NzA5MTEmYStiCmE9NTM2ODcw
+OTExJmErKCg1MjQyODcmYSk8PDEwKQpyZXR1cm4gYV5hPj4+Nn0sCnJFOmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciB0PVcuQzAoVy5DMChXLkMwKFcuQzAoMCxhKSxiKSxjKSxkKSxzPTUzNjg3MDkxMSZ0KygoNjcx
+MDg4NjMmdCk8PDMpCnNePXM+Pj4xMQpyZXR1cm4gNTM2ODcwOTExJnMrKCgxNjM4MyZzKTw8MTUpfSwK
+VE46ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9YS5jbGFzc0xpc3QKZm9yKHQ9Yi5sZW5ndGgscz0wO3M8
+Yi5sZW5ndGg7Yi5sZW5ndGg9PT10fHwoMCxILmxrKShiKSwrK3Mpci5hZGQoYltzXSl9LApKRTpmdW5j
+dGlvbihhLGIsYyxkLGUpe3ZhciB0PVcuYUYobmV3IFcudk4oYyksdS5CKQppZih0IT1udWxsJiYhMClK
+LmRaKGEsYix0LCExKQpyZXR1cm4gbmV3IFcueEMoYSxiLHQsITEsZS5DKCJ4QzwwPiIpKX0sClR3OmZ1
+bmN0aW9uKGEpe3ZhciB0PVcuSjYobnVsbCkscz13aW5kb3cubG9jYXRpb24KdD1uZXcgVy5KUShuZXcg
+Vy5tayh0LHMpKQp0LkNZKGEpCnJldHVybiB0fSwKcUQ6ZnVuY3Rpb24oYSxiLGMsZCl7dS5oLmIoYSkK
+SC55KGIpCkgueShjKQp1Lk8uYihkKQpyZXR1cm4hMH0sClFXOmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0
+LHMscgp1LmguYihhKQpILnkoYikKSC55KGMpCnQ9dS5PLmIoZCkuYQpzPXQuYQpzLmhyZWY9YwpyPXMu
+aG9zdG5hbWUKdD10LmIKaWYoIShyPT10Lmhvc3RuYW1lJiZzLnBvcnQ9PXQucG9ydCYmcy5wcm90b2Nv
+bD09dC5wcm90b2NvbCkpaWYocj09PSIiKWlmKHMucG9ydD09PSIiKXt0PXMucHJvdG9jb2wKdD10PT09
+IjoifHx0PT09IiJ9ZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITAKcmV0dXJuIHR9LApCbDpmdW5j
+dGlvbigpe3ZhciB0PXUuTixzPVAudE0oQy5ReCx0KSxyPXUuZEcuYihuZXcgVy5JQSgpKSxxPUguVk0o
+WyJURU1QTEFURSJdLHUucykKdD1uZXcgVy5jdChzLFAuTHModCksUC5Mcyh0KSxQLkxzKHQpLG51bGwp
+CnQuQ1kobnVsbCxuZXcgSC5BOChDLlF4LHIsdS5kdikscSxudWxsKQpyZXR1cm4gdH0sCnVWOmZ1bmN0
+aW9uKGEpe2lmKGE9PW51bGwpcmV0dXJuIG51bGwKcmV0dXJuIFcuUDEoYSl9LApxYzpmdW5jdGlvbihh
+KXt2YXIgdAppZihhPT1udWxsKXJldHVybiBudWxsCmlmKCJwb3N0TWVzc2FnZSIgaW4gYSl7dD1XLlAx
+KGEpCmlmKHUuci5jKHQpKXJldHVybiB0CnJldHVybiBudWxsfWVsc2UgcmV0dXJuIHUuci5iKGEpfSwK
+UDE6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdylyZXR1cm4gdS5jaS5iKGEpCmVsc2UgcmV0dXJuIG5l
+dyBXLmRXKGEpfSwKSEg6ZnVuY3Rpb24oYSl7aWYoYT09PXdpbmRvdy5sb2NhdGlvbilyZXR1cm4gYQpl
+bHNlIHJldHVybiBuZXcgVy5GYigpfSwKYUY6ZnVuY3Rpb24oYSxiKXt2YXIgdD0kLlgzCmlmKHQ9PT1D
+Lk5VKXJldHVybiBhCnJldHVybiB0LlB5KGEsYil9LApxRTpmdW5jdGlvbiBxRSgpe30sCkdoOmZ1bmN0
+aW9uIEdoKCl7fSwKZlk6ZnVuY3Rpb24gZlkoKXt9LApuQjpmdW5jdGlvbiBuQigpe30sCkF6OmZ1bmN0
+aW9uIEF6KCl7fSwKUVA6ZnVuY3Rpb24gUVAoKXt9LApueDpmdW5jdGlvbiBueCgpe30sCm9KOmZ1bmN0
+aW9uIG9KKCl7fSwKaWQ6ZnVuY3Rpb24gaWQoKXt9LApRRjpmdW5jdGlvbiBRRigpe30sCk5oOmZ1bmN0
+aW9uIE5oKCl7fSwKSUI6ZnVuY3Rpb24gSUIoKXt9LApuNzpmdW5jdGlvbiBuNygpe30sCnd6OmZ1bmN0
+aW9uIHd6KGEsYil7dGhpcy5hPWEKdGhpcy4kdGk9Yn0sCmN2OmZ1bmN0aW9uIGN2KCl7fSwKQ3Y6ZnVu
+Y3Rpb24gQ3YoKXt9LAplYTpmdW5jdGlvbiBlYSgpe30sCkQwOmZ1bmN0aW9uIEQwKCl7fSwKaEg6ZnVu
+Y3Rpb24gaEgoKXt9LApoNDpmdW5jdGlvbiBoNCgpe30sCmJyOmZ1bmN0aW9uIGJyKCl7fSwKVmI6ZnVu
+Y3Rpb24gVmIoKXt9LApPNzpmdW5jdGlvbiBPNygpe30sCndhOmZ1bmN0aW9uIHdhKCl7fSwKU2c6ZnVu
+Y3Rpb24gU2coKXt9LAp1ODpmdW5jdGlvbiB1OCgpe30sCkFqOmZ1bmN0aW9uIEFqKCl7fSwKZTc6ZnVu
+Y3Rpb24gZTcoYSl7dGhpcy5hPWF9LAp1SDpmdW5jdGlvbiB1SCgpe30sCkJIOmZ1bmN0aW9uIEJIKCl7
+fSwKU046ZnVuY3Rpb24gU04oKXt9LApldzpmdW5jdGlvbiBldygpe30sCmxwOmZ1bmN0aW9uIGxwKCl7
+fSwKVGI6ZnVuY3Rpb24gVGIoKXt9LApJdjpmdW5jdGlvbiBJdigpe30sCldQOmZ1bmN0aW9uIFdQKCl7
+fSwKeVk6ZnVuY3Rpb24geVkoKXt9LAp3NjpmdW5jdGlvbiB3Nigpe30sCks1OmZ1bmN0aW9uIEs1KCl7
+fSwKQ206ZnVuY3Rpb24gQ20oKXt9LApDUTpmdW5jdGlvbiBDUSgpe30sCnc0OmZ1bmN0aW9uIHc0KCl7
+fSwKcmg6ZnVuY3Rpb24gcmgoKXt9LApjZjpmdW5jdGlvbiBjZigpe30sCmk3OmZ1bmN0aW9uIGk3KGEp
+e3RoaXMuYT1hfSwKU3k6ZnVuY3Rpb24gU3koYSl7dGhpcy5hPWF9LApLUzpmdW5jdGlvbiBLUyhhLGIp
+e3RoaXMuYT1hCnRoaXMuYj1ifSwKQTM6ZnVuY3Rpb24gQTMoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+Ckk0OmZ1bmN0aW9uIEk0KGEpe3RoaXMuYT1hfSwKRms6ZnVuY3Rpb24gRmsoYSxiKXt0aGlzLmE9YQp0
+aGlzLiR0aT1ifSwKUk86ZnVuY3Rpb24gUk8oYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9Ygpf
+LmM9YwpfLiR0aT1kfSwKZXU6ZnVuY3Rpb24gZXUoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmE9YQpfLmI9
+YgpfLmM9YwpfLiR0aT1kfSwKeEM6ZnVuY3Rpb24geEMoYSxiLGMsZCxlKXt2YXIgXz10aGlzCl8uYj1h
+Cl8uYz1iCl8uZD1jCl8uZT1kCl8uJHRpPWV9LAp2TjpmdW5jdGlvbiB2TihhKXt0aGlzLmE9YX0sCkpR
+OmZ1bmN0aW9uIEpRKGEpe3RoaXMuYT1hfSwKR206ZnVuY3Rpb24gR20oKXt9LAp2RDpmdW5jdGlvbiB2
+RChhKXt0aGlzLmE9YX0sClV2OmZ1bmN0aW9uIFV2KGEpe3RoaXMuYT1hfSwKRWc6ZnVuY3Rpb24gRWco
+YSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKbTY6ZnVuY3Rpb24gbTYoKXt9LApFbzpm
+dW5jdGlvbiBFbygpe30sCldrOmZ1bmN0aW9uIFdrKCl7fSwKY3Q6ZnVuY3Rpb24gY3QoYSxiLGMsZCxl
+KXt2YXIgXz10aGlzCl8uZT1hCl8uYT1iCl8uYj1jCl8uYz1kCl8uZD1lfSwKSUE6ZnVuY3Rpb24gSUEo
+KXt9LApPdzpmdW5jdGlvbiBPdygpe30sClc5OmZ1bmN0aW9uIFc5KGEsYixjKXt2YXIgXz10aGlzCl8u
+YT1hCl8uYj1iCl8uYz0tMQpfLmQ9bnVsbApfLiR0aT1jfSwKZFc6ZnVuY3Rpb24gZFcoYSl7dGhpcy5h
+PWF9LApGYjpmdW5jdGlvbiBGYigpe30sCmtGOmZ1bmN0aW9uIGtGKCl7fSwKbWs6ZnVuY3Rpb24gbWso
+YSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sCktvOmZ1bmN0aW9uIEtvKGEpe3RoaXMuYT1hfSwKZm06ZnVu
+Y3Rpb24gZm0oYSl7dGhpcy5hPWF9LApMZTpmdW5jdGlvbiBMZSgpe30sCks3OmZ1bmN0aW9uIEs3KCl7
+fSwKckI6ZnVuY3Rpb24gckIoKXt9LApYVzpmdW5jdGlvbiBYVygpe30sCm9hOmZ1bmN0aW9uIG9hKCl7
+fX0sTT17Ck9YOmZ1bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIEMuQWQ6cmV0dXJuIkFkZCAvKj8qLyBo
+aW50IgpjYXNlIEMubmU6cmV0dXJuIkFkZCAvKiEqLyBoaW50IgpjYXNlIEMud1Y6cmV0dXJuIlJlbW92
+ZSAvKj8qLyBoaW50IgpjYXNlIEMuZlI6cmV0dXJuIlJlbW92ZSAvKiEqLyBoaW50IgpjYXNlIEMubXk6
+cmV0dXJuIkNoYW5nZSB0byAvKj8qLyBoaW50IgpjYXNlIEMucng6cmV0dXJuIkNoYW5nZSB0byAvKiEq
+LyBoaW50In1yZXR1cm4gbnVsbH0sCkg3OmZ1bmN0aW9uIEg3KGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9
+LApZRjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuCmZvcih0PWIubGVuZ3RoLHM9MTtzPHQ7
+KytzKXtpZihiW3NdPT1udWxsfHxiW3MtMV0hPW51bGwpY29udGludWUKZm9yKDt0Pj0xO3Q9cil7cj10
+LTEKaWYoYltyXSE9bnVsbClicmVha31xPW5ldyBQLlJuKCIiKQpwPWErIigiCnEuYT1wCm89SC5xQyhi
+LDAsdCxILnQ2KGIpLmQpCm49by4kdGkKbj1wK25ldyBILkE4KG8sbi5DKCJxVShhTC5FKSIpLmIobmV3
+IE0uTm8oKSksbi5DKCJBODxhTC5FLHFVPiIpKS5IKDAsIiwgIikKcS5hPW4KcS5hPW4rKCIpOiBwYXJ0
+ICIrKHMtMSkrIiB3YXMgbnVsbCwgYnV0IHBhcnQgIitzKyIgd2FzIG5vdC4iKQp0aHJvdyBILmIoUC54
+WShxLncoMCkpKX19LApsSTpmdW5jdGlvbiBsSShhKXt0aGlzLmE9YX0sCk1pOmZ1bmN0aW9uIE1pKCl7
+fSwKcTc6ZnVuY3Rpb24gcTcoKXt9LApObzpmdW5jdGlvbiBObygpe319LFU9ewpuejpmdW5jdGlvbihh
+KXt2YXIgdD1ILldZKGEucSgwLCJub2RlSWQiKSkKcmV0dXJuIG5ldyBVLkxMKEMuTm0uSHQoQy5yayxu
+ZXcgVS5NRChhKSksdCl9LApMTDpmdW5jdGlvbiBMTChhLGIpe3RoaXMuYT1hCnRoaXMuYj1ifSwKTUQ6
+ZnVuY3Rpb24gTUQoYSl7dGhpcy5hPWF9LApqZjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscQppZihhPT1u
+dWxsKXQ9bnVsbAplbHNle3Q9SC5WTShbXSx1LmZBKQpmb3Iocz1KLklUKHUuUi5iKGEpKTtzLkYoKTsp
+e3I9cy5nbCgpCnE9Si5VNihyKQpDLk5tLmkodCxuZXcgVS5TZShILmMwKHEucShyLCJkZXNjcmlwdGlv
+biIpKSxILmMwKHEucShyLCJocmVmIikpKSl9fXJldHVybiB0fSwKTmQ6ZnVuY3Rpb24oYSl7dmFyIHQs
+cwppZihhPT1udWxsKXQ9bnVsbAplbHNle3Q9SC5WTShbXSx1LmhoKQpmb3Iocz1KLklUKHUuUi5iKGEp
+KTtzLkYoKTspQy5ObS5pKHQsVS5OZihzLmdsKCkpKX1yZXR1cm4gdH0sCk5mOmZ1bmN0aW9uKGEpe3Zh
+ciB0PUouVTYoYSkscz1ILmMwKHQucShhLCJkZXNjcmlwdGlvbiIpKSxyPUguVk0oW10sdS5hSikKZm9y
+KHQ9Si5JVCh1LlIuYih0LnEoYSwiZW50cmllcyIpKSk7dC5GKCk7KUMuTm0uaShyLFUuUmoodC5nbCgp
+KSkKcmV0dXJuIG5ldyBVLnlEKHMscil9LApSajpmdW5jdGlvbihhKXt2YXIgdCxzPUouVTYoYSkscj1I
+LmMwKHMucShhLCJkZXNjcmlwdGlvbiIpKSxxPUguYzAocy5xKGEsImZ1bmN0aW9uIikpLHA9cy5xKGEs
+ImxpbmsiKQppZihwPT1udWxsKXA9bnVsbAplbHNle3Q9Si5VNihwKQpwPW5ldyBVLk1sKEguYzAodC5x
+KHAsImhyZWYiKSksSC5XWSh0LnEocCwibGluZSIpKSxILmMwKHQucShwLCJwYXRoIikpKX1zPXUuai5h
+KHMucShhLCJoaW50QWN0aW9ucyIpKQpzPXM9PW51bGw/bnVsbDpKLk0xKHMsbmV3IFUuYU4oKSx1LkQp
+CnM9cz09bnVsbD9udWxsOnMuYnIoMCkKcmV0dXJuIG5ldyBVLndiKHIscSxwLHM9PW51bGw/Qy5kbjpz
+KX0sCmQyOmZ1bmN0aW9uIGQyKGEsYixjLGQsZSxmKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1j
+Cl8uZD1kCl8uZT1lCl8uZj1mfSwKU2U6ZnVuY3Rpb24gU2UoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0s
+Ck1sOmZ1bmN0aW9uIE1sKGEsYixjKXt0aGlzLmE9YQp0aGlzLmI9Ygp0aGlzLmM9Y30sCnlEOmZ1bmN0
+aW9uIHlEKGEsYil7dGhpcy5hPWEKdGhpcy5iPWJ9LAp3YjpmdW5jdGlvbiB3YihhLGIsYyxkKXt2YXIg
+Xz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1kfSwKYU46ZnVuY3Rpb24gYU4oKXt9LApiMDpmdW5j
+dGlvbiBiMCgpe319LEI9ewpZZjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9SC5jMChh
+LnEoMCwicmVnaW9ucyIpKSxrPUguYzAoYS5xKDAsIm5hdmlnYXRpb25Db250ZW50IikpLGo9SC5jMChh
+LnEoMCwic291cmNlQ29kZSIpKSxpPVAuRmwodS5OLHUuZjQpCmZvcih0PXUuUy5hKGEucSgwLCJlZGl0
+cyIpKSx0PXQuZ1B1KHQpLHQ9dC5na3oodCkscz11LlIscj11LmdpO3QuRigpOyl7cT10LmdsKCkKcD1x
+LmEKbz1ILlZNKFtdLHIpCmZvcihxPUouSVQocy5iKHEuYikpO3EuRigpOyl7bj1xLmdsKCkKbT1KLlU2
+KG4pCkMuTm0uaShvLG5ldyBCLmo4KEguV1kobS5xKG4sImxpbmUiKSksSC5jMChtLnEobiwiZXhwbGFu
+YXRpb24iKSksSC5XWShtLnEobiwib2Zmc2V0IikpKSl9aS5ZKDAscCxvKX1yZXR1cm4gbmV3IEIucXAo
+bCxrLGosaSl9LApqODpmdW5jdGlvbiBqOChhLGIsYyl7dGhpcy5hPWEKdGhpcy5iPWIKdGhpcy5jPWN9
+LApxcDpmdW5jdGlvbiBxcChhLGIsYyxkKXt2YXIgXz10aGlzCl8uYT1hCl8uYj1iCl8uYz1jCl8uZD1k
+fSwKZnY6ZnVuY3Rpb24gZnYoKXt9LApPUzpmdW5jdGlvbihhKXt2YXIgdAppZighKGE+PTY1JiZhPD05
+MCkpdD1hPj05NyYmYTw9MTIyCmVsc2UgdD0hMApyZXR1cm4gdH0sCll1OmZ1bmN0aW9uKGEsYil7dmFy
+IHQ9YS5sZW5ndGgscz1iKzIKaWYodDxzKXJldHVybiExCmlmKCFCLk9TKEMueEIubShhLGIpKSlyZXR1
+cm4hMQppZihDLnhCLm0oYSxiKzEpIT09NTgpcmV0dXJuITEKaWYodD09PXMpcmV0dXJuITAKcmV0dXJu
+IEMueEIubShhLHMpPT09NDd9fSxUPXttUTpmdW5jdGlvbiBtUSgpe319LEw9ewpJcTpmdW5jdGlvbigp
+e0MuQlouQihkb2N1bWVudCwiRE9NQ29udGVudExvYWRlZCIsbmV3IEwuZSgpKQpDLm9sLkIod2luZG93
+LCJwb3BzdGF0ZSIsbmV3IEwuTCgpKX0sCmt6OmZ1bmN0aW9uKGEpe3ZhciB0LHM9dS5oLmEoYS5wYXJl
+bnROb2RlKS5xdWVyeVNlbGVjdG9yKCI6c2NvcGUgPiB1bCIpLHI9cy5zdHlsZSxxPSIiK0MuQ0QuelEo
+cy5vZmZzZXRIZWlnaHQpKjIrInB4IgpyLm1heEhlaWdodD1xCnI9Si5xRihhKQpxPXIuJHRpCnQ9cS5D
+KCJ+KDEpIikuYihuZXcgTC5XeChzLGEpKQp1Lk0uYihudWxsKQpXLkpFKHIuYSxyLmIsdCwhMSxxLmQp
+fSwKeVg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89InF1ZXJ5U2VsZWN0b3JBbGwiLG49ZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcihhKSxtPXUuaApuLnRvU3RyaW5nCkguRGgobSxtLCJUIixvKQp0PXUu
+VApzPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLm5hdi1saW5rIiksdCkKcy5LKHMsbmV3IEwu
+QU8oYikpCkguRGgobSxtLCJUIixvKQpyPW5ldyBXLnd6KG4ucXVlcnlTZWxlY3RvckFsbCgiLnJlZ2lv
+biIpLHQpCmlmKHIuZ0EocikhPT0wKXtxPW4ucXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIp
+CnEudG9TdHJpbmcKci5LKHIsbmV3IEwuSG8ocS5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShu
+ZXcgVy5pNyhxKSkuTygicGF0aCIpKSkpfUguRGgobSxtLCJUIixvKQpwPW5ldyBXLnd6KG4ucXVlcnlT
+ZWxlY3RvckFsbCgiLmFkZC1oaW50LWxpbmsiKSx0KQpwLksocCxuZXcgTC5JQygpKX0sClE2OmZ1bmN0
+aW9uKGEsYixjKXt2YXIgdD1uZXcgWE1MSHR0cFJlcXVlc3QoKQpDLkR0LmVvKHQsIkdFVCIsTC5RNChh
+LGIpLCEwKQp0LnNldFJlcXVlc3RIZWFkZXIoIkNvbnRlbnQtVHlwZSIsImFwcGxpY2F0aW9uL2pzb247
+IGNoYXJzZXQ9VVRGLTgiKQpyZXR1cm4gTC5MVSh0LG51bGwsYyl9LAp0eTpmdW5jdGlvbihhLGIpe3Zh
+ciB0PW5ldyBYTUxIdHRwUmVxdWVzdCgpLHM9dS5OCkMuRHQuZW8odCwiUE9TVCIsTC5RNChhLFAuRmwo
+cyxzKSksITApCnQuc2V0UmVxdWVzdEhlYWRlcigiQ29udGVudC1UeXBlIiwiYXBwbGljYXRpb24vanNv
+bjsgY2hhcnNldD1VVEYtOCIpCnJldHVybiBMLkxVKHQsYix1LlMpfSwKTFU6ZnVuY3Rpb24oYSxiLGMp
+e3JldHVybiBMLlRnKGEsYixjLGMpfSwKVGc6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQ9MCxzPVAuRlgo
+ZCkscixxPTIscCxvPVtdLG4sbSxsLGssaixpLGgsZwp2YXIgJGFzeW5jJExVPVAubHooZnVuY3Rpb24o
+ZSxmKXtpZihlPT09MSl7cD1mCnQ9cX13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6aj1uZXcgUC5a
+ZihuZXcgUC52cygkLlgzLHUuYW8pLHUuYmopCmk9dS5hbgpoPWkuYihuZXcgTC5mQyhqLGEpKQp1Lk0u
+YihudWxsKQptPXUucApXLkpFKGEsImxvYWQiLGgsITEsbSkKVy5KRShhLCJlcnJvciIsaS5iKGouZ1lK
+KCkpLCExLG0pCmEuc2VuZChiPT1udWxsP251bGw6Qy5DdC5PQihiLG51bGwpKQpxPTQKdD03CnJldHVy
+biBQLmpRKGouYSwkYXN5bmMkTFUpCmNhc2UgNzpxPTIKdD02CmJyZWFrCmNhc2UgNDpxPTMKZz1wCkgu
+UnUoZykKbj1ILnRzKGcpCmk9UC5UbCgiRXJyb3IgcmVhY2hpbmcgbWlncmF0aW9uIHByZXZpZXcgc2Vy
+dmVyLiIsbikKdGhyb3cgSC5iKGkpCnQ9NgpicmVhawpjYXNlIDM6dD0yCmJyZWFrCmNhc2UgNjprPUMu
+Q3QucFcoMCxhLnJlc3BvbnNlVGV4dCxudWxsKQppZihhLnN0YXR1cz09PTIwMCl7cj1jLmEoaykKdD0x
+CmJyZWFrfWVsc2UgdGhyb3cgSC5iKGspCmNhc2UgMTpyZXR1cm4gUC55QyhyLHMpCmNhc2UgMjpyZXR1
+cm4gUC5mMyhwLHMpfX0pCnJldHVybiBQLkRJKCRhc3luYyRMVSxzKX0sCmFLOmZ1bmN0aW9uKGEpe3Zh
+ciB0PVAuaEsoYSkuZ2hZKCkucSgwLCJsaW5lIikKcmV0dXJuIHQ9PW51bGw/bnVsbDpILkhwKHQsbnVs
+bCl9LApHNjpmdW5jdGlvbihhKXt2YXIgdD1QLmhLKGEpLmdoWSgpLnEoMCwib2Zmc2V0IikKcmV0dXJu
+IHQ9PW51bGw/bnVsbDpILkhwKHQsbnVsbCl9LAppNjpmdW5jdGlvbihhKXtyZXR1cm4gTC5uVyh1LlYu
+YihhKSl9LApuVzpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0s
+bCxrCnZhciAkYXN5bmMkaTY9UC5seihmdW5jdGlvbihiLGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxl
+KHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpsPXUuaC5hKFcucWMoYS5jdXJyZW50VGFyZ2V0KSkuZ2V0QXR0
+cmlidXRlKCJocmVmIikKYS5wcmV2ZW50RGVmYXVsdCgpCnI9Mwp0PTYKcmV0dXJuIFAualEoTC50eShs
+LG51bGwpLCRhc3luYyRpNikKY2FzZSA2OnUuYV8uYShKLkdyKFcudVYoZG9jdW1lbnQuZGVmYXVsdFZp
+ZXcpKSkucmVsb2FkKCkKcj0xCnQ9NQpicmVhawpjYXNlIDM6cj0yCms9cQpvPUguUnUoaykKbj1ILnRz
+KGspCkwuQzIoIkNvdWxkIG5vdCBhZGQvcmVtb3ZlIGhpbnQiLG8sbikKdD01CmJyZWFrCmNhc2UgMjp0
+PTEKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscykKY2FzZSAxOnJldHVybiBQLmYzKHEscyl9
+fSkKcmV0dXJuIFAuREkoJGFzeW5jJGk2LHMpfSwKQzI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj0i
+ZXhjZXB0aW9uIixxPSJzdGFja1RyYWNlIixwPXUuUy5jKGIpJiZKLlJNKGIucSgwLCJzdWNjZXNzIiks
+ITEpJiZILm9UKGIueDQocikpJiZILm9UKGIueDQocSkpLG89Si5pYShiKQppZihwKXt0PUguYzAoby5x
+KGIscikpCmM9by5xKGIscSl9ZWxzZSB0PW8udyhiKQpwPWRvY3VtZW50CnM9cC5xdWVyeVNlbGVjdG9y
+KCIucG9wdXAtcGFuZSIpCnMucXVlcnlTZWxlY3RvcigiaDIiKS5pbm5lclRleHQ9YQpzLnF1ZXJ5U2Vs
+ZWN0b3IoInAiKS5pbm5lclRleHQ9dApzLnF1ZXJ5U2VsZWN0b3IoInByZSIpLmlubmVyVGV4dD1KLmoo
+YykKbz11Lk4KdS5icS5hKHMucXVlcnlTZWxlY3RvcigiYS5ib3R0b20iKSkuaHJlZj1QLlhkKCJodHRw
+cyIsImdpdGh1Yi5jb20iLCJkYXJ0LWxhbmcvc2RrL2lzc3Vlcy9uZXciLFAuRUYoWyJ0aXRsZSIsIkN1
+c3RvbWVyLXJlcG9ydGVkIGlzc3VlIHdpdGggTk5CRCBtaWdyYXRpb24gdG9vbDogIithLCJsYWJlbHMi
+LCJhcmVhLWFuYWx5emVyLGFuYWx5emVyLW5uYmQtbWlncmF0aW9uLHR5cGUtYnVnIiwiYm9keSIsYSsi
+XG5cbkVycm9yOiAiK0guZCh0KSsiXG5cblBsZWFzZSBmaWxsIGluIHRoZSBmb2xsb3dpbmc6XG5cbioq
+TmFtZSBvZiBwYWNrYWdlIGJlaW5nIG1pZ3JhdGVkIChpZiBwdWJsaWMpKio6XG4qKldoYXQgSSB3YXMg
+ZG9pbmcgd2hlbiB0aGlzIGlzc3VlIG9jY3VycmVkKio6XG4qKklzIGl0IHBvc3NpYmxlIHRvIHdvcmsg
+YXJvdW5kIHRoaXMgaXNzdWUqKjpcbioqSGFzIHRoaXMgaXNzdWUgaGFwcGVuZWQgYmVmb3JlLCBhbmQg
+aWYgc28sIGhvdyBvZnRlbioqOlxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5kKHAuZ2V0RWxlbWVu
+dEJ5SWQoInNkay12ZXJzaW9uIikudGV4dENvbnRlbnQpKyJcbioqQWRkaXRpb25hbCBkZXRhaWxzKio6
+XG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuXG5TdGFja3RyYWNlOiBfYXV0byBwb3B1bGF0ZWQgYnkgbWln
+cmF0aW9uIHByZXZpZXcgdG9vbC5fXG5cbmBgYFxuIitILmQoYykrIlxuYGBgXG4iXSxvLG8pKS53KDAp
+Cm89cy5zdHlsZQpvLmRpc3BsYXk9ImluaXRpYWwiCnA9YSsiOiAiK0guZChiKQp3aW5kb3cKaWYodHlw
+ZW9mIGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLmVycm9yKHApCndpbmRvdwpwPUgu
+ZChjKQppZih0eXBlb2YgY29uc29sZSE9InVuZGVmaW5lZCIpd2luZG93LmNvbnNvbGUuZXJyb3IocCl9
+LAp0MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscD17fSxvPXUuaC5hKFcucWMoYS5jdXJyZW50
+VGFyZ2V0KSkKYS5wcmV2ZW50RGVmYXVsdCgpCnQ9cC5hPW8uZ2V0QXR0cmlidXRlKCJocmVmIikKcz1K
+LnpsKHQsIj8iKT9wLmE9Qy54Qi5Oaih0LDAsQy54Qi5PWSh0LCI/IikpOnQKcj1MLkc2KHQpCnE9TC5h
+Syh0KQppZihyIT1udWxsKUwuYWYocyxyLHEsYixuZXcgTC5uVChwLHIscSkpCmVsc2UgTC5hZihzLG51
+bGwsbnVsbCxiLG5ldyBMLkJaKHApKX0sCnZVOmZ1bmN0aW9uKCl7dmFyIHQ9ZG9jdW1lbnQscz11LmgK
+SC5EaChzLHMsIlQiLCJxdWVyeVNlbGVjdG9yQWxsIikKdD1uZXcgVy53eih0LnF1ZXJ5U2VsZWN0b3JB
+bGwoIi5jb2RlIiksdS5UKQp0LksodCxuZXcgTC5HSCgpKX0sCmhYOmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gTC5ZdyhhLGIsYyl9LApZdzpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9MCxzPVAuRlgodS56KSxyPTEs
+cSxwPVtdLG8sbixtLGwsayxqLGksaAp2YXIgJGFzeW5jJGhYPVAubHooZnVuY3Rpb24oZCxlKXtpZihk
+PT09MSl7cT1lCnQ9cn13aGlsZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6cj0zCms9dS5OCnQ9NgpyZXR1
+cm4gUC5qUShMLlE2KGEsUC5FRihbInJlZ2lvbiIsInJlZ2lvbiIsIm9mZnNldCIsSC5kKGIpXSxrLGsp
+LHUuUyksJGFzeW5jJGhYKQpjYXNlIDY6bz1lCms9bwpqPUouVTYoaykKbj1uZXcgVS5kMihVLmpmKGou
+cShrLCJlZGl0cyIpKSxILmMwKGoucShrLCJleHBsYW5hdGlvbiIpKSxILldZKGoucShrLCJsaW5lIikp
+LEguYzAoai5xKGssImRpc3BsYXlQYXRoIikpLEguYzAoai5xKGssInVyaVBhdGgiKSksVS5OZChqLnEo
+aywidHJhY2VzIikpKQpMLlQxKG4pCkwuRnIoYSxiLGMpCkwueVgoIi5lZGl0LXBhbmVsIC5wYW5lbC1j
+b250ZW50IiwhMSkKcj0xCnQ9NQpicmVhawpjYXNlIDM6cj0yCmg9cQptPUguUnUoaCkKbD1ILnRzKGgp
+CkwuQzIoIkNvdWxkIG5vdCBsb2FkIGVkaXQgZGV0YWlscyIsbSxsKQp0PTUKYnJlYWsKY2FzZSAyOnQ9
+MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNlIDE6cmV0dXJuIFAuZjMocSxzKX19
+KQpyZXR1cm4gUC5ESSgkYXN5bmMkaFgscyl9LApHNzpmdW5jdGlvbihhLGIsYyxkLGUpe3JldHVybiBM
+Lkw1KGEsYixjLGQsZSl9LApMNTpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0PTAscz1QLkZYKHUueiks
+cixxPTIscCxvPVtdLG4sbSxsLGssaixpLGgKdmFyICRhc3luYyRHNz1QLmx6KGZ1bmN0aW9uKGYsZyl7
+aWYoZj09PTEpe3A9Zwp0PXF9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOmlmKCFKLnJZKGEpLlRj
+KGEsIi5kYXJ0Iikpe0wuQkUoYSxuZXcgQi5xcCgiIiwiIiwiIixDLkNNKSxkKQpMLkJYKGEsbnVsbCkK
+aWYoZSE9bnVsbCllLiQwKCkKdD0xCmJyZWFrfXE9NApqPXUuTgp0PTcKcmV0dXJuIFAualEoTC5RNihh
+LFAuRUYoWyJpbmxpbmUiLCJ0cnVlIl0saixqKSx1LlMpLCRhc3luYyRHNykKY2FzZSA3Om49ZwpMLkJF
+KGEsQi5ZZihuKSxkKQpMLmZHKGIsYykKbT1DLnhCLnRnKGEsIj8iKT9DLnhCLk5qKGEsMCxDLnhCLk9Z
+KGEsIj8iKSk6YQpMLkJYKG0sYikKaWYoZSE9bnVsbCllLiQwKCkKcT0yCnQ9NgpicmVhawpjYXNlIDQ6
+cT0zCmg9cApsPUguUnUoaCkKaz1ILnRzKGgpCkwuQzIoIkNvdWxkIG5vdCBsb2FkIGRhcnQgZmlsZSAi
+K2EsbCxrKQp0PTYKYnJlYWsKY2FzZSAzOnQ9MgpicmVhawpjYXNlIDY6Y2FzZSAxOnJldHVybiBQLnlD
+KHIscykKY2FzZSAyOnJldHVybiBQLmYzKHAscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJEc3LHMpfSwK
+R2U6ZnVuY3Rpb24oKXt2YXIgdD0wLHM9UC5GWCh1LnopLHI9MSxxLHA9W10sbyxuLG0sbCxrLGosaQp2
+YXIgJGFzeW5jJEdlPVAubHooZnVuY3Rpb24oYSxiKXtpZihhPT09MSl7cT1iCnQ9cn13aGlsZSh0cnVl
+KXN3aXRjaCh0KXtjYXNlIDA6aj0iL19wcmV2aWV3L25hdmlnYXRpb25UcmVlLmpzb24iCnI9Mwp0PTYK
+cmV0dXJuIFAualEoTC5RNihqLEMuV08sdS5ldyksJGFzeW5jJEdlKQpjYXNlIDY6bz1iCm49ZG9jdW1l
+bnQucXVlcnlTZWxlY3RvcigiLm5hdi10cmVlIikKSi5sNShuLCIiKQpMLnRYKG4sTC5tSyhvKSkKcj0x
+CnQ9NQpicmVhawpjYXNlIDM6cj0yCmk9cQptPUguUnUoaSkKbD1ILnRzKGkpCkwuQzIoIkNvdWxkIG5v
+dCBsb2FkIG5hdmlnYXRpb24gdHJlZSIsbSxsKQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNl
+IDU6cmV0dXJuIFAueUMobnVsbCxzKQpjYXNlIDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5E
+SSgkYXN5bmMkR2Uscyl9LApxTzpmdW5jdGlvbihhKXt2YXIgdD1hLmdldEJvdW5kaW5nQ2xpZW50UmVj
+dCgpLHM9Qy5DRC56USgkLmZpKCkub2Zmc2V0SGVpZ2h0KSxyPXdpbmRvdy5pbm5lckhlaWdodCxxPUMu
+Q0QuelEoJC5EVygpLm9mZnNldEhlaWdodCkKaWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5I
+TigpCmlmKHQuYm90dG9tPnItKHErMTQpKUouZGgoYSkKZWxzZSBpZih0LnRvcDxzKzE0KUouZGgoYSl9
+LApmRzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgppZihhIT1udWxsKXt0PWRvY3VtZW50CnM9dC5nZXRF
+bGVtZW50QnlJZCgibyIrSC5kKGEpKQpyPXQucXVlcnlTZWxlY3RvcigiLmxpbmUtIitILmQoYikpCmlm
+KHMhPW51bGwpe0wucU8ocykKSi5kUihzKS5pKDAsInRhcmdldCIpfWVsc2UgaWYociE9bnVsbClMLnFP
+KHIucGFyZW50RWxlbWVudCkKaWYociE9bnVsbClKLmRSKHUuaC5hKHIucGFyZW50Tm9kZSkpLmkoMCwi
+aGlnaGxpZ2h0Iil9ZWxzZSBMLnFPKCQuRDkoKSl9LAphZjpmdW5jdGlvbihhLGIsYyxkLGUpe3ZhciB0
+LHMscj1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKSxxPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYp
+CmlmKHIhPW51bGwpe3Q9ZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoIm8iK0guZChyKSkKaWYodCE9bnVs
+bClKLmRSKHQpLlIoMCwidGFyZ2V0Iil9aWYocSE9bnVsbCl7cz1kb2N1bWVudC5xdWVyeVNlbGVjdG9y
+KCIubGluZS0iK0guZChxKSkKaWYocyE9bnVsbClKLmRSKHMucGFyZW50RWxlbWVudCkuUigwLCJoaWdo
+bGlnaHQiKX1pZihhPT13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUpe0wuZkcoYixjKQplLiQwKCl9ZWxz
+ZSBMLkc3KGEsYixjLGQsZSl9LApRNDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1QLmhLKGEpLHE9dS5O
+CnE9UC5GbChxLHEpCmZvcih0PXIuZ2hZKCksdD10LmdQdSh0KSx0PXQuZ2t6KHQpO3QuRigpOyl7cz10
+LmdsKCkKcS5ZKDAscy5hLHMuYil9Zm9yKHQ9Yi5nUHUoYiksdD10Lmdreih0KTt0LkYoKTspe3M9dC5n
+bCgpCnEuWSgwLHMuYSxzLmIpfXEuWSgwLCJhdXRoVG9rZW4iLCQuVUUoKSkKcmV0dXJuIHIubm0oMCxx
+KS53KDApfSwKVDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGs9JC5oTCgpCkoubDUo
+aywiIikKaWYoYT09bnVsbCl7dD1kb2N1bWVudC5jcmVhdGVFbGVtZW50KCJwIikKdC50ZXh0Q29udGVu
+dD0iU2VlIGRldGFpbHMgYWJvdXQgYSBwcm9wb3NlZCBlZGl0LiIKQy5MdC5zUCh0LEguVk0oWyJwbGFj
+ZWhvbGRlciJdLHUucykpCmsuYXBwZW5kQ2hpbGQodCkKQy5MdC5GRih0KQpyZXR1cm59cz1hLmQKcj0k
+Lm5VKCkKcT1yLnpmKHMpCnA9YS5iCm89ZG9jdW1lbnQKbj1yLkhQKHMsSi5UMChvLnF1ZXJ5U2VsZWN0
+b3IoIi5yb290IikudGV4dENvbnRlbnQpKQptPWEuYwpsPW8uY3JlYXRlRWxlbWVudCgicCIpCmsuYXBw
+ZW5kQ2hpbGQobCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKEguZChwKSsiIGF0ICIpKQpy
+PXUuTgpyPVcuSjYoTC5RNChhLmUsUC5FRihbImxpbmUiLEouaihtKV0scixyKSkpCnIuYXBwZW5kQ2hp
+bGQoby5jcmVhdGVUZXh0Tm9kZShILmQobikrIjoiK0guZChtKSsiLiIpKQpsLmFwcGVuZENoaWxkKHIp
+CkouZGgobCkKTC5DQyhhLGsscSkKTC5GeihhLGspfSwKTEg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbCxrLGosaSxoLGc9JC55UCgpCkoubDUoZywiIikKaWYoYi5nQShiKT09PTApe3Q9
+ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpnLmFwcGVuZENoaWxkKHMpCnMuYXBwZW5kQ2hp
+bGQodC5jcmVhdGVUZXh0Tm9kZSgiTm8gcHJvcG9zZWQgZWRpdHMiKSl9ZWxzZSBmb3IoZz1iLmdQdShi
+KSxnPWcuZ2t6KGcpLHQ9dS5RLHI9dC5DKCJ+KDEpIikscT11Lk0sdD10LmQ7Zy5GKCk7KXtwPWcuZ2wo
+KQpvPWRvY3VtZW50CnM9by5jcmVhdGVFbGVtZW50KCJwIikKbj0kLnlQKCkKbi5hcHBlbmRDaGlsZChz
+KQpzLmFwcGVuZENoaWxkKG8uY3JlYXRlVGV4dE5vZGUoSC5kKHAuYSkrIjoiKSkKbT1vLmNyZWF0ZUVs
+ZW1lbnQoInVsIikKbi5hcHBlbmRDaGlsZChtKQpmb3IocD1KLklUKHAuYik7cC5GKCk7KXtuPXAuZ2wo
+KQpsPW8uY3JlYXRlRWxlbWVudCgibGkiKQptLmFwcGVuZENoaWxkKGwpCkouZFIobCkuaSgwLCJlZGl0
+IikKaz1vLmNyZWF0ZUVsZW1lbnQoImEiKQpsLmFwcGVuZENoaWxkKGspCmsuY2xhc3NMaXN0LmFkZCgi
+ZWRpdC1saW5rIikKaj1uLmMKaT1ILmQoaikKay5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShu
+ZXcgVy5pNyhrKSkuTygib2Zmc2V0IiksaSkKaD1uLmEKaT1ILmQoaCkKay5zZXRBdHRyaWJ1dGUoImRh
+dGEtIituZXcgVy5TeShuZXcgVy5pNyhrKSkuTygibGluZSIpLGkpCmsuYXBwZW5kQ2hpbGQoby5jcmVh
+dGVUZXh0Tm9kZSgibGluZSAiK0guZChoKSkpCmk9ci5iKG5ldyBMLkVFKGosaCxhKSkKcS5iKG51bGwp
+ClcuSkUoaywiY2xpY2siLGksITEsdCkKbC5hcHBlbmRDaGlsZChvLmNyZWF0ZVRleHROb2RlKCI6ICIr
+SC5kKG4uYikpKX19aWYoYylMLlQxKG51bGwpfSwKRnI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj13
+aW5kb3cubG9jYXRpb24scT1QLmhLKChyJiZDLkV4KS5nRHIocikrSC5kKGEpKQpyPXUuTgpyPVAuRmwo
+cixyKQppZihiIT1udWxsKXIuWSgwLCJvZmZzZXQiLEguZChiKSkKaWYoYyE9bnVsbClyLlkoMCwibGlu
+ZSIsSC5kKGMpKQpyLlkoMCwiYXV0aFRva2VuIiwkLlVFKCkpCnE9cS5ubSgwLHIpCnI9d2luZG93Lmhp
+c3RvcnkKdD11LnoKcz1xLncoMCkKci50b1N0cmluZwpyLnB1c2hTdGF0ZShuZXcgUC5CZihbXSxbXSku
+UHYoUC5GbCh0LHQpKSwiIixzKX0sCkVuOmZ1bmN0aW9uKGEpe3ZhciB0PUouYmIoZG9jdW1lbnQucXVl
+cnlTZWxlY3RvcigiLnJvb3QiKS50ZXh0Q29udGVudCwiLyIpCmlmKEMueEIubihhLHQpKXJldHVybiBD
+LnhCLkcoYSx0Lmxlbmd0aCkKZWxzZSByZXR1cm4gYX0sCkJYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
+PXt9CnIuYT1hCmE9TC5FbihhKQpyLmE9YQokLkQ5KCkudGV4dENvbnRlbnQ9YQp0PWRvY3VtZW50CnM9
+dS5oCkguRGgocyxzLCJUIiwicXVlcnlTZWxlY3RvckFsbCIpCnQ9bmV3IFcud3oodC5xdWVyeVNlbGVj
+dG9yQWxsKCIubmF2LXBhbmVsIC5uYXYtbGluayIpLHUuVCkKdC5LKHQsbmV3IEwuVlMocikpfSwKQkU6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PSIucmVnaW9ucyIscz1kb2N1bWVudCxyPXMucXVlcnlTZWxlY3Rv
+cih0KSxxPXMucXVlcnlTZWxlY3RvcigiLmNvZGUiKQpKLnRIKHIsYi5hLCQuS0coKSkKSi50SChxLGIu
+YiwkLktHKCkpCkwuTEgoYSxiLmQsYykKTC52VSgpCkwueVgoIi5jb2RlIiwhMCkKTC55WCh0LCEwKX0s
+CnRYOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGssaixpLGgsZz1kb2N1bWVudCxm
+PWcuY3JlYXRlRWxlbWVudCgidWwiKQphLmFwcGVuZENoaWxkKGYpCmZvcih0PWIubGVuZ3RoLHM9dS5N
+LHI9MDtyPGIubGVuZ3RoO2IubGVuZ3RoPT09dHx8KDAsSC5saykoYiksKytyKXtxPWJbcl0KcD1nLmNy
+ZWF0ZUVsZW1lbnQoImxpIikKZi5hcHBlbmRDaGlsZChwKQpvPUouUkUocCkKaWYocS5hPT09Qy5ZMil7
+by5nUChwKS5pKDAsImRpciIpCm49Zy5jcmVhdGVFbGVtZW50KCJzcGFuIikKcC5hcHBlbmRDaGlsZChu
+KQpvPUouUkUobikKby5nUChuKS5pKDAsImFycm93IikKby5zaGYobiwiJiN4MjVCQzsiKQptPWcuY3Jl
+YXRlRWxlbWVudCgic3BhbiIpCnAuYXBwZW5kQ2hpbGQobSkKSi5sNShtLCImI3gxRjRDMTsiKQpwLmFw
+cGVuZENoaWxkKGcuY3JlYXRlVGV4dE5vZGUocS5iKSkKTC50WChwLHEuYykKTC5reihuKX1lbHNle28u
+c2hmKHAsIiYjeDFGNEM0OyIpCmw9Zy5jcmVhdGVFbGVtZW50KCJhIikKcC5hcHBlbmRDaGlsZChsKQpv
+PUouUkUobCkKby5nUChsKS5pKDAsIm5hdi1saW5rIikKbC5zZXRBdHRyaWJ1dGUoImRhdGEtIituZXcg
+Vy5TeShuZXcgVy5pNyhsKSkuTygibmFtZSIpLHEuZCkKbC5zZXRBdHRyaWJ1dGUoImhyZWYiLHEuZSkK
+bC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKHEuYikpCm89by5nVmwobCkKaz1vLiR0aQpqPWsu
+QygifigxKSIpLmIobmV3IEwuVEQoKSkKcy5iKG51bGwpClcuSkUoby5hLG8uYixqLCExLGsuZCkKaT1x
+LmYKaWYodHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5vcygpCmlmKGk+MCl7aD1nLmNyZWF0ZUVs
+ZW1lbnQoInNwYW4iKQpwLmFwcGVuZENoaWxkKGgpCkouZFIoaCkuaSgwLCJlZGl0LWNvdW50IikKbz0i
+IitpKyIgIgppZihpPT09MSlrPSJlZGl0IgplbHNlIGs9ImVkaXRzIgpoLnNldEF0dHJpYnV0ZSgidGl0
+bGUiLG8raykKaC5hcHBlbmRDaGlsZChnLmNyZWF0ZVRleHROb2RlKEMuam4udyhpKSkpfX19fSwKRno6
+ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGk9YS5hCmlmKGk9PW51bGwpcmV0
+dXJuCnQ9ZG9jdW1lbnQKcz10LmNyZWF0ZUVsZW1lbnQoInAiKQpyPWIuYXBwZW5kQ2hpbGQocykKcz10
+LmNyZWF0ZUVsZW1lbnQoInNwYW4iKQpxPXUucwpKLk11KHMsSC5WTShbInR5cGUtZGVzY3JpcHRpb24i
+XSxxKSkKcy5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCJBY3Rpb25zIikpCnIuYXBwZW5kQ2hp
+bGQocykKci5hcHBlbmRDaGlsZCh0LmNyZWF0ZVRleHROb2RlKCI6IikpCnA9dC5jcmVhdGVFbGVtZW50
+KCJwIikKYi5hcHBlbmRDaGlsZChwKQpmb3Iocz1pLmxlbmd0aCxvPXUuWCxuPTA7bjxpLmxlbmd0aDtp
+Lmxlbmd0aD09PXN8fCgwLEgubGspKGkpLCsrbil7bT1pW25dCmw9dC5jcmVhdGVFbGVtZW50KCJhIikK
+cC5hcHBlbmRDaGlsZChsKQpsLmFwcGVuZENoaWxkKHQuY3JlYXRlVGV4dE5vZGUobS5hKSkKbC5zZXRB
+dHRyaWJ1dGUoImhyZWYiLG0uYikKaz1vLmIoSC5WTShbImFkZC1oaW50LWxpbmsiLCJiZWZvcmUtYXBw
+bHkiLCJidXR0b24iXSxxKSkKaj1KLmRSKGwpCmouVjEoMCkKai5GVigwLGspfX0sCkNDOmZ1bmN0aW9u
+KGE4LGE5LGIwKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZSxkLGMsYixhLGEwLGEx
+LGEyLGEzLGE0LGE1LGE2LGE3CmZvcih0PWE4LmYscz10Lmxlbmd0aCxyPXUucyxxPXUuWCxwPXUuUSxv
+PXAuQygifigxKSIpLG49dS5NLHA9cC5kLG09MDttPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5s
+aykodCksKyttKXtsPXRbbV0Kaz1kb2N1bWVudApqPWsuY3JlYXRlRWxlbWVudCgicCIpCmk9cS5iKEgu
+Vk0oWyJ0cmFjZSJdLHIpKQpoPUouZFIoaikKaC5WMSgwKQpoLkZWKDAsaSkKZz1hOS5hcHBlbmRDaGls
+ZChqKQpqPWsuY3JlYXRlRWxlbWVudCgic3BhbiIpCmk9cS5iKEguVk0oWyJ0eXBlLWRlc2NyaXB0aW9u
+Il0scikpCmg9Si5kUihqKQpoLlYxKDApCmguRlYoMCxpKQpqLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4
+dE5vZGUobC5hKSkKZy5hcHBlbmRDaGlsZChqKQpnLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4dE5vZGUo
+IjoiKSkKaj1rLmNyZWF0ZUVsZW1lbnQoInVsIikKaT1xLmIoSC5WTShbInRyYWNlIl0scikpCmg9Si5k
+UihqKQpoLlYxKDApCmguRlYoMCxpKQpmPWcuYXBwZW5kQ2hpbGQoaikKZm9yKGo9bC5iLGk9ai5sZW5n
+dGgsZT0wO2U8ai5sZW5ndGg7ai5sZW5ndGg9PT1pfHwoMCxILmxrKShqKSwrK2Upe2Q9altlXQpjPWsu
+Y3JlYXRlRWxlbWVudCgibGkiKQpmLmFwcGVuZENoaWxkKGMpCmI9ay5jcmVhdGVFbGVtZW50KCJzcGFu
+IikKYT1xLmIoSC5WTShbImZ1bmN0aW9uIl0scikpCmg9Si5kUihiKQpoLlYxKDApCmguRlYoMCxhKQph
+PWQuYgpMLmtEKGIsYT09bnVsbD8idW5rbm93biI6YSkKYy5hcHBlbmRDaGlsZChiKQphMD1kLmMKaWYo
+YTAhPW51bGwpe2MuYXBwZW5kQ2hpbGQoay5jcmVhdGVUZXh0Tm9kZSgiICgiKSkKYTE9YTAuYgphMj1r
+LmNyZWF0ZUVsZW1lbnQoImEiKQphMi5hcHBlbmRDaGlsZChrLmNyZWF0ZVRleHROb2RlKEguZChhMC5j
+KSsiOiIrSC5kKGExKSkpCmEyLnNldEF0dHJpYnV0ZSgiaHJlZiIsYTAuYSkKYTIuY2xhc3NMaXN0LmFk
+ZCgibmF2LWxpbmsiKQpjLmFwcGVuZENoaWxkKGEyKQpjLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4dE5v
+ZGUoIikiKSl9Yy5hcHBlbmRDaGlsZChrLmNyZWF0ZVRleHROb2RlKCI6ICIpKQpiPWQuYQpMLmtEKGMs
+Yj09bnVsbD8idW5rbm93biI6YikKYj1kLmQKaWYoYi5sZW5ndGghPT0wKXthPWsuY3JlYXRlRWxlbWVu
+dCgicCIpCmEzPXEuYihILlZNKFsiZHJhd2VyIiwiYmVmb3JlLWFwcGx5Il0scikpCmg9Si5kUihhKQpo
+LlYxKDApCmguRlYoMCxhMykKYTQ9Yy5hcHBlbmRDaGlsZChhKQpmb3IoYT1iLmxlbmd0aCxhNT0wO2E1
+PGIubGVuZ3RoO2IubGVuZ3RoPT09YXx8KDAsSC5saykoYiksKythNSl7YTY9YlthNV0KYTM9ay5jcmVh
+dGVFbGVtZW50KCJidXR0b24iKQphNz1vLmIobmV3IEwuQVMoYTYsYTApKQpuLmIobnVsbCkKVy5KRShh
+MywiY2xpY2siLGE3LCExLHApCmEzLmFwcGVuZENoaWxkKGsuY3JlYXRlVGV4dE5vZGUoTS5PWChhNi5h
+KSkpCmE0LmFwcGVuZENoaWxkKGEzKX19fX19LAprRDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj1ILlZN
+KGIuc3BsaXQoIi4iKSx1LnMpLHE9Qy5ObS5ndEgocikscD1kb2N1bWVudAphLmFwcGVuZENoaWxkKHAu
+Y3JlYXRlVGV4dE5vZGUocSkpCmZvcihxPUgucUMociwxLG51bGwsdS5OKSxxPW5ldyBILmE3KHEscS5n
+QShxKSxxLiR0aS5DKCJhNzxhTC5FPiIpKSx0PUouUkUoYSk7cS5GKCk7KXtzPXEuZAp0Lm56KGEsImJl
+Zm9yZWVuZCIsIiYjODIwMzsuIixudWxsLG51bGwpCmEuYXBwZW5kQ2hpbGQocC5jcmVhdGVUZXh0Tm9k
+ZShzKSl9fSwKZTpmdW5jdGlvbiBlKCl7fSwKVlc6ZnVuY3Rpb24gVlcoYSxiLGMpe3RoaXMuYT1hCnRo
+aXMuYj1iCnRoaXMuYz1jfSwKb1o6ZnVuY3Rpb24gb1ooKXt9LApqcjpmdW5jdGlvbiBqcigpe30sCnFs
+OmZ1bmN0aW9uIHFsKCl7fSwKeTg6ZnVuY3Rpb24geTgoKXt9LApIaTpmdW5jdGlvbiBIaSgpe30sCkJU
+OmZ1bmN0aW9uIEJUKCl7fSwKTDpmdW5jdGlvbiBMKCl7fSwKV3g6ZnVuY3Rpb24gV3goYSxiKXt0aGlz
+LmE9YQp0aGlzLmI9Yn0sCkFPOmZ1bmN0aW9uIEFPKGEpe3RoaXMuYT1hfSwKZE46ZnVuY3Rpb24gZE4o
+YSl7dGhpcy5hPWF9LApIbzpmdW5jdGlvbiBIbyhhKXt0aGlzLmE9YX0sCnh6OmZ1bmN0aW9uIHh6KGEs
+Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApJQzpmdW5jdGlvbiBJQygpe30sCmZDOmZ1bmN0aW9uIGZDKGEs
+Yil7dGhpcy5hPWEKdGhpcy5iPWJ9LApuVDpmdW5jdGlvbiBuVChhLGIsYyl7dGhpcy5hPWEKdGhpcy5i
+PWIKdGhpcy5jPWN9LApCWjpmdW5jdGlvbiBCWihhKXt0aGlzLmE9YX0sCkdIOmZ1bmN0aW9uIEdIKCl7
+fSwKRUU6ZnVuY3Rpb24gRUUoYSxiLGMpe3RoaXMuYT1hCnRoaXMuYj1iCnRoaXMuYz1jfSwKUUw6ZnVu
+Y3Rpb24gUUwoYSxiKXt0aGlzLmE9YQp0aGlzLmI9Yn0sClZTOmZ1bmN0aW9uIFZTKGEpe3RoaXMuYT1h
+fSwKVEQ6ZnVuY3Rpb24gVEQoKXt9LApBUzpmdW5jdGlvbiBBUyhhLGIpe3RoaXMuYT1hCnRoaXMuYj1i
+fSwKWEE6ZnVuY3Rpb24gWEEoKXt9LAptSzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbj1ILlZN
+KFtdLHUuZmgpCmZvcih0PUouSVQodS5SLmIoYSkpO3QuRigpOyl7cz10LmdsKCkKcj1KLlU2KHMpCnE9
+TC5wMihILmMwKHIucShzLCJ0eXBlIikpKQpwPUguYzAoci5xKHMsIm5hbWUiKSkKbz1yLnEocywic3Vi
+dHJlZSIpCm89bz09bnVsbD9udWxsOkwubUsobykKQy5ObS5pKG4sbmV3IEwuWloocSxwLG8sSC5jMChy
+LnEocywicGF0aCIpKSxILmMwKHIucShzLCJocmVmIikpLEguV1koci5xKHMsImVkaXRDb3VudCIpKSkp
+fXJldHVybiBufSwKVkQ6ZnVuY3Rpb24oYSl7dmFyIHQscyxyPUguVk0oW10sdS5KKQpmb3IodD1hLmxl
+bmd0aCxzPTA7czxhLmxlbmd0aDthLmxlbmd0aD09PXR8fCgwLEgubGspKGEpLCsrcylDLk5tLmkocixh
+W3NdLkx0KCkpCnJldHVybiByfSwKcDI6ZnVuY3Rpb24oYSl7c3dpdGNoKGEpe2Nhc2UiZGlyZWN0b3J5
+IjpyZXR1cm4gQy5ZMgpjYXNlImZpbGUiOnJldHVybiBDLnJmCmRlZmF1bHQ6dGhyb3cgSC5iKFAuUFYo
+IlVucmVjb2duaXplZCBuYXZpZ2F0aW9uIHRyZWUgbm9kZSB0eXBlOiAiK0guZChhKSkpfX0sCnZ5OmZ1
+bmN0aW9uKGEpe3N3aXRjaChhKXtjYXNlIEMuWTI6cmV0dXJuImRpcmVjdG9yeSIKY2FzZSBDLnJmOnJl
+dHVybiJmaWxlIn10aHJvdyBILmIoUC5QVigiVW5yZWNvZ25pemVkIG5hdmlnYXRpb24gdHJlZSBub2Rl
+IHR5cGU6ICIrYS53KDApKSl9LApaWjpmdW5jdGlvbiBaWihhLGIsYyxkLGUsZil7dmFyIF89dGhpcwpf
+LmE9YQpfLmI9YgpfLmM9YwpfLmQ9ZApfLmU9ZQpfLmY9Zn0sCk85OmZ1bmN0aW9uIE85KGEpe3RoaXMu
+Yj1hfSwKSVY6ZnVuY3Rpb24gSVYoYSxiLGMsZCl7dmFyIF89dGhpcwpfLmQ9YQpfLmU9YgpfLmY9Ywpf
+LnI9ZH19LFg9ewpDTDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbz1iLnhaKGEpCmIuaEsoYSkK
+aWYobyE9bnVsbClhPUouS1YoYSxvLmxlbmd0aCkKdD11LnMKcz1ILlZNKFtdLHQpCnI9SC5WTShbXSx0
+KQp0PWEubGVuZ3RoCmlmKHQhPT0wJiZiLnI0KEMueEIuVyhhLDApKSl7aWYoMD49dClyZXR1cm4gSC5P
+SChhLDApCkMuTm0uaShyLGFbMF0pCnE9MX1lbHNle0MuTm0uaShyLCIiKQpxPTB9Zm9yKHA9cTtwPHQ7
+KytwKWlmKGIucjQoQy54Qi5XKGEscCkpKXtDLk5tLmkocyxDLnhCLk5qKGEscSxwKSkKQy5ObS5pKHIs
+YVtwXSkKcT1wKzF9aWYocTx0KXtDLk5tLmkocyxDLnhCLkcoYSxxKSkKQy5ObS5pKHIsIiIpfXJldHVy
+biBuZXcgWC5XRChiLG8scyxyKX0sCldEOmZ1bmN0aW9uIFdEKGEsYixjLGQpe3ZhciBfPXRoaXMKXy5h
+PWEKXy5iPWIKXy5kPWMKXy5lPWR9LApJNzpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFguZHYoYSl9LApk
+djpmdW5jdGlvbiBkdihhKXt0aGlzLmE9YX19LE89ewpSaDpmdW5jdGlvbigpe3ZhciB0LHM9bnVsbApp
+ZihQLnVvKCkuZ0ZpKCkhPT0iZmlsZSIpcmV0dXJuICQuRWIoKQp0PVAudW8oKQppZighQy54Qi5UYyh0
+LmdJaSh0KSwiLyIpKXJldHVybiAkLkViKCkKaWYoUC5LTChzLCJhL2IiLHMscyxzLHMscykudDQoKT09
+PSJhXFxiIilyZXR1cm4gJC5LaygpCnJldHVybiAkLmJEKCl9LAp6TDpmdW5jdGlvbiB6TCgpe319LEU9
+e09GOmZ1bmN0aW9uIE9GKGEsYixjKXt0aGlzLmQ9YQp0aGlzLmU9Ygp0aGlzLmY9Y319LEY9e3J1OmZ1
+bmN0aW9uIHJ1KGEsYixjLGQpe3ZhciBfPXRoaXMKXy5kPWEKXy5lPWIKXy5mPWMKXy5yPWR9fSxEPXsK
+Ulg6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPW51bGwKdHJ5e3A9UC51bygpfWNhdGNoKHQpe2lmKHUu
+ZzguYyhILlJ1KHQpKSl7cz0kLkZmCmlmKHMhPW51bGwpcmV0dXJuIHMKdGhyb3cgdH1lbHNlIHRocm93
+IHR9aWYoSi5STShwLCQuSTYpKXJldHVybiAkLkZmCiQuSTY9cAppZigkLkhrKCk9PSQuRWIoKSlzPSQu
+RmY9cC5aSSgiLiIpLncoMCkKZWxzZXtyPXAudDQoKQpxPXIubGVuZ3RoLTEKcz0kLkZmPXE9PT0wP3I6
+Qy54Qi5OaihyLDAscSl9cmV0dXJuIHN9fQp2YXIgdz1bQyxILEosUCxXLE0sVSxCLFQsTCxYLE8sRSxG
+LERdCmh1bmtIZWxwZXJzLnNldEZ1bmN0aW9uTmFtZXNJZk5lY2Vzc2FyeSh3KQp2YXIgJD17fQpILmVv
+LnByb3RvdHlwZT17fQpKLnZCLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PT1i
+fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKGEpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4iSW5z
+dGFuY2Ugb2YgJyIrSC5kKEguTShhKSkrIicifSwKZTc6ZnVuY3Rpb24oYSxiKXt1Lm8uYihiKQp0aHJv
+dyBILmIoUC5scihhLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9fQpKLnlFLnByb3RvdHlwZT17Cnc6
+ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX0sCmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gYT81MTkw
+MTg6MjE4MTU5fSwKJGlhMjoxfQpKLllFLnByb3RvdHlwZT17CkROOmZ1bmN0aW9uKGEsYil7cmV0dXJu
+IG51bGw9PWJ9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiJudWxsIn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1
+cm4gMH0sCmU3OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU2ooYSx1Lm8uYihiKSl9LAokaWM4OjF9
+CkouTUYucHJvdG90eXBlPXsKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiAwfSwKdzpmdW5jdGlvbihhKXty
+ZXR1cm4gU3RyaW5nKGEpfSwKJGl2bToxfQpKLmlDLnByb3RvdHlwZT17fQpKLmtkLnByb3RvdHlwZT17
+fQpKLmM1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9YVskLncoKV0KaWYodD09bnVsbCly
+ZXR1cm4gdGhpcy50KGEpCnJldHVybiJKYXZhU2NyaXB0IGZ1bmN0aW9uIGZvciAiK0guZChKLmoodCkp
+fSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm57ZnVuYzoxLG9wdDpbLCwsLCwsLCwsLCwsLCwsLF19fSwKJGlF
+SDoxfQpKLmpkLnByb3RvdHlwZT17Cmk6ZnVuY3Rpb24oYSxiKXtILnQ2KGEpLmQuYihiKQppZighIWEu
+Zml4ZWQkbGVuZ3RoKUgudmgoUC5MNCgiYWRkIikpCmEucHVzaChiKX0sClc0OmZ1bmN0aW9uKGEsYil7
+dmFyIHQKaWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInJlbW92ZUF0IikpCnQ9YS5sZW5ndGgK
+aWYoYj49dCl0aHJvdyBILmIoUC54KGIsbnVsbCkpCnJldHVybiBhLnNwbGljZShiLDEpWzBdfSwKVUc6
+ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscgpILnQ2KGEpLkMoImNYPDE+IikuYihjKQppZighIWEuZml4
+ZWQkbGVuZ3RoKUgudmgoUC5MNCgiaW5zZXJ0QWxsIikpCnQ9YS5sZW5ndGgKUC53QShiLDAsdCwiaW5k
+ZXgiKQpzPWMubGVuZ3RoCnRoaXMuc0EoYSx0K3MpCnI9YitzCnRoaXMuWVcoYSxyLGEubGVuZ3RoLGEs
+YikKdGhpcy52ZyhhLGIscixjKX0sCm12OmZ1bmN0aW9uKGEpe2lmKCEhYS5maXhlZCRsZW5ndGgpSC52
+aChQLkw0KCJyZW1vdmVMYXN0IikpCmlmKGEubGVuZ3RoPT09MCl0aHJvdyBILmIoSC5IWShhLC0xKSkK
+cmV0dXJuIGEucG9wKCl9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0CkgudDYoYSkuQygiY1g8MT4iKS5i
+KGIpCmlmKCEhYS5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJhZGRBbGwiKSkKZm9yKHQ9Si5JVChiKTt0
+LkYoKTspYS5wdXNoKHQuZ2woKSl9LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoIn4o
+MSkiKS5iKGIpCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKXtiLiQxKGFbc10pCmlmKGEubGVuZ3Ro
+IT09dCl0aHJvdyBILmIoUC5hNChhKSl9fSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgudDYoYSkK
+cmV0dXJuIG5ldyBILkE4KGEsdC5LcShjKS5DKCIxKDIpIikuYihiKSx0LkMoIkA8MT4iKS5LcShjKS5D
+KCJBODwxLDI+IikpfSwKSDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9bmV3IEFycmF5KGEubGVuZ3RoKQpz
+LmZpeGVkJGxlbmd0aD1BcnJheQpmb3IodD0wO3Q8YS5sZW5ndGg7Kyt0KXRoaXMuWShzLHQsSC5kKGFb
+dF0pKQpyZXR1cm4gcy5qb2luKGIpfSwKTjA6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmQuYihi
+KQpILnQ2KGEpLktxKGQpLkMoIjEoMSwyKSIpLmIoYykKdD1hLmxlbmd0aApmb3Iocz1iLHI9MDtyPHQ7
+KytyKXtzPWMuJDIocyxhW3JdKQppZihhLmxlbmd0aCE9PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVy
+biBzfSwKSHQ6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG89SC50NihhKQpvLkMoImEyKDEpIiku
+YihiKQpvLkMoIjEoKSIpLmIobnVsbCkKdD1hLmxlbmd0aApmb3Iocz1udWxsLHI9ITEscT0wO3E8dDsr
+K3Epe3A9YVtxXQppZihILm9UKGIuJDEocCkpKXtpZihyKXRocm93IEguYihILmRVKCkpCnM9cApyPSEw
+fWlmKHQhPT1hLmxlbmd0aCl0aHJvdyBILmIoUC5hNChhKSl9aWYocilyZXR1cm4gcwp0aHJvdyBILmIo
+SC5XcCgpKX0sCkU6ZnVuY3Rpb24oYSxiKXtpZihiPDB8fGI+PWEubGVuZ3RoKXJldHVybiBILk9IKGEs
+YikKcmV0dXJuIGFbYl19LApENjpmdW5jdGlvbihhLGIsYyl7aWYoYjwwfHxiPmEubGVuZ3RoKXRocm93
+IEguYihQLlRFKGIsMCxhLmxlbmd0aCwic3RhcnQiLG51bGwpKQppZihjPGJ8fGM+YS5sZW5ndGgpdGhy
+b3cgSC5iKFAuVEUoYyxiLGEubGVuZ3RoLCJlbmQiLG51bGwpKQppZihiPT09YylyZXR1cm4gSC5WTShb
+XSxILnQ2KGEpKQpyZXR1cm4gSC5WTShhLnNsaWNlKGIsYyksSC50NihhKSl9LApndEg6ZnVuY3Rpb24o
+YSl7aWYoYS5sZW5ndGg+MClyZXR1cm4gYVswXQp0aHJvdyBILmIoSC5XcCgpKX0sCmdyWjpmdW5jdGlv
+bihhKXt2YXIgdD1hLmxlbmd0aAppZih0PjApcmV0dXJuIGFbdC0xXQp0aHJvdyBILmIoSC5XcCgpKX0s
+CllXOmZ1bmN0aW9uKGEsYixjLGQsZSl7dmFyIHQscyxyPUgudDYoYSkKci5DKCJjWDwxPiIpLmIoZCkK
+aWYoISFhLmltbXV0YWJsZSRsaXN0KUgudmgoUC5MNCgic2V0UmFuZ2UiKSkKUC5qQihiLGMsYS5sZW5n
+dGgpCnQ9Yy1iCmlmKHQ9PT0wKXJldHVybgpQLmsxKGUsInNraXBDb3VudCIpCnIuQygiek08MT4iKS5i
+KGQpCnI9Si5VNihkKQppZihlK3Q+ci5nQShkKSl0aHJvdyBILmIoSC5hcigpKQppZihlPGIpZm9yKHM9
+dC0xO3M+PTA7LS1zKWFbYitzXT1yLnEoZCxlK3MpCmVsc2UgZm9yKHM9MDtzPHQ7KytzKWFbYitzXT1y
+LnEoZCxlK3MpfSwKdmc6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIHRoaXMuWVcoYSxiLGMsZCwwKX0s
+ClZyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILnQ2KGEpLkMoImEyKDEpIikuYihiKQp0PWEubGVuZ3Ro
+CmZvcihzPTA7czx0Oysrcyl7aWYoSC5vVChiLiQxKGFbc10pKSlyZXR1cm4hMAppZihhLmxlbmd0aCE9
+PXQpdGhyb3cgSC5iKFAuYTQoYSkpfXJldHVybiExfSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdApmb3Io
+dD0wO3Q8YS5sZW5ndGg7Kyt0KWlmKEouUk0oYVt0XSxiKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsMDpm
+dW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGg9PT0wfSwKZ29yOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxl
+bmd0aCE9PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9LApna3o6ZnVuY3Rp
+b24oYSl7cmV0dXJuIG5ldyBKLm0xKGEsYS5sZW5ndGgsSC50NihhKS5DKCJtMTwxPiIpKX0sCmdpTzpm
+dW5jdGlvbihhKXtyZXR1cm4gSC5lUShhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0s
+CnNBOmZ1bmN0aW9uKGEsYil7aWYoISFhLmZpeGVkJGxlbmd0aClILnZoKFAuTDQoInNldCBsZW5ndGgi
+KSkKaWYoYjwwKXRocm93IEguYihQLlRFKGIsMCxudWxsLCJuZXdMZW5ndGgiLG51bGwpKQphLmxlbmd0
+aD1ifSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fGI8MCl0aHJvdyBILmIo
+SC5IWShhLGIpKQpyZXR1cm4gYVtiXX0sClk6ZnVuY3Rpb24oYSxiLGMpe0gudDYoYSkuZC5iKGMpCmlm
+KCEhYS5pbW11dGFibGUkbGlzdClILnZoKFAuTDQoImluZGV4ZWQgc2V0IikpCmlmKGI+PWEubGVuZ3Ro
+fHxiPDApdGhyb3cgSC5iKEguSFkoYSxiKSkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0K
+Si5Qby5wcm90b3R5cGU9e30KSi5tMS5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlz
+LmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9cy5hLHE9ci5sZW5ndGgKaWYocy5iIT09cSl0
+aHJvdyBILmIoSC5sayhyKSkKdD1zLmMKaWYodD49cSl7cy5zTShudWxsKQpyZXR1cm4hMX1zLnNNKHJb
+dF0pOysrcy5jCnJldHVybiEwfSwKc006ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihhKX0s
+CiRpQW46MX0KSi5xSS5wcm90b3R5cGU9ewp5dTpmdW5jdGlvbihhKXt2YXIgdAppZihhPj0tMjE0NzQ4
+MzY0OCYmYTw9MjE0NzQ4MzY0NylyZXR1cm4gYXwwCmlmKGlzRmluaXRlKGEpKXt0PWE8MD9NYXRoLmNl
+aWwoYSk6TWF0aC5mbG9vcihhKQpyZXR1cm4gdCswfXRocm93IEguYihQLkw0KCIiK2ErIi50b0ludCgp
+IikpfSwKelE6ZnVuY3Rpb24oYSl7aWYoYT4wKXtpZihhIT09MS8wKXJldHVybiBNYXRoLnJvdW5kKGEp
+fWVsc2UgaWYoYT4tMS8wKXJldHVybiAwLU1hdGgucm91bmQoMC1hKQp0aHJvdyBILmIoUC5MNCgiIith
+KyIucm91bmQoKSIpKX0sCldaOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKaWYoYjwyfHxiPjM2KXRo
+cm93IEguYihQLlRFKGIsMiwzNiwicmFkaXgiLG51bGwpKQp0PWEudG9TdHJpbmcoYikKaWYoQy54Qi5t
+KHQsdC5sZW5ndGgtMSkhPT00MSlyZXR1cm4gdApzPS9eKFtcZGEtel0rKSg/OlwuKFtcZGEtel0rKSk/
+XChlXCsoXGQrKVwpJC8uZXhlYyh0KQppZihzPT1udWxsKUgudmgoUC5MNCgiVW5leHBlY3RlZCB0b1N0
+cmluZyByZXN1bHQ6ICIrdCkpCnI9cy5sZW5ndGgKaWYoMT49cilyZXR1cm4gSC5PSChzLDEpCnQ9c1sx
+XQppZigzPj1yKXJldHVybiBILk9IKHMsMykKcT0rc1szXQpyPXNbMl0KaWYociE9bnVsbCl7dCs9cgpx
+LT1yLmxlbmd0aH1yZXR1cm4gdCtDLnhCLkl4KCIwIixxKX0sCnc6ZnVuY3Rpb24oYSl7aWYoYT09PTAm
+JjEvYTwwKXJldHVybiItMC4wIgplbHNlIHJldHVybiIiK2F9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyLHEscD1hfDAKaWYoYT09PXApcmV0dXJuIDUzNjg3MDkxMSZwCnQ9TWF0aC5hYnMoYSkKcz1NYXRo
+LmxvZyh0KS8wLjY5MzE0NzE4MDU1OTk0NTN8MApyPU1hdGgucG93KDIscykKcT10PDE/dC9yOnIvdApy
+ZXR1cm4gNTM2ODcwOTExJigocSo5MDA3MTk5MjU0NzQwOTkyfDApKyhxKjM1NDIyNDMxODExNzY1MjF8
+MCkpKjU5OTE5NytzKjEyNTl9LAp6WTpmdW5jdGlvbihhLGIpe3ZhciB0PWElYgppZih0PT09MClyZXR1
+cm4gMAppZih0PjApcmV0dXJuIHQKaWYoYjwwKXJldHVybiB0LWIKZWxzZSByZXR1cm4gdCtifSwKd0c6
+ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPjApdD10aGlzLnAzKGEsYikKZWxzZXt0PWI+MzE/MzE6Ygp0
+PWE+PnQ+Pj4wfXJldHVybiB0fSwKYmY6ZnVuY3Rpb24oYSxiKXtpZihiPDApdGhyb3cgSC5iKEgudEwo
+YikpCnJldHVybiB0aGlzLnAzKGEsYil9LApwMzpmdW5jdGlvbihhLGIpe3JldHVybiBiPjMxPzA6YT4+
+PmJ9LAokaUNQOjEsCiRpRks6MX0KSi5iVS5wcm90b3R5cGU9eyRpS046MX0KSi5WQS5wcm90b3R5cGU9
+e30KSi5Eci5wcm90b3R5cGU9ewptOmZ1bmN0aW9uKGEsYil7aWYoYjwwKXRocm93IEguYihILkhZKGEs
+YikpCmlmKGI+PWEubGVuZ3RoKUgudmgoSC5IWShhLGIpKQpyZXR1cm4gYS5jaGFyQ29kZUF0KGIpfSwK
+VzpmdW5jdGlvbihhLGIpe2lmKGI+PWEubGVuZ3RoKXRocm93IEguYihILkhZKGEsYikpCnJldHVybiBh
+LmNoYXJDb2RlQXQoYil9LApkZDpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgSC51bihiLGEsMCl9LApo
+OmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciKXRocm93IEguYihQLkwzKGIsbnVsbCxu
+dWxsKSkKcmV0dXJuIGErYn0sClRjOmZ1bmN0aW9uKGEsYil7dmFyIHQ9Yi5sZW5ndGgscz1hLmxlbmd0
+aAppZih0PnMpcmV0dXJuITEKcmV0dXJuIGI9PT10aGlzLkcoYSxzLXQpfSwKaTc6ZnVuY3Rpb24oYSxi
+LGMsZCl7dmFyIHQscwpjPVAuakIoYixjLGEubGVuZ3RoKQp0PWEuc3Vic3RyaW5nKDAsYikKcz1hLnN1
+YnN0cmluZyhjKQpyZXR1cm4gdCtkK3N9LApRaTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKaWYoIUgub2so
+YykpSC52aChILnRMKGMpKQppZih0eXBlb2YgYyE9PSJudW1iZXIiKXJldHVybiBjLkooKQppZihjPDB8
+fGM+YS5sZW5ndGgpdGhyb3cgSC5iKFAuVEUoYywwLGEubGVuZ3RoLG51bGwsbnVsbCkpCnQ9YytiLmxl
+bmd0aAppZih0PmEubGVuZ3RoKXJldHVybiExCnJldHVybiBiPT09YS5zdWJzdHJpbmcoYyx0KX0sCm46
+ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5RaShhLGIsMCl9LApOajpmdW5jdGlvbihhLGIsYyl7aWYo
+IUgub2soYikpSC52aChILnRMKGIpKQppZihjPT1udWxsKWM9YS5sZW5ndGgKaWYodHlwZW9mIGIhPT0i
+bnVtYmVyIilyZXR1cm4gYi5KKCkKaWYoYjwwKXRocm93IEguYihQLngoYixudWxsKSkKaWYoYj5jKXRo
+cm93IEguYihQLngoYixudWxsKSkKaWYoYz5hLmxlbmd0aCl0aHJvdyBILmIoUC54KGMsbnVsbCkpCnJl
+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
+dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKaWYoYj49YS5sZW5ndGh8fCExKXRo
+cm93IEguYihILkhZKGEsYikpCnJldHVybiBhW2JdfSwKJGl2WDoxLAokaXFVOjF9CkgucWoucHJvdG90
+eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7
+cmV0dXJuIEMueEIubSh0aGlzLmEsSC5TYyhiKSl9fQpILmJRLnByb3RvdHlwZT17fQpILmFMLnByb3Rv
+dHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzCnJldHVybiBuZXcgSC5hNyh0LHQuZ0EodCks
+SC5MaCh0KS5DKCJhNzxhTC5FPiIpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQSh0aGlz
+KT09PTB9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9dGhpcyxwPXEuZ0EocSkKaWYoYi5sZW5n
+dGghPT0wKXtpZihwPT09MClyZXR1cm4iIgp0PUguZChxLkUoMCwwKSkKaWYocCE9PXEuZ0EocSkpdGhy
+b3cgSC5iKFAuYTQocSkpCmZvcihzPXQscj0xO3I8cDsrK3Ipe3M9cytiK0guZChxLkUoMCxyKSkKaWYo
+cCE9PXEuZ0EocSkpdGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpz
+fWVsc2V7Zm9yKHI9MCxzPSIiO3I8cDsrK3Ipe3MrPUguZChxLkUoMCxyKSkKaWYocCE9PXEuZ0EocSkp
+dGhyb3cgSC5iKFAuYTQocSkpfXJldHVybiBzLmNoYXJDb2RlQXQoMCk9PTA/czpzfX0sCmV2OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIHRoaXMuR0coMCxILkxoKHRoaXMpLkMoImEyKGFMLkUpIikuYihiKSl9LApF
+MjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguQTgodGhpcyx0Lktx
+KGMpLkMoIjEoYUwuRSkiKS5iKGIpLHQuQygiQDxhTC5FPiIpLktxKGMpLkMoIkE4PDEsMj4iKSl9LAp0
+dDpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPUguVk0oW10sSC5MaChzKS5DKCJqZDxhTC5FPiIp
+KQpDLk5tLnNBKHIscy5nQShzKSkKZm9yKHQ9MDt0PHMuZ0Eocyk7Kyt0KUMuTm0uWShyLHQscy5FKDAs
+dCkpCnJldHVybiByfSwKYnI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudHQoYSwhMCl9fQpILm5ILnBy
+b3RvdHlwZT17CmdVRDpmdW5jdGlvbigpe3ZhciB0PUouSG0odGhpcy5hKSxzPXRoaXMuYwppZihzPT1u
+dWxsfHxzPnQpcmV0dXJuIHQKcmV0dXJuIHN9LApnQXM6ZnVuY3Rpb24oKXt2YXIgdD1KLkhtKHRoaXMu
+YSkscz10aGlzLmIKaWYocz50KXJldHVybiB0CnJldHVybiBzfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQs
+cz1KLkhtKHRoaXMuYSkscj10aGlzLmIKaWYocj49cylyZXR1cm4gMAp0PXRoaXMuYwppZih0PT1udWxs
+fHx0Pj1zKXJldHVybiBzLXIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5ITigpCnJldHVy
+biB0LXJ9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLHI9cy5nQXMoKStiCmlmKGI+PTApe3Q9
+cy5nVUQoKQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiBILnBZKHQpCnQ9cj49dH1lbHNlIHQ9
+ITAKaWYodCl0aHJvdyBILmIoUC5DZihiLHMsImluZGV4IixudWxsLG51bGwpKQpyZXR1cm4gSi5HQShz
+LmEscil9fQpILmE3LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZH0sCkY6ZnVu
+Y3Rpb24oKXt2YXIgdCxzPXRoaXMscj1zLmEscT1KLlU2KHIpLHA9cS5nQShyKQppZihzLmIhPT1wKXRo
+cm93IEguYihQLmE0KHIpKQp0PXMuYwppZih0Pj1wKXtzLnNJKG51bGwpCnJldHVybiExfXMuc0kocS5F
+KHIsdCkpOysrcy5jCnJldHVybiEwfSwKc0k6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmQuYihh
+KX0sCiRpQW46MX0KSC5pMS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9SC5MaCh0aGlz
+KQpyZXR1cm4gbmV3IEguTUgoSi5JVCh0aGlzLmEpLHRoaXMuYix0LkMoIkA8MT4iKS5LcSh0LmNoWzFd
+KS5DKCJNSDwxLDI+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIEouSG0odGhpcy5hKX19CkgueHku
 cHJvdG90eXBlPXskaWJROjF9CkguTUgucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMs
 cz10LmIKaWYocy5GKCkpe3Quc0kodC5jLiQxKHMuZ2woKSkpCnJldHVybiEwfXQuc0kobnVsbCkKcmV0
 dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmF9LApzSTpmdW5jdGlvbihhKXt0aGlzLmE9
-dGhpcy4kdGkuUVsxXS5hKGEpfX0KSC5sSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-Si5IKHRoaXMuYSl9LApFOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYi4kMShKLkdBKHRoaXMuYSxi
-KSl9fQpILlU1LnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IEgudkcoSi5JVCh0
-aGlzLmEpLHRoaXMuYix0aGlzLiR0aS5DKCJ2RzwxPiIpKX19CkgudkcucHJvdG90eXBlPXsKRjpmdW5j
-dGlvbigpe3ZhciB0LHMKZm9yKHQ9dGhpcy5hLHM9dGhpcy5iO3QuRigpOylpZihILm9UKHMuJDEodC5n
-bCgpKSkpcmV0dXJuITAKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmEuZ2woKX19
-CkguU1UucHJvdG90eXBlPXt9CkguUmUucHJvdG90eXBlPXsKWTpmdW5jdGlvbihhLGIsYyl7SC5MaCh0
-aGlzKS5DKCJSZS5FIikuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBhbiB1bm1vZGlm
-aWFibGUgbGlzdCIpKX19CkgudzIucHJvdG90eXBlPXt9Ckgud3YucHJvdG90eXBlPXsKZ2lPOmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuX2hhc2hDb2RlCmlmKHQhPW51bGwpcmV0dXJuIHQKdD01MzY4NzA5MTEm
-NjY0NTk3KkouaGYodGhpcy5hKQp0aGlzLl9oYXNoQ29kZT10CnJldHVybiB0fSwKWjpmdW5jdGlvbihh
-KXtyZXR1cm4nU3ltYm9sKCInK0guZCh0aGlzLmEpKyciKSd9LApETjpmdW5jdGlvbihhLGIpe2lmKGI9
-PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBILnd2JiZ0aGlzLmE9PWIuYX0sCiRpR0Q6
-MX0KSC5QRC5wcm90b3R5cGU9e30KSC5XVS5wcm90b3R5cGU9ewpnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ0EodGhpcyk9PT0wfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sClk6ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdC5jLmEoYikKdC5RWzFdLmEoYykKcmV0dXJuIEgu
-ZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xNChhLEguTGgodGhpcykuQygiTjM8MSwy
-PiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpyZXR1cm4gUC5sMChmdW5jdGlvbigpe3Zh
-ciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbQpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQpe2lm
-KGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8uZ2t6
-KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uUVsxXSkuQygiTjM8MSwyPiIpCmNhc2UgMjpp
-Zighby5GKCkpe3I9MwpicmVha31tPW8uZ2woKQpyPTQKcmV0dXJuIG5ldyBQLk4zKG0sdC5xKDAsbSks
-bikKY2FzZSA0OnI9MgpicmVhawpjYXNlIDM6cmV0dXJuIFAuVGgoKQpjYXNlIDE6cmV0dXJuIFAuWW0o
-cCl9fX0sYil9LAokaVowOjF9CkguTFAucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
-aXMuYX0sCng0OmZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBhIT0ic3RyaW5nIilyZXR1cm4hMQppZigiX19w
-cm90b19fIj09PWEpcmV0dXJuITEKcmV0dXJuIHRoaXMuYi5oYXNPd25Qcm9wZXJ0eShhKX0sCnE6ZnVu
-Y3Rpb24oYSxiKXtpZighdGhpcy54NChiKSlyZXR1cm4gbnVsbApyZXR1cm4gdGhpcy5EKGIpfSwKRDpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iW0guYyhhKV19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxy
-LHEscD1ILkxoKHRoaXMpCnAuQygifigxLDIpIikuYShiKQp0PXRoaXMuYwpmb3Iocz10Lmxlbmd0aCxw
-PXAuUVsxXSxyPTA7cjxzOysrcil7cT10W3JdCmIuJDIocSxwLmEodGhpcy5EKHEpKSl9fSwKZ1Y6ZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IEguWFIodGhpcyxILkxoKHRoaXMpLkMoIlhSPDE+IikpfX0KSC5YUi5w
-cm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmMKcmV0dXJuIG5ldyBKLm0xKHQs
-dC5sZW5ndGgsSC50Nih0KS5DKCJtMTwxPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEu
-Yy5sZW5ndGh9fQpILkxJLnByb3RvdHlwZT17CmdXYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYQpyZXR1
-cm4gdH0sCmduZDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLmM9PT0xKXJldHVybiBD
-LmhVCnQ9cC5kCnM9dC5sZW5ndGgtcC5lLmxlbmd0aC1wLmYKaWYocz09PTApcmV0dXJuIEMuaFUKcj1b
-XQpmb3IocT0wO3E8czsrK3Epe2lmKHE+PXQubGVuZ3RoKXJldHVybiBILmsodCxxKQpyLnB1c2godFtx
-XSl9cmV0dXJuIEoudW4ocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhp
-cwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxlbmd0aC1z
-LWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxzOysrbyl7
-aWYobz49dC5sZW5ndGgpcmV0dXJuIEguayh0LG8pCm49dFtvXQptPXErbwppZihtPDB8fG0+PXIubGVu
-Z3RoKXJldHVybiBILmsocixtKQpwLlkoMCxuZXcgSC53dihuKSxyW21dKX1yZXR1cm4gbmV3IEguUEQo
-cCx1LmdGKX0sCiRpdlE6MX0KSC5Dai5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0Ckgu
-YyhhKQp0PXRoaXMuYQp0LmI9dC5iKyIkIitILmQoYSkKQy5ObS5pKHRoaXMuYixhKQpDLk5tLmkodGhp
-cy5jLGIpOysrdC5hfSwKJFM6MTJ9CkguZjkucHJvdG90eXBlPXsKcVM6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyPXRoaXMscT1uZXcgUmVnRXhwKHIuYSkuZXhlYyhhKQppZihxPT1udWxsKXJldHVybiBudWxsCnQ9
-T2JqZWN0LmNyZWF0ZShudWxsKQpzPXIuYgppZihzIT09LTEpdC5hcmd1bWVudHM9cVtzKzFdCnM9ci5j
-CmlmKHMhPT0tMSl0LmFyZ3VtZW50c0V4cHI9cVtzKzFdCnM9ci5kCmlmKHMhPT0tMSl0LmV4cHI9cVtz
-KzFdCnM9ci5lCmlmKHMhPT0tMSl0Lm1ldGhvZD1xW3MrMV0Kcz1yLmYKaWYocyE9PS0xKXQucmVjZWl2
-ZXI9cVtzKzFdCnJldHVybiB0fX0KSC5XMC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMuYgppZih0PT1udWxsKXJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogIitILmQodGhpcy5hKQpyZXR1
-cm4iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK3QrIicgb24gbnVsbCJ9fQpI
-LmF6LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9Ik5vU3VjaE1ldGhvZEVy
-cm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIixxPXMuYgppZihxPT1udWxsKXJldHVybiJOb1N1Y2hNZXRo
-b2RFcnJvcjogIitILmQocy5hKQp0PXMuYwppZih0PT1udWxsKXJldHVybiByK3ErIicgKCIrSC5kKHMu
-YSkrIikiCnJldHVybiByK3ErIicgb24gJyIrdCsiJyAoIitILmQocy5hKSsiKSJ9fQpILnZWLnByb3Rv
-dHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0Lmxlbmd0aD09PTA/IkVycm9y
-IjoiRXJyb3I6ICIrdH19CkguYnEucHJvdG90eXBlPXt9CkguQW0ucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7aWYodS5XLmIoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClhLiR0aHJvd25Kc0Vycm9y
-PXRoaXMuYQpyZXR1cm4gYX0sCiRTOjF9CkguWE8ucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIg
-dCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9PW51bGwmJnR5cGVvZiBz
-PT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVsbD8iIjp0fSwKJGlHejox
-fQpILlRwLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1Y3RvcixzPXQ9
-PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1bmtub3duIjpz
-KSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQxIiwKJFI6MSwK
-JEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2YgdW5rbm93biBz
-dGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguankucHJvdG90eXBl
-PXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEKaWYodD09PWIp
-cmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5qeSkpcmV0dXJuITEKcmV0dXJuIHQuYT09PWIuYSYm
-dC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmMKaWYocz09
-bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhmKHMpOkguZVEo
-cykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpp
-Zih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlzLmQpKyInIG9mICIrKCJJ
-bnN0YW5jZSBvZiAnIitILmQoSC5saCh0KSkrIiciKX19CkguRXEucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iUnVudGltZUVycm9yOiAiK0guZCh0aGlzLmEpfX0KSC5rWS5wcm90b3R5cGU9ewpa
-OmZ1bmN0aW9uKGEpe3JldHVybiJBc3NlcnRpb24gZmFpbGVkOiAiK1AuaCh0aGlzLmEpfX0KSC5ONS5w
-cm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKZ2wwOmZ1bmN0aW9uKGEpe3Jl
-dHVybiB0aGlzLmE9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEguaTUodGhpcyxILkxoKHRo
-aXMpLkMoImk1PDE+IikpfSwKeDQ6ZnVuY3Rpb24oYSl7dmFyIHQscwppZih0eXBlb2YgYT09InN0cmlu
-ZyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHRoaXMuWHUodCxhKX1lbHNle3M9
-dGhpcy5DWChhKQpyZXR1cm4gc319LApDWDpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmQKaWYodD09bnVs
-bClyZXR1cm4hMQpyZXR1cm4gdGhpcy5GaCh0aGlzLkJ0KHQsSi5oZihhKSYweDNmZmZmZmYpLGEpPj0w
-fSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwKaWYodHlwZW9mIGI9PSJz
-dHJpbmciKXt0PXAuYgppZih0PT1udWxsKXJldHVybiBvCnM9cC5qMih0LGIpCnI9cz09bnVsbD9vOnMu
-YgpyZXR1cm4gcn1lbHNlIGlmKHR5cGVvZiBiPT0ibnVtYmVyIiYmKGImMHgzZmZmZmZmKT09PWIpe3E9
-cC5jCmlmKHE9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHEsYikKcj1zPT1udWxsP286cy5iCnJldHVybiBy
-fWVsc2UgcmV0dXJuIHAuYWEoYil9LAphYTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcy5kCmlmKHI9
-PW51bGwpcmV0dXJuIG51bGwKdD10aGlzLkJ0KHIsSi5oZihhKSYweDNmZmZmZmYpCnM9dGhpcy5GaCh0
-LGEpCmlmKHM8MClyZXR1cm4gbnVsbApyZXR1cm4gdFtzXS5ifSwKWTpmdW5jdGlvbihhLGIsYyl7dmFy
-IHQscyxyLHEscCxvLG49dGhpcyxtPUguTGgobikKbS5jLmEoYikKbS5RWzFdLmEoYykKaWYodHlwZW9m
-IGI9PSJzdHJpbmciKXt0PW4uYgpuLkVIKHQ9PW51bGw/bi5iPW4ueksoKTp0LGIsYyl9ZWxzZSBpZih0
-eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtzPW4uYwpuLkVIKHM9PW51bGw/bi5j
-PW4ueksoKTpzLGIsYyl9ZWxzZXtyPW4uZAppZihyPT1udWxsKXI9bi5kPW4ueksoKQpxPUouaGYoYikm
-MHgzZmZmZmZmCnA9bi5CdChyLHEpCmlmKHA9PW51bGwpbi5FSShyLHEsW24uSG4oYixjKV0pCmVsc2V7
-bz1uLkZoKHAsYikKaWYobz49MClwW29dLmI9YwplbHNlIHAucHVzaChuLkhuKGIsYykpfX19LApLOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5DKCJ+KDEsMikiKS5hKGIpCnQ9ci5lCnM9
-ci5yCmZvcig7dCE9bnVsbDspe2IuJDIodC5hLHQuYikKaWYocyE9PXIucil0aHJvdyBILmIoUC5hNChy
-KSkKdD10LmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9dGhpcyxyPUguTGgocykKci5jLmEo
-YikKci5RWzFdLmEoYykKdD1zLmoyKGEsYikKaWYodD09bnVsbClzLkVJKGEsYixzLkhuKGIsYykpCmVs
-c2UgdC5iPWN9LAprczpmdW5jdGlvbigpe3RoaXMucj10aGlzLnIrMSY2NzEwODg2M30sCkhuOmZ1bmN0
-aW9uKGEsYil7dmFyIHQscz10aGlzLHI9SC5MaChzKSxxPW5ldyBILmRiKHIuYy5hKGEpLHIuUVsxXS5h
-KGIpKQppZihzLmU9PW51bGwpcy5lPXMuZj1xCmVsc2V7dD1zLmYKcS5kPXQKcy5mPXQuYz1xfSsrcy5h
-CnMua3MoKQpyZXR1cm4gcX0sCkZoOmZ1bmN0aW9uKGEsYil7dmFyIHQscwppZihhPT1udWxsKXJldHVy
-bi0xCnQ9YS5sZW5ndGgKZm9yKHM9MDtzPHQ7KytzKWlmKEouUk0oYVtzXS5hLGIpKXJldHVybiBzCnJl
-dHVybi0xfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5uTyh0aGlzKX0sCmoyOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIGFbYl19LApCdDpmdW5jdGlvbihhLGIpe3JldHVybiBhW2JdfSwKRUk6ZnVuY3Rpb24oYSxi
-LGMpe2FbYl09Y30sCnJuOmZ1bmN0aW9uKGEsYil7ZGVsZXRlIGFbYl19LApYdTpmdW5jdGlvbihhLGIp
-e3JldHVybiB0aGlzLmoyKGEsYikhPW51bGx9LAp6SzpmdW5jdGlvbigpe3ZhciB0PSI8bm9uLWlkZW50
-aWZpZXIta2V5PiIscz1PYmplY3QuY3JlYXRlKG51bGwpCnRoaXMuRUkocyx0LHMpCnRoaXMucm4ocyx0
-KQpyZXR1cm4gc30sCiRpRm86MX0KSC5kYi5wcm90b3R5cGU9e30KSC5pNS5wcm90b3R5cGU9ewpnQTpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmF9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5h
-PT09MH0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz1uZXcgSC5ONih0LHQucix0aGlzLiR0
-aS5DKCJONjwxPiIpKQpzLmM9dC5lCnJldHVybiBzfSwKdGc6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhp
-cy5hLng0KGIpfX0KSC5ONi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9LApG
-OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYQppZih0LmIhPT1zLnIpdGhyb3cgSC5iKFAuYTQocykp
-CmVsc2V7cz10LmMKaWYocz09bnVsbCl7dC5zcVkobnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNxWShzLmEp
-CnQuYz10LmMuYwpyZXR1cm4hMH19fSwKc3FZOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlzLiR0aS5jLmEo
-YSl9LAokaUFuOjF9Ckguci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hKGEp
-fSwKJFM6MX0KSC5kQy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEoYSxi
-KX0sCiRTOjQ2fQpILndOLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEoSC5j
-KGEpKX0sCiRTOjM5fQpILlZSLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIlJlZ0V4cC8i
-K3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQuYwpp
-ZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9SC52NCh0LmEscy5tdWx0aWxpbmUsIXMu
-aWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwKZGQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4g
-bmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMuZ0hjKCkKcy5s
-YXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJldHVybiBudWxsCnJldHVybiBuZXcgSC5F
-Syh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXt2YXIg
-dApILldZKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJldHVybiBILmsodCxiKQpyZXR1cm4gdFti
-XX0sCiRpT2Q6MSwKJGlpYjoxfQpILktXLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4g
-bmV3IEguUGIodGhpcy5hLHRoaXMuYix0aGlzLmMpfX0KSC5QYi5wcm90b3R5cGU9ewpnbDpmdW5jdGlv
-bigpe3JldHVybiB0aGlzLmR9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89cC5iCmlm
-KG89PW51bGwpcmV0dXJuITEKdD1wLmMKaWYodDw9by5sZW5ndGgpe3M9cC5hCnI9cy5VWihvLHQpCmlm
-KHIhPW51bGwpe3AuZD1yCm89ci5iCnQ9by5pbmRleApxPXQrb1swXS5sZW5ndGgKaWYodD09PXEpe2lm
-KHMuYi51bmljb2RlKXtvPXAuYwp0PW8rMQpzPXAuYgppZih0PHMubGVuZ3RoKXtvPUouclkocykubShz
-LG8pCmlmKG8+PTU1Mjk2JiZvPD01NjMxOSl7bz1DLnhCLm0ocyx0KQpvPW8+PTU2MzIwJiZvPD01NzM0
-M31lbHNlIG89ITF9ZWxzZSBvPSExfWVsc2Ugbz0hMQpxPShvP3ErMTpxKSsxfXAuYz1xCnJldHVybiEw
-fX1wLmI9cC5kPW51bGwKcmV0dXJuITF9LAokaUFuOjF9CkgudFEucHJvdG90eXBlPXsKcTpmdW5jdGlv
-bihhLGIpe0guV1koYikKaWYoYiE9PTApSC52aChQLk83KGIsbnVsbCkpCnJldHVybiB0aGlzLmN9LAok
-aU9kOjF9CkguTkYucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5TZCh0aGlz
-LmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9
-dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgKaWYocStvPm0pe3IuZD1u
-dWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsxCnIuZD1udWxsCnJldHVy
-biExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpzCnJldHVybiEwfSwKZ2w6
-ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpILmVILnByb3RvdHlwZT17JGllSDoxLCRp
-ZXE6MX0KSC5MWi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LAokaVhq
-OjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5sZW5n
-dGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5kaihjKQpILm9kKGIsYSxhLmxlbmd0
-aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5cGU9ewpZOmZ1bmN0
-aW9uKGEsYixjKXtILldZKGMpCkgub2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAokaWJROjEsCiRpY1g6
-MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixh
-LGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0gu
-V1koYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90b3R5cGU9ewpxOmZ1
-bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFbYl19fQpILndmLnBy
-b3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4g
-YVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guV1koYikKSC5vZChiLGEsYS5s
-ZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4g
-YS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5XWShiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJu
-IGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6
-ZnVuY3Rpb24oYSxiKXtILldZKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX0sCiRpVjY6
-MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpILldCLnByb3RvdHlw
-ZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3JldHVybiBILnY1KHYu
-dHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkVULnByb3RvdHlwZT17fQpILnU5LnByb3RvdHlwZT17Clo6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYX19CkgueC5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9
-ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmEKdC5hPW51bGwKcy4kMCgpfSwKJFM6MTB9
-ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp0aGlzLmEuYT11Lk0uYShhKQp0
-PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/dC5yZW1vdmVDaGlsZChzKTp0LmFwcGVuZENoaWxk
-KHMpfSwKJFM6MjB9ClAuVnMucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRD
-OiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAo
-KX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMucHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtp
-ZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5zZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxi
-KSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJgc2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0K
-UC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwK
-JFM6Mn0KUC5paC5wcm90b3R5cGU9ewphTTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscj10aGlzLiR0aQpy
-LkMoIjEvIikuYShiKQp0PSF0aGlzLmJ8fHIuQygiYjg8MT4iKS5iKGIpCnM9dGhpcy5hCmlmKHQpcy5Y
-ZihiKQplbHNlIHMuWDIoci5jLmEoYikpfSwKdzA6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiPT1udWxs
-KWI9UC52MChhKQp0PXRoaXMuYQppZih0aGlzLmIpdC5aTChhLGIpCmVsc2UgdC5OayhhLGIpfX0KUC5X
-TS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLiQyKDAsYSl9LAokUzo1MH0K
-UC5TWC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS4kMigxLG5ldyBILmJxKGEsdS5s
-LmEoYikpKX0sCiRDOiIkMiIsCiRSOjIsCiRTOjIxfQpQLkdzLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9u
-KGEsYil7dGhpcy5hKEguV1koYSksYil9LAokUzoyNn0KUC5GeS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9u
-KGEpe3JldHVybiJJdGVyYXRpb25NYXJrZXIoIit0aGlzLmIrIiwgIitILmQodGhpcy5hKSsiKSJ9fQpQ
-LkdWLnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJu
-IHRoaXMuYgpyZXR1cm4gdGhpcy4kdGkuYy5hKHQuZ2woKSl9LApGOmZ1bmN0aW9uKCl7dmFyIHQscyxy
-LHEscD10aGlzCmZvcig7ITA7KXt0PXAuYwppZih0IT1udWxsKWlmKHQuRigpKXJldHVybiEwCmVsc2Ug
-cC5jPW51bGwKcz1mdW5jdGlvbihhLGIsYyl7dmFyIG8sbj1iCndoaWxlKHRydWUpdHJ5e3JldHVybiBh
-KG4sbyl9Y2F0Y2gobSl7bz1tCm49Y319KHAuYSwwLDEpCmlmKHMgaW5zdGFuY2VvZiBQLkZ5KXtyPXMu
-YgppZihyPT09Mil7dD1wLmQKaWYodD09bnVsbHx8dC5sZW5ndGg9PT0wKXtwLnNFQyhudWxsKQpyZXR1
-cm4hMX1pZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnAuYT10LnBvcCgpCmNvbnRpbnVlfWVs
-c2V7dD1zLmEKaWYocj09PTMpdGhyb3cgdAplbHNle3E9Si5JVCh0KQppZihxIGluc3RhbmNlb2YgUC5H
-Vil7dD1wLmQKaWYodD09bnVsbCl0PXAuZD1bXQpDLk5tLmkodCxwLmEpCnAuYT1xLmEKY29udGludWV9
-ZWxzZXtwLmM9cQpjb250aW51ZX19fX1lbHNle3Auc0VDKHMpCnJldHVybiEwfX1yZXR1cm4hMX0sCnNF
-QzpmdW5jdGlvbihhKXt0aGlzLmI9dGhpcy4kdGkuYy5hKGEpfSwKJGlBbjoxfQpQLnE0LnByb3RvdHlw
-ZT17CmdrejpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuR1YodGhpcy5hKCksdGhpcy4kdGkuQygiR1Y8
-MT4iKSl9fQpQLmI4LnByb3RvdHlwZT17fQpQLlBmLnByb3RvdHlwZT17CncwOmZ1bmN0aW9uKGEsYil7
-dmFyIHQKUC5VSShhLCJlcnJvciIsdS5LKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93IEguYihQLlBW
-KCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5OayhhLGI9PW51bGw/UC52MChhKTpiKX0sCnBt
-OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLncwKGEsbnVsbCl9fQpQLlpmLnByb3RvdHlwZT17CmFNOmZ1
-bmN0aW9uKGEsYil7dmFyIHQKdGhpcy4kdGkuQygiMS8iKS5hKGIpCnQ9dGhpcy5hCmlmKHQuYSE9PTAp
-dGhyb3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0LlhmKGIpfX0KUC5GZS5w
-cm90b3R5cGU9ewpIUjpmdW5jdGlvbihhKXtpZigodGhpcy5jJjE1KSE9PTYpcmV0dXJuITAKcmV0dXJu
-IHRoaXMuYi5iLmJ2KHUuYWwuYSh0aGlzLmQpLGEuYSx1LnksdS5LKX0sCkt3OmZ1bmN0aW9uKGEpe3Zh
-ciB0PXRoaXMuZSxzPXUueixyPXUuSyxxPXRoaXMuJHRpLkMoIjIvIikscD10aGlzLmIuYgppZih1LmFn
-LmIodCkpcmV0dXJuIHEuYShwLnJwKHQsYS5hLGEuYixzLHIsdS5sKSkKZWxzZSByZXR1cm4gcS5hKHAu
-YnYodS5iSS5hKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5hKGEpCnQ9JC5YMwppZih0IT09
-Qy5OVSl7Yy5DKCJAPDAvPiIpLktxKHEuYykuQygiMSgyKSIpLmEoYSkKaWYoYiE9bnVsbCliPVAuVkgo
-Yix0KX1zPW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRoaXMueGYobmV3
-IFAuRmUocyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gc30sClc3
-OmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmEoYSkKdD1uZXcgUC52cygkLlgzLGMu
-QygidnM8MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LDE5LGEsYixzLkMoIkA8MT4iKS5LcShjKS5DKCJG
-ZTwxLDI+IikpKQpyZXR1cm4gdH0sCnhmOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcyxyPXMuYQppZihy
-PD0xKXthLmE9dS54LmEocy5jKQpzLmM9YX1lbHNle2lmKHI9PT0yKXt0PXUuXy5hKHMuYykKcj10LmEK
-aWYocjw0KXt0LnhmKGEpCnJldHVybn1zLmE9cgpzLmM9dC5jfVAuVGsobnVsbCxudWxsLHMuYix1Lk0u
-YShuZXcgUC5kYShzLGEpKSl9fSwKalE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvPXRoaXMsbj17
-fQpuLmE9YQppZihhPT1udWxsKXJldHVybgp0PW8uYQppZih0PD0xKXtzPXUueC5hKG8uYykKcj1vLmM9
-YQppZihzIT1udWxsKXtmb3IoO3E9ci5hLHEhPW51bGw7cj1xKTtyLmE9c319ZWxzZXtpZih0PT09Mil7
-cD11Ll8uYShvLmMpCnQ9cC5hCmlmKHQ8NCl7cC5qUShhKQpyZXR1cm59by5hPXQKby5jPXAuY31uLmE9
-by5OOChhKQpQLlRrKG51bGwsbnVsbCxvLmIsdS5NLmEobmV3IFAub1EobixvKSkpfX0sCmFoOmZ1bmN0
-aW9uKCl7dmFyIHQ9dS54LmEodGhpcy5jKQp0aGlzLmM9bnVsbApyZXR1cm4gdGhpcy5OOCh0KX0sCk44
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscgpmb3IodD1hLHM9bnVsbDt0IT1udWxsO3M9dCx0PXIpe3I9dC5h
-CnQuYT1zfXJldHVybiBzfSwKSEg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9cy4kdGkKci5DKCIx
-LyIpLmEoYSkKaWYoci5DKCJiODwxPiIpLmIoYSkpaWYoci5iKGEpKVAuQTkoYSxzKQplbHNlIFAuazMo
-YSxzKQplbHNle3Q9cy5haCgpCnIuYy5hKGEpCnMuYT00CnMuYz1hClAuSFoocyx0KX19LApYMjpmdW5j
-dGlvbihhKXt2YXIgdCxzPXRoaXMKcy4kdGkuYy5hKGEpCnQ9cy5haCgpCnMuYT00CnMuYz1hClAuSFoo
-cyx0KX0sClpMOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKdS5sLmEoYikKdD1yLmFoKCkKcz1Q
-LlRsKGEsYikKci5hPTgKci5jPXMKUC5IWihyLHQpfSwKWGY6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxz
-PXQuJHRpCnMuQygiMS8iKS5hKGEpCmlmKHMuQygiYjg8MT4iKS5iKGEpKXt0LmNVKGEpCnJldHVybn10
-LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmEobmV3IFAuckgodCxhKSkpfSwKY1U6ZnVuY3Rpb24o
-YSl7dmFyIHQ9dGhpcyxzPXQuJHRpCnMuQygiYjg8MT4iKS5hKGEpCmlmKHMuYihhKSl7aWYoYS5hPT09
-OCl7dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUuTS5hKG5ldyBQLktGKHQsYSkpKX1lbHNlIFAuQTko
-YSx0KQpyZXR1cm59UC5rMyhhLHQpfSwKTms6ZnVuY3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRrKG51bGws
-bnVsbCx0aGlzLmIsdS5NLmEobmV3IFAuWkwodGhpcyxhLGIpKSl9LAokaWI4OjF9ClAuZGEucHJvdG90
-eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5wcm90b3R5
-cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5iLHRoaXMuYS5hKX0sCiRTOjB9ClAucFYucHJvdG90
-eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnQuYT0wCnQuSEgoYSl9LAokUzoxMH0KUC5V
-Ny5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3UubC5hKGIpCnRoaXMuYS5aTChhLGIpfSwKJDE6
-ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuJDIoYSxudWxsKX0sCiRDOiIkMiIsCiREOmZ1bmN0aW9uKCl7
-cmV0dXJuW251bGxdfSwKJFM6Mjl9ClAudnIucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEu
-WkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFy
-IHQ9dGhpcy5hCnQuWDIodC4kdGkuYy5hKHRoaXMuYikpfSwKJFM6MH0KUC5LRi5wcm90b3R5cGU9ewok
-MDpmdW5jdGlvbigpe1AuQTkodGhpcy5iLHRoaXMuYSl9LAokUzowfQpQLlpMLnByb3RvdHlwZT17CiQw
-OmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KUC5SVC5wcm90b3R5cGU9
-ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1udWxsCnRyeXtyPW4uYwptPXIu
-Yi5iLnp6KHUuZk8uYShyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQppZihuLmQp
-e3I9dS5uLmEobi5hLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVsc2Ugcj0h
-MQpwPW4uYgppZihyKXAuYj11Lm4uYShuLmEuYS5jKQplbHNlIHAuYj1QLlRsKHQscykKcC5hPSEwCnJl
-dHVybn1pZih1LmMuYihtKSl7aWYobSBpbnN0YW5jZW9mIFAudnMmJm0uYT49NCl7aWYobS5hPT09OCl7
-cj1uLmIKci5iPXUubi5hKG0uYykKci5hPSEwfXJldHVybn1vPW4uYS5hCnI9bi5iCnIuYj1tLlc3KG5l
-dyBQLmpaKG8pLHUueikKci5hPSExfX0sCiRTOjJ9ClAualoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
-YSl7cmV0dXJuIHRoaXMuYX0sCiRTOjMyfQpQLnJxLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFy
-IHQscyxyLHEscCxvLG4sbT10aGlzCnRyeXtyPW0uYgpxPXIuJHRpCnA9cS5jCm89cC5hKG0uYykKbS5h
-LmI9ci5iLmIuYnYocS5DKCIyLygxKSIpLmEoci5kKSxvLHEuQygiMi8iKSxwKX1jYXRjaChuKXt0PUgu
-UnUobikKcz1ILnRzKG4pCnI9bS5hCnIuYj1QLlRsKHQscykKci5hPSEwfX0sCiRTOjJ9ClAuUlcucHJv
-dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp0cnl7dD11Lm4u
-YShsLmEuYS5jKQpxPWwuYwppZihILm9UKHEuSFIodCkpJiZxLmUhPW51bGwpe3A9bC5iCnAuYj1xLkt3
-KHQpCnAuYT0hMX19Y2F0Y2gobyl7cz1ILlJ1KG8pCnI9SC50cyhvKQpxPXUubi5hKGwuYS5hLmMpCnA9
-cS5hCm49cwptPWwuYgppZihwPT1udWxsP249PW51bGw6cD09PW4pbS5iPXEKZWxzZSBtLmI9UC5UbChz
-LHIpCm0uYT0hMH19LAokUzoyfQpQLk9NLnByb3RvdHlwZT17fQpQLnFoLnByb3RvdHlwZT17CmdBOmZ1
-bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9e30scD1uZXcgUC52cygkLlgzLHUuZkopCnEuYT0wCnQ9
-SC5MaChyKQpzPXQuQygifigxKSIpLmEobmV3IFAuQjUocSxyKSkKdS5NLmEobmV3IFAudU8ocSxwKSkK
-Vy5KRShyLmEsci5iLHMsITEsdC5jKQpyZXR1cm4gcH19ClAuQjUucHJvdG90eXBlPXsKJDE6ZnVuY3Rp
-b24oYSl7SC5MaCh0aGlzLmIpLmMuYShhKTsrK3RoaXMuYS5hfSwKJFM6ZnVuY3Rpb24oKXtyZXR1cm4g
-SC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLnVPLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dGhp
-cy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9ClAua1QucHJvdG90eXBlPXt9
-ClAueEkucHJvdG90eXBlPXt9ClAuT0gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gSC5k
-KHRoaXMuYSl9LAokaVhTOjEsCmdJSTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9fQpQLm0wLnByb3Rv
-dHlwZT17JGlKQjoxfQpQLnBLLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLmEs
-cj1zLmIKaWYocj09bnVsbCl0aHJvdyBILmIocy5hKQp0PUguYihzLmEpCnQuc3RhY2s9ci5aKDApCnRo
-cm93IHR9LAokUzowfQpQLkppLnByb3RvdHlwZT17CmJIOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPW51
-bGwKdS5NLmEoYSkKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQwKCkKcmV0dXJufVAuVDgocSxxLHRoaXMs
-YSx1LkgpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihxLHEsdGhpcyx0LHUubC5hKHMp
-KX19LApEbDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9bnVsbApjLkMoIn4oMCkiKS5hKGEpCmMu
-YShiKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDEoYikKcmV0dXJufVAueXYocSxxLHRoaXMsYSxiLHUu
-SCxjKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxxLHRoaXMsdCx1LmwuYShzKSl9
-fSwKUlQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuaGoodGhpcyxiLkMoIjAoKSIpLmEoYSksYil9
-LApHWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVnAodGhpcyx1Lk0uYShhKSl9LApQeTpmdW5jdGlv
-bihhLGIpe3JldHVybiBuZXcgUC5PUih0aGlzLGIuQygifigwKSIpLmEoYSksYil9LApxOmZ1bmN0aW9u
-KGEsYil7cmV0dXJuIG51bGx9LAp6ejpmdW5jdGlvbihhLGIpe2IuQygiMCgpIikuYShhKQppZigkLlgz
-PT09Qy5OVSlyZXR1cm4gYS4kMCgpCnJldHVybiBQLlQ4KG51bGwsbnVsbCx0aGlzLGEsYil9LApidjpm
-dW5jdGlvbihhLGIsYyxkKXtjLkMoIkA8MD4iKS5LcShkKS5DKCIxKDIpIikuYShhKQpkLmEoYikKaWYo
-JC5YMz09PUMuTlUpcmV0dXJuIGEuJDEoYikKcmV0dXJuIFAueXYobnVsbCxudWxsLHRoaXMsYSxiLGMs
-ZCl9LApycDpmdW5jdGlvbihhLGIsYyxkLGUsZil7ZC5DKCJAPDA+IikuS3EoZSkuS3EoZikuQygiMSgy
-LDMpIikuYShhKQplLmEoYikKZi5hKGMpCmlmKCQuWDM9PT1DLk5VKXJldHVybiBhLiQyKGIsYykKcmV0
-dXJuIFAuUXgobnVsbCxudWxsLHRoaXMsYSxiLGMsZCxlLGYpfSwKTGo6ZnVuY3Rpb24oYSxiLGMsZCl7
-cmV0dXJuIGIuQygiQDwwPiIpLktxKGMpLktxKGQpLkMoIjEoMiwzKSIpLmEoYSl9fQpQLmhqLnByb3Rv
-dHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS56eih0aGlzLmIsdGhpcy5jKX0sCiRTOmZ1
-bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCIwKCkiKX19ClAuVnAucHJvdG90eXBlPXsKJDA6ZnVuY3Rp
-b24oKXtyZXR1cm4gdGhpcy5hLmJIKHRoaXMuYil9LAokUzoyfQpQLk9SLnByb3RvdHlwZT17CiQxOmZ1
-bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdGhpcy5hLkRsKHRoaXMuYix0LmEoYSksdCl9LAok
-UzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygifigwKSIpfX0KUC5iNi5wcm90b3R5cGU9ewpna3o6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBQLmxtKHQsdC5yLEguTGgodCkuQygibG08MT4iKSkK
-cy5jPXQuZQpyZXR1cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAp0ZzpmdW5jdGlv
-bihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpe3Q9dGhp
-cy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUuRC5hKHRbYl0pIT1udWxsfWVsc2V7cz10aGlz
-LlBSKGIpCnJldHVybiBzfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJl
-dHVybiExCnJldHVybiB0aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0sCmk6ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHI9dGhpcwpILkxoKHIpLmMuYShiKQppZih0eXBlb2YgYj09InN0cmluZyImJmIhPT0iX19w
-cm90b19fIil7dD1yLmIKcmV0dXJuIHIuYlEodD09bnVsbD9yLmI9UC5UMigpOnQsYil9ZWxzZSBpZih0
-eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1yLmMKcmV0dXJuIHIuYlEocz09
-bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0sCkI3OmZ1bmN0aW9uKGEpe3Zh
-ciB0LHMscixxPXRoaXMKSC5MaChxKS5jLmEoYSkKdD1xLmQKaWYodD09bnVsbCl0PXEuZD1QLlQyKCkK
-cz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0KZWxzZXtpZihxLkRGKHIsYSk+
-PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0
-PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9fXyIpcmV0dXJuIHQuSDQodC5i
-LGIpCmVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYxMDczNzQxODIzKT09PWIpcmV0dXJuIHQu
-SDQodC5jLGIpCmVsc2UgcmV0dXJuIHQucWcoYil9LApxZzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxw
-PXRoaXMsbz1wLmQKaWYobz09bnVsbClyZXR1cm4hMQp0PXAuTihhKQpzPW9bdF0Kcj1wLkRGKHMsYSkK
-aWYocjwwKXJldHVybiExCnE9cy5zcGxpY2UociwxKVswXQppZigwPT09cy5sZW5ndGgpZGVsZXRlIG9b
-dF0KcC5HUyhxKQpyZXR1cm4hMH0sCmJROmZ1bmN0aW9uKGEsYil7SC5MaCh0aGlzKS5jLmEoYikKaWYo
-dS5ELmEoYVtiXSkhPW51bGwpcmV0dXJuITEKYVtiXT10aGlzLnlvKGIpCnJldHVybiEwfSwKSDQ6ZnVu
-Y3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiExCnQ9dS5ELmEoYVtiXSkKaWYodD09bnVs
-bClyZXR1cm4hMQp0aGlzLkdTKHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwKUzpmdW5jdGlvbigpe3Ro
-aXMucj0xMDczNzQxODIzJnRoaXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9bmV3
-IFAuYm4oSC5MaChzKS5jLmEoYSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIKZWxzZXt0PXMuZgpyLmM9
-dApzLmY9dC5iPXJ9KytzLmEKcy5TKCkKcmV0dXJuIHJ9LApHUzpmdW5jdGlvbihhKXt2YXIgdD10aGlz
-LHM9YS5jLHI9YS5iCmlmKHM9PW51bGwpdC5lPXIKZWxzZSBzLmI9cgppZihyPT1udWxsKXQuZj1zCmVs
-c2Ugci5jPXM7LS10LmEKdC5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBKLmhmKGEpJjEwNzM3NDE4
-MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1cm4tMQp0PWEubGVuZ3Ro
-CmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpyZXR1cm4tMX19ClAuYm4u
-cHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwK
-RjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRocm93IEguYihQLmE0KHMp
-KQplbHNle3M9dC5jCmlmKHM9PW51bGwpe3Quc2oobnVsbCkKcmV0dXJuITF9ZWxzZXt0LnNqKHQuJHRp
-LmMuYShzLmEpKQp0LmM9dC5jLmIKcmV0dXJuITB9fX0sCnNqOmZ1bmN0aW9uKGEpe3RoaXMuZD10aGlz
-LiR0aS5jLmEoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXkucHJvdG90eXBlPXskaWJR
-OjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7cmV0dXJuIG5l
-dyBILmE3KGEsdGhpcy5nQShhKSxILnEoYSkuQygiYTc8bEQuRT4iKSl9LApFOmZ1bmN0aW9uKGEsYil7
-cmV0dXJuIHRoaXMucShhLGIpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKSC5xKGEpLkMoIn4obEQu
-RSkiKS5hKGIpCnQ9dGhpcy5nQShhKQpmb3Iocz0wO3M8dDsrK3Mpe2IuJDEodGhpcy5xKGEscykpCmlm
-KHQhPT10aGlzLmdBKGEpKXRocm93IEguYihQLmE0KGEpKX19LApnb3I6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ0EoYSkhPT0wfSwKRTI6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgucShhKQpyZXR1cm4gbmV3
-IEgubEooYSx0LktxKGMpLkMoIjEobEQuRSkiKS5hKGIpLHQuQygiQDxsRC5FPiIpLktxKGMpLkMoImxK
-PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdApILnEoYSkuQygibEQuRSIpLmEoZCkK
-UC5qQihiLGMsdGhpcy5nQShhKSkKZm9yKHQ9Yjt0PGM7Kyt0KXRoaXMuWShhLHQsZCl9LApaOmZ1bmN0
-aW9uKGEpe3JldHVybiBQLldFKGEsIlsiLCJdIil9fQpQLmlsLnByb3RvdHlwZT17fQpQLnJhLnByb3Rv
-dHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoIXMuYSl0aGlzLmIuYSs9Iiwg
-IgpzLmE9ITEKcz10aGlzLmIKdD1zLmErPUguZChhKQpzLmE9dCsiOiAiCnMuYSs9SC5kKGIpfSwKJFM6
-NH0KUC5Zay5wcm90b3R5cGU9ewpLOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILkxoKHRoaXMpLkMoIn4o
-WWsuSyxZay5WKSIpLmEoYikKZm9yKHQ9Si5JVCh0aGlzLmdWKCkpO3QuRigpOyl7cz10LmdsKCkKYi4k
-MihzLHRoaXMucSgwLHMpKX19LApnUHU6ZnVuY3Rpb24oYSl7cmV0dXJuIEouTTEodGhpcy5nVigpLG5l
-dyBQLnlRKHRoaXMpLEguTGgodGhpcykuQygiTjM8WWsuSyxZay5WPiIpKX0sCng0OmZ1bmN0aW9uKGEp
-e3JldHVybiBKLnpsKHRoaXMuZ1YoKSxhKX0sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiBKLkgodGhpcy5n
-VigpKX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4gSi5DaSh0aGlzLmdWKCkpfSwKWjpmdW5jdGlvbihh
-KXtyZXR1cm4gUC5uTyh0aGlzKX0sCiRpWjA6MX0KUC55US5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
-KXt2YXIgdD10aGlzLmEscz1ILkxoKHQpCnMuQygiWWsuSyIpLmEoYSkKcmV0dXJuIG5ldyBQLk4zKGEs
-dC5xKDAsYSkscy5DKCJAPFlrLks+IikuS3Eocy5DKCJZay5WIikpLkMoIk4zPDEsMj4iKSl9LAokUzpm
-dW5jdGlvbigpe3JldHVybiBILkxoKHRoaXMuYSkuQygiTjM8WWsuSyxZay5WPihZay5LKSIpfX0KUC5L
-UC5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnQuYy5hKGIpCnQu
-UVsxXS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IHVubW9kaWZpYWJsZSBtYXAiKSl9
-fQpQLlBuLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLnEoMCxiKX0sClk6
-ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdGhpcy5hLlkoMCx0LmMuYShiKSx0LlFbMV0u
-YShjKSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLng0KGEpfSwKSzpmdW5jdGlvbihhLGIp
-e3RoaXMuYS5LKDAsSC5MaCh0aGlzKS5DKCJ+KDEsMikiKS5hKGIpKX0sCmdsMDpmdW5jdGlvbihhKXt2
-YXIgdD10aGlzLmEKcmV0dXJuIHQuZ2wwKHQpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJl
-dHVybiB0LmdBKHQpfSwKWjpmdW5jdGlvbihhKXtyZXR1cm4gSi5BYyh0aGlzLmEpfSwKZ1B1OmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nUHUodCl9LAokaVowOjF9ClAuR2oucHJvdG90eXBl
-PXt9ClAuTWEucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRSh0aGlzLCJ7IiwifSIp
-fX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dToxfQpQLlh2LnByb3RvdHlwZT17CkZW
-OmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChILkxoKHRoaXMpLkMoImNYPDE+IikuYShiKSk7
-dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBQLldFKHRoaXMsInsi
-LCJ9Iil9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRoaXMsdGhpcy5yLEguTGgodGhpcyku
-YykKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpkbyB0Kz1ILmQocy5kKQp3aGlsZShz
-LkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCtiK0guZChzLmQpfXJldHVybiB0LmNo
-YXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRpeHU6MX0KUC5uWS5wcm90b3R5cGU9
-e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30KUC51dy5wcm90b3R5cGU9ewpxOmZ1
-bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbClyZXR1cm4gdGhpcy5jLnEoMCxiKQpl
-bHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbAplbHNle3Q9c1tiXQpyZXR1cm4gdHlw
-ZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhp
-cy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtpZih0aGlzLmI9PW51bGwpe3ZhciB0PXRo
-aXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxoKHQpLkMoImk1PDE+IikpfXJldHVybiBuZXcgUC5pOCh0
-aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj10aGlzCmlmKHIuYj09bnVsbClyLmMuWSgw
-LGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIuYgp0W2JdPWMKcz1yLmEKaWYocz09bnVsbD90IT1udWxs
-OnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEsoKS5ZKDAsYixjKX0sCng0OmZ1bmN0aW9uKGEpe2lmKHRo
-aXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJldHVybiBPYmplY3QucHJvdG90eXBlLmhhc093
-blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHA9dGhp
-cwp1LmNBLmEoYikKaWYocC5iPT1udWxsKXJldHVybiBwLmMuSygwLGIpCnQ9cC5DZigpCmZvcihzPTA7
-czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAuYltyXQppZih0eXBlb2YgcT09InVuZGVmaW5lZCIpe3E9
-UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIocixxKQppZih0IT09cC5jKXRocm93IEguYihQLmE0KHAp
-KX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUuai5hKHRoaXMuYykKaWYodD09bnVsbCl0PXRoaXMuYz1I
-LlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5zKQpyZXR1cm4gdH0sClhLOmZ1bmN0aW9uKCl7dmFyIHQs
-cyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxsKXJldHVybiBvLmMKdD1QLkZsKHUuTix1LnopCnM9by5D
-ZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7KytyKXtwPXNbcl0KdC5ZKDAscCxvLnEoMCxwKSl9aWYo
-cT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBDLk5tLnNBKHMsMCkKby5hPW8uYj1udWxsCnJldHVybiBv
-LmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3QucHJvdG90eXBlLmhhc093blByb3Bl
-cnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0aGlzLmFbYV0pCnJldHVybiB0aGlz
-LmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVy
-biB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwpdD10LmdW
-KCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikK
-dD10W2JdfXJldHVybiB0fSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0LmI9PW51bGwp
-e3Q9dC5nVigpCnQ9dC5na3oodCl9ZWxzZXt0PXQuQ2YoKQp0PW5ldyBKLm0xKHQsdC5sZW5ndGgsSC50
-Nih0KS5DKCJtMTwxPiIpKX1yZXR1cm4gdH0sCnRnOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS54
-NChiKX19ClAuQ1YucHJvdG90eXBlPXsKeXI6ZnVuY3Rpb24oYSxhMCxhMSl7dmFyIHQscyxyLHEscCxv
-LG4sbSxsLGssaixpLGgsZyxmLGUsZCxjLGI9IkludmFsaWQgYmFzZTY0IGVuY29kaW5nIGxlbmd0aCAi
-CmExPVAuakIoYTAsYTEsYS5sZW5ndGgpCnQ9JC5WNygpCmZvcihzPWEwLHI9cyxxPW51bGwscD0tMSxv
-PS0xLG49MDtzPGExO3M9bSl7bT1zKzEKbD1DLnhCLlcoYSxzKQppZihsPT09Mzcpe2s9bSsyCmlmKGs8
-PWExKXtqPUgub28oQy54Qi5XKGEsbSkpCmk9SC5vbyhDLnhCLlcoYSxtKzEpKQpoPWoqMTYraS0oaSYy
-NTYpCmlmKGg9PT0zNyloPS0xCm09a31lbHNlIGg9LTF9ZWxzZSBoPWwKaWYoMDw9aCYmaDw9MTI3KXtp
-ZihoPDB8fGg+PXQubGVuZ3RoKXJldHVybiBILmsodCxoKQpnPXRbaF0KaWYoZz49MCl7aD1DLnhCLm0o
-IkFCQ0RFRkdISUpLTE1OT1BRUlNUVVZXWFlaYWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXowMTIzNDU2
-Nzg5Ky8iLGcpCmlmKGg9PT1sKWNvbnRpbnVlCmw9aH1lbHNle2lmKGc9PT0tMSl7aWYocDwwKXtmPXE9
-PW51bGw/bnVsbDpxLmEubGVuZ3RoCmlmKGY9PW51bGwpZj0wCnA9Zisocy1yKQpvPXN9KytuCmlmKGw9
-PT02MSljb250aW51ZX1sPWh9aWYoZyE9PS0yKXtpZihxPT1udWxsKXE9bmV3IFAuUm4oIiIpCnEuYSs9
-Qy54Qi5OaihhLHIscykKcS5hKz1ILkx3KGwpCnI9bQpjb250aW51ZX19dGhyb3cgSC5iKFAucnIoIklu
-dmFsaWQgYmFzZTY0IGRhdGEiLGEscykpfWlmKHEhPW51bGwpe2Y9cS5hKz1DLnhCLk5qKGEscixhMSkK
-ZT1mLmxlbmd0aAppZihwPj0wKVAueE0oYSxvLGExLHAsbixlKQplbHNle2Q9Qy5qbi56WShlLTEsNCkr
-MQppZihkPT09MSl0aHJvdyBILmIoUC5ycihiLGEsYTEpKQpmb3IoO2Q8NDspe2YrPSI9IgpxLmE9Zjsr
-K2R9fWY9cS5hCnJldHVybiBDLnhCLmk3KGEsYTAsYTEsZi5jaGFyQ29kZUF0KDApPT0wP2Y6Zil9Yz1h
-MS1hMAppZihwPj0wKVAueE0oYSxvLGExLHAsbixjKQplbHNle2Q9Qy5qbi56WShjLDQpCmlmKGQ9PT0x
-KXRocm93IEguYihQLnJyKGIsYSxhMSkpCmlmKGQ+MSlhPUMueEIuaTcoYSxhMSxhMSxkPT09Mj8iPT0i
-OiI9Iil9cmV0dXJuIGF9fQpQLlU4LnByb3RvdHlwZT17fQpQLlVrLnByb3RvdHlwZT17fQpQLndJLnBy
-b3RvdHlwZT17fQpQLlppLnByb3RvdHlwZT17fQpQLlVkLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7
-dmFyIHQ9UC5oKHRoaXMuYSkKcmV0dXJuKHRoaXMuYiE9bnVsbD8iQ29udmVydGluZyBvYmplY3QgdG8g
-YW4gZW5jb2RhYmxlIG9iamVjdCBmYWlsZWQ6IjoiQ29udmVydGluZyBvYmplY3QgZGlkIG5vdCByZXR1
-cm4gYW4gZW5jb2RhYmxlIG9iamVjdDoiKSsiICIrdH19ClAuSzgucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iQ3ljbGljIGVycm9yIGluIEpTT04gc3RyaW5naWZ5In19ClAuYnkucHJvdG90eXBl
-PXsKcFc6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0CnUuZXAuYShjKQp0PVAuQlMoYix0aGlzLmdIZSgpLmEp
-CnJldHVybiB0fSwKT0I6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LmJjLmEoYikKdD1QLnVYKGEsdGhpcy5n
-WkUoKS5iLG51bGwpCnJldHVybiB0fSwKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMublh9LApnSGU6ZnVu
-Y3Rpb24oKXtyZXR1cm4gQy5BM319ClAub2oucHJvdG90eXBlPXt9ClAuTXgucHJvdG90eXBlPXt9ClAu
-U2gucHJvdG90eXBlPXsKdnA6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49YS5sZW5ndGgKZm9y
-KHQ9Si5yWShhKSxzPXRoaXMuYyxyPTAscT0wO3E8bjsrK3Epe3A9dC5XKGEscSkKaWYocD45Miljb250
-aW51ZQppZihwPDMyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpzLmErPUguTHcoOTIp
-CnN3aXRjaChwKXtjYXNlIDg6cy5hKz1ILkx3KDk4KQpicmVhawpjYXNlIDk6cy5hKz1ILkx3KDExNikK
-YnJlYWsKY2FzZSAxMDpzLmErPUguTHcoMTEwKQpicmVhawpjYXNlIDEyOnMuYSs9SC5MdygxMDIpCmJy
-ZWFrCmNhc2UgMTM6cy5hKz1ILkx3KDExNCkKYnJlYWsKZGVmYXVsdDpzLmErPUguTHcoMTE3KQpzLmEr
-PUguTHcoNDgpCnMuYSs9SC5Mdyg0OCkKbz1wPj4+NCYxNQpzLmErPUguTHcobzwxMD80OCtvOjg3K28p
-Cm89cCYxNQpzLmErPUguTHcobzwxMD80OCtvOjg3K28pCmJyZWFrfX1lbHNlIGlmKHA9PT0zNHx8cD09
-PTkyKXtpZihxPnIpcy5hKz1DLnhCLk5qKGEscixxKQpyPXErMQpzLmErPUguTHcoOTIpCnMuYSs9SC5M
-dyhwKX19aWYocj09PTApcy5hKz1ILmQoYSkKZWxzZSBpZihyPG4pcy5hKz10Lk5qKGEscixuKX0sCkpu
-OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxCmZvcih0PXRoaXMuYSxzPXQubGVuZ3RoLHI9MDtyPHM7Kyty
-KXtxPXRbcl0KaWYoYT09bnVsbD9xPT1udWxsOmE9PT1xKXRocm93IEguYihuZXcgUC5LOChhLG51bGwp
-KX1DLk5tLmkodCxhKX0sCmlVOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHA9dGhpcwppZihwLnRNKGEp
-KXJldHVybgpwLkpuKGEpCnRyeXt0PXAuYi4kMShhKQppZighcC50TSh0KSl7cj1QLkd5KGEsbnVsbCxw
-LmdWSygpKQp0aHJvdyBILmIocil9cj1wLmEKaWYoMD49ci5sZW5ndGgpcmV0dXJuIEguayhyLC0xKQpy
-LnBvcCgpfWNhdGNoKHEpe3M9SC5SdShxKQpyPVAuR3koYSxzLHAuZ1ZLKCkpCnRocm93IEguYihyKX19
-LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwppZih0eXBlb2YgYT09Im51bWJlciIpe2lmKCFp
-c0Zpbml0ZShhKSlyZXR1cm4hMQpyLmMuYSs9Qy5DRC5aKGEpCnJldHVybiEwfWVsc2UgaWYoYT09PSEw
-KXtyLmMuYSs9InRydWUiCnJldHVybiEwfWVsc2UgaWYoYT09PSExKXtyLmMuYSs9ImZhbHNlIgpyZXR1
-cm4hMH1lbHNlIGlmKGE9PW51bGwpe3IuYy5hKz0ibnVsbCIKcmV0dXJuITB9ZWxzZSBpZih0eXBlb2Yg
-YT09InN0cmluZyIpe3Q9ci5jCnQuYSs9JyInCnIudnAoYSkKdC5hKz0nIicKcmV0dXJuITB9ZWxzZSBp
-Zih1LmouYihhKSl7ci5KbihhKQpyLmxLKGEpCnQ9ci5hCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILmso
-dCwtMSkKdC5wb3AoKQpyZXR1cm4hMH1lbHNlIGlmKHUuRy5iKGEpKXtyLkpuKGEpCnM9ci5qdyhhKQp0
-PXIuYQppZigwPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkKcmV0dXJuIHN9ZWxzZSBy
-ZXR1cm4hMX0sCmxLOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLmMKci5hKz0iWyIKdD1KLlU2KGEp
-CmlmKHQuZ29yKGEpKXt0aGlzLmlVKHQucShhLDApKQpmb3Iocz0xO3M8dC5nQShhKTsrK3Mpe3IuYSs9
-IiwiCnRoaXMuaVUodC5xKGEscykpfX1yLmErPSJdIn0sCmp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixx
-LHAsbyxuPXRoaXMsbT17fQppZihhLmdsMChhKSl7bi5jLmErPSJ7fSIKcmV0dXJuITB9dD1hLmdBKGEp
-KjIKcz1uZXcgQXJyYXkodCkKcy5maXhlZCRsZW5ndGg9QXJyYXkKcj1tLmE9MAptLmI9ITAKYS5LKDAs
-bmV3IFAudGkobSxzKSkKaWYoIW0uYilyZXR1cm4hMQpxPW4uYwpxLmErPSJ7Igpmb3IocD0nIic7cjx0
-O3IrPTIscD0nLCInKXtxLmErPXAKbi52cChILmMoc1tyXSkpCnEuYSs9JyI6JwpvPXIrMQppZihvPj10
-KXJldHVybiBILmsocyxvKQpuLmlVKHNbb10pfXEuYSs9In0iCnJldHVybiEwfX0KUC50aS5wcm90b3R5
-cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGEhPSJzdHJpbmciKXRoaXMuYS5i
-PSExCnQ9dGhpcy5iCnM9dGhpcy5hCkMuTm0uWSh0LHMuYSsrLGEpCkMuTm0uWSh0LHMuYSsrLGIpfSwK
-JFM6NH0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmMuYQpyZXR1cm4g
-dC5jaGFyQ29kZUF0KDApPT0wP3Q6dH19ClAudTUucHJvdG90eXBlPXsKZ1pFOmZ1bmN0aW9uKCl7cmV0
-dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj1QLmpCKDAs
-bnVsbCxhLmxlbmd0aCkscT1yLTAKaWYocT09PTApcmV0dXJuIG5ldyBVaW50OEFycmF5KDApCnQ9bmV3
-IFVpbnQ4QXJyYXkocSozKQpzPW5ldyBQLlJ3KHQpCmlmKHMuR3goYSwwLHIpIT09cilzLk82KEouYTYo
-YSxyLTEpLDApCnJldHVybiBuZXcgVWludDhBcnJheSh0LnN1YmFycmF5KDAsSC5yTSgwLHMuYix0Lmxl
-bmd0aCkpKX19ClAuUncucHJvdG90eXBlPXsKTzY6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1z
-LmMscT1zLmIscD1xKzEsbz1yLmxlbmd0aAppZigoYiY2NDUxMik9PT01NjMyMCl7dD02NTUzNisoKGEm
-MTAyMyk8PDEwKXxiJjEwMjMKcy5iPXAKaWYocT49bylyZXR1cm4gSC5rKHIscSkKcltxXT0yNDB8dD4+
-PjE4CnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILmsocixwKQpyW3BdPTEyOHx0Pj4+MTImNjMKcD1z
-LmI9cSsxCmlmKHE+PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MTI4fHQ+Pj42JjYzCnMuYj1wKzEKaWYo
-cD49bylyZXR1cm4gSC5rKHIscCkKcltwXT0xMjh8dCY2MwpyZXR1cm4hMH1lbHNle3MuYj1wCmlmKHE+
-PW8pcmV0dXJuIEguayhyLHEpCnJbcV09MjI0fGE+Pj4xMgpxPXMuYj1wKzEKaWYocD49bylyZXR1cm4g
-SC5rKHIscCkKcltwXT0xMjh8YT4+PjYmNjMKcy5iPXErMQppZihxPj1vKXJldHVybiBILmsocixxKQpy
-W3FdPTEyOHxhJjYzCnJldHVybiExfX0sCkd4OmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8s
-bixtPXRoaXMKaWYoYiE9PWMmJihDLnhCLm0oYSxjLTEpJjY0NTEyKT09PTU1Mjk2KS0tYwpmb3IodD1t
-LmMscz10Lmxlbmd0aCxyPWI7cjxjOysrcil7cT1DLnhCLlcoYSxyKQppZihxPD0xMjcpe3A9bS5iCmlm
-KHA+PXMpYnJlYWsKbS5iPXArMQp0W3BdPXF9ZWxzZSBpZigocSY2NDUxMik9PT01NTI5Nil7aWYobS5i
-KzM+PXMpYnJlYWsKbz1yKzEKaWYobS5PNihxLEMueEIuVyhhLG8pKSlyPW99ZWxzZSBpZihxPD0yMDQ3
-KXtwPW0uYgpuPXArMQppZihuPj1zKWJyZWFrCm0uYj1uCmlmKHA+PXMpcmV0dXJuIEguayh0LHApCnRb
-cF09MTkyfHE+Pj42Cm0uYj1uKzEKdFtuXT0xMjh8cSY2M31lbHNle3A9bS5iCmlmKHArMj49cylicmVh
-awpuPW0uYj1wKzEKaWYocD49cylyZXR1cm4gSC5rKHQscCkKdFtwXT0yMjR8cT4+PjEyCnA9bS5iPW4r
-MQppZihuPj1zKXJldHVybiBILmsodCxuKQp0W25dPTEyOHxxPj4+NiY2MwptLmI9cCsxCmlmKHA+PXMp
-cmV0dXJuIEguayh0LHApCnRbcF09MTI4fHEmNjN9fXJldHVybiByfX0KUC5HWS5wcm90b3R5cGU9ewpX
-SjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwKdS5MLmEoYSkKdD1QLmt5KCExLGEsMCxu
-dWxsKQppZih0IT1udWxsKXJldHVybiB0CnM9UC5qQigwLG51bGwsSi5IKGEpKQpyPVAuY1AoYSwwLHMp
-CmlmKHI+MCl7cT1QLkhNKGEsMCxyKQppZihyPT09cylyZXR1cm4gcQpwPW5ldyBQLlJuKHEpCm89cgpu
-PSExfWVsc2V7bz0wCnA9bnVsbApuPSEwfWlmKHA9PW51bGwpcD1uZXcgUC5SbigiIikKbT1uZXcgUC5i
-eighMSxwKQptLmM9bgptLk1FKGEsbyxzKQppZihtLmU+MCl7SC52aChQLnJyKCJVbmZpbmlzaGVkIFVU
-Ri04IG9jdGV0IHNlcXVlbmNlIixhLHMpKQpwLmErPUguTHcoNjU1MzMpCm0uZj1tLmU9bS5kPTB9bD1w
-LmEKcmV0dXJuIGwuY2hhckNvZGVBdCgwKT09MD9sOmx9fQpQLmJ6LnByb3RvdHlwZT17Ck1FOmZ1bmN0
-aW9uKGEsYixjKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10aGlzLGc9IkJhZCBVVEYtOCBl
-bmNvZGluZyAweCIKdS5MLmEoYSkKdD1oLmQKcz1oLmUKcj1oLmYKaC5mPWguZT1oLmQ9MAokbGFiZWww
-JDA6Zm9yKHE9Si5VNihhKSxwPWguYixvPWI7ITA7bz1qKXskbGFiZWwxJDE6aWYocz4wKXtkb3tpZihv
-PT09YylicmVhayAkbGFiZWwwJDAKbj1xLnEoYSxvKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVy
-biBuLnpNKCkKaWYoKG4mMTkyKSE9PTEyOCl7bT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLG8pCnRocm93
-IEguYihtKX1lbHNle3Q9KHQ8PDZ8biY2Myk+Pj4wOy0tczsrK299fXdoaWxlKHM+MCkKbT1yLTEKaWYo
-bTwwfHxtPj00KXJldHVybiBILmsoQy5HYixtKQppZih0PD1DLkdiW21dKXttPVAucnIoIk92ZXJsb25n
-IGVuY29kaW5nIG9mIDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEpCnRocm93IEguYihtKX1pZih0PjEx
-MTQxMTEpe209UC5ycigiQ2hhcmFjdGVyIG91dHNpZGUgdmFsaWQgVW5pY29kZSByYW5nZTogMHgiK0Mu
-am4uV1oodCwxNiksYSxvLXItMSkKdGhyb3cgSC5iKG0pfWlmKCFoLmN8fHQhPT02NTI3OSlwLmErPUgu
-THcodCkKaC5jPSExfWZvcihtPW88YzttOyl7bD1QLmNQKGEsbyxjKQppZihsPjApe2guYz0hMQprPW8r
-bApwLmErPVAuSE0oYSxvLGspCmlmKGs9PT1jKWJyZWFrfWVsc2Ugaz1vCmo9aysxCm49cS5xKGEsaykK
-aWYodHlwZW9mIG4hPT0ibnVtYmVyIilyZXR1cm4gbi5KKCkKaWYobjwwKXtpPVAucnIoIk5lZ2F0aXZl
-IFVURi04IGNvZGUgdW5pdDogLTB4IitDLmpuLldaKC1uLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfWVs
-c2V7aWYoKG4mMjI0KT09PTE5Mil7dD1uJjMxCnM9MQpyPTEKY29udGludWUgJGxhYmVsMCQwfWlmKChu
-JjI0MCk9PT0yMjQpe3Q9biYxNQpzPTIKcj0yCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDgpPT09
-MjQwJiZuPDI0NSl7dD1uJjcKcz0zCnI9Mwpjb250aW51ZSAkbGFiZWwwJDB9aT1QLnJyKGcrQy5qbi5X
-WihuLDE2KSxhLGotMSkKdGhyb3cgSC5iKGkpfX1icmVhayAkbGFiZWwwJDB9aWYocz4wKXtoLmQ9dApo
-LmU9cwpoLmY9cn19fQpQLldGLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyCnUu
-Zm8uYShhKQp0PXRoaXMuYgpzPXRoaXMuYQp0LmErPXMuYQpyPXQuYSs9SC5kKGEuYSkKdC5hPXIrIjog
-Igp0LmErPVAuaChiKQpzLmE9IiwgIn0sCiRTOjQwfQpQLmEyLnByb3RvdHlwZT17fQpQLmlQLnByb3Rv
-dHlwZT17CkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5j
-ZW9mIFAuaVAmJnRoaXMuYT09PWIuYSYmITB9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJl
-dHVybih0XkMuam4ud0codCwzMCkpJjEwNzM3NDE4MjN9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMs
-cz1QLkdxKEgudEoodCkpLHI9UC5oMChILk5TKHQpKSxxPVAuaDAoSC5qQSh0KSkscD1QLmgwKEguSVgo
-dCkpLG89UC5oMChILmNoKHQpKSxuPVAuaDAoSC5KZCh0KSksbT1QLlZ4KEguVmEodCkpLGw9cysiLSIr
-cisiLSIrcSsiICIrcCsiOiIrbysiOiIrbisiLiIrbQpyZXR1cm4gbH19ClAuQ1AucHJvdG90eXBlPXt9
-ClAuWFMucHJvdG90eXBlPXsKZ0lJOmZ1bmN0aW9uKCl7cmV0dXJuIEgudHModGhpcy4kdGhyb3duSnNF
-cnJvcil9fQpQLkM2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQhPW51
-bGwpcmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5oKHQpCnJldHVybiJBc3NlcnRpb24gZmFpbGVk
-In19ClAuTEsucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVGhyb3cgb2YgbnVsbC4ifX0K
-UC5BVC5wcm90b3R5cGU9ewpnTDpmdW5jdGlvbigpe3JldHVybiJJbnZhbGlkIGFyZ3VtZW50IisoIXRo
-aXMuYT8iKHMpIjoiIil9LApndTpmdW5jdGlvbigpe3JldHVybiIifSwKWjpmdW5jdGlvbihhKXt2YXIg
-dCxzLHIscSxwPXRoaXMsbz1wLmMsbj1vIT1udWxsPyIgKCIrbysiKSI6IiIKbz1wLmQKdD1vPT1udWxs
-PyIiOiI6ICIrSC5kKG8pCnM9cC5nTCgpK24rdAppZighcC5hKXJldHVybiBzCnI9cC5ndSgpCnE9UC5o
-KHAuYikKcmV0dXJuIHMrcisiOiAiK3F9fQpQLmJKLnByb3RvdHlwZT17CmdMOmZ1bmN0aW9uKCl7cmV0
-dXJuIlJhbmdlRXJyb3IifSwKZ3U6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcy5lCmlmKHI9PW51bGwp
-e3I9dGhpcy5mCnQ9ciE9bnVsbD8iOiBOb3QgbGVzcyB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpOiIi
-fWVsc2V7cz10aGlzLmYKaWYocz09bnVsbCl0PSI6IE5vdCBncmVhdGVyIHRoYW4gb3IgZXF1YWwgdG8g
-IitILmQocikKZWxzZSBpZihzPnIpdD0iOiBOb3QgaW4gcmFuZ2UgIitILmQocikrIi4uIitILmQocykr
-IiwgaW5jbHVzaXZlIgplbHNlIHQ9czxyPyI6IFZhbGlkIHZhbHVlIHJhbmdlIGlzIGVtcHR5IjoiOiBP
-bmx5IHZhbGlkIHZhbHVlIGlzICIrSC5kKHIpfXJldHVybiB0fX0KUC5lWS5wcm90b3R5cGU9ewpnTDpm
-dW5jdGlvbigpe3JldHVybiJSYW5nZUVycm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscz1ILldZKHRo
-aXMuYikKaWYodHlwZW9mIHMhPT0ibnVtYmVyIilyZXR1cm4gcy5KKCkKaWYoczwwKXJldHVybiI6IGlu
-ZGV4IG11c3Qgbm90IGJlIG5lZ2F0aXZlIgp0PXRoaXMuZgppZih0PT09MClyZXR1cm4iOiBubyBpbmRp
-Y2VzIGFyZSB2YWxpZCIKcmV0dXJuIjogaW5kZXggc2hvdWxkIGJlIGxlc3MgdGhhbiAiK0guZCh0KX0s
-CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmZ9fQpQLm1wLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24o
-YSl7dmFyIHQscyxyLHEscCxvLG4sbSxsPXRoaXMsaz17fSxqPW5ldyBQLlJuKCIiKQprLmE9IiIKZm9y
-KHQ9bC5jLHM9dC5sZW5ndGgscj0wLHE9IiIscD0iIjtyPHM7KytyLHA9IiwgIil7bz10W3JdCmouYT1x
-K3AKcT1qLmErPVAuaChvKQprLmE9IiwgIn1sLmQuSygwLG5ldyBQLldGKGssaikpCm49UC5oKGwuYSkK
-bT1qLlooMCkKdD0iTm9TdWNoTWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciK0guZChsLmIu
-YSkrIidcblJlY2VpdmVyOiAiK24rIlxuQXJndW1lbnRzOiBbIittKyJdIgpyZXR1cm4gdH19ClAudWIu
-cHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXtyZXR1cm4iVW5zdXBwb3J0ZWQgb3BlcmF0aW9uOiAiK3Ro
-aXMuYX19ClAuZHMucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQh
-PW51bGw/IlVuaW1wbGVtZW50ZWRFcnJvcjogIit0OiJVbmltcGxlbWVudGVkRXJyb3IifX0KUC5sai5w
-cm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJCYWQgc3RhdGU6ICIrdGhpcy5hfX0KUC5VVi5w
-cm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQppZih0PT1udWxsKXJldHVybiJDb25j
-dXJyZW50IG1vZGlmaWNhdGlvbiBkdXJpbmcgaXRlcmF0aW9uLiIKcmV0dXJuIkNvbmN1cnJlbnQgbW9k
-aWZpY2F0aW9uIGR1cmluZyBpdGVyYXRpb246ICIrUC5oKHQpKyIuIn19ClAuazUucHJvdG90eXBlPXsK
-WjpmdW5jdGlvbihhKXtyZXR1cm4iT3V0IG9mIE1lbW9yeSJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4g
-bnVsbH0sCiRpWFM6MX0KUC5LWS5wcm90b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiJTdGFjayBP
-dmVyZmxvdyJ9LApnSUk6ZnVuY3Rpb24oKXtyZXR1cm4gbnVsbH0sCiRpWFM6MX0KUC50Ny5wcm90b3R5
-cGU9ewpaOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdD09bnVsbD8iUmVhZGluZyBzdGF0
-aWMgdmFyaWFibGUgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiI6IlJlYWRpbmcgc3RhdGljIHZhcmlh
-YmxlICciK3QrIicgZHVyaW5nIGl0cyBpbml0aWFsaXphdGlvbiJ9fQpQLkNELnByb3RvdHlwZT17Clo6
-ZnVuY3Rpb24oYSl7cmV0dXJuIkV4Y2VwdGlvbjogIit0aGlzLmF9LAokaVJ6OjF9ClAuYUUucHJvdG90
-eXBlPXsKWjpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaD10aGlzLmEsZz1o
-IT1udWxsJiYiIiE9PWg/IkZvcm1hdEV4Y2VwdGlvbjogIitILmQoaCk6IkZvcm1hdEV4Y2VwdGlvbiIs
-Zj10aGlzLmMsZT10aGlzLmIKaWYodHlwZW9mIGU9PSJzdHJpbmciKXtpZihmIT1udWxsKWg9ZjwwfHxm
-PmUubGVuZ3RoCmVsc2UgaD0hMQppZihoKWY9bnVsbAppZihmPT1udWxsKXt0PWUubGVuZ3RoPjc4P0Mu
-eEIuTmooZSwwLDc1KSsiLi4uIjplCnJldHVybiBnKyJcbiIrdH1mb3Iocz0xLHI9MCxxPSExLHA9MDtw
-PGY7KytwKXtvPUMueEIuVyhlLHApCmlmKG89PT0xMCl7aWYociE9PXB8fCFxKSsrcwpyPXArMQpxPSEx
-fWVsc2UgaWYobz09PTEzKXsrK3MKcj1wKzEKcT0hMH19Zz1zPjE/ZysoIiAoYXQgbGluZSAiK3MrIiwg
-Y2hhcmFjdGVyICIrKGYtcisxKSsiKVxuIik6ZysoIiAoYXQgY2hhcmFjdGVyICIrKGYrMSkrIilcbiIp
-Cm49ZS5sZW5ndGgKZm9yKHA9ZjtwPG47KytwKXtvPUMueEIubShlLHApCmlmKG89PT0xMHx8bz09PTEz
-KXtuPXAKYnJlYWt9fWlmKG4tcj43OClpZihmLXI8NzUpe209cis3NQpsPXIKaz0iIgpqPSIuLi4ifWVs
-c2V7aWYobi1mPDc1KXtsPW4tNzUKbT1uCmo9IiJ9ZWxzZXtsPWYtMzYKbT1mKzM2Cmo9Ii4uLiJ9az0i
-Li4uIn1lbHNle209bgpsPXIKaz0iIgpqPSIifWk9Qy54Qi5OaihlLGwsbSkKcmV0dXJuIGcraytpK2or
-IlxuIitDLnhCLkl4KCIgIixmLWwray5sZW5ndGgpKyJeXG4ifWVsc2UgcmV0dXJuIGYhPW51bGw/Zyso
-IiAoYXQgb2Zmc2V0ICIrSC5kKGYpKyIpIik6Z30sCiRpUno6MX0KUC5FSC5wcm90b3R5cGU9e30KUC5J
-Zi5wcm90b3R5cGU9e30KUC5jWC5wcm90b3R5cGU9ewpFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5M
-aCh0aGlzKQpyZXR1cm4gSC5LMSh0aGlzLHQuS3EoYykuQygiMShjWC5FKSIpLmEoYiksdC5DKCJjWC5F
-IiksYyl9LApldjpmdW5jdGlvbihhLGIpe3ZhciB0PUguTGgodGhpcykKcmV0dXJuIG5ldyBILlU1KHRo
-aXMsdC5DKCJhMihjWC5FKSIpLmEoYiksdC5DKCJVNTxjWC5FPiIpKX0sCmdBOmZ1bmN0aW9uKGEpe3Zh
-ciB0LHM9dGhpcy5na3oodGhpcykKZm9yKHQ9MDtzLkYoKTspKyt0CnJldHVybiB0fSwKZ2wwOmZ1bmN0
-aW9uKGEpe3JldHVybiF0aGlzLmdreih0aGlzKS5GKCl9LApncjg6ZnVuY3Rpb24oYSl7dmFyIHQscz10
-aGlzLmdreih0aGlzKQppZighcy5GKCkpdGhyb3cgSC5iKEguV3AoKSkKdD1zLmdsKCkKaWYocy5GKCkp
-dGhyb3cgSC5iKEguZFUoKSkKcmV0dXJuIHR9LApFOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHE9Imlu
-ZGV4IgpQLlVJKGIscSx1LnApClAuazEoYixxKQpmb3IodD10aGlzLmdreih0aGlzKSxzPTA7dC5GKCk7
-KXtyPXQuZ2woKQppZihiPT09cylyZXR1cm4gcjsrK3N9dGhyb3cgSC5iKFAudChiLHRoaXMscSxudWxs
-LHMpKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90
-eXBlPXt9ClAuek0ucHJvdG90eXBlPXskaWJROjEsJGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLk4z
-LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5kKHRoaXMuYSkrIjog
-IitILmQodGhpcy5iKSsiKSJ9fQpQLmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4g
-UC5NaC5wcm90b3R5cGUuZ2lPLmNhbGwodGhpcyx0aGlzKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIm51
-bGwifX0KUC5sZi5wcm90b3R5cGU9e30KUC5NaC5wcm90b3R5cGU9e2NvbnN0cnVjdG9yOlAuTWgsJGlN
-aDoxLApETjpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzPT09Yn0sCmdpTzpmdW5jdGlvbihhKXtyZXR1
-cm4gSC5lUSh0aGlzKX0sClo6ZnVuY3Rpb24oYSl7cmV0dXJuIkluc3RhbmNlIG9mICciK0guZChILmxo
-KHRoaXMpKSsiJyJ9LAplNzpmdW5jdGlvbihhLGIpe3Uuby5hKGIpCnRocm93IEguYihQLmxyKHRoaXMs
-Yi5nV2EoKSxiLmduZCgpLGIuZ1ZtKCkpKX0sCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMu
-Wih0aGlzKX19ClAuT2QucHJvdG90eXBlPXt9ClAuaWIucHJvdG90eXBlPXskaU9kOjF9ClAueHUucHJv
-dG90eXBlPXt9ClAuR3oucHJvdG90eXBlPXt9ClAuWmQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
-ZXR1cm4iIn0sCiRpR3o6MX0KUC5xVS5wcm90b3R5cGU9eyRpdlg6MX0KUC5Sbi5wcm90b3R5cGU9ewpn
-QTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmxlbmd0aH0sClo6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
-cy5hCnJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGlCTDoxfQpQLkdELnByb3RvdHlwZT17
-fQpQLm4xLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5mLmEoYSkKSC5j
-KGIpCnQ9Si5yWShiKS5PWShiLCI9IikKaWYodD09PS0xKXtpZihiIT09IiIpYS5ZKDAsUC5rdShiLDAs
-Yi5sZW5ndGgsdGhpcy5hLCEwKSwiIil9ZWxzZSBpZih0IT09MCl7cz1DLnhCLk5qKGIsMCx0KQpyPUMu
-eEIuRyhiLHQrMSkKcT10aGlzLmEKYS5ZKDAsUC5rdShzLDAscy5sZW5ndGgscSwhMCksUC5rdShyLDAs
-ci5sZW5ndGgscSwhMCkpfXJldHVybiBhfSwKJFM6NDR9ClAuY1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rp
-b24oYSxiKXt0aHJvdyBILmIoUC5ycigiSWxsZWdhbCBJUHY0IGFkZHJlc3MsICIrYSx0aGlzLmEsYikp
-fSwKJFM6MTl9ClAuVkMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aHJvdyBILmIoUC5ycigi
-SWxsZWdhbCBJUHY2IGFkZHJlc3MsICIrYSx0aGlzLmEsYikpfSwKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
-IHRoaXMuJDIoYSxudWxsKX0sCiRTOjQ4fQpQLkpULnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
-dmFyIHQKaWYoYi1hPjQpdGhpcy5hLiQyKCJhbiBJUHY2IHBhcnQgY2FuIG9ubHkgY29udGFpbiBhIG1h
-eGltdW0gb2YgNCBoZXggZGlnaXRzIixhKQp0PVAuUUEoQy54Qi5Oaih0aGlzLmIsYSxiKSxudWxsLDE2
-KQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PDB8fHQ+NjU1MzUpdGhpcy5h
-LiQyKCJlYWNoIHBhcnQgbXVzdCBiZSBpbiB0aGUgcmFuZ2Ugb2YgYDB4MC4uMHhGRkZGYCIsYSkKcmV0
-dXJuIHR9LAokUzo0OX0KUC5Ebi5wcm90b3R5cGU9ewpna3U6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5i
-fSwKZ0pmOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwppZih0PT1udWxsKXJldHVybiIiCmlmKEMueEIu
-bih0LCJbIikpcmV0dXJuIEMueEIuTmoodCwxLHQubGVuZ3RoLTEpCnJldHVybiB0fSwKZ3RwOmZ1bmN0
-aW9uKGEpe3ZhciB0PXRoaXMuZAppZih0PT1udWxsKXJldHVybiBQLndLKHRoaXMuYSkKcmV0dXJuIHR9
-LApndFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKcmV0dXJuIHQ9PW51bGw/IiI6dH0sCmdLYTpmdW5j
-dGlvbigpe3ZhciB0PXRoaXMucgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKbm06ZnVuY3Rpb24oYSxiKXt2
-YXIgdCxzLHIscSxwLG8sbixtLGw9dGhpcwp1LlguYShudWxsKQp1LmsuYShiKQp0PWwuYQpzPXQ9PT0i
-ZmlsZSIKcj1sLmIKcT1sLmQKcD1sLmMKaWYoIShwIT1udWxsKSlwPXIubGVuZ3RoIT09MHx8cSE9bnVs
-bHx8cz8iIjpudWxsCm89bC5lCmlmKCFzKW49cCE9bnVsbCYmby5sZW5ndGghPT0wCmVsc2Ugbj0hMApp
-ZihuJiYhQy54Qi5uKG8sIi8iKSlvPSIvIitvCm09UC5sZShudWxsLDAsMCxiKQpyZXR1cm4gbmV3IFAu
-RG4odCxyLHAscSxvLG0sbC5yKX0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHM9dGhpcy54CmlmKHMhPW51
-bGwpcmV0dXJuIHMKdD10aGlzLmUKaWYodC5sZW5ndGghPT0wJiZDLnhCLlcodCwwKT09PTQ3KXQ9Qy54
-Qi5HKHQsMSkKcz10PT09IiI/Qy54RDpQLkFGKG5ldyBILmxKKEguVk0odC5zcGxpdCgiLyIpLHUucyks
-dS5kTy5hKFAuUEgoKSksdS5kbyksdS5OKQp0aGlzLnNvNihzKQpyZXR1cm4gc30sCmdoWTpmdW5jdGlv
-bigpe3ZhciB0LHM9dGhpcwppZihzLlE9PW51bGwpe3Q9cy5mCnMuc1JIKG5ldyBQLkdqKFAuV1godD09
-bnVsbD8iIjp0KSx1LnYpKX1yZXR1cm4gcy5RfSwKSmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxw
-LG8KZm9yKHQ9MCxzPTA7Qy54Qi5RaShiLCIuLi8iLHMpOyl7cys9MzsrK3R9cj1DLnhCLmNuKGEsIi8i
-KQp3aGlsZSghMCl7aWYoIShyPjAmJnQ+MCkpYnJlYWsKcT1DLnhCLlBrKGEsIi8iLHItMSkKaWYocTww
-KWJyZWFrCnA9ci1xCm89cCE9PTIKaWYoIW98fHA9PT0zKWlmKEMueEIubShhLHErMSk9PT00NilvPSFv
-fHxDLnhCLm0oYSxxKzIpPT09NDYKZWxzZSBvPSExCmVsc2Ugbz0hMQppZihvKWJyZWFrOy0tdApyPXF9
-cmV0dXJuIEMueEIuaTcoYSxyKzEsbnVsbCxDLnhCLkcoYixzLTMqdCkpfSwKWkk6ZnVuY3Rpb24oYSl7
-cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsaz10aGlzLGo9bnVsbAppZihhLmdGaSgpLmxlbmd0aCE9PTApe3Q9YS5nRmkoKQppZihhLmdjaigp
-KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPWEuZ3hBKCk/YS5ndHAoYSk6an1lbHNle3E9agpyPXEKcz0i
-In1wPVAueGUoYS5nSWkoYSkpCm89YS5nUUQoKT9hLmd0UCgpOmp9ZWxzZXt0PWsuYQppZihhLmdjaigp
-KXtzPWEuZ2t1KCkKcj1hLmdKZihhKQpxPVAud0IoYS5neEEoKT9hLmd0cChhKTpqLHQpCnA9UC54ZShh
-LmdJaShhKSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3M9ay5iCnI9ay5jCnE9ay5kCmlmKGEuZ0lp
-KGEpPT09IiIpe3A9ay5lCm89YS5nUUQoKT9hLmd0UCgpOmsuZn1lbHNle2lmKGEuZ3RUKCkpcD1QLnhl
-KGEuZ0lpKGEpKQplbHNle249ay5lCmlmKG4ubGVuZ3RoPT09MClpZihyPT1udWxsKXA9dC5sZW5ndGg9
-PT0wP2EuZ0lpKGEpOlAueGUoYS5nSWkoYSkpCmVsc2UgcD1QLnhlKCIvIithLmdJaShhKSkKZWxzZXtt
-PWsuSmgobixhLmdJaShhKSkKbD10Lmxlbmd0aD09PTAKaWYoIWx8fHIhPW51bGx8fEMueEIubihuLCIv
-IikpcD1QLnhlKG0pCmVsc2UgcD1QLndGKG0sIWx8fHIhPW51bGwpfX1vPWEuZ1FEKCk/YS5ndFAoKTpq
-fX19cmV0dXJuIG5ldyBQLkRuKHQscyxyLHEscCxvLGEuZ1o4KCk/YS5nS2EoKTpqKX0sCmdjajpmdW5j
-dGlvbigpe3JldHVybiB0aGlzLmMhPW51bGx9LApneEE6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kIT1u
-dWxsfSwKZ1FEOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuZiE9bnVsbH0sCmdaODpmdW5jdGlvbigpe3Jl
-dHVybiB0aGlzLnIhPW51bGx9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5uKHRoaXMuZSwiLyIp
-fSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHI9dGhpcyxxPXIuYQppZihxIT09IiImJnEhPT0iZmlsZSIp
-dGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChxKSsi
-IFVSSSIpKQpxPXIuZgppZigocT09bnVsbD8iIjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3Qg
-ZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKcT1y
-LnIKaWYoKHE9PW51bGw/IiI6cSkhPT0iIil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBm
-aWxlIHBhdGggZnJvbSBhIFVSSSB3aXRoIGEgZnJhZ21lbnQgY29tcG9uZW50IikpCnQ9JC5PeCgpCmlm
-KEgub1QodCkpcT1QLm1uKHIpCmVsc2V7aWYoci5jIT1udWxsJiZyLmdKZihyKSE9PSIiKUgudmgoUC5M
-NCgiQ2Fubm90IGV4dHJhY3QgYSBub24tV2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdp
-dGggYW4gYXV0aG9yaXR5IikpCnM9ci5nRmooKQpQLmtFKHMsITEpCnE9UC52ZyhDLnhCLm4oci5lLCIv
-Iik/Ii8iOiIiLHMsIi8iKQpxPXEuY2hhckNvZGVBdCgwKT09MD9xOnF9cmV0dXJuIHF9LApaOmZ1bmN0
-aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD1xLnkKaWYocD09bnVsbCl7cD1xLmEKdD1wLmxlbmd0aCE9
-PTA/cCsiOiI6IiIKcz1xLmMKcj1zPT1udWxsCmlmKCFyfHxwPT09ImZpbGUiKXtwPXQrIi8vIgp0PXEu
-YgppZih0Lmxlbmd0aCE9PTApcD1wK3QrIkAiCmlmKCFyKXArPXMKdD1xLmQKaWYodCE9bnVsbClwPXAr
-IjoiK0guZCh0KX1lbHNlIHA9dApwKz1xLmUKdD1xLmYKaWYodCE9bnVsbClwPXArIj8iK3QKdD1xLnIK
-aWYodCE9bnVsbClwPXArIiMiK3QKcD1xLnk9cC5jaGFyQ29kZUF0KDApPT0wP3A6cH1yZXR1cm4gcH0s
-CkROOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKaWYoYj09bnVsbClyZXR1cm4hMQppZihyPT09
-YilyZXR1cm4hMAppZih1LncuYihiKSlpZihyLmE9PWIuZ0ZpKCkpaWYoci5jIT1udWxsPT09Yi5nY2oo
-KSlpZihyLmI9PWIuZ2t1KCkpaWYoci5nSmYocik9PWIuZ0pmKGIpKWlmKHIuZ3RwKHIpPT1iLmd0cChi
-KSlpZihyLmU9PT1iLmdJaShiKSl7dD1yLmYKcz10PT1udWxsCmlmKCFzPT09Yi5nUUQoKSl7aWYocyl0
-PSIiCmlmKHQ9PT1iLmd0UCgpKXt0PXIucgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdaOCgpKXtpZihzKXQ9
-IiIKdD10PT09Yi5nS2EoKX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMX1lbHNlIHQ9ITEKZWxz
-ZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQplbHNlIHQ9ITEKcmV0
-dXJuIHR9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy56CnJldHVybiB0PT1udWxsP3RoaXMuej1D
-LnhCLmdpTyh0aGlzLlooMCkpOnR9LApzbzY6ZnVuY3Rpb24oYSl7dGhpcy54PXUuYS5hKGEpfSwKc1JI
-OmZ1bmN0aW9uKGEpe3RoaXMuUT11LmYuYShhKX0sCiRpaUQ6MSwKZ0ZpOmZ1bmN0aW9uKCl7cmV0dXJu
-IHRoaXMuYX0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5lfX0KUC5lMS5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt0aHJvdyBILmIoUC5ycigiSW52YWxpZCBwb3J0Iix0aGlzLmEsdGhpcy5iKzEp
-KX0sCiRTOjEzfQpQLk5ZLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PSJJbGxlZ2FsIHBh
-dGggY2hhcmFjdGVyICIKSC5jKGEpCmlmKEouemwoYSwiLyIpKWlmKHRoaXMuYSl0aHJvdyBILmIoUC54
-WSh0K2EpKQplbHNlIHRocm93IEguYihQLkw0KHQrYSkpfSwKJFM6MTN9ClAuUloucHJvdG90eXBlPXsK
-JDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFAuZVAoQy5aSixILmMoYSksQy54TSwhMSl9LAokUzo1fQpQLk1F
-LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5iLHM9dGhpcy5hCnQuYSs9cy5h
-CnMuYT0iJiIKcz10LmErPUguZChQLmVQKEMuRjMsYSxDLnhNLCEwKSkKaWYoYiE9bnVsbCYmYi5sZW5n
-dGghPT0wKXt0LmE9cysiPSIKdC5hKz1ILmQoUC5lUChDLkYzLGIsQy54TSwhMCkpfX0sCiRTOjIyfQpQ
-Lnk1LnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7dmFyIHQscwpILmMoYSkKaWYoYj09bnVsbHx8
-dHlwZW9mIGI9PSJzdHJpbmciKXRoaXMuYS4kMihhLEguYyhiKSkKZWxzZSBmb3IodD1KLklUKHUuUi5h
-KGIpKSxzPXRoaXMuYTt0LkYoKTspcy4kMihhLEguYyh0LmdsKCkpKX0sCiRTOjEyfQpQLlBFLnByb3Rv
-dHlwZT17CmdsUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcyxvPW51bGwsbj1wLmMKaWYobiE9
-bnVsbClyZXR1cm4gbgpuPXAuYgppZigwPj1uLmxlbmd0aClyZXR1cm4gSC5rKG4sMCkKdD1wLmEKbj1u
-WzBdKzEKcz1DLnhCLlhVKHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLlBJKHQscysxLHIs
-Qy5WQywhMSkKcj1zfWVsc2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAuUEko
-dCxuLHIsQy5XZCwhMSkscSxvKX0sClo6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5s
-ZW5ndGgpcmV0dXJuIEguayhzLDApCnQ9dGhpcy5hCnJldHVybiBzWzBdPT09LTE/ImRhdGE6Iit0OnR9
-fQpQLnEzLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVWludDhBcnJheSg5Nil9
-LAokUzoyM30KUC55SS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYQppZihh
-Pj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYSkKdD10W2FdCkouQ00odCwwLDk2LGIpCnJldHVybiB0fSwK
-JFM6MjR9ClAuYzYucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixxCmZvcih0
-PWIubGVuZ3RoLHM9YS5sZW5ndGgscj0wO3I8dDsrK3Ipe3E9Qy54Qi5XKGIscileOTYKaWYocT49cyly
-ZXR1cm4gSC5rKGEscSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMp
-e3ZhciB0LHMscixxCmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1z
-OysrdCl7cT0odF45Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguayhhLHEpCmFbcV09Y319fQpQLlVmLnBy
-b3RvdHlwZT17CmdjajpmdW5jdGlvbigpe3JldHVybiB0aGlzLmM+MH0sCmd4QTpmdW5jdGlvbigpe3Zh
-ciB0LHMKaWYodGhpcy5jPjApe3Q9dGhpcy5kCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQu
-aCgpCnM9dGhpcy5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIEgucFkocykKcz10KzE8cwp0
-PXN9ZWxzZSB0PSExCnJldHVybiB0fSwKZ1FEOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5mCmlmKHR5cGVv
-ZiB0IT09Im51bWJlciIpcmV0dXJuIHQuSigpCnJldHVybiB0PHRoaXMucn0sCmdaODpmdW5jdGlvbigp
-e3JldHVybiB0aGlzLnI8dGhpcy5hLmxlbmd0aH0sCmdOdzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9
-PT00JiZDLnhCLm4odGhpcy5hLCJmaWxlIil9LApndmg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09
-NCYmQy54Qi5uKHRoaXMuYSwiaHR0cCIpfSwKZ1JlOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTUm
-JkMueEIubih0aGlzLmEsImh0dHBzIil9LApndFQ6ZnVuY3Rpb24oKXtyZXR1cm4gQy54Qi5RaSh0aGlz
-LmEsIi8iLHRoaXMuZSl9LApnRmk6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMscj0icGFja2FnZSIscT1z
-LmIKaWYocTw9MClyZXR1cm4iIgp0PXMueAppZih0IT1udWxsKXJldHVybiB0CmlmKHMuZ3ZoKCkpcT1z
-Lng9Imh0dHAiCmVsc2UgaWYocy5nUmUoKSl7cy54PSJodHRwcyIKcT0iaHR0cHMifWVsc2UgaWYocy5n
-TncoKSl7cy54PSJmaWxlIgpxPSJmaWxlIn1lbHNlIGlmKHE9PT03JiZDLnhCLm4ocy5hLHIpKXtzLng9
-cgpxPXJ9ZWxzZXtxPUMueEIuTmoocy5hLDAscSkKcy54PXF9cmV0dXJuIHF9LApna3U6ZnVuY3Rpb24o
-KXt2YXIgdD10aGlzLmMscz10aGlzLmIrMwpyZXR1cm4gdD5zP0MueEIuTmoodGhpcy5hLHMsdC0xKToi
-In0sCmdKZjpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmMKcmV0dXJuIHQ+MD9DLnhCLk5qKHRoaXMuYSx0
-LHRoaXMuZCk6IiJ9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzCmlmKHMuZ3hBKCkpe3Q9cy5k
-CmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQuaCgpCnJldHVybiBQLlFBKEMueEIuTmoocy5h
-LHQrMSxzLmUpLG51bGwsbnVsbCl9aWYocy5ndmgoKSlyZXR1cm4gODAKaWYocy5nUmUoKSlyZXR1cm4g
-NDQzCnJldHVybiAwfSwKZ0lpOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLk5qKHRoaXMuYSx0aGlzLmUs
-dGhpcy5mKX0sCmd0UDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZixzPXRoaXMucgppZih0eXBlb2YgdCE9
-PSJudW1iZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDxzP0MueEIuTmoodGhpcy5hLHQrMSxzKToiIn0s
-CmdLYTpmdW5jdGlvbigpe3ZhciB0PXRoaXMucixzPXRoaXMuYQpyZXR1cm4gdDxzLmxlbmd0aD9DLnhC
-Lkcocyx0KzEpOiIifSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMuZSxxPXRoaXMuZixwPXRo
-aXMuYQppZihDLnhCLlFpKHAsIi8iLHIpKXtpZih0eXBlb2YgciE9PSJudW1iZXIiKXJldHVybiByLmgo
-KTsrK3J9aWYocj09cSlyZXR1cm4gQy54RAp0PUguVk0oW10sdS5zKQpzPXIKd2hpbGUoITApe2lmKHR5
-cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHR5cGVvZiBxIT09Im51bWJlciIpcmV0dXJu
-IEgucFkocSkKaWYoIShzPHEpKWJyZWFrCmlmKEMueEIubShwLHMpPT09NDcpe0MuTm0uaSh0LEMueEIu
-TmoocCxyLHMpKQpyPXMrMX0rK3N9Qy5ObS5pKHQsQy54Qi5OaihwLHIscSkpCnJldHVybiBQLkFGKHQs
-dS5OKX0sCmdoWTpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJl
-dHVybiB0LkooKQppZih0Pj10aGlzLnIpcmV0dXJuIEMuV08KcmV0dXJuIG5ldyBQLkdqKFAuV1godGhp
-cy5ndFAoKSksdS52KX0sCmtYOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcy5kCmlmKHR5cGVvZiBzIT09
-Im51bWJlciIpcmV0dXJuIHMuaCgpCnQ9cysxCnJldHVybiB0K2EubGVuZ3RoPT09dGhpcy5lJiZDLnhC
-LlFpKHRoaXMuYSxhLHQpfSwKTjk6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5yLHI9dC5hCmlmKHM+
-PXIubGVuZ3RoKXJldHVybiB0CnJldHVybiBuZXcgUC5VZihDLnhCLk5qKHIsMCxzKSx0LmIsdC5jLHQu
-ZCx0LmUsdC5mLHMsdC54KX0sCm5tOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvLG4sbSxsLGss
-aj10aGlzLGk9bnVsbAp1LlguYShudWxsKQp1LmsuYShiKQp0PWouZ0ZpKCkKcz10PT09ImZpbGUiCnI9
-ai5jCnE9cj4wP0MueEIuTmooai5hLGouYiszLHIpOiIiCnA9ai5neEEoKT9qLmd0cChqKTppCnI9ai5j
-CmlmKHI+MClvPUMueEIuTmooai5hLHIsai5kKQplbHNlIG89cS5sZW5ndGghPT0wfHxwIT1udWxsfHxz
-PyIiOmkKcj1qLmEKbj1DLnhCLk5qKHIsai5lLGouZikKaWYoIXMpbT1vIT1udWxsJiZuLmxlbmd0aCE9
-PTAKZWxzZSBtPSEwCmlmKG0mJiFDLnhCLm4obiwiLyIpKW49Ii8iK24KbD1QLmxlKGksMCwwLGIpCm09
-ai5yCms9bTxyLmxlbmd0aD9DLnhCLkcocixtKzEpOmkKcmV0dXJuIG5ldyBQLkRuKHQscSxvLHAsbixs
-LGspfSwKWkk6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMubVMoUC5oSyhhKSl9LAptUzpmdW5jdGlvbihh
-KXtpZihhIGluc3RhbmNlb2YgUC5VZilyZXR1cm4gdGhpcy51MSh0aGlzLGEpCnJldHVybiB0aGlzLnZz
-KCkubVMoYSl9LAp1MTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcs
-ZixlPWIuYgppZihlPjApcmV0dXJuIGIKdD1iLmMKaWYodD4wKXtzPWEuYgppZihzPD0wKXJldHVybiBi
-CmlmKGEuZ053KCkpcj1iLmUhPWIuZgplbHNlIGlmKGEuZ3ZoKCkpcj0hYi5rWCgiODAiKQplbHNlIHI9
-IWEuZ1JlKCl8fCFiLmtYKCI0NDMiKQppZihyKXtxPXMrMQpwPUMueEIuTmooYS5hLDAscSkrQy54Qi5H
-KGIuYSxlKzEpCmU9Yi5kCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCm89Yi5lCmlm
-KHR5cGVvZiBvIT09Im51bWJlciIpcmV0dXJuIG8uaCgpCm49Yi5mCmlmKHR5cGVvZiBuIT09Im51bWJl
-ciIpcmV0dXJuIG4uaCgpCnJldHVybiBuZXcgUC5VZihwLHMsdCtxLGUrcSxvK3EsbitxLGIucitxLGEu
-eCl9ZWxzZSByZXR1cm4gdGhpcy52cygpLm1TKGIpfW09Yi5lCmU9Yi5mCmlmKG09PWUpe3Q9Yi5yCmlm
-KHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuSigpCmlmKGU8dCl7cz1hLmYKaWYodHlwZW9mIHMh
-PT0ibnVtYmVyIilyZXR1cm4gcy5ITigpCnE9cy1lCnJldHVybiBuZXcgUC5VZihDLnhCLk5qKGEuYSww
-LHMpK0MueEIuRyhiLmEsZSksYS5iLGEuYyxhLmQsYS5lLGUrcSx0K3EsYS54KX1lPWIuYQppZih0PGUu
-bGVuZ3RoKXtzPWEucgpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkcoZSx0KSxh
-LmIsYS5jLGEuZCxhLmUsYS5mLHQrKHMtdCksYS54KX1yZXR1cm4gYS5OOSgpfXQ9Yi5hCmlmKEMueEIu
-UWkodCwiLyIsbSkpe3M9YS5lCmlmKHR5cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSE4oKQppZih0
-eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBILnBZKG0pCnE9cy1tCnA9Qy54Qi5OaihhLmEsMCxzKStD
-LnhCLkcodCxtKQppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAu
-VWYocCxhLmIsYS5jLGEuZCxzLGUrcSxiLnIrcSxhLngpfWw9YS5lCms9YS5mCmlmKGw9PWsmJmEuYz4w
-KXtmb3IoO0MueEIuUWkodCwiLi4vIixtKTspe2lmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0u
-aCgpCm0rPTN9aWYodHlwZW9mIGwhPT0ibnVtYmVyIilyZXR1cm4gbC5ITigpCmlmKHR5cGVvZiBtIT09
-Im51bWJlciIpcmV0dXJuIEgucFkobSkKcT1sLW0rMQpwPUMueEIuTmooYS5hLDAsbCkrIi8iK0MueEIu
-Ryh0LG0pCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJuIGUuaCgpCnJldHVybiBuZXcgUC5VZihw
-LGEuYixhLmMsYS5kLGwsZStxLGIucitxLGEueCl9aj1hLmEKZm9yKGk9bDtDLnhCLlFpKGosIi4uLyIs
-aSk7KXtpZih0eXBlb2YgaSE9PSJudW1iZXIiKXJldHVybiBpLmgoKQppKz0zfWg9MAp3aGlsZSghMCl7
-aWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4gbS5oKCkKZz1tKzMKaWYodHlwZW9mIGUhPT0ibnVt
-YmVyIilyZXR1cm4gSC5wWShlKQppZighKGc8PWUmJkMueEIuUWkodCwiLi4vIixtKSkpYnJlYWs7Kyto
-Cm09Z31mPSIiCndoaWxlKCEwKXtpZih0eXBlb2YgayE9PSJudW1iZXIiKXJldHVybiBrLm9zKCkKaWYo
-dHlwZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gSC5wWShpKQppZighKGs+aSkpYnJlYWs7LS1rCmlmKEMu
-eEIubShqLGspPT09NDcpe2lmKGg9PT0wKXtmPSIvIgpicmVha30tLWgKZj0iLyJ9fWlmKGs9PT1pJiZh
-LmI8PTAmJiFDLnhCLlFpKGosIi8iLGwpKXttLT1oKjMKZj0iIn1xPWstbStmLmxlbmd0aApyZXR1cm4g
-bmV3IFAuVWYoQy54Qi5OaihqLDAsaykrZitDLnhCLkcodCxtKSxhLmIsYS5jLGEuZCxsLGUrcSxiLnIr
-cSxhLngpfSwKdDQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMKaWYocC5iPj0wJiYhcC5nTnco
-KSl0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHAu
-Z0ZpKCkpKyIgVVJJIikpCnQ9cC5mCnM9cC5hCmlmKHR5cGVvZiB0IT09Im51bWJlciIpcmV0dXJuIHQu
-SigpCmlmKHQ8cy5sZW5ndGgpe2lmKHQ8cC5yKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBh
-IGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBxdWVyeSBjb21wb25lbnQiKSkKdGhyb3cgSC5iKFAu
-TDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSBVUkkgd2l0aCBhIGZyYWdtZW50IGNv
-bXBvbmVudCIpKX1yPSQuT3goKQppZihILm9UKHIpKXQ9UC5tbihwKQplbHNle3E9cC5kCmlmKHR5cGVv
-ZiBxIT09Im51bWJlciIpcmV0dXJuIEgucFkocSkKaWYocC5jPHEpSC52aChQLkw0KCJDYW5ub3QgZXh0
-cmFjdCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3Jp
-dHkiKSkKdD1DLnhCLk5qKHMscC5lLHQpfXJldHVybiB0fSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
-aXMueQpyZXR1cm4gdD09bnVsbD90aGlzLnk9Qy54Qi5naU8odGhpcy5hKTp0fSwKRE46ZnVuY3Rpb24o
-YSxiKXtpZihiPT1udWxsKXJldHVybiExCmlmKHRoaXM9PT1iKXJldHVybiEwCnJldHVybiB1LncuYihi
-KSYmdGhpcy5hPT09Yi5aKDApfSwKdnM6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9bnVsbCxyPXQuZ0Zp
-KCkscT10LmdrdSgpLHA9dC5jPjA/dC5nSmYodCk6cyxvPXQuZ3hBKCk/dC5ndHAodCk6cyxuPXQuYSxt
-PXQuZixsPUMueEIuTmoobix0LmUsbSksaz10LnIKaWYodHlwZW9mIG0hPT0ibnVtYmVyIilyZXR1cm4g
-bS5KKCkKbT1tPGs/dC5ndFAoKTpzCnJldHVybiBuZXcgUC5EbihyLHEscCxvLGwsbSxrPG4ubGVuZ3Ro
-P3QuZ0thKCk6cyl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokaWlEOjF9ClAucWUucHJv
-dG90eXBlPXt9ClcucUUucHJvdG90eXBlPXt9ClcuR2gucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
-ZXR1cm4gU3RyaW5nKGEpfSwKJGlHaDoxfQpXLmZZLnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIFN0cmluZyhhKX19ClcubkIucHJvdG90eXBlPXskaW5COjF9ClcuQXoucHJvdG90eXBlPXskaUF6
-OjF9ClcuUVAucHJvdG90eXBlPXskaVFQOjF9ClcubngucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7
-cmV0dXJuIGEubGVuZ3RofX0KVy5vSi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
-ZW5ndGh9fQpXLmlkLnByb3RvdHlwZT17fQpXLlFGLnByb3RvdHlwZT17fQpXLk5oLnByb3RvdHlwZT17
-Clo6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmluZyhhKX19ClcuSUIucHJvdG90eXBlPXsKWjpmdW5jdGlv
-bihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0gu
-ZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxs
-KXJldHVybiExCnJldHVybiB1LnEuYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53
-aWR0aD09Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBX
-LnJFKEouaGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX0s
-CiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpX
-Lnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3RofSwKcTpmdW5j
-dGlvbihhLGIpe3ZhciB0CkguV1koYikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4g
-SC5rKHQsYikKcmV0dXJuIHRoaXMuJHRpLmMuYSh0W2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMu
-JHRpLmMuYShjKQp0aHJvdyBILmIoUC5MNCgiQ2Fubm90IG1vZGlmeSBsaXN0IikpfX0KVy5jdi5wcm90
-b3R5cGU9ewpnUWc6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBXLmk3KGEpfSwKZ1A6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBXLkk0KGEpfSwKc1A6ZnVuY3Rpb24oYSxiKXt2YXIgdAp1LlguYShiKQp0PXRoaXMu
-Z1AoYSkKdC5WMSgwKQp0LkZWKDAsYil9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2FsTmFtZX0s
-CkZGOmZ1bmN0aW9uKGEpe3ZhciB0PSEhYS5zY3JvbGxJbnRvVmlld0lmTmVlZGVkCmlmKHQpYS5zY3Jv
-bGxJbnRvVmlld0lmTmVlZGVkKCkKZWxzZSBhLnNjcm9sbEludG9WaWV3KCl9LApuejpmdW5jdGlvbihh
-LGIsYyxkLGUpe3ZhciB0LHM9dGhpcy5yNihhLGMsZCxlKQpzd2l0Y2goYi50b0xvd2VyQ2FzZSgpKXtj
-YXNlImJlZm9yZWJlZ2luIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYSkKYnJlYWsKY2FzZSJh
-ZnRlcmJlZ2luIjp0PWEuY2hpbGROb2RlcwphLmluc2VydEJlZm9yZShzLHQubGVuZ3RoPjA/dFswXTpu
-dWxsKQpicmVhawpjYXNlImJlZm9yZWVuZCI6YS5hcHBlbmRDaGlsZChzKQpicmVhawpjYXNlImFmdGVy
-ZW5kIjphLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKHMsYS5uZXh0U2libGluZykKYnJlYWsKZGVmYXVs
-dDpILnZoKFAueFkoIkludmFsaWQgcG9zaXRpb24gIitiKSl9fSwKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7
-dmFyIHQscyxyLHEKaWYoYz09bnVsbCl7aWYoZD09bnVsbCl7dD0kLmx0CmlmKHQ9PW51bGwpe3Q9SC5W
-TShbXSx1LmkpCnM9bmV3IFcudkQodCkKQy5ObS5pKHQsVy5UdyhudWxsKSkKQy5ObS5pKHQsVy5CbCgp
-KQokLmx0PXMKZD1zfWVsc2UgZD10fXQ9JC5FVQppZih0PT1udWxsKXt0PW5ldyBXLktvKGQpCiQuRVU9
-dApjPXR9ZWxzZXt0LmE9ZApjPXR9fWVsc2UgaWYoZCE9bnVsbCl0aHJvdyBILmIoUC54WSgidmFsaWRh
-dG9yIGNhbiBvbmx5IGJlIHBhc3NlZCBpZiB0cmVlU2FuaXRpemVyIGlzIG51bGwiKSkKaWYoJC54bz09
-bnVsbCl7dD1kb2N1bWVudApzPXQuaW1wbGVtZW50YXRpb24uY3JlYXRlSFRNTERvY3VtZW50KCIiKQok
-LnhvPXMKJC5CTz1zLmNyZWF0ZVJhbmdlKCkKcz0kLnhvLmNyZWF0ZUVsZW1lbnQoImJhc2UiKQp1LmNS
-LmEocykKcy5ocmVmPXQuYmFzZVVSSQokLnhvLmhlYWQuYXBwZW5kQ2hpbGQocyl9dD0kLnhvCmlmKHQu
-Ym9keT09bnVsbCl7cz10LmNyZWF0ZUVsZW1lbnQoImJvZHkiKQp0LmJvZHk9dS5ZLmEocyl9dD0kLnhv
-CmlmKHUuWS5iKGEpKXI9dC5ib2R5CmVsc2V7cj10LmNyZWF0ZUVsZW1lbnQoYS50YWdOYW1lKQokLnhv
-LmJvZHkuYXBwZW5kQ2hpbGQocil9aWYoImNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudCIgaW4gd2luZG93
-LlJhbmdlLnByb3RvdHlwZSYmIUMuTm0udGcoQy5TcSxhLnRhZ05hbWUpKXskLkJPLnNlbGVjdE5vZGVD
-b250ZW50cyhyKQpxPSQuQk8uY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50KGIpfWVsc2V7ci5pbm5lckhU
-TUw9YgpxPSQueG8uY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCmZvcig7dD1yLmZpcnN0Q2hpbGQsdCE9
-bnVsbDspcS5hcHBlbmRDaGlsZCh0KX10PSQueG8uYm9keQppZihyPT1udWxsP3QhPW51bGw6ciE9PXQp
-Si5MdChyKQpjLlBuKHEpCmRvY3VtZW50LmFkb3B0Tm9kZShxKQpyZXR1cm4gcX0sCkFIOmZ1bmN0aW9u
-KGEsYixjKXtyZXR1cm4gdGhpcy5yNihhLGIsYyxudWxsKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMu
-WUMoYSxiKX0sCnBrOmZ1bmN0aW9uKGEsYixjKXthLnRleHRDb250ZW50PW51bGwKYS5hcHBlbmRDaGls
-ZCh0aGlzLnI2KGEsYixudWxsLGMpKX0sCllDOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMucGsoYSxi
-LG51bGwpfSwKZ25zOmZ1bmN0aW9uKGEpe3JldHVybiBhLnRhZ05hbWV9LApnVmw6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBXLmV1KGEsImNsaWNrIiwhMSx1LlEpfSwKJGljdjoxfQpXLkN2LnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmguYih1LkEuYShhKSl9LAokUzoyNX0KVy5lYS5wcm90b3R5
-cGU9eyRpZWE6MX0KVy5EMC5wcm90b3R5cGU9ewpPbjpmdW5jdGlvbihhLGIsYyxkKXt1LlUuYShjKQpp
-ZihjIT1udWxsKXRoaXMudihhLGIsYyxkKX0sCkI6ZnVuY3Rpb24oYSxiLGMpe3JldHVybiB0aGlzLk9u
-KGEsYixjLG51bGwpfSwKdjpmdW5jdGlvbihhLGIsYyxkKXtyZXR1cm4gYS5hZGRFdmVudExpc3RlbmVy
-KGIsSC50Uih1LlUuYShjKSwxKSxkKX0sCiRpRDA6MX0KVy5oSC5wcm90b3R5cGU9eyRpaEg6MX0KVy5o
-NC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLmJyLnByb3RvdHlw
-ZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVmIucHJvdG90eXBlPXt9ClcuZkou
-cHJvdG90eXBlPXsKZW86ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEub3BlbihiLGMsITApfSwKJGlm
-SjoxfQpXLndhLnByb3RvdHlwZT17fQpXLlNnLnByb3RvdHlwZT17JGlTZzoxfQpXLnU4LnByb3RvdHlw
-ZT17CmdEcjpmdW5jdGlvbihhKXtpZigib3JpZ2luIiBpbiBhKXJldHVybiBhLm9yaWdpbgpyZXR1cm4g
-SC5kKGEucHJvdG9jb2wpKyIvLyIrSC5kKGEuaG9zdCl9LApaOmZ1bmN0aW9uKGEpe3JldHVybiBTdHJp
-bmcoYSl9LAokaXU4OjF9ClcuT0sucHJvdG90eXBlPXskaU9LOjF9ClcuZTcucHJvdG90eXBlPXsKZ3I4
-OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPXQuY2hpbGROb2Rlcy5sZW5ndGgKaWYocz09PTApdGhy
-b3cgSC5iKFAuUFYoIk5vIGVsZW1lbnRzIikpCmlmKHM+MSl0aHJvdyBILmIoUC5QVigiTW9yZSB0aGFu
-IG9uZSBlbGVtZW50IikpCnJldHVybiB0LmZpcnN0Q2hpbGR9LApGVjpmdW5jdGlvbihhLGIpe3ZhciB0
-LHMscixxCnUuZWguYShiKQp0PWIuYQpzPXRoaXMuYQppZih0IT09cylmb3Iocj10LmNoaWxkTm9kZXMu
-bGVuZ3RoLHE9MDtxPHI7KytxKXMuYXBwZW5kQ2hpbGQodC5maXJzdENoaWxkKQpyZXR1cm59LApZOmZ1
-bmN0aW9uKGEsYixjKXt2YXIgdCxzCnUuQS5hKGMpCnQ9dGhpcy5hCnM9dC5jaGlsZE5vZGVzCmlmKGI8
-MHx8Yj49cy5sZW5ndGgpcmV0dXJuIEguayhzLGIpCnQucmVwbGFjZUNoaWxkKGMsc1tiXSl9LApna3o6
-ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmNoaWxkTm9kZXMKcmV0dXJuIG5ldyBXLlc5KHQsdC5sZW5n
-dGgsSC5xKHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5jaGls
-ZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILldZKGIpCnQ9dGhpcy5hLmNoaWxk
-Tm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5rKHQsYikKcmV0dXJuIHRbYl19fQpXLnVI
-LnByb3RvdHlwZT17CndnOmZ1bmN0aW9uKGEpe3ZhciB0PWEucGFyZW50Tm9kZQppZih0IT1udWxsKXQu
-cmVtb3ZlQ2hpbGQoYSl9LApENDpmdW5jdGlvbihhKXt2YXIgdApmb3IoO3Q9YS5maXJzdENoaWxkLHQh
-PW51bGw7KWEucmVtb3ZlQ2hpbGQodCl9LApaOmZ1bmN0aW9uKGEpe3ZhciB0PWEubm9kZVZhbHVlCnJl
-dHVybiB0PT1udWxsP3RoaXMuVShhKTp0fSwKJGl1SDoxfQpXLkJILnByb3RvdHlwZT17CmdBOmZ1bmN0
-aW9uKGEpe3JldHVybiBhLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILldZKGIpCmlmKGI+Pj4wIT09
-Ynx8Yj49YS5sZW5ndGgpdGhyb3cgSC5iKFAudChiLGEsbnVsbCxudWxsLG51bGwpKQpyZXR1cm4gYVti
-XX0sClk6ZnVuY3Rpb24oYSxiLGMpe3UuQS5hKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgYXNzaWdu
-IGVsZW1lbnQgb2YgaW1tdXRhYmxlIExpc3QuIikpfSwKRTpmdW5jdGlvbihhLGIpe2lmKGI8MHx8Yj49
-YS5sZW5ndGgpcmV0dXJuIEguayhhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6
-MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17JGlldzoxfQpXLmxwLnBy
-b3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19ClcuVGIucHJvdG90eXBlPXsK
-cjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigiY3JlYXRlQ29udGV4dHVhbEZyYWdtZW50IiBp
-biB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixjLGQpCnQ9Vy5VOSgiPHRh
-YmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRvY3VtZW50LmNyZWF0ZURvY3VtZW50RnJhZ21l
-bnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxuZXcgVy5lNyh0KSkKcmV0
-dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQpe3ZhciB0LHMscixxCmlm
+dGhpcy4kdGkuY2hbMV0uYihhKX19CkguQTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IEouSG0odGhpcy5hKX0sCkU6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5iLiQxKEouR0EodGhpcy5h
+LGIpKX19CkguVTUucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgSC5TTyhKLklU
+KHRoaXMuYSksdGhpcy5iLHRoaXMuJHRpLkMoIlNPPDE+IikpfX0KSC5TTy5wcm90b3R5cGU9ewpGOmZ1
+bmN0aW9uKCl7dmFyIHQscwpmb3IodD10aGlzLmEscz10aGlzLmI7dC5GKCk7KWlmKEgub1Qocy4kMSh0
+LmdsKCkpKSlyZXR1cm4hMApyZXR1cm4hMX0sCmdsOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS5nbCgp
+fX0KSC5TVS5wcm90b3R5cGU9e30KSC5SZS5wcm90b3R5cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILkxo
+KHRoaXMpLkMoIlJlLkUiKS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5IGFuIHVubW9k
+aWZpYWJsZSBsaXN0IikpfX0KSC5YQy5wcm90b3R5cGU9e30KSC53di5wcm90b3R5cGU9ewpnaU86ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5faGFzaENvZGUKaWYodCE9bnVsbClyZXR1cm4gdAp0PTUzNjg3MDkx
+MSY2NjQ1OTcqSi5oZih0aGlzLmEpCnRoaXMuX2hhc2hDb2RlPXQKcmV0dXJuIHR9LAp3OmZ1bmN0aW9u
+KGEpe3JldHVybidTeW1ib2woIicrSC5kKHRoaXMuYSkrJyIpJ30sCkROOmZ1bmN0aW9uKGEsYil7aWYo
+Yj09bnVsbClyZXR1cm4hMQpyZXR1cm4gYiBpbnN0YW5jZW9mIEgud3YmJnRoaXMuYT09Yi5hfSwKJGlH
+RDoxfQpILlBELnByb3RvdHlwZT17fQpILldVLnByb3RvdHlwZT17CmdsMDpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5nQSh0aGlzKT09PTB9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKWTpm
+dW5jdGlvbihhLGIsYyl7dmFyIHQ9SC5MaCh0aGlzKQp0LmQuYihiKQp0LmNoWzFdLmIoYykKcmV0dXJu
+IEguZGMoKX0sCmdQdTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5xNChhLEguTGgodGhpcykuQygiTjM8
+MSwyPiIpKX0sCnE0OmZ1bmN0aW9uKGEsYil7dmFyIHQ9dGhpcwpyZXR1cm4gUC5sMChmdW5jdGlvbigp
+e3ZhciBzPWEKdmFyIHI9MCxxPTEscCxvLG4sbQpyZXR1cm4gZnVuY3Rpb24gJGFzeW5jJGdQdShjLGQp
+e2lmKGM9PT0xKXtwPWQKcj1xfXdoaWxlKHRydWUpc3dpdGNoKHIpe2Nhc2UgMDpvPXQuZ1YoKSxvPW8u
+Z2t6KG8pLG49SC5MaCh0KSxuPW4uQygiQDwxPiIpLktxKG4uY2hbMV0pLkMoIk4zPDEsMj4iKQpjYXNl
+IDI6aWYoIW8uRigpKXtyPTMKYnJlYWt9bT1vLmdsKCkKcj00CnJldHVybiBuZXcgUC5OMyhtLHQucSgw
+LG0pLG4pCmNhc2UgNDpyPTIKYnJlYWsKY2FzZSAzOnJldHVybiBQLlRoKCkKY2FzZSAxOnJldHVybiBQ
+LlltKHApfX19LGIpfSwKJGlaMDoxfQpILkxQLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmF9LAp4NDpmdW5jdGlvbihhKXtpZih0eXBlb2YgYSE9InN0cmluZyIpcmV0dXJuITEKaWYo
+Il9fcHJvdG9fXyI9PT1hKXJldHVybiExCnJldHVybiB0aGlzLmIuaGFzT3duUHJvcGVydHkoYSl9LApx
+OmZ1bmN0aW9uKGEsYil7aWYoIXRoaXMueDQoYikpcmV0dXJuIG51bGwKcmV0dXJuIHRoaXMuRChiKX0s
+CkQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYltILnkoYSldfSwKSzpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMscixxLHA9SC5MaCh0aGlzKQpwLkMoIn4oMSwyKSIpLmIoYikKdD10aGlzLmMKZm9yKHM9dC5sZW5n
+dGgscD1wLmNoWzFdLHI9MDtyPHM7KytyKXtxPXRbcl0KYi4kMihxLHAuYih0aGlzLkQocSkpKX19LApn
+VjpmdW5jdGlvbigpe3JldHVybiBuZXcgSC5YUih0aGlzLEguTGgodGhpcykuQygiWFI8MT4iKSl9fQpI
+LlhSLnByb3RvdHlwZT17CmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuYwpyZXR1cm4gbmV3IEou
+bTEodCx0Lmxlbmd0aCxILnQ2KHQpLkMoIm0xPDE+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRo
+aXMuYS5jLmxlbmd0aH19CkguTEkucHJvdG90eXBlPXsKZ1dhOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcy5h
+CnJldHVybiB0fSwKZ25kOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYz09PTEpcmV0
+dXJuIEMuaFUKdD1wLmQKcz10Lmxlbmd0aC1wLmUubGVuZ3RoLXAuZgppZihzPT09MClyZXR1cm4gQy5o
+VQpyPVtdCmZvcihxPTA7cTxzOysrcSl7aWYocT49dC5sZW5ndGgpcmV0dXJuIEguT0godCxxKQpyLnB1
+c2godFtxXSl9cmV0dXJuIEouekMocil9LApnVm06ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwLG8sbixt
+LGw9dGhpcwppZihsLmMhPT0wKXJldHVybiBDLkR4CnQ9bC5lCnM9dC5sZW5ndGgKcj1sLmQKcT1yLmxl
+bmd0aC1zLWwuZgppZihzPT09MClyZXR1cm4gQy5EeApwPW5ldyBILk41KHUuZW8pCmZvcihvPTA7bzxz
+Oysrbyl7aWYobz49dC5sZW5ndGgpcmV0dXJuIEguT0godCxvKQpuPXRbb10KbT1xK28KaWYobTwwfHxt
+Pj1yLmxlbmd0aClyZXR1cm4gSC5PSChyLG0pCnAuWSgwLG5ldyBILnd2KG4pLHJbbV0pfXJldHVybiBu
+ZXcgSC5QRChwLHUuZ0YpfSwKJGl2UToxfQpILkNqLnByb3RvdHlwZT17CiQyOmZ1bmN0aW9uKGEsYil7
+dmFyIHQKSC55KGEpCnQ9dGhpcy5hCnQuYj10LmIrIiQiK0guZChhKQpDLk5tLmkodGhpcy5iLGEpCkMu
+Tm0uaSh0aGlzLmMsYik7Kyt0LmF9LAokUzoxMn0KSC5mOS5wcm90b3R5cGU9ewpxUzpmdW5jdGlvbihh
+KXt2YXIgdCxzLHI9dGhpcyxxPW5ldyBSZWdFeHAoci5hKS5leGVjKGEpCmlmKHE9PW51bGwpcmV0dXJu
+IG51bGwKdD1PYmplY3QuY3JlYXRlKG51bGwpCnM9ci5iCmlmKHMhPT0tMSl0LmFyZ3VtZW50cz1xW3Mr
+MV0Kcz1yLmMKaWYocyE9PS0xKXQuYXJndW1lbnRzRXhwcj1xW3MrMV0Kcz1yLmQKaWYocyE9PS0xKXQu
+ZXhwcj1xW3MrMV0Kcz1yLmUKaWYocyE9PS0xKXQubWV0aG9kPXFbcysxXQpzPXIuZgppZihzIT09LTEp
+dC5yZWNlaXZlcj1xW3MrMV0KcmV0dXJuIHR9fQpILlcwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7
+dmFyIHQ9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuIk5vU3VjaE1ldGhvZEVycm9yOiAiK0guZCh0aGlz
+LmEpCnJldHVybiJOb1N1Y2hNZXRob2RFcnJvcjogbWV0aG9kIG5vdCBmb3VuZDogJyIrdCsiJyBvbiBu
+dWxsIn19CkguYXoucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj0iTm9TdWNo
+TWV0aG9kRXJyb3I6IG1ldGhvZCBub3QgZm91bmQ6ICciLHE9cy5iCmlmKHE9PW51bGwpcmV0dXJuIk5v
+U3VjaE1ldGhvZEVycm9yOiAiK0guZChzLmEpCnQ9cy5jCmlmKHQ9PW51bGwpcmV0dXJuIHIrcSsiJyAo
+IitILmQocy5hKSsiKSIKcmV0dXJuIHIrcSsiJyBvbiAnIit0KyInICgiK0guZChzLmEpKyIpIn19Ckgu
+dlYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQubGVuZ3RoPT09
+MD8iRXJyb3IiOiJFcnJvcjogIit0fX0KSC5icS5wcm90b3R5cGU9e30KSC5BbS5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXtpZih1LmJVLmMoYSkpaWYoYS4kdGhyb3duSnNFcnJvcj09bnVsbClhLiR0aHJv
+d25Kc0Vycm9yPXRoaXMuYQpyZXR1cm4gYX0sCiRTOjF9CkguWE8ucHJvdG90eXBlPXsKdzpmdW5jdGlv
+bihhKXt2YXIgdCxzPXRoaXMuYgppZihzIT1udWxsKXJldHVybiBzCnM9dGhpcy5hCnQ9cyE9PW51bGwm
+JnR5cGVvZiBzPT09Im9iamVjdCI/cy5zdGFjazpudWxsCnJldHVybiB0aGlzLmI9dD09bnVsbD8iIjp0
+fSwKJGlHejoxfQpILlRwLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5jb25zdHJ1
+Y3RvcixzPXQ9PW51bGw/bnVsbDp0Lm5hbWUKcmV0dXJuIkNsb3N1cmUgJyIrSC5OUShzPT1udWxsPyJ1
+bmtub3duIjpzKSsiJyJ9LAokaUVIOjEsCmdRbDpmdW5jdGlvbigpe3JldHVybiB0aGlzfSwKJEM6IiQx
+IiwKJFI6MSwKJEQ6bnVsbH0KSC5sYy5wcm90b3R5cGU9e30KSC56eC5wcm90b3R5cGU9ewp3OmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuJHN0YXRpY19uYW1lCmlmKHQ9PW51bGwpcmV0dXJuIkNsb3N1cmUgb2Yg
+dW5rbm93biBzdGF0aWMgbWV0aG9kIgpyZXR1cm4iQ2xvc3VyZSAnIitILk5RKHQpKyInIn19CkguclQu
+cHJvdG90eXBlPXsKRE46ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzCmlmKGI9PW51bGwpcmV0dXJuITEK
+aWYodD09PWIpcmV0dXJuITAKaWYoIShiIGluc3RhbmNlb2YgSC5yVCkpcmV0dXJuITEKcmV0dXJuIHQu
+YT09PWIuYSYmdC5iPT09Yi5iJiZ0LmM9PT1iLmN9LApnaU86ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlz
+LmMKaWYocz09bnVsbCl0PUguZVEodGhpcy5hKQplbHNlIHQ9dHlwZW9mIHMhPT0ib2JqZWN0Ij9KLmhm
+KHMpOkguZVEocykKcmV0dXJuKHReSC5lUSh0aGlzLmIpKT4+PjB9LAp3OmZ1bmN0aW9uKGEpe3ZhciB0
+PXRoaXMuYwppZih0PT1udWxsKXQ9dGhpcy5hCnJldHVybiJDbG9zdXJlICciK0guZCh0aGlzLmQpKyIn
+IG9mICIrKCJJbnN0YW5jZSBvZiAnIitILmQoSC5NKHQpKSsiJyIpfX0KSC5FcS5wcm90b3R5cGU9ewp3
+OmZ1bmN0aW9uKGEpe3JldHVybiJSdW50aW1lRXJyb3I6ICIrSC5kKHRoaXMuYSl9fQpILmtZLnByb3Rv
+dHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHRoaXMuYSl9
+fQpILk41LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LApnbDA6ZnVuY3Rp
+b24oYSl7cmV0dXJuIHRoaXMuYT09PTB9LApnVjpmdW5jdGlvbigpe3JldHVybiBuZXcgSC5pNSh0aGlz
+LEguTGgodGhpcykuQygiaTU8MT4iKSl9LAp4NDpmdW5jdGlvbihhKXt2YXIgdCxzCmlmKHR5cGVvZiBh
+PT0ic3RyaW5nIil7dD10aGlzLmIKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gdGhpcy5YdSh0LGEp
+fWVsc2V7cz10aGlzLkNYKGEpCnJldHVybiBzfX0sCkNYOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuZApp
+Zih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkZoKHRoaXMuQnQodCxKLmhmKGEpJjB4M2ZmZmZm
+ZiksYSk+PTB9LApxOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbAppZih0eXBl
+b2YgYj09InN0cmluZyIpe3Q9cC5iCmlmKHQ9PW51bGwpcmV0dXJuIG8Kcz1wLmoyKHQsYikKcj1zPT1u
+dWxsP286cy5iCnJldHVybiByfWVsc2UgaWYodHlwZW9mIGI9PSJudW1iZXIiJiYoYiYweDNmZmZmZmYp
+PT09Yil7cT1wLmMKaWYocT09bnVsbClyZXR1cm4gbwpzPXAuajIocSxiKQpyPXM9PW51bGw/bzpzLmIK
+cmV0dXJuIHJ9ZWxzZSByZXR1cm4gcC5hYShiKX0sCmFhOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlz
+LmQKaWYocj09bnVsbClyZXR1cm4gbnVsbAp0PXRoaXMuQnQocixKLmhmKGEpJjB4M2ZmZmZmZikKcz10
+aGlzLkZoKHQsYSkKaWYoczwwKXJldHVybiBudWxsCnJldHVybiB0W3NdLmJ9LApZOmZ1bmN0aW9uKGEs
+YixjKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLG09SC5MaChuKQptLmQuYihiKQptLmNoWzFdLmIoYykK
+aWYodHlwZW9mIGI9PSJzdHJpbmciKXt0PW4uYgpuLkVIKHQ9PW51bGw/bi5iPW4ueksoKTp0LGIsYyl9
+ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjB4M2ZmZmZmZik9PT1iKXtzPW4uYwpuLkVIKHM9
+PW51bGw/bi5jPW4ueksoKTpzLGIsYyl9ZWxzZXtyPW4uZAppZihyPT1udWxsKXI9bi5kPW4ueksoKQpx
+PUouaGYoYikmMHgzZmZmZmZmCnA9bi5CdChyLHEpCmlmKHA9PW51bGwpbi5FSShyLHEsW24uSG4oYixj
+KV0pCmVsc2V7bz1uLkZoKHAsYikKaWYobz49MClwW29dLmI9YwplbHNlIHAucHVzaChuLkhuKGIsYykp
+fX19LApLOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyPXRoaXMKSC5MaChyKS5DKCJ+KDEsMikiKS5iKGIp
+CnQ9ci5lCnM9ci5yCmZvcig7dCE9bnVsbDspe2IuJDIodC5hLHQuYikKaWYocyE9PXIucil0aHJvdyBI
+LmIoUC5hNChyKSkKdD10LmN9fSwKRUg6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHM9dGhpcyxyPUguTGgo
+cykKci5kLmIoYikKci5jaFsxXS5iKGMpCnQ9cy5qMihhLGIpCmlmKHQ9PW51bGwpcy5FSShhLGIscy5I
+bihiLGMpKQplbHNlIHQuYj1jfSwKa3M6ZnVuY3Rpb24oKXt0aGlzLnI9dGhpcy5yKzEmNjcxMDg4NjN9
+LApIbjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcyxyPUguTGgocykscT1uZXcgSC5kYihyLmQuYihh
+KSxyLmNoWzFdLmIoYikpCmlmKHMuZT09bnVsbClzLmU9cy5mPXEKZWxzZXt0PXMuZgpxLmQ9dApzLmY9
+dC5jPXF9KytzLmEKcy5rcygpCnJldHVybiBxfSwKRmg6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCmlmKGE9
+PW51bGwpcmV0dXJuLTEKdD1hLmxlbmd0aApmb3Iocz0wO3M8dDsrK3MpaWYoSi5STShhW3NdLmEsYikp
+cmV0dXJuIHMKcmV0dXJuLTF9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKajI6ZnVu
+Y3Rpb24oYSxiKXtyZXR1cm4gYVtiXX0sCkJ0OmZ1bmN0aW9uKGEsYil7cmV0dXJuIGFbYl19LApFSTpm
+dW5jdGlvbihhLGIsYyl7YVtiXT1jfSwKcm46ZnVuY3Rpb24oYSxiKXtkZWxldGUgYVtiXX0sClh1OmZ1
+bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuajIoYSxiKSE9bnVsbH0sCnpLOmZ1bmN0aW9uKCl7dmFyIHQ9
+Ijxub24taWRlbnRpZmllci1rZXk+IixzPU9iamVjdC5jcmVhdGUobnVsbCkKdGhpcy5FSShzLHQscykK
+dGhpcy5ybihzLHQpCnJldHVybiBzfSwKJGlGbzoxfQpILmRiLnByb3RvdHlwZT17fQpILmk1LnByb3Rv
+dHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuYX0sCmdsMDpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5hLmE9PT0wfSwKZ2t6OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPW5ldyBILk42KHQs
+dC5yLHRoaXMuJHRpLkMoIk42PDE+IikpCnMuYz10LmUKcmV0dXJuIHN9LAp0ZzpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLmEueDQoYil9fQpILk42LnByb3RvdHlwZT17CmdsOmZ1bmN0aW9uKCl7cmV0dXJu
+IHRoaXMuZH0sCkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5hCmlmKHQuYiE9PXMucil0aHJvdyBI
+LmIoUC5hNChzKSkKZWxzZXtzPXQuYwppZihzPT1udWxsKXt0LnNxWShudWxsKQpyZXR1cm4hMX1lbHNl
+e3Quc3FZKHMuYSkKdC5jPXQuYy5jCnJldHVybiEwfX19LApzcVk6ZnVuY3Rpb24oYSl7dGhpcy5kPXRo
+aXMuJHRpLmQuYihhKX0sCiRpQW46MX0KSC5kQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5hKGEpfSwKJFM6MX0KSC53Ti5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3JldHVy
+biB0aGlzLmEoYSxiKX0sCiRTOjQ0fQpILlZYLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmEoSC55KGEpKX0sCiRTOjQwfQpILlZSLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0
+dXJuIlJlZ0V4cC8iK3RoaXMuYSsiLyIrdGhpcy5iLmZsYWdzfSwKZ0hjOmZ1bmN0aW9uKCl7dmFyIHQ9
+dGhpcyxzPXQuYwppZihzIT1udWxsKXJldHVybiBzCnM9dC5iCnJldHVybiB0LmM9SC52NCh0LmEscy5t
+dWx0aWxpbmUsIXMuaWdub3JlQ2FzZSxzLnVuaWNvZGUscy5kb3RBbGwsITApfSwKZGQ6ZnVuY3Rpb24o
+YSxiKXtyZXR1cm4gbmV3IEguS1codGhpcyxiLDApfSwKVVo6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRo
+aXMuZ0hjKCkKcy5sYXN0SW5kZXg9Ygp0PXMuZXhlYyhhKQppZih0PT1udWxsKXJldHVybiBudWxsCnJl
+dHVybiBuZXcgSC5FSyh0KX0sCiRpdlg6MSwKJGl3TDoxfQpILkVLLnByb3RvdHlwZT17CnE6ZnVuY3Rp
+b24oYSxiKXt2YXIgdApILlNjKGIpCnQ9dGhpcy5iCmlmKGI+PXQubGVuZ3RoKXJldHVybiBILk9IKHQs
+YikKcmV0dXJuIHRbYl19LAokaU9kOjEsCiRpaWI6MX0KSC5LVy5wcm90b3R5cGU9ewpna3o6ZnVuY3Rp
+b24oYSl7cmV0dXJuIG5ldyBILlBiKHRoaXMuYSx0aGlzLmIsdGhpcy5jKX19CkguUGIucHJvdG90eXBl
+PXsKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9
+dGhpcyxvPXAuYgppZihvPT1udWxsKXJldHVybiExCnQ9cC5jCmlmKHQ8PW8ubGVuZ3RoKXtzPXAuYQpy
+PXMuVVoobyx0KQppZihyIT1udWxsKXtwLmQ9cgpvPXIuYgp0PW8uaW5kZXgKcT10K29bMF0ubGVuZ3Ro
+CmlmKHQ9PT1xKXtpZihzLmIudW5pY29kZSl7bz1wLmMKdD1vKzEKcz1wLmIKaWYodDxzLmxlbmd0aCl7
+bz1KLnJZKHMpLm0ocyxvKQppZihvPj01NTI5NiYmbzw9NTYzMTkpe289Qy54Qi5tKHMsdCkKbz1vPj01
+NjMyMCYmbzw9NTczNDN9ZWxzZSBvPSExfWVsc2Ugbz0hMX1lbHNlIG89ITEKcT0obz9xKzE6cSkrMX1w
+LmM9cQpyZXR1cm4hMH19cC5iPXAuZD1udWxsCnJldHVybiExfSwKJGlBbjoxfQpILnRRLnByb3RvdHlw
+ZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCmlmKGIhPT0wKUgudmgoUC54KGIsbnVsbCkpCnJldHVy
+biB0aGlzLmN9LAokaU9kOjF9CkgudW4ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBu
+ZXcgSC5TZCh0aGlzLmEsdGhpcy5iLHRoaXMuYyl9fQpILlNkLnByb3RvdHlwZT17CkY6ZnVuY3Rpb24o
+KXt2YXIgdCxzLHI9dGhpcyxxPXIuYyxwPXIuYixvPXAubGVuZ3RoLG49ci5hLG09bi5sZW5ndGgKaWYo
+cStvPm0pe3IuZD1udWxsCnJldHVybiExfXQ9bi5pbmRleE9mKHAscSkKaWYodDwwKXtyLmM9bSsxCnIu
+ZD1udWxsCnJldHVybiExfXM9dCtvCnIuZD1uZXcgSC50USh0LHApCnIuYz1zPT09ci5jP3MrMTpzCnJl
+dHVybiEwfSwKZ2w6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKJGlBbjoxfQpILkVULnByb3RvdHlw
+ZT17JGlFVDoxLCRpZXE6MX0KSC5MWi5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+ZW5ndGh9LAokaVhqOjF9CkguRGcucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikKSC5v
+ZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7SC5JZyhjKQpILm9k
+KGIsYSxhLmxlbmd0aCkKYVtiXT1jfSwKJGliUToxLAokaWNYOjEsCiRpek06MX0KSC5QZy5wcm90b3R5
+cGU9ewpZOmZ1bmN0aW9uKGEsYixjKXtILlNjKGMpCkgub2QoYixhLGEubGVuZ3RoKQphW2JdPWN9LAok
+aWJROjEsCiRpY1g6MSwKJGl6TToxfQpILnhqLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNj
+KGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4gYVtiXX19CkguZEUucHJvdG90eXBlPXsKcTpmdW5j
+dGlvbihhLGIpe0guU2MoYikKSC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5aQS5wcm90
+b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxlbmd0aCkKcmV0dXJuIGFb
+Yl19fQpILndmLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVu
+Z3RoKQpyZXR1cm4gYVtiXX19CkguUHEucHJvdG90eXBlPXsKcTpmdW5jdGlvbihhLGIpe0guU2MoYikK
+SC5vZChiLGEsYS5sZW5ndGgpCnJldHVybiBhW2JdfX0KSC5lRS5wcm90b3R5cGU9ewpnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQpILm9kKGIsYSxhLmxl
+bmd0aCkKcmV0dXJuIGFbYl19fQpILlY2LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBh
+Lmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXtILlNjKGIpCkgub2QoYixhLGEubGVuZ3RoKQpyZXR1cm4g
+YVtiXX0sCiRpVjY6MSwKJGluNjoxfQpILlJHLnByb3RvdHlwZT17fQpILlZQLnByb3RvdHlwZT17fQpI
+LldCLnByb3RvdHlwZT17fQpILlpHLnByb3RvdHlwZT17fQpILkpjLnByb3RvdHlwZT17CkM6ZnVuY3Rp
+b24oYSl7cmV0dXJuIEguY0Uodi50eXBlVW5pdmVyc2UsdGhpcyxhKX0sCktxOmZ1bmN0aW9uKGEpe3Jl
+dHVybiBILnY1KHYudHlwZVVuaXZlcnNlLHRoaXMsYSl9fQpILkcucHJvdG90eXBlPXt9CkgudTkucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfX0KSC5oei5wcm90b3R5cGU9e30KSC5p
+TS5wcm90b3R5cGU9e30KUC50aC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEs
+cz10LmEKdC5hPW51bGwKcy4kMCgpfSwKJFM6MTB9ClAuaGEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24o
+YSl7dmFyIHQscwp0aGlzLmEuYT11Lk0uYihhKQp0PXRoaXMuYgpzPXRoaXMuYwp0LmZpcnN0Q2hpbGQ/
+dC5yZW1vdmVDaGlsZChzKTp0LmFwcGVuZENoaWxkKHMpfSwKJFM6MjB9ClAuVnMucHJvdG90eXBlPXsK
+JDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuRnQucHJvdG90
+eXBlPXsKJDA6ZnVuY3Rpb24oKXt0aGlzLmEuJDAoKX0sCiRDOiIkMCIsCiRSOjAsCiRTOjB9ClAuVzMu
+cHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSxiKXtpZihzZWxmLnNldFRpbWVvdXQhPW51bGwpc2VsZi5z
+ZXRUaW1lb3V0KEgudFIobmV3IFAueUgodGhpcyxiKSwwKSxhKQplbHNlIHRocm93IEguYihQLkw0KCJg
+c2V0VGltZW91dCgpYCBub3QgZm91bmQuIikpfX0KUC55SC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigp
+e3RoaXMuYi4kMCgpfSwKJEM6IiQwIiwKJFI6MCwKJFM6Mn0KUC5paC5wcm90b3R5cGU9ewphTTpmdW5j
+dGlvbihhLGIpe3ZhciB0LHMscj10aGlzLiR0aQpyLkMoIjEvIikuYihiKQp0PSF0aGlzLmJ8fHIuQygi
+Yjg8MT4iKS5jKGIpCnM9dGhpcy5hCmlmKHQpcy5YZihiKQplbHNlIHMuWDIoci5kLmIoYikpfSwKdzA6
+ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYodGhpcy5iKXQuWkwoYSxiKQplbHNlIHQuTmsoYSxi
+KX19ClAuV00ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS4kMigwLGEpfSwK
+JFM6NDl9ClAuU1gucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuJDIoMSxuZXcgSC5i
+cShhLHUubC5iKGIpKSl9LAokQzoiJDIiLAokUjoyLAokUzoyMX0KUC5Hcy5wcm90b3R5cGU9ewokMjpm
+dW5jdGlvbihhLGIpe3RoaXMuYShILlNjKGEpLGIpfSwKJFM6MjZ9ClAuRnkucHJvdG90eXBlPXsKdzpm
+dW5jdGlvbihhKXtyZXR1cm4iSXRlcmF0aW9uTWFya2VyKCIrdGhpcy5iKyIsICIrSC5kKHRoaXMuYSkr
+IikifX0KUC5HVi5wcm90b3R5cGU9ewpnbDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuYwppZih0PT1udWxs
+KXJldHVybiB0aGlzLmIKcmV0dXJuIHRoaXMuJHRpLmQuYih0LmdsKCkpfSwKRjpmdW5jdGlvbigpe3Zh
+ciB0LHMscixxLHA9dGhpcwpmb3IoOyEwOyl7dD1wLmMKaWYodCE9bnVsbClpZih0LkYoKSlyZXR1cm4h
+MAplbHNlIHAuYz1udWxsCnM9ZnVuY3Rpb24oYSxiLGMpe3ZhciBvLG49Ygp3aGlsZSh0cnVlKXRyeXty
+ZXR1cm4gYShuLG8pfWNhdGNoKG0pe289bQpuPWN9fShwLmEsMCwxKQppZihzIGluc3RhbmNlb2YgUC5G
+eSl7cj1zLmIKaWYocj09PTIpe3Q9cC5kCmlmKHQ9PW51bGx8fHQubGVuZ3RoPT09MCl7cC5zRUMobnVs
+bCkKcmV0dXJuITF9aWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkKcC5hPXQucG9wKCkKY29u
+dGludWV9ZWxzZXt0PXMuYQppZihyPT09Myl0aHJvdyB0CmVsc2V7cT1KLklUKHQpCmlmKHEgaW5zdGFu
+Y2VvZiBQLkdWKXt0PXAuZAppZih0PT1udWxsKXQ9cC5kPVtdCkMuTm0uaSh0LHAuYSkKcC5hPXEuYQpj
+b250aW51ZX1lbHNle3AuYz1xCmNvbnRpbnVlfX19fWVsc2V7cC5zRUMocykKcmV0dXJuITB9fXJldHVy
+biExfSwKc0VDOmZ1bmN0aW9uKGEpe3RoaXMuYj10aGlzLiR0aS5kLmIoYSl9LAokaUFuOjF9ClAucTQu
+cHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgUC5HVih0aGlzLmEoKSx0aGlzLiR0
+aS5DKCJHVjwxPiIpKX19ClAuYjgucHJvdG90eXBlPXt9ClAuUGYucHJvdG90eXBlPXsKdzA6ZnVuY3Rp
+b24oYSxiKXt2YXIgdAppZihhPT1udWxsKWE9bmV3IFAubigpCnQ9dGhpcy5hCmlmKHQuYSE9PTApdGhy
+b3cgSC5iKFAuUFYoIkZ1dHVyZSBhbHJlYWR5IGNvbXBsZXRlZCIpKQp0Lk5rKGEsYil9LApwbTpmdW5j
+dGlvbihhKXtyZXR1cm4gdGhpcy53MChhLG51bGwpfX0KUC5aZi5wcm90b3R5cGU9ewphTTpmdW5jdGlv
+bihhLGIpe3ZhciB0CnRoaXMuJHRpLkMoIjEvIikuYihiKQp0PXRoaXMuYQppZih0LmEhPT0wKXRocm93
+IEguYihQLlBWKCJGdXR1cmUgYWxyZWFkeSBjb21wbGV0ZWQiKSkKdC5YZihiKX19ClAuRmUucHJvdG90
+eXBlPXsKSFI6ZnVuY3Rpb24oYSl7aWYoKHRoaXMuYyYxNSkhPT02KXJldHVybiEwCnJldHVybiB0aGlz
+LmIuYi5idih1LmFsLmIodGhpcy5kKSxhLmEsdS5jSix1LkspfSwKS3c6ZnVuY3Rpb24oYSl7dmFyIHQ9
+dGhpcy5lLHM9dS56LHI9dS5LLHE9dGhpcy4kdGkuQygiMi8iKSxwPXRoaXMuYi5iCmlmKHUuRS5jKHQp
+KXJldHVybiBxLmIocC5ycCh0LGEuYSxhLmIscyxyLHUubCkpCmVsc2UgcmV0dXJuIHEuYihwLmJ2KHUu
+dy5iKHQpLGEuYSxzLHIpKX19ClAudnMucHJvdG90eXBlPXsKU3E6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMscixxPXRoaXMuJHRpCnEuS3EoYykuQygiMS8oMikiKS5iKGEpCnQ9JC5YMwppZih0IT09Qy5OVSl7
+Yy5DKCJAPDAvPiIpLktxKHEuZCkuQygiMSgyKSIpLmIoYSkKaWYoYiE9bnVsbCliPVAuVkgoYix0KX1z
+PW5ldyBQLnZzKCQuWDMsYy5DKCJ2czwwPiIpKQpyPWI9PW51bGw/MTozCnRoaXMueGYobmV3IFAuRmUo
+cyxyLGEsYixxLkMoIkA8MT4iKS5LcShjKS5DKCJGZTwxLDI+IikpKQpyZXR1cm4gc30sClc3OmZ1bmN0
+aW9uKGEsYil7cmV0dXJuIHRoaXMuU3EoYSxudWxsLGIpfSwKUWQ6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHM9dGhpcy4kdGkKcy5LcShjKS5DKCIxLygyKSIpLmIoYSkKdD1uZXcgUC52cygkLlgzLGMuQygidnM8
+MD4iKSkKdGhpcy54ZihuZXcgUC5GZSh0LChiPT1udWxsPzE6Myl8MTYsYSxiLHMuQygiQDwxPiIpLktx
+KGMpLkMoIkZlPDEsMj4iKSkpCnJldHVybiB0fSwKeGY6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLHI9
+cy5hCmlmKHI8PTEpe2EuYT11LnguYihzLmMpCnMuYz1hfWVsc2V7aWYocj09PTIpe3Q9dS5fLmIocy5j
+KQpyPXQuYQppZihyPDQpe3QueGYoYSkKcmV0dXJufXMuYT1yCnMuYz10LmN9UC5UayhudWxsLG51bGws
+cy5iLHUuTS5iKG5ldyBQLmRhKHMsYSkpKX19LApqUTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG89
+dGhpcyxuPXt9Cm4uYT1hCmlmKGE9PW51bGwpcmV0dXJuCnQ9by5hCmlmKHQ8PTEpe3M9dS54LmIoby5j
+KQpyPW8uYz1hCmlmKHMhPW51bGwpe2Zvcig7cT1yLmEscSE9bnVsbDtyPXEpO3IuYT1zfX1lbHNle2lm
+KHQ9PT0yKXtwPXUuXy5iKG8uYykKdD1wLmEKaWYodDw0KXtwLmpRKGEpCnJldHVybn1vLmE9dApvLmM9
+cC5jfW4uYT1vLk44KGEpClAuVGsobnVsbCxudWxsLG8uYix1Lk0uYihuZXcgUC5vUShuLG8pKSl9fSwK
+YWg6ZnVuY3Rpb24oKXt2YXIgdD11LnguYih0aGlzLmMpCnRoaXMuYz1udWxsCnJldHVybiB0aGlzLk44
+KHQpfSwKTjg6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCmZvcih0PWEscz1udWxsO3QhPW51bGw7cz10LHQ9
+cil7cj10LmEKdC5hPXN9cmV0dXJuIHN9LApISDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMscj1zLiR0
+aQpyLkMoIjEvIikuYihhKQppZihyLkMoImI4PDE+IikuYyhhKSlpZihyLmMoYSkpUC5BOShhLHMpCmVs
+c2UgUC5rMyhhLHMpCmVsc2V7dD1zLmFoKCkKci5kLmIoYSkKcy5hPTQKcy5jPWEKUC5IWihzLHQpfX0s
+ClgyOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcwpzLiR0aS5kLmIoYSkKdD1zLmFoKCkKcy5hPTQKcy5j
+PWEKUC5IWihzLHQpfSwKWkw6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMKdS5sLmIoYikKdD1zLmFo
+KCkKcy5hPTgKcy5jPW5ldyBQLkN3KGEsYikKUC5IWihzLHQpfSwKWGY6ZnVuY3Rpb24oYSl7dmFyIHQ9
+dGhpcyxzPXQuJHRpCnMuQygiMS8iKS5iKGEpCmlmKHMuQygiYjg8MT4iKS5jKGEpKXt0LmNVKGEpCnJl
+dHVybn10LmE9MQpQLlRrKG51bGwsbnVsbCx0LmIsdS5NLmIobmV3IFAuckgodCxhKSkpfSwKY1U6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcyxzPXQuJHRpCnMuQygiYjg8MT4iKS5iKGEpCmlmKHMuYyhhKSl7aWYo
+YS5hPT09OCl7dC5hPTEKUC5UayhudWxsLG51bGwsdC5iLHUuTS5iKG5ldyBQLktGKHQsYSkpKX1lbHNl
+IFAuQTkoYSx0KQpyZXR1cm59UC5rMyhhLHQpfSwKTms6ZnVuY3Rpb24oYSxiKXt0aGlzLmE9MQpQLlRr
+KG51bGwsbnVsbCx0aGlzLmIsdS5NLmIobmV3IFAuWkwodGhpcyxhLGIpKSl9LAokaWI4OjF9ClAuZGEu
+cHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtQLkhaKHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KUC5vUS5w
+cm90b3R5cGU9ewokMDpmdW5jdGlvbigpe1AuSFoodGhpcy5iLHRoaXMuYS5hKX0sCiRTOjB9ClAucFYu
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnQuYT0wCnQuSEgoYSl9LAokUzox
+MH0KUC5VNy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3UubC5iKGIpCnRoaXMuYS5aTChhLGIp
+fSwKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuJDIoYSxudWxsKX0sCiRDOiIkMiIsCiREOmZ1bmN0
+aW9uKCl7cmV0dXJuW251bGxdfSwKJFM6Mjl9ClAudnIucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt0
+aGlzLmEuWkwodGhpcy5iLHRoaXMuYyl9LAokUzowfQpQLnJILnByb3RvdHlwZT17CiQwOmZ1bmN0aW9u
+KCl7dmFyIHQ9dGhpcy5hCnQuWDIodC4kdGkuZC5iKHRoaXMuYikpfSwKJFM6MH0KUC5LRi5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe1AuQTkodGhpcy5iLHRoaXMuYSl9LAokUzowfQpQLlpMLnByb3RvdHlw
+ZT17CiQwOmZ1bmN0aW9uKCl7dGhpcy5hLlpMKHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KUC5SVC5wcm90
+b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuPXRoaXMsbT1udWxsCnRyeXtyPW4u
+YwptPXIuYi5iLnp6KHUuZk8uYihyLmQpLHUueil9Y2F0Y2gocSl7dD1ILlJ1KHEpCnM9SC50cyhxKQpp
+ZihuLmQpe3I9dS5uLmIobi5hLmEuYykuYQpwPXQKcD1yPT1udWxsP3A9PW51bGw6cj09PXAKcj1wfWVs
+c2Ugcj0hMQpwPW4uYgppZihyKXAuYj11Lm4uYihuLmEuYS5jKQplbHNlIHAuYj1uZXcgUC5Ddyh0LHMp
+CnAuYT0hMApyZXR1cm59aWYodS5jLmMobSkpe2lmKG0gaW5zdGFuY2VvZiBQLnZzJiZtLmE+PTQpe2lm
+KG0uYT09PTgpe3I9bi5iCnIuYj11Lm4uYihtLmMpCnIuYT0hMH1yZXR1cm59bz1uLmEuYQpyPW4uYgpy
+LmI9bS5XNyhuZXcgUC5qWihvKSx1LnopCnIuYT0hMX19LAokUzoyfQpQLmpaLnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmF9LAokUzozOX0KUC5ycS5wcm90b3R5cGU9ewokMDpmdW5j
+dGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcwp0cnl7cj1tLmIKcT1yLiR0aQpwPXEuZApvPXAu
+YihtLmMpCm0uYS5iPXIuYi5iLmJ2KHEuQygiMi8oMSkiKS5iKHIuZCksbyxxLkMoIjIvIikscCl9Y2F0
+Y2gobil7dD1ILlJ1KG4pCnM9SC50cyhuKQpyPW0uYQpyLmI9bmV3IFAuQ3codCxzKQpyLmE9ITB9fSwK
+JFM6Mn0KUC5SVy5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG0sbD10
+aGlzCnRyeXt0PXUubi5iKGwuYS5hLmMpCnE9bC5jCmlmKEgub1QocS5IUih0KSkmJnEuZSE9bnVsbCl7
+cD1sLmIKcC5iPXEuS3codCkKcC5hPSExfX1jYXRjaChvKXtzPUguUnUobykKcj1ILnRzKG8pCnE9dS5u
+LmIobC5hLmEuYykKcD1xLmEKbj1zCm09bC5iCmlmKHA9PW51bGw/bj09bnVsbDpwPT09biltLmI9cQpl
+bHNlIG0uYj1uZXcgUC5DdyhzLHIpCm0uYT0hMH19LAokUzoyfQpQLk9NLnByb3RvdHlwZT17fQpQLnFo
+LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9e30scD1uZXcgUC52cygk
+LlgzLHUuZkopCnEuYT0wCnQ9SC5MaChyKQpzPXQuQygifigxKSIpLmIobmV3IFAuQjUocSxyKSkKdS5N
+LmIobmV3IFAudU8ocSxwKSkKVy5KRShyLmEsci5iLHMsITEsdC5kKQpyZXR1cm4gcH19ClAuQjUucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7SC5MaCh0aGlzLmIpLmQuYihhKTsrK3RoaXMuYS5hfSwKJFM6
+ZnVuY3Rpb24oKXtyZXR1cm4gSC5MaCh0aGlzLmIpLkMoImM4KDEpIil9fQpQLnVPLnByb3RvdHlwZT17
+CiQwOmZ1bmN0aW9uKCl7dGhpcy5iLkhIKHRoaXMuYS5hKX0sCiRTOjB9ClAuTU8ucHJvdG90eXBlPXt9
+ClAua1QucHJvdG90eXBlPXt9ClAueEkucHJvdG90eXBlPXt9ClAuQ3cucHJvdG90eXBlPXsKdzpmdW5j
+dGlvbihhKXtyZXR1cm4gSC5kKHRoaXMuYSl9LAokaVhTOjF9ClAubTAucHJvdG90eXBlPXskaUpCOjF9
+ClAucEsucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXt2YXIgdCxzPXRoaXMuYSxyPXMuYQpzPXI9PW51
+bGw/cy5hPW5ldyBQLm4oKTpyCnI9dGhpcy5iCmlmKHI9PW51bGwpdGhyb3cgSC5iKHMpCnQ9SC5iKHMp
+CnQuc3RhY2s9ci53KDApCnRocm93IHR9LAokUzowfQpQLkppLnByb3RvdHlwZT17CmJIOmZ1bmN0aW9u
+KGEpe3ZhciB0LHMscixxPW51bGwKdS5NLmIoYSkKdHJ5e2lmKEMuTlU9PT0kLlgzKXthLiQwKCkKcmV0
+dXJufVAuVDgocSxxLHRoaXMsYSx1LkgpfWNhdGNoKHIpe3Q9SC5SdShyKQpzPUgudHMocikKUC5MMihx
+LHEsdGhpcyx0LHUubC5iKHMpKX19LApEbDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHE9bnVsbApj
+LkMoIn4oMCkiKS5iKGEpCmMuYihiKQp0cnl7aWYoQy5OVT09PSQuWDMpe2EuJDEoYikKcmV0dXJufVAu
+eXYocSxxLHRoaXMsYSxiLHUuSCxjKX1jYXRjaChyKXt0PUguUnUocikKcz1ILnRzKHIpClAuTDIocSxx
+LHRoaXMsdCx1LmwuYihzKSl9fSwKUlQ6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gbmV3IFAuaGoodGhpcyxi
+LkMoIjAoKSIpLmIoYSksYil9LApHWTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuVnAodGhpcyx1Lk0u
+YihhKSl9LApQeTpmdW5jdGlvbihhLGIpe3JldHVybiBuZXcgUC5PUih0aGlzLGIuQygifigwKSIpLmIo
+YSksYil9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIG51bGx9LAp6ejpmdW5jdGlvbihhLGIpe2IuQygi
+MCgpIikuYihhKQppZigkLlgzPT09Qy5OVSlyZXR1cm4gYS4kMCgpCnJldHVybiBQLlQ4KG51bGwsbnVs
+bCx0aGlzLGEsYil9LApidjpmdW5jdGlvbihhLGIsYyxkKXtjLkMoIkA8MD4iKS5LcShkKS5DKCIxKDIp
+IikuYihhKQpkLmIoYikKaWYoJC5YMz09PUMuTlUpcmV0dXJuIGEuJDEoYikKcmV0dXJuIFAueXYobnVs
+bCxudWxsLHRoaXMsYSxiLGMsZCl9LApycDpmdW5jdGlvbihhLGIsYyxkLGUsZil7ZC5DKCJAPDA+Iiku
+S3EoZSkuS3EoZikuQygiMSgyLDMpIikuYihhKQplLmIoYikKZi5iKGMpCmlmKCQuWDM9PT1DLk5VKXJl
+dHVybiBhLiQyKGIsYykKcmV0dXJuIFAuUXgobnVsbCxudWxsLHRoaXMsYSxiLGMsZCxlLGYpfSwKTGo6
+ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGIuQygiQDwwPiIpLktxKGMpLktxKGQpLkMoIjEoMiwzKSIp
+LmIoYSl9fQpQLmhqLnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYS56eih0aGlz
+LmIsdGhpcy5jKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYy5DKCIwKCkiKX19ClAuVnAucHJv
+dG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hLmJIKHRoaXMuYil9LAokUzoyfQpQLk9S
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYwpyZXR1cm4gdGhpcy5hLkRsKHRo
+aXMuYix0LmIoYSksdCl9LAokUzpmdW5jdGlvbigpe3JldHVybiB0aGlzLmMuQygifigwKSIpfX0KUC5i
+Ni5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcyxzPW5ldyBQLmxtKHQsdC5yLEgu
+TGgodCkuQygibG08MT4iKSkKcy5jPXQuZQpyZXR1cm4gc30sCmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0
+aGlzLmF9LAp0ZzpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09
+Il9fcHJvdG9fXyIpe3Q9dGhpcy5iCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIHUueS5iKHRbYl0p
+IT1udWxsfWVsc2V7cz10aGlzLlBSKGIpCnJldHVybiBzfX0sClBSOmZ1bmN0aW9uKGEpe3ZhciB0PXRo
+aXMuZAppZih0PT1udWxsKXJldHVybiExCnJldHVybiB0aGlzLkRGKHRbdGhpcy5OKGEpXSxhKT49MH0s
+Cmk6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHI9dGhpcwpILkxoKHIpLmQuYihiKQppZih0eXBlb2YgYj09
+InN0cmluZyImJmIhPT0iX19wcm90b19fIil7dD1yLmIKcmV0dXJuIHIuYlEodD09bnVsbD9yLmI9UC5U
+MigpOnQsYil9ZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4MjMpPT09Yil7cz1y
+LmMKcmV0dXJuIHIuYlEocz09bnVsbD9yLmM9UC5UMigpOnMsYil9ZWxzZSByZXR1cm4gci5CNyhiKX0s
+CkI3OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMKSC5MaChxKS5kLmIoYSkKdD1xLmQKaWYodD09
+bnVsbCl0PXEuZD1QLlQyKCkKcz1xLk4oYSkKcj10W3NdCmlmKHI9PW51bGwpdFtzXT1bcS55byhhKV0K
+ZWxzZXtpZihxLkRGKHIsYSk+PTApcmV0dXJuITEKci5wdXNoKHEueW8oYSkpfXJldHVybiEwfSwKUjpm
+dW5jdGlvbihhLGIpe3ZhciB0PXRoaXMKaWYodHlwZW9mIGI9PSJzdHJpbmciJiZiIT09Il9fcHJvdG9f
+XyIpcmV0dXJuIHQuTCh0LmIsYikKZWxzZSBpZih0eXBlb2YgYj09Im51bWJlciImJihiJjEwNzM3NDE4
+MjMpPT09YilyZXR1cm4gdC5MKHQuYyxiKQplbHNlIHJldHVybiB0LnFnKGIpfSwKcWc6ZnVuY3Rpb24o
+YSl7dmFyIHQscyxyLHEscD10aGlzLG89cC5kCmlmKG89PW51bGwpcmV0dXJuITEKdD1wLk4oYSkKcz1v
+W3RdCnI9cC5ERihzLGEpCmlmKHI8MClyZXR1cm4hMQpxPXMuc3BsaWNlKHIsMSlbMF0KaWYoMD09PXMu
+bGVuZ3RoKWRlbGV0ZSBvW3RdCnAuR1MocSkKcmV0dXJuITB9LApiUTpmdW5jdGlvbihhLGIpe0guTGgo
+dGhpcykuZC5iKGIpCmlmKHUueS5iKGFbYl0pIT1udWxsKXJldHVybiExCmFbYl09dGhpcy55byhiKQpy
+ZXR1cm4hMH0sCkw6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihhPT1udWxsKXJldHVybiExCnQ9dS55LmIo
+YVtiXSkKaWYodD09bnVsbClyZXR1cm4hMQp0aGlzLkdTKHQpCmRlbGV0ZSBhW2JdCnJldHVybiEwfSwK
+UzpmdW5jdGlvbigpe3RoaXMucj0xMDczNzQxODIzJnRoaXMucisxfSwKeW86ZnVuY3Rpb24oYSl7dmFy
+IHQscz10aGlzLHI9bmV3IFAuYm4oSC5MaChzKS5kLmIoYSkpCmlmKHMuZT09bnVsbClzLmU9cy5mPXIK
+ZWxzZXt0PXMuZgpyLmM9dApzLmY9dC5iPXJ9KytzLmEKcy5TKCkKcmV0dXJuIHJ9LApHUzpmdW5jdGlv
+bihhKXt2YXIgdD10aGlzLHM9YS5jLHI9YS5iCmlmKHM9PW51bGwpdC5lPXIKZWxzZSBzLmI9cgppZihy
+PT1udWxsKXQuZj1zCmVsc2Ugci5jPXM7LS10LmEKdC5TKCl9LApOOmZ1bmN0aW9uKGEpe3JldHVybiBK
+LmhmKGEpJjEwNzM3NDE4MjN9LApERjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYoYT09bnVsbClyZXR1
+cm4tMQp0PWEubGVuZ3RoCmZvcihzPTA7czx0OysrcylpZihKLlJNKGFbc10uYSxiKSlyZXR1cm4gcwpy
+ZXR1cm4tMX19ClAuYm4ucHJvdG90eXBlPXt9ClAubG0ucHJvdG90eXBlPXsKZ2w6ZnVuY3Rpb24oKXty
+ZXR1cm4gdGhpcy5kfSwKRjpmdW5jdGlvbigpe3ZhciB0PXRoaXMscz10LmEKaWYodC5iIT09cy5yKXRo
+cm93IEguYihQLmE0KHMpKQplbHNle3M9dC5jCmlmKHM9PW51bGwpe3Quc2oobnVsbCkKcmV0dXJuITF9
+ZWxzZXt0LnNqKHQuJHRpLmQuYihzLmEpKQp0LmM9dC5jLmIKcmV0dXJuITB9fX0sCnNqOmZ1bmN0aW9u
+KGEpe3RoaXMuZD10aGlzLiR0aS5kLmIoYSl9LAokaUFuOjF9ClAubVcucHJvdG90eXBlPXt9ClAudXku
+cHJvdG90eXBlPXskaWJROjEsJGljWDoxLCRpek06MX0KUC5sRC5wcm90b3R5cGU9ewpna3o6ZnVuY3Rp
+b24oYSl7cmV0dXJuIG5ldyBILmE3KGEsdGhpcy5nQShhKSxILnpLKGEpLkMoImE3PGxELkU+IikpfSwK
+RTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLnEoYSxiKX0sCks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxz
+CkgueksoYSkuQygifihsRC5FKSIpLmIoYikKdD10aGlzLmdBKGEpCmZvcihzPTA7czx0Oysrcyl7Yi4k
+MSh0aGlzLnEoYSxzKSkKaWYodCE9PXRoaXMuZ0EoYSkpdGhyb3cgSC5iKFAuYTQoYSkpfX0sCmdvcjpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nQShhKSE9PTB9LApFMjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9
+SC56SyhhKQpyZXR1cm4gbmV3IEguQTgoYSx0LktxKGMpLkMoIjEobEQuRSkiKS5iKGIpLHQuQygiQDxs
+RC5FPiIpLktxKGMpLkMoIkE4PDEsMj4iKSl9LApkdTpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdApILnpL
+KGEpLkMoImxELkUiKS5iKGQpClAuakIoYixjLHRoaXMuZ0EoYSkpCmZvcih0PWI7dDxjOysrdCl0aGlz
+LlkoYSx0LGQpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gUC5XRShhLCJbIiwiXSIpfX0KUC5pbC5wcm90
+b3R5cGU9e30KUC5yYS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHM9dGhpcy5hCmlm
+KCFzLmEpdGhpcy5iLmErPSIsICIKcy5hPSExCnM9dGhpcy5iCnQ9cy5hKz1ILmQoYSkKcy5hPXQrIjog
+IgpzLmErPUguZChiKX0sCiRTOjR9ClAuWWsucHJvdG90eXBlPXsKSzpmdW5jdGlvbihhLGIpe3ZhciB0
+LHMKSC5MaCh0aGlzKS5DKCJ+KFlrLkssWWsuVikiKS5iKGIpCmZvcih0PUouSVQodGhpcy5nVigpKTt0
+LkYoKTspe3M9dC5nbCgpCmIuJDIocyx0aGlzLnEoMCxzKSl9fSwKZ1B1OmZ1bmN0aW9uKGEpe3JldHVy
+biBKLk0xKHRoaXMuZ1YoKSxuZXcgUC55USh0aGlzKSxILkxoKHRoaXMpLkMoIk4zPFlrLkssWWsuVj4i
+KSl9LAp4NDpmdW5jdGlvbihhKXtyZXR1cm4gSi56bCh0aGlzLmdWKCksYSl9LApnQTpmdW5jdGlvbihh
+KXtyZXR1cm4gSi5IbSh0aGlzLmdWKCkpfSwKZ2wwOmZ1bmN0aW9uKGEpe3JldHVybiBKLnVVKHRoaXMu
+Z1YoKSl9LAp3OmZ1bmN0aW9uKGEpe3JldHVybiBQLm5PKHRoaXMpfSwKJGlaMDoxfQpQLnlRLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYSxzPUguTGgodCkKcy5DKCJZay5LIikuYihh
+KQpyZXR1cm4gbmV3IFAuTjMoYSx0LnEoMCxhKSxzLkMoIkA8WWsuSz4iKS5LcShzLkMoIllrLlYiKSku
+QygiTjM8MSwyPiIpKX0sCiRTOmZ1bmN0aW9uKCl7cmV0dXJuIEguTGgodGhpcy5hKS5DKCJOMzxZay5L
+LFlrLlY+KFlrLkspIil9fQpQLktQLnByb3RvdHlwZT17Clk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUgu
+TGgodGhpcykKdC5kLmIoYikKdC5jaFsxXS5iKGMpCnRocm93IEguYihQLkw0KCJDYW5ub3QgbW9kaWZ5
+IHVubW9kaWZpYWJsZSBtYXAiKSl9fQpQLlBuLnByb3RvdHlwZT17CnE6ZnVuY3Rpb24oYSxiKXtyZXR1
+cm4gdGhpcy5hLnEoMCxiKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PUguTGgodGhpcykKdGhpcy5h
+LlkoMCx0LmQuYihiKSx0LmNoWzFdLmIoYykpfSwKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS54
+NChhKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLEguTGgodGhpcykuQygifigxLDIpIikuYihi
+KSl9LApnbDA6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdsMCh0KX0sCmdBOmZ1bmN0
+aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nQSh0KX0sCnc6ZnVuY3Rpb24oYSl7cmV0dXJuIEou
+aih0aGlzLmEpfSwKZ1B1OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4gdC5nUHUodCl9LAok
+aVowOjF9ClAuR2oucHJvdG90eXBlPXt9ClAubGYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4gUC5XRSh0aGlzLCJ7IiwifSIpfX0KUC5Wai5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl4dTox
+fQpQLlh2LnByb3RvdHlwZT17CkZWOmZ1bmN0aW9uKGEsYil7dmFyIHQKZm9yKHQ9Si5JVChILkxoKHRo
+aXMpLkMoImNYPDE+IikuYihiKSk7dC5GKCk7KXRoaXMuaSgwLHQuZ2woKSl9LAp3OmZ1bmN0aW9uKGEp
+e3JldHVybiBQLldFKHRoaXMsInsiLCJ9Iil9LApIOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1QLnJqKHRo
+aXMsdGhpcy5yLEguTGgodGhpcykuZCkKaWYoIXMuRigpKXJldHVybiIiCmlmKGI9PT0iIil7dD0iIgpk
+byB0Kz1ILmQocy5kKQp3aGlsZShzLkYoKSl9ZWxzZXt0PUguZChzLmQpCmZvcig7cy5GKCk7KXQ9dCti
+K0guZChzLmQpfXJldHVybiB0LmNoYXJDb2RlQXQoMCk9PTA/dDp0fSwKJGliUToxLAokaWNYOjEsCiRp
+eHU6MX0KUC5uWS5wcm90b3R5cGU9e30KUC5UQy5wcm90b3R5cGU9e30KUC5SVS5wcm90b3R5cGU9e30K
+UC51dy5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmIKaWYocz09bnVsbCly
+ZXR1cm4gdGhpcy5jLnEoMCxiKQplbHNlIGlmKHR5cGVvZiBiIT0ic3RyaW5nIilyZXR1cm4gbnVsbApl
+bHNle3Q9c1tiXQpyZXR1cm4gdHlwZW9mIHQ9PSJ1bmRlZmluZWQiP3RoaXMuZmIoYik6dH19LApnQTpm
+dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5iPT1udWxsP3RoaXMuYy5hOnRoaXMuQ2YoKS5sZW5ndGh9LApn
+bDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ0EodGhpcyk9PT0wfSwKZ1Y6ZnVuY3Rpb24oKXtpZih0
+aGlzLmI9PW51bGwpe3ZhciB0PXRoaXMuYwpyZXR1cm4gbmV3IEguaTUodCxILkxoKHQpLkMoImk1PDE+
+IikpfXJldHVybiBuZXcgUC5pOCh0aGlzKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscj10aGlz
+CmlmKHIuYj09bnVsbClyLmMuWSgwLGIsYykKZWxzZSBpZihyLng0KGIpKXt0PXIuYgp0W2JdPWMKcz1y
+LmEKaWYocz09bnVsbD90IT1udWxsOnMhPT10KXNbYl09bnVsbH1lbHNlIHIuWEsoKS5ZKDAsYixjKX0s
+Cng0OmZ1bmN0aW9uKGEpe2lmKHRoaXMuYj09bnVsbClyZXR1cm4gdGhpcy5jLng0KGEpCnJldHVybiBP
+YmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpfSwKSzpmdW5jdGlvbihh
+LGIpe3ZhciB0LHMscixxLHA9dGhpcwp1LmNBLmIoYikKaWYocC5iPT1udWxsKXJldHVybiBwLmMuSygw
+LGIpCnQ9cC5DZigpCmZvcihzPTA7czx0Lmxlbmd0aDsrK3Mpe3I9dFtzXQpxPXAuYltyXQppZih0eXBl
+b2YgcT09InVuZGVmaW5lZCIpe3E9UC5RZShwLmFbcl0pCnAuYltyXT1xfWIuJDIocixxKQppZih0IT09
+cC5jKXRocm93IEguYihQLmE0KHApKX19LApDZjpmdW5jdGlvbigpe3ZhciB0PXUuai5iKHRoaXMuYykK
+aWYodD09bnVsbCl0PXRoaXMuYz1ILlZNKE9iamVjdC5rZXlzKHRoaXMuYSksdS5zKQpyZXR1cm4gdH0s
+ClhLOmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvPXRoaXMKaWYoby5iPT1udWxsKXJldHVybiBvLmMK
+dD1QLkZsKHUuTix1LnopCnM9by5DZigpCmZvcihyPTA7cT1zLmxlbmd0aCxyPHE7KytyKXtwPXNbcl0K
+dC5ZKDAscCxvLnEoMCxwKSl9aWYocT09PTApQy5ObS5pKHMsbnVsbCkKZWxzZSBDLk5tLnNBKHMsMCkK
+by5hPW8uYj1udWxsCnJldHVybiBvLmM9dH0sCmZiOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKCFPYmplY3Qu
+cHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwodGhpcy5hLGEpKXJldHVybiBudWxsCnQ9UC5RZSh0
+aGlzLmFbYV0pCnJldHVybiB0aGlzLmJbYV09dH19ClAuaTgucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0LmdBKHQpfSwKRTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMu
+YQppZih0LmI9PW51bGwpdD10LmdWKCkuRSgwLGIpCmVsc2V7dD10LkNmKCkKaWYoYjwwfHxiPj10Lmxl
+bmd0aClyZXR1cm4gSC5PSCh0LGIpCnQ9dFtiXX1yZXR1cm4gdH0sCmdrejpmdW5jdGlvbihhKXt2YXIg
+dD10aGlzLmEKaWYodC5iPT1udWxsKXt0PXQuZ1YoKQp0PXQuZ2t6KHQpfWVsc2V7dD10LkNmKCkKdD1u
+ZXcgSi5tMSh0LHQubGVuZ3RoLEgudDYodCkuQygibTE8MT4iKSl9cmV0dXJuIHR9LAp0ZzpmdW5jdGlv
+bihhLGIpe3JldHVybiB0aGlzLmEueDQoYil9fQpQLkNWLnByb3RvdHlwZT17CnlyOmZ1bmN0aW9uKGEs
+YTAsYTEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoLGcsZixlLGQsYyxiPSJJbnZhbGlkIGJh
+c2U2NCBlbmNvZGluZyBsZW5ndGggIgphMT1QLmpCKGEwLGExLGEubGVuZ3RoKQp0PSQuVjcoKQpmb3Io
+cz1hMCxyPXMscT1udWxsLHA9LTEsbz0tMSxuPTA7czxhMTtzPW0pe209cysxCmw9Qy54Qi5XKGEscykK
+aWYobD09PTM3KXtrPW0rMgppZihrPD1hMSl7aj1ILm9vKEMueEIuVyhhLG0pKQppPUgub28oQy54Qi5X
+KGEsbSsxKSkKaD1qKjE2K2ktKGkmMjU2KQppZihoPT09MzcpaD0tMQptPWt9ZWxzZSBoPS0xfWVsc2Ug
+aD1sCmlmKDA8PWgmJmg8PTEyNyl7aWYoaDwwfHxoPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGgpCmc9
+dFtoXQppZihnPj0wKXtoPUMueEIubSgiQUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlq
+a2xtbm9wcXJzdHV2d3h5ejAxMjM0NTY3ODkrLyIsZykKaWYoaD09PWwpY29udGludWUKbD1ofWVsc2V7
+aWYoZz09PS0xKXtpZihwPDApe2Y9cT09bnVsbD9udWxsOnEuYS5sZW5ndGgKaWYoZj09bnVsbClmPTAK
+cD1mKyhzLXIpCm89c30rK24KaWYobD09PTYxKWNvbnRpbnVlfWw9aH1pZihnIT09LTIpe2lmKHE9PW51
+bGwpcT1uZXcgUC5SbigiIikKcS5hKz1DLnhCLk5qKGEscixzKQpxLmErPUguTHcobCkKcj1tCmNvbnRp
+bnVlfX10aHJvdyBILmIoUC5ycigiSW52YWxpZCBiYXNlNjQgZGF0YSIsYSxzKSl9aWYocSE9bnVsbCl7
+Zj1xLmErPUMueEIuTmooYSxyLGExKQplPWYubGVuZ3RoCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGUp
+CmVsc2V7ZD1DLmpuLnpZKGUtMSw0KSsxCmlmKGQ9PT0xKXRocm93IEguYihQLnJyKGIsYSxhMSkpCmZv
+cig7ZDw0Oyl7Zis9Ij0iCnEuYT1mOysrZH19Zj1xLmEKcmV0dXJuIEMueEIuaTcoYSxhMCxhMSxmLmNo
+YXJDb2RlQXQoMCk9PTA/ZjpmKX1jPWExLWEwCmlmKHA+PTApUC54TShhLG8sYTEscCxuLGMpCmVsc2V7
+ZD1DLmpuLnpZKGMsNCkKaWYoZD09PTEpdGhyb3cgSC5iKFAucnIoYixhLGExKSkKaWYoZD4xKWE9Qy54
+Qi5pNyhhLGExLGExLGQ9PT0yPyI9PSI6Ij0iKX1yZXR1cm4gYX19ClAuVTgucHJvdG90eXBlPXt9ClAu
+VWsucHJvdG90eXBlPXt9ClAud0kucHJvdG90eXBlPXt9ClAuWmkucHJvdG90eXBlPXt9ClAuVWQucHJv
+dG90eXBlPXsKdzpmdW5jdGlvbihhKXt2YXIgdD1QLnAodGhpcy5hKQpyZXR1cm4odGhpcy5iIT1udWxs
+PyJDb252ZXJ0aW5nIG9iamVjdCB0byBhbiBlbmNvZGFibGUgb2JqZWN0IGZhaWxlZDoiOiJDb252ZXJ0
+aW5nIG9iamVjdCBkaWQgbm90IHJldHVybiBhbiBlbmNvZGFibGUgb2JqZWN0OiIpKyIgIit0fX0KUC5L
+OC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJDeWNsaWMgZXJyb3IgaW4gSlNPTiBzdHJp
+bmdpZnkifX0KUC5ieS5wcm90b3R5cGU9ewpwVzpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdS5lcC5iKGMp
+CnQ9UC5CUyhiLHRoaXMuZ0hlKCkuYSkKcmV0dXJuIHR9LApPQjpmdW5jdGlvbihhLGIpe3ZhciB0CnUu
+YmMuYihiKQp0PVAudVgoYSx0aGlzLmdaRSgpLmIsbnVsbCkKcmV0dXJuIHR9LApnWkU6ZnVuY3Rpb24o
+KXtyZXR1cm4gQy5uWH0sCmdIZTpmdW5jdGlvbigpe3JldHVybiBDLkEzfX0KUC5vai5wcm90b3R5cGU9
+e30KUC5NeC5wcm90b3R5cGU9e30KUC5TaC5wcm90b3R5cGU9ewp2cDpmdW5jdGlvbihhKXt2YXIgdCxz
+LHIscSxwLG8sbj1hLmxlbmd0aApmb3IodD1KLnJZKGEpLHM9dGhpcy5jLHI9MCxxPTA7cTxuOysrcSl7
+cD10LlcoYSxxKQppZihwPjkyKWNvbnRpbnVlCmlmKHA8MzIpe2lmKHE+cilzLmErPUMueEIuTmooYSxy
+LHEpCnI9cSsxCnMuYSs9SC5Mdyg5MikKc3dpdGNoKHApe2Nhc2UgODpzLmErPUguTHcoOTgpCmJyZWFr
+CmNhc2UgOTpzLmErPUguTHcoMTE2KQpicmVhawpjYXNlIDEwOnMuYSs9SC5MdygxMTApCmJyZWFrCmNh
+c2UgMTI6cy5hKz1ILkx3KDEwMikKYnJlYWsKY2FzZSAxMzpzLmErPUguTHcoMTE0KQpicmVhawpkZWZh
+dWx0OnMuYSs9SC5MdygxMTcpCnMuYSs9SC5Mdyg0OCkKcy5hKz1ILkx3KDQ4KQpvPXA+Pj40JjE1CnMu
+YSs9SC5MdyhvPDEwPzQ4K286ODcrbykKbz1wJjE1CnMuYSs9SC5MdyhvPDEwPzQ4K286ODcrbykKYnJl
+YWt9fWVsc2UgaWYocD09PTM0fHxwPT09OTIpe2lmKHE+cilzLmErPUMueEIuTmooYSxyLHEpCnI9cSsx
+CnMuYSs9SC5Mdyg5MikKcy5hKz1ILkx3KHApfX1pZihyPT09MClzLmErPUguZChhKQplbHNlIGlmKHI8
+bilzLmErPXQuTmooYSxyLG4pfSwKSm46ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEKZm9yKHQ9dGhpcy5h
+LHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9dFtyXQppZihhPT1udWxsP3E9PW51bGw6YT09PXEpdGhy
+b3cgSC5iKG5ldyBQLks4KGEsbnVsbCkpfUMuTm0uaSh0LGEpfSwKaVU6ZnVuY3Rpb24oYSl7dmFyIHQs
+cyxyLHEscD10aGlzCmlmKHAudE0oYSkpcmV0dXJuCnAuSm4oYSkKdHJ5e3Q9cC5iLiQxKGEpCmlmKCFw
+LnRNKHQpKXtyPVAuR3koYSxudWxsLHAuZ1ZLKCkpCnRocm93IEguYihyKX1yPXAuYQppZigwPj1yLmxl
+bmd0aClyZXR1cm4gSC5PSChyLC0xKQpyLnBvcCgpfWNhdGNoKHEpe3M9SC5SdShxKQpyPVAuR3koYSxz
+LHAuZ1ZLKCkpCnRocm93IEguYihyKX19LAp0TTpmdW5jdGlvbihhKXt2YXIgdCxzLHI9dGhpcwppZih0
+eXBlb2YgYT09Im51bWJlciIpe2lmKCFpc0Zpbml0ZShhKSlyZXR1cm4hMQpyLmMuYSs9Qy5DRC53KGEp
+CnJldHVybiEwfWVsc2UgaWYoYT09PSEwKXtyLmMuYSs9InRydWUiCnJldHVybiEwfWVsc2UgaWYoYT09
+PSExKXtyLmMuYSs9ImZhbHNlIgpyZXR1cm4hMH1lbHNlIGlmKGE9PW51bGwpe3IuYy5hKz0ibnVsbCIK
+cmV0dXJuITB9ZWxzZSBpZih0eXBlb2YgYT09InN0cmluZyIpe3Q9ci5jCnQuYSs9JyInCnIudnAoYSkK
+dC5hKz0nIicKcmV0dXJuITB9ZWxzZSBpZih1LmouYyhhKSl7ci5KbihhKQpyLmxLKGEpCnQ9ci5hCmlm
+KDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkKcmV0dXJuITB9ZWxzZSBpZih1Lkcu
+YyhhKSl7ci5KbihhKQpzPXIuancoYSkKdD1yLmEKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwt
+MSkKdC5wb3AoKQpyZXR1cm4gc31lbHNlIHJldHVybiExfSwKbEs6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+PXRoaXMuYwpyLmErPSJbIgp0PUouVTYoYSkKaWYodC5nb3IoYSkpe3RoaXMuaVUodC5xKGEsMCkpCmZv
+cihzPTE7czx0LmdBKGEpOysrcyl7ci5hKz0iLCIKdGhpcy5pVSh0LnEoYSxzKSl9fXIuYSs9Il0ifSwK
+anc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPXt9CmlmKGEuZ2wwKGEpKXtuLmMu
+YSs9Int9IgpyZXR1cm4hMH10PWEuZ0EoYSkqMgpzPW5ldyBBcnJheSh0KQpzLmZpeGVkJGxlbmd0aD1B
+cnJheQpyPW0uYT0wCm0uYj0hMAphLksoMCxuZXcgUC50aShtLHMpKQppZighbS5iKXJldHVybiExCnE9
+bi5jCnEuYSs9InsiCmZvcihwPSciJztyPHQ7cis9MixwPScsIicpe3EuYSs9cApuLnZwKEgueShzW3Jd
+KSkKcS5hKz0nIjonCm89cisxCmlmKG8+PXQpcmV0dXJuIEguT0gocyxvKQpuLmlVKHNbb10pfXEuYSs9
+In0iCnJldHVybiEwfX0KUC50aS5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKaWYo
+dHlwZW9mIGEhPSJzdHJpbmciKXRoaXMuYS5iPSExCnQ9dGhpcy5iCnM9dGhpcy5hCkMuTm0uWSh0LHMu
+YSsrLGEpCkMuTm0uWSh0LHMuYSsrLGIpfSwKJFM6NH0KUC50dS5wcm90b3R5cGU9ewpnVks6ZnVuY3Rp
+b24oKXt2YXIgdD10aGlzLmMuYQpyZXR1cm4gdC5jaGFyQ29kZUF0KDApPT0wP3Q6dH19ClAudTUucHJv
+dG90eXBlPXsKZ1pFOmZ1bmN0aW9uKCl7cmV0dXJuIEMuUWt9fQpQLkUzLnByb3RvdHlwZT17CldKOmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj1QLmpCKDAsbnVsbCxhLmxlbmd0aCkscT1yLTAKaWYocT09PTApcmV0
+dXJuIG5ldyBVaW50OEFycmF5KDApCnQ9bmV3IFVpbnQ4QXJyYXkocSozKQpzPW5ldyBQLlJ3KHQpCmlm
+KHMuR3goYSwwLHIpIT09cilzLk82KEouYTYoYSxyLTEpLDApCnJldHVybiBuZXcgVWludDhBcnJheSh0
+LnN1YmFycmF5KDAsSC5yTSgwLHMuYix0Lmxlbmd0aCkpKX19ClAuUncucHJvdG90eXBlPXsKTzY6ZnVu
+Y3Rpb24oYSxiKXt2YXIgdCxzPXRoaXMscj1zLmMscT1zLmIscD1xKzEsbz1yLmxlbmd0aAppZigoYiY2
+NDUxMik9PT01NjMyMCl7dD02NTUzNisoKGEmMTAyMyk8PDEwKXxiJjEwMjMKcy5iPXAKaWYocT49byly
+ZXR1cm4gSC5PSChyLHEpCnJbcV09MjQwfHQ+Pj4xOApxPXMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5P
+SChyLHApCnJbcF09MTI4fHQ+Pj4xMiY2MwpwPXMuYj1xKzEKaWYocT49bylyZXR1cm4gSC5PSChyLHEp
+CnJbcV09MTI4fHQ+Pj42JjYzCnMuYj1wKzEKaWYocD49bylyZXR1cm4gSC5PSChyLHApCnJbcF09MTI4
+fHQmNjMKcmV0dXJuITB9ZWxzZXtzLmI9cAppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0yMjR8
+YT4+PjEyCnE9cy5iPXArMQppZihwPj1vKXJldHVybiBILk9IKHIscCkKcltwXT0xMjh8YT4+PjYmNjMK
+cy5iPXErMQppZihxPj1vKXJldHVybiBILk9IKHIscSkKcltxXT0xMjh8YSY2MwpyZXR1cm4hMX19LApH
+eDpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzCmlmKGIhPT1jJiYoQy54Qi5t
+KGEsYy0xKSY2NDUxMik9PT01NTI5NiktLWMKZm9yKHQ9bS5jLHM9dC5sZW5ndGgscj1iO3I8YzsrK3Ip
+e3E9Qy54Qi5XKGEscikKaWYocTw9MTI3KXtwPW0uYgppZihwPj1zKWJyZWFrCm0uYj1wKzEKdFtwXT1x
+fWVsc2UgaWYoKHEmNjQ1MTIpPT09NTUyOTYpe2lmKG0uYiszPj1zKWJyZWFrCm89cisxCmlmKG0uTzYo
+cSxDLnhCLlcoYSxvKSkpcj1vfWVsc2UgaWYocTw9MjA0Nyl7cD1tLmIKbj1wKzEKaWYobj49cylicmVh
+awptLmI9bgppZihwPj1zKXJldHVybiBILk9IKHQscCkKdFtwXT0xOTJ8cT4+PjYKbS5iPW4rMQp0W25d
+PTEyOHxxJjYzfWVsc2V7cD1tLmIKaWYocCsyPj1zKWJyZWFrCm49bS5iPXArMQppZihwPj1zKXJldHVy
+biBILk9IKHQscCkKdFtwXT0yMjR8cT4+PjEyCnA9bS5iPW4rMQppZihuPj1zKXJldHVybiBILk9IKHQs
+bikKdFtuXT0xMjh8cT4+PjYmNjMKbS5iPXArMQppZihwPj1zKXJldHVybiBILk9IKHQscCkKdFtwXT0x
+Mjh8cSY2M319cmV0dXJuIHJ9fQpQLkdZLnByb3RvdHlwZT17CldKOmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbAp1LkwuYihhKQp0PVAua3koITEsYSwwLG51bGwpCmlmKHQhPW51bGwpcmV0dXJu
+IHQKcz1QLmpCKDAsbnVsbCxKLkhtKGEpKQpyPVAuY1AoYSwwLHMpCmlmKHI+MCl7cT1QLkhNKGEsMCxy
+KQppZihyPT09cylyZXR1cm4gcQpwPW5ldyBQLlJuKHEpCm89cgpuPSExfWVsc2V7bz0wCnA9bnVsbApu
+PSEwfWlmKHA9PW51bGwpcD1uZXcgUC5SbigiIikKbT1uZXcgUC5ieighMSxwKQptLmM9bgptLk1FKGEs
+byxzKQppZihtLmU+MCl7SC52aChQLnJyKCJVbmZpbmlzaGVkIFVURi04IG9jdGV0IHNlcXVlbmNlIixh
+LHMpKQpwLmErPUguTHcoNjU1MzMpCm0uZj1tLmU9bS5kPTB9bD1wLmEKcmV0dXJuIGwuY2hhckNvZGVB
+dCgwKT09MD9sOmx9fQpQLmJ6LnByb3RvdHlwZT17Ck1FOmZ1bmN0aW9uKGEsYixjKXt2YXIgdCxzLHIs
+cSxwLG8sbixtLGwsayxqLGksaD10aGlzLGc9IkJhZCBVVEYtOCBlbmNvZGluZyAweCIKdS5MLmIoYSkK
+dD1oLmQKcz1oLmUKcj1oLmYKaC5mPWguZT1oLmQ9MAokbGFiZWwwJDA6Zm9yKHE9Si5VNihhKSxwPWgu
+YixvPWI7ITA7bz1qKXskbGFiZWwxJDE6aWYocz4wKXtkb3tpZihvPT09YylicmVhayAkbGFiZWwwJDAK
+bj1xLnEoYSxvKQppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBuLnpNKCkKaWYoKG4mMTkyKSE9
+PTEyOCl7bT1QLnJyKGcrQy5qbi5XWihuLDE2KSxhLG8pCnRocm93IEguYihtKX1lbHNle3Q9KHQ8PDZ8
+biY2Myk+Pj4wOy0tczsrK299fXdoaWxlKHM+MCkKbT1yLTEKaWYobTwwfHxtPj00KXJldHVybiBILk9I
+KEMuR2IsbSkKaWYodDw9Qy5HYlttXSl7bT1QLnJyKCJPdmVybG9uZyBlbmNvZGluZyBvZiAweCIrQy5q
+bi5XWih0LDE2KSxhLG8tci0xKQp0aHJvdyBILmIobSl9aWYodD4xMTE0MTExKXttPVAucnIoIkNoYXJh
+Y3RlciBvdXRzaWRlIHZhbGlkIFVuaWNvZGUgcmFuZ2U6IDB4IitDLmpuLldaKHQsMTYpLGEsby1yLTEp
+CnRocm93IEguYihtKX1pZighaC5jfHx0IT09NjUyNzkpcC5hKz1ILkx3KHQpCmguYz0hMX1mb3IobT1v
+PGM7bTspe2w9UC5jUChhLG8sYykKaWYobD4wKXtoLmM9ITEKaz1vK2wKcC5hKz1QLkhNKGEsbyxrKQpp
+ZihrPT09YylicmVha31lbHNlIGs9bwpqPWsrMQpuPXEucShhLGspCmlmKHR5cGVvZiBuIT09Im51bWJl
+ciIpcmV0dXJuIG4uSigpCmlmKG48MCl7aT1QLnJyKCJOZWdhdGl2ZSBVVEYtOCBjb2RlIHVuaXQ6IC0w
+eCIrQy5qbi5XWigtbiwxNiksYSxqLTEpCnRocm93IEguYihpKX1lbHNle2lmKChuJjIyNCk9PT0xOTIp
+e3Q9biYzMQpzPTEKcj0xCmNvbnRpbnVlICRsYWJlbDAkMH1pZigobiYyNDApPT09MjI0KXt0PW4mMTUK
+cz0yCnI9Mgpjb250aW51ZSAkbGFiZWwwJDB9aWYoKG4mMjQ4KT09PTI0MCYmbjwyNDUpe3Q9biY3CnM9
+MwpyPTMKY29udGludWUgJGxhYmVsMCQwfWk9UC5ycihnK0Muam4uV1oobiwxNiksYSxqLTEpCnRocm93
+IEguYihpKX19YnJlYWsgJGxhYmVsMCQwfWlmKHM+MCl7aC5kPXQKaC5lPXMKaC5mPXJ9fX0KUC5XRi5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3ZhciB0LHMscgp1LmZvLmIoYSkKdD10aGlzLmIKcz10
+aGlzLmEKdC5hKz1zLmEKcj10LmErPUguZChhLmEpCnQuYT1yKyI6ICIKdC5hKz1QLnAoYikKcy5hPSIs
+ICJ9LAokUzo0Mn0KUC5hMi5wcm90b3R5cGU9e30KUC5pUC5wcm90b3R5cGU9ewpETjpmdW5jdGlvbihh
+LGIpe2lmKGI9PW51bGwpcmV0dXJuITEKcmV0dXJuIGIgaW5zdGFuY2VvZiBQLmlQJiZ0aGlzLmE9PT1i
+LmEmJiEwfSwKZ2lPOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYQpyZXR1cm4odF5DLmpuLndHKHQsMzAp
+KSYxMDczNzQxODIzfSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLHM9UC5HcShILnRKKHQpKSxyPVAu
+aDAoSC5OUyh0KSkscT1QLmgwKEguakEodCkpLHA9UC5oMChILklYKHQpKSxvPVAuaDAoSC5jaCh0KSks
+bj1QLmgwKEguSmQodCkpLG09UC5WeChILm8xKHQpKSxsPXMrIi0iK3IrIi0iK3ErIiAiK3ArIjoiK28r
+IjoiK24rIi4iK20KcmV0dXJuIGx9fQpQLkNQLnByb3RvdHlwZT17fQpQLlhTLnByb3RvdHlwZT17fQpQ
+LkM2LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCmlmKHQhPW51bGwpcmV0dXJu
+IkFzc2VydGlvbiBmYWlsZWQ6ICIrUC5wKHQpCnJldHVybiJBc3NlcnRpb24gZmFpbGVkIn19ClAubi5w
+cm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiJUaHJvdyBvZiBudWxsLiJ9fQpQLnUucHJvdG90
+eXBlPXsKZ1o6ZnVuY3Rpb24oKXtyZXR1cm4iSW52YWxpZCBhcmd1bWVudCIrKCF0aGlzLmE/IihzKSI6
+IiIpfSwKZ3U6ZnVuY3Rpb24oKXtyZXR1cm4iIn0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscD10
+aGlzLG89cC5jLG49byE9bnVsbD8iICgiK28rIikiOiIiCm89cC5kCnQ9bz09bnVsbD8iIjoiOiAiK0gu
+ZChvKQpzPXAuZ1ooKStuK3QKaWYoIXAuYSlyZXR1cm4gcwpyPXAuZ3UoKQpxPVAucChwLmIpCnJldHVy
+biBzK3IrIjogIitxfX0KUC5iSi5wcm90b3R5cGU9ewpnWjpmdW5jdGlvbigpe3JldHVybiJSYW5nZUVy
+cm9yIn0sCmd1OmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMuZQppZihyPT1udWxsKXtyPXRoaXMuZgp0
+PXIhPW51bGw/IjogTm90IGxlc3MgdGhhbiBvciBlcXVhbCB0byAiK0guZChyKToiIn1lbHNle3M9dGhp
+cy5mCmlmKHM9PW51bGwpdD0iOiBOb3QgZ3JlYXRlciB0aGFuIG9yIGVxdWFsIHRvICIrSC5kKHIpCmVs
+c2UgaWYocz5yKXQ9IjogTm90IGluIHJhbmdlICIrSC5kKHIpKyIuLiIrSC5kKHMpKyIsIGluY2x1c2l2
+ZSIKZWxzZSB0PXM8cj8iOiBWYWxpZCB2YWx1ZSByYW5nZSBpcyBlbXB0eSI6IjogT25seSB2YWxpZCB2
+YWx1ZSBpcyAiK0guZChyKX1yZXR1cm4gdH19ClAuZVkucHJvdG90eXBlPXsKZ1o6ZnVuY3Rpb24oKXty
+ZXR1cm4iUmFuZ2VFcnJvciJ9LApndTpmdW5jdGlvbigpe3ZhciB0LHM9SC5TYyh0aGlzLmIpCmlmKHR5
+cGVvZiBzIT09Im51bWJlciIpcmV0dXJuIHMuSigpCmlmKHM8MClyZXR1cm4iOiBpbmRleCBtdXN0IG5v
+dCBiZSBuZWdhdGl2ZSIKdD10aGlzLmYKaWYodD09PTApcmV0dXJuIjogbm8gaW5kaWNlcyBhcmUgdmFs
+aWQiCnJldHVybiI6IGluZGV4IHNob3VsZCBiZSBsZXNzIHRoYW4gIitILmQodCl9LApnQTpmdW5jdGlv
+bihhKXtyZXR1cm4gdGhpcy5mfX0KUC5tcC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3ZhciB0LHMs
+cixxLHAsbyxuLG0sbD10aGlzLGs9e30saj1uZXcgUC5SbigiIikKay5hPSIiCmZvcih0PWwuYyxzPXQu
+bGVuZ3RoLHI9MCxxPSIiLHA9IiI7cjxzOysrcixwPSIsICIpe289dFtyXQpqLmE9cStwCnE9ai5hKz1Q
+LnAobykKay5hPSIsICJ9bC5kLksoMCxuZXcgUC5XRihrLGopKQpuPVAucChsLmEpCm09ai53KDApCnQ9
+Ik5vU3VjaE1ldGhvZEVycm9yOiBtZXRob2Qgbm90IGZvdW5kOiAnIitILmQobC5iLmEpKyInXG5SZWNl
+aXZlcjogIituKyJcbkFyZ3VtZW50czogWyIrbSsiXSIKcmV0dXJuIHR9fQpQLnViLnByb3RvdHlwZT17
+Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIlVuc3VwcG9ydGVkIG9wZXJhdGlvbjogIit0aGlzLmF9fQpQLmRz
+LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0IT1udWxsPyJVbmlt
+cGxlbWVudGVkRXJyb3I6ICIrdDoiVW5pbXBsZW1lbnRlZEVycm9yIn19ClAubGoucHJvdG90eXBlPXsK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iQmFkIHN0YXRlOiAiK3RoaXMuYX19ClAuVVYucHJvdG90eXBlPXsK
+dzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKaWYodD09bnVsbClyZXR1cm4iQ29uY3VycmVudCBtb2Rp
+ZmljYXRpb24gZHVyaW5nIGl0ZXJhdGlvbi4iCnJldHVybiJDb25jdXJyZW50IG1vZGlmaWNhdGlvbiBk
+dXJpbmcgaXRlcmF0aW9uOiAiK1AucCh0KSsiLiJ9fQpQLms1LnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24o
+YSl7cmV0dXJuIk91dCBvZiBNZW1vcnkifSwKJGlYUzoxfQpQLktZLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIlN0YWNrIE92ZXJmbG93In0sCiRpWFM6MX0KUC5jLnByb3RvdHlwZT17Cnc6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5hCnJldHVybiB0PT1udWxsPyJSZWFkaW5nIHN0YXRpYyB2YXJpYWJs
+ZSBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIjoiUmVhZGluZyBzdGF0aWMgdmFyaWFibGUgJyIrdCsi
+JyBkdXJpbmcgaXRzIGluaXRpYWxpemF0aW9uIn19ClAuQ0QucHJvdG90eXBlPXsKdzpmdW5jdGlvbihh
+KXtyZXR1cm4iRXhjZXB0aW9uOiAiK3RoaXMuYX0sCiRpUno6MX0KUC5hRS5wcm90b3R5cGU9ewp3OmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGosaSxoPXRoaXMuYSxnPWghPW51bGwmJiIi
+IT09aD8iRm9ybWF0RXhjZXB0aW9uOiAiK0guZChoKToiRm9ybWF0RXhjZXB0aW9uIixmPXRoaXMuYyxl
+PXRoaXMuYgppZih0eXBlb2YgZT09InN0cmluZyIpe2lmKGYhPW51bGwpaD1mPDB8fGY+ZS5sZW5ndGgK
+ZWxzZSBoPSExCmlmKGgpZj1udWxsCmlmKGY9PW51bGwpe3Q9ZS5sZW5ndGg+Nzg/Qy54Qi5OaihlLDAs
+NzUpKyIuLi4iOmUKcmV0dXJuIGcrIlxuIit0fWZvcihzPTEscj0wLHE9ITEscD0wO3A8ZjsrK3Ape289
+Qy54Qi5XKGUscCkKaWYobz09PTEwKXtpZihyIT09cHx8IXEpKytzCnI9cCsxCnE9ITF9ZWxzZSBpZihv
+PT09MTMpeysrcwpyPXArMQpxPSEwfX1nPXM+MT9nKygiIChhdCBsaW5lICIrcysiLCBjaGFyYWN0ZXIg
+IisoZi1yKzEpKyIpXG4iKTpnKygiIChhdCBjaGFyYWN0ZXIgIisoZisxKSsiKVxuIikKbj1lLmxlbmd0
+aApmb3IocD1mO3A8bjsrK3Ape289Qy54Qi5tKGUscCkKaWYobz09PTEwfHxvPT09MTMpe249cApicmVh
+a319aWYobi1yPjc4KWlmKGYtcjw3NSl7bT1yKzc1Cmw9cgprPSIiCmo9Ii4uLiJ9ZWxzZXtpZihuLWY8
+NzUpe2w9bi03NQptPW4Kaj0iIn1lbHNle2w9Zi0zNgptPWYrMzYKaj0iLi4uIn1rPSIuLi4ifWVsc2V7
+bT1uCmw9cgprPSIiCmo9IiJ9aT1DLnhCLk5qKGUsbCxtKQpyZXR1cm4gZytrK2kraisiXG4iK0MueEIu
+SXgoIiAiLGYtbCtrLmxlbmd0aCkrIl5cbiJ9ZWxzZSByZXR1cm4gZiE9bnVsbD9nKygiIChhdCBvZmZz
+ZXQgIitILmQoZikrIikiKTpnfSwKJGlSejoxfQpQLkVILnByb3RvdHlwZT17fQpQLktOLnByb3RvdHlw
+ZT17fQpQLmNYLnByb3RvdHlwZT17CkUyOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD1ILkxoKHRoaXMpCnJl
+dHVybiBILksxKHRoaXMsdC5LcShjKS5DKCIxKGNYLkUpIikuYihiKSx0LkMoImNYLkUiKSxjKX0sCmV2
+OmZ1bmN0aW9uKGEsYil7dmFyIHQ9SC5MaCh0aGlzKQpyZXR1cm4gbmV3IEguVTUodGhpcyx0LkMoImEy
+KGNYLkUpIikuYihiKSx0LkMoIlU1PGNYLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlz
+Lmdreih0aGlzKQpmb3IodD0wO3MuRigpOykrK3QKcmV0dXJuIHR9LApnbDA6ZnVuY3Rpb24oYSl7cmV0
+dXJuIXRoaXMuZ2t6KHRoaXMpLkYoKX0sCmdyODpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZ2t6KHRo
+aXMpCmlmKCFzLkYoKSl0aHJvdyBILmIoSC5XcCgpKQp0PXMuZ2woKQppZihzLkYoKSl0aHJvdyBILmIo
+SC5kVSgpKQpyZXR1cm4gdH0sCkU6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIKUC5rMShiLCJpbmRleCIp
+CmZvcih0PXRoaXMuZ2t6KHRoaXMpLHM9MDt0LkYoKTspe3I9dC5nbCgpCmlmKGI9PT1zKXJldHVybiBy
+Oysrc310aHJvdyBILmIoUC5DZihiLHRoaXMsImluZGV4IixudWxsLHMpKX0sCnc6ZnVuY3Rpb24oYSl7
+cmV0dXJuIFAuRVAodGhpcywiKCIsIikiKX19ClAuQW4ucHJvdG90eXBlPXt9ClAuek0ucHJvdG90eXBl
+PXskaWJROjEsJGljWDoxfQpQLlowLnByb3RvdHlwZT17fQpQLk4zLnByb3RvdHlwZT17Cnc6ZnVuY3Rp
+b24oYSl7cmV0dXJuIk1hcEVudHJ5KCIrSC5kKHRoaXMuYSkrIjogIitILmQodGhpcy5iKSsiKSJ9fQpQ
+LmM4LnByb3RvdHlwZT17CmdpTzpmdW5jdGlvbihhKXtyZXR1cm4gUC5rLnByb3RvdHlwZS5naU8uY2Fs
+bCh0aGlzLHRoaXMpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4ibnVsbCJ9fQpQLkZLLnByb3RvdHlwZT17
+fQpQLmsucHJvdG90eXBlPXtjb25zdHJ1Y3RvcjpQLmssJGlrOjEsCkROOmZ1bmN0aW9uKGEsYil7cmV0
+dXJuIHRoaXM9PT1ifSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBILmVRKHRoaXMpfSwKdzpmdW5jdGlv
+bihhKXtyZXR1cm4iSW5zdGFuY2Ugb2YgJyIrSC5kKEguTSh0aGlzKSkrIicifSwKZTc6ZnVuY3Rpb24o
+YSxiKXt1Lm8uYihiKQp0aHJvdyBILmIoUC5scih0aGlzLGIuZ1dhKCksYi5nbmQoKSxiLmdWbSgpKSl9
+LAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiB0aGlzLncodGhpcyl9fQpQLk9kLnByb3RvdHlwZT17
+fQpQLmliLnByb3RvdHlwZT17JGlPZDoxfQpQLnh1LnByb3RvdHlwZT17fQpQLkd6LnByb3RvdHlwZT17
+fQpQLnFVLnByb3RvdHlwZT17JGl2WDoxfQpQLlJuLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3Jl
+dHVybiB0aGlzLmEubGVuZ3RofSwKdzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEKcmV0dXJuIHQuY2hh
+ckNvZGVBdCgwKT09MD90OnR9LAokaUJMOjF9ClAuR0QucHJvdG90eXBlPXt9ClAubjEucHJvdG90eXBl
+PXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscQp1LmYuYihhKQpILnkoYikKdD1KLnJZKGIpLk9Z
+KGIsIj0iKQppZih0PT09LTEpe2lmKGIhPT0iIilhLlkoMCxQLmt1KGIsMCxiLmxlbmd0aCx0aGlzLmEs
+ITApLCIiKX1lbHNlIGlmKHQhPT0wKXtzPUMueEIuTmooYiwwLHQpCnI9Qy54Qi5HKGIsdCsxKQpxPXRo
+aXMuYQphLlkoMCxQLmt1KHMsMCxzLmxlbmd0aCxxLCEwKSxQLmt1KHIsMCxyLmxlbmd0aCxxLCEwKSl9
+cmV0dXJuIGF9LAokUzoxOX0KUC5jUy5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEgu
+YihQLnJyKCJJbGxlZ2FsIElQdjQgYWRkcmVzcywgIithLHRoaXMuYSxiKSl9LAokUzo0Nn0KUC5WQy5w
+cm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3Rocm93IEguYihQLnJyKCJJbGxlZ2FsIElQdjYgYWRk
+cmVzcywgIithLHRoaXMuYSxiKSl9LAokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy4kMihhLG51bGwp
+fSwKJFM6NDd9ClAuSlQucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdAppZihiLWE+NCl0
+aGlzLmEuJDIoImFuIElQdjYgcGFydCBjYW4gb25seSBjb250YWluIGEgbWF4aW11bSBvZiA0IGhleCBk
+aWdpdHMiLGEpCnQ9UC5RQShDLnhCLk5qKHRoaXMuYixhLGIpLG51bGwsMTYpCmlmKHR5cGVvZiB0IT09
+Im51bWJlciIpcmV0dXJuIHQuSigpCmlmKHQ8MHx8dD42NTUzNSl0aGlzLmEuJDIoImVhY2ggcGFydCBt
+dXN0IGJlIGluIHRoZSByYW5nZSBvZiBgMHgwLi4weEZGRkZgIixhKQpyZXR1cm4gdH0sCiRTOjQ4fQpQ
+LkRuLnByb3RvdHlwZT17CmdrdTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmJ9LApnSmY6ZnVuY3Rpb24o
+YSl7dmFyIHQ9dGhpcy5jCmlmKHQ9PW51bGwpcmV0dXJuIiIKaWYoQy54Qi5uKHQsIlsiKSlyZXR1cm4g
+Qy54Qi5Oaih0LDEsdC5sZW5ndGgtMSkKcmV0dXJuIHR9LApndHA6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
+cy5kCmlmKHQ9PW51bGwpcmV0dXJuIFAud0sodGhpcy5hKQpyZXR1cm4gdH0sCmd0UDpmdW5jdGlvbigp
+e3ZhciB0PXRoaXMuZgpyZXR1cm4gdD09bnVsbD8iIjp0fSwKZ0thOmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
+cy5yCnJldHVybiB0PT1udWxsPyIiOnR9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxu
+LG0sbD10aGlzCnUuWC5iKG51bGwpCnUuay5iKGIpCnQ9bC5hCnM9dD09PSJmaWxlIgpyPWwuYgpxPWwu
+ZApwPWwuYwppZighKHAhPW51bGwpKXA9ci5sZW5ndGghPT0wfHxxIT1udWxsfHxzPyIiOm51bGwKbz1s
+LmUKaWYoIXMpbj1wIT1udWxsJiZvLmxlbmd0aCE9PTAKZWxzZSBuPSEwCmlmKG4mJiFDLnhCLm4obywi
+LyIpKW89Ii8iK28KbT1QLmxlKG51bGwsMCwwLGIpCnJldHVybiBuZXcgUC5Ebih0LHIscCxxLG8sbSxs
+LnIpfSwKZ0ZqOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLngKaWYocyE9bnVsbClyZXR1cm4gcwp0PXRo
+aXMuZQppZih0Lmxlbmd0aCE9PTAmJkMueEIuVyh0LDApPT09NDcpdD1DLnhCLkcodCwxKQpzPXQ9PT0i
+Ij9DLnhEOlAuQUYobmV3IEguQTgoSC5WTSh0LnNwbGl0KCIvIiksdS5zKSx1LmRPLmIoUC5QSCgpKSx1
+LmRvKSx1Lk4pCnRoaXMuc282KHMpCnJldHVybiBzfSwKZ2hZOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlz
+CmlmKHMuUT09bnVsbCl7dD1zLmYKcy5zUkgobmV3IFAuR2ooUC5XWCh0PT1udWxsPyIiOnQpLHUuVykp
+fXJldHVybiBzLlF9LApKaDpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbwpmb3IodD0wLHM9MDtD
+LnhCLlFpKGIsIi4uLyIscyk7KXtzKz0zOysrdH1yPUMueEIuY24oYSwiLyIpCndoaWxlKCEwKXtpZigh
+KHI+MCYmdD4wKSlicmVhawpxPUMueEIuUGsoYSwiLyIsci0xKQppZihxPDApYnJlYWsKcD1yLXEKbz1w
+IT09MgppZighb3x8cD09PTMpaWYoQy54Qi5tKGEscSsxKT09PTQ2KW89IW98fEMueEIubShhLHErMik9
+PT00NgplbHNlIG89ITEKZWxzZSBvPSExCmlmKG8pYnJlYWs7LS10CnI9cX1yZXR1cm4gQy54Qi5pNyhh
+LHIrMSxudWxsLEMueEIuRyhiLHMtMyp0KSl9LApaSTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5tUyhQ
+LmhLKGEpKX0sCm1TOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrPXRoaXMsaj1udWxs
+CmlmKGEuZ0ZpKCkubGVuZ3RoIT09MCl7dD1hLmdGaSgpCmlmKGEuZ2NqKCkpe3M9YS5na3UoKQpyPWEu
+Z0pmKGEpCnE9YS5neEEoKT9hLmd0cChhKTpqfWVsc2V7cT1qCnI9cQpzPSIifXA9UC54ZShhLmdJaShh
+KSkKbz1hLmdRRCgpP2EuZ3RQKCk6an1lbHNle3Q9ay5hCmlmKGEuZ2NqKCkpe3M9YS5na3UoKQpyPWEu
+Z0pmKGEpCnE9UC53QihhLmd4QSgpP2EuZ3RwKGEpOmosdCkKcD1QLnhlKGEuZ0lpKGEpKQpvPWEuZ1FE
+KCk/YS5ndFAoKTpqfWVsc2V7cz1rLmIKcj1rLmMKcT1rLmQKaWYoYS5nSWkoYSk9PT0iIil7cD1rLmUK
+bz1hLmdRRCgpP2EuZ3RQKCk6ay5mfWVsc2V7aWYoYS5ndFQoKSlwPVAueGUoYS5nSWkoYSkpCmVsc2V7
+bj1rLmUKaWYobi5sZW5ndGg9PT0wKWlmKHI9PW51bGwpcD10Lmxlbmd0aD09PTA/YS5nSWkoYSk6UC54
+ZShhLmdJaShhKSkKZWxzZSBwPVAueGUoIi8iK2EuZ0lpKGEpKQplbHNle209ay5KaChuLGEuZ0lpKGEp
+KQpsPXQubGVuZ3RoPT09MAppZighbHx8ciE9bnVsbHx8Qy54Qi5uKG4sIi8iKSlwPVAueGUobSkKZWxz
+ZSBwPVAud0YobSwhbHx8ciE9bnVsbCl9fW89YS5nUUQoKT9hLmd0UCgpOmp9fX1yZXR1cm4gbmV3IFAu
+RG4odCxzLHIscSxwLG8sYS5nWjgoKT9hLmdLYSgpOmopfSwKZ2NqOmZ1bmN0aW9uKCl7cmV0dXJuIHRo
+aXMuYyE9bnVsbH0sCmd4QTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmQhPW51bGx9LApnUUQ6ZnVuY3Rp
+b24oKXtyZXR1cm4gdGhpcy5mIT1udWxsfSwKZ1o4OmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuciE9bnVs
+bH0sCmd0VDpmdW5jdGlvbigpe3JldHVybiBDLnhCLm4odGhpcy5lLCIvIil9LAp0NDpmdW5jdGlvbigp
+e3ZhciB0LHMscj10aGlzLHE9ci5hCmlmKHEhPT0iIiYmcSE9PSJmaWxlIil0aHJvdyBILmIoUC5MNCgi
+Q2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGggZnJvbSBhICIrSC5kKHEpKyIgVVJJIikpCnE9ci5mCmlm
+KChxPT1udWxsPyIiOnEpIT09IiIpdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBw
+YXRoIGZyb20gYSBVUkkgd2l0aCBhIHF1ZXJ5IGNvbXBvbmVudCIpKQpxPXIucgppZigocT09bnVsbD8i
+IjpxKSE9PSIiKXRocm93IEguYihQLkw0KCJDYW5ub3QgZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEg
+VVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSkKdD0kLndRKCkKaWYoSC5vVCh0KSlxPVAubW4o
+cikKZWxzZXtpZihyLmMhPW51bGwmJnIuZ0pmKHIpIT09IiIpSC52aChQLkw0KCJDYW5ub3QgZXh0cmFj
+dCBhIG5vbi1XaW5kb3dzIGZpbGUgcGF0aCBmcm9tIGEgZmlsZSBVUkkgd2l0aCBhbiBhdXRob3JpdHki
+KSkKcz1yLmdGaigpClAua0UocywhMSkKcT1QLnZnKEMueEIubihyLmUsIi8iKT8iLyI6IiIscywiLyIp
+CnE9cS5jaGFyQ29kZUF0KDApPT0wP3E6cX1yZXR1cm4gcX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscyxy
+LHE9dGhpcyxwPXEueQppZihwPT1udWxsKXtwPXEuYQp0PXAubGVuZ3RoIT09MD9wKyI6IjoiIgpzPXEu
+YwpyPXM9PW51bGwKaWYoIXJ8fHA9PT0iZmlsZSIpe3A9dCsiLy8iCnQ9cS5iCmlmKHQubGVuZ3RoIT09
+MClwPXArdCsiQCIKaWYoIXIpcCs9cwp0PXEuZAppZih0IT1udWxsKXA9cCsiOiIrSC5kKHQpfWVsc2Ug
+cD10CnArPXEuZQp0PXEuZgppZih0IT1udWxsKXA9cCsiPyIrdAp0PXEucgppZih0IT1udWxsKXA9cCsi
+IyIrdApwPXEueT1wLmNoYXJDb2RlQXQoMCk9PTA/cDpwfXJldHVybiBwfSwKRE46ZnVuY3Rpb24oYSxi
+KXt2YXIgdCxzLHI9dGhpcwppZihiPT1udWxsKXJldHVybiExCmlmKHI9PT1iKXJldHVybiEwCmlmKHUu
+di5jKGIpKWlmKHIuYT09Yi5nRmkoKSlpZihyLmMhPW51bGw9PT1iLmdjaigpKWlmKHIuYj09Yi5na3Uo
+KSlpZihyLmdKZihyKT09Yi5nSmYoYikpaWYoci5ndHAocik9PWIuZ3RwKGIpKWlmKHIuZT09PWIuZ0lp
+KGIpKXt0PXIuZgpzPXQ9PW51bGwKaWYoIXM9PT1iLmdRRCgpKXtpZihzKXQ9IiIKaWYodD09PWIuZ3RQ
+KCkpe3Q9ci5yCnM9dD09bnVsbAppZighcz09PWIuZ1o4KCkpe2lmKHMpdD0iIgp0PXQ9PT1iLmdLYSgp
+fWVsc2UgdD0hMX1lbHNlIHQ9ITF9ZWxzZSB0PSExfWVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSEx
+CmVsc2UgdD0hMQplbHNlIHQ9ITEKZWxzZSB0PSExCmVsc2UgdD0hMQpyZXR1cm4gdH0sCmdpTzpmdW5j
+dGlvbihhKXt2YXIgdD10aGlzLnoKcmV0dXJuIHQ9PW51bGw/dGhpcy56PUMueEIuZ2lPKHRoaXMudygw
+KSk6dH0sCnNvNjpmdW5jdGlvbihhKXt0aGlzLng9dS5hLmIoYSl9LApzUkg6ZnVuY3Rpb24oYSl7dGhp
+cy5RPXUuZi5iKGEpfSwKJGlpRDoxLApnRmk6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5hfSwKZ0lpOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLmV9fQpQLmUxLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Ro
+cm93IEguYihQLnJyKCJJbnZhbGlkIHBvcnQiLHRoaXMuYSx0aGlzLmIrMSkpfSwKJFM6MTN9ClAuTlku
+cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9IklsbGVnYWwgcGF0aCBjaGFyYWN0ZXIgIgpI
+LnkoYSkKaWYoSi56bChhLCIvIikpaWYodGhpcy5hKXRocm93IEguYihQLnhZKHQrYSkpCmVsc2UgdGhy
+b3cgSC5iKFAuTDQodCthKSl9LAokUzoxM30KUC5SWi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
+ZXR1cm4gUC5lUChDLlpKLEgueShhKSxDLnhNLCExKX0sCiRTOjV9ClAuTUUucHJvdG90eXBlPXsKJDI6
+ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmIscz10aGlzLmEKdC5hKz1zLmEKcy5hPSImIgpzPXQuYSs9
+SC5kKFAuZVAoQy5GMyxhLEMueE0sITApKQppZihiIT1udWxsJiZiLmxlbmd0aCE9PTApe3QuYT1zKyI9
+Igp0LmErPUguZChQLmVQKEMuRjMsYixDLnhNLCEwKSl9fSwKJFM6MjJ9ClAueTUucHJvdG90eXBlPXsK
+JDI6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzCkgueShhKQppZihiPT1udWxsfHx0eXBlb2YgYj09InN0cmlu
+ZyIpdGhpcy5hLiQyKGEsSC55KGIpKQplbHNlIGZvcih0PUouSVQodS5SLmIoYikpLHM9dGhpcy5hO3Qu
+RigpOylzLiQyKGEsSC55KHQuZ2woKSkpfSwKJFM6MTJ9ClAuUEUucHJvdG90eXBlPXsKZ2xSOmZ1bmN0
+aW9uKCl7dmFyIHQscyxyLHEscD10aGlzLG89bnVsbCxuPXAuYwppZihuIT1udWxsKXJldHVybiBuCm49
+cC5iCmlmKDA+PW4ubGVuZ3RoKXJldHVybiBILk9IKG4sMCkKdD1wLmEKbj1uWzBdKzEKcz1DLnhCLlhV
+KHQsIj8iLG4pCnI9dC5sZW5ndGgKaWYocz49MCl7cT1QLlBJKHQscysxLHIsQy5WQywhMSkKcj1zfWVs
+c2UgcT1vCnJldHVybiBwLmM9bmV3IFAucWUoImRhdGEiLG8sbyxvLFAuUEkodCxuLHIsQy5XZCwhMSks
+cSxvKX0sCnc6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmIKaWYoMD49cy5sZW5ndGgpcmV0dXJuIEgu
+T0gocywwKQp0PXRoaXMuYQpyZXR1cm4gc1swXT09PS0xPyJkYXRhOiIrdDp0fX0KUC5xMy5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFVpbnQ4QXJyYXkoOTYpfSwKJFM6MjN9ClAueUku
+cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEKaWYoYT49dC5sZW5ndGgpcmV0
+dXJuIEguT0godCxhKQp0PXRbYV0KSi5DTSh0LDAsOTYsYikKcmV0dXJuIHR9LAokUzoyNH0KUC5jNi5w
+cm90b3R5cGU9ewokMzpmdW5jdGlvbihhLGIsYyl7dmFyIHQscyxyLHEKZm9yKHQ9Yi5sZW5ndGgscz1h
+Lmxlbmd0aCxyPTA7cjx0Oysrcil7cT1DLnhCLlcoYixyKV45NgppZihxPj1zKXJldHVybiBILk9IKGEs
+cSkKYVtxXT1jfX19ClAucWQucHJvdG90eXBlPXsKJDM6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMscixx
+CmZvcih0PUMueEIuVyhiLDApLHM9Qy54Qi5XKGIsMSkscj1hLmxlbmd0aDt0PD1zOysrdCl7cT0odF45
+Nik+Pj4wCmlmKHE+PXIpcmV0dXJuIEguT0goYSxxKQphW3FdPWN9fX0KUC5VZi5wcm90b3R5cGU9ewpn
+Y2o6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5jPjB9LApneEE6ZnVuY3Rpb24oKXt2YXIgdCxzCmlmKHRo
+aXMuYz4wKXt0PXRoaXMuZAppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpzPXRoaXMu
+ZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBILnBZKHMpCnM9dCsxPHMKdD1zfWVsc2UgdD0h
+MQpyZXR1cm4gdH0sCmdRRDpmdW5jdGlvbigpe3ZhciB0PXRoaXMuZgppZih0eXBlb2YgdCE9PSJudW1i
+ZXIiKXJldHVybiB0LkooKQpyZXR1cm4gdDx0aGlzLnJ9LApnWjg6ZnVuY3Rpb24oKXtyZXR1cm4gdGhp
+cy5yPHRoaXMuYS5sZW5ndGh9LApnTnc6ZnVuY3Rpb24oKXtyZXR1cm4gdGhpcy5iPT09NCYmQy54Qi5u
+KHRoaXMuYSwiZmlsZSIpfSwKZ3ZoOmZ1bmN0aW9uKCl7cmV0dXJuIHRoaXMuYj09PTQmJkMueEIubih0
+aGlzLmEsImh0dHAiKX0sCmdSZTpmdW5jdGlvbigpe3JldHVybiB0aGlzLmI9PT01JiZDLnhCLm4odGhp
+cy5hLCJodHRwcyIpfSwKZ3RUOmZ1bmN0aW9uKCl7cmV0dXJuIEMueEIuUWkodGhpcy5hLCIvIix0aGlz
+LmUpfSwKZ0ZpOmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9InBhY2thZ2UiLHE9cy5iCmlmKHE8PTAp
+cmV0dXJuIiIKdD1zLngKaWYodCE9bnVsbClyZXR1cm4gdAppZihzLmd2aCgpKXE9cy54PSJodHRwIgpl
+bHNlIGlmKHMuZ1JlKCkpe3MueD0iaHR0cHMiCnE9Imh0dHBzIn1lbHNlIGlmKHMuZ053KCkpe3MueD0i
+ZmlsZSIKcT0iZmlsZSJ9ZWxzZSBpZihxPT09NyYmQy54Qi5uKHMuYSxyKSl7cy54PXIKcT1yfWVsc2V7
+cT1DLnhCLk5qKHMuYSwwLHEpCnMueD1xfXJldHVybiBxfSwKZ2t1OmZ1bmN0aW9uKCl7dmFyIHQ9dGhp
+cy5jLHM9dGhpcy5iKzMKcmV0dXJuIHQ+cz9DLnhCLk5qKHRoaXMuYSxzLHQtMSk6IiJ9LApnSmY6ZnVu
+Y3Rpb24oYSl7dmFyIHQ9dGhpcy5jCnJldHVybiB0PjA/Qy54Qi5Oaih0aGlzLmEsdCx0aGlzLmQpOiIi
+fSwKZ3RwOmZ1bmN0aW9uKGEpe3ZhciB0LHM9dGhpcwppZihzLmd4QSgpKXt0PXMuZAppZih0eXBlb2Yg
+dCE9PSJudW1iZXIiKXJldHVybiB0LmgoKQpyZXR1cm4gUC5RQShDLnhCLk5qKHMuYSx0KzEscy5lKSxu
+dWxsLG51bGwpfWlmKHMuZ3ZoKCkpcmV0dXJuIDgwCmlmKHMuZ1JlKCkpcmV0dXJuIDQ0MwpyZXR1cm4g
+MH0sCmdJaTpmdW5jdGlvbihhKXtyZXR1cm4gQy54Qi5Oaih0aGlzLmEsdGhpcy5lLHRoaXMuZil9LApn
+dFA6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYscz10aGlzLnIKaWYodHlwZW9mIHQhPT0ibnVtYmVyIily
+ZXR1cm4gdC5KKCkKcmV0dXJuIHQ8cz9DLnhCLk5qKHRoaXMuYSx0KzEscyk6IiJ9LApnS2E6ZnVuY3Rp
+b24oKXt2YXIgdD10aGlzLnIscz10aGlzLmEKcmV0dXJuIHQ8cy5sZW5ndGg/Qy54Qi5HKHMsdCsxKToi
+In0sCmdGajpmdW5jdGlvbigpe3ZhciB0LHMscj10aGlzLmUscT10aGlzLmYscD10aGlzLmEKaWYoQy54
+Qi5RaShwLCIvIixyKSl7aWYodHlwZW9mIHIhPT0ibnVtYmVyIilyZXR1cm4gci5oKCk7KytyfWlmKHI9
+PXEpcmV0dXJuIEMueEQKdD1ILlZNKFtdLHUucykKcz1yCndoaWxlKCEwKXtpZih0eXBlb2YgcyE9PSJu
+dW1iZXIiKXJldHVybiBzLkooKQppZih0eXBlb2YgcSE9PSJudW1iZXIiKXJldHVybiBILnBZKHEpCmlm
+KCEoczxxKSlicmVhawppZihDLnhCLm0ocCxzKT09PTQ3KXtDLk5tLmkodCxDLnhCLk5qKHAscixzKSkK
+cj1zKzF9KytzfUMuTm0uaSh0LEMueEIuTmoocCxyLHEpKQpyZXR1cm4gUC5BRih0LHUuTil9LApnaFk6
+ZnVuY3Rpb24oKXt2YXIgdD10aGlzLmYKaWYodHlwZW9mIHQhPT0ibnVtYmVyIilyZXR1cm4gdC5KKCkK
+aWYodD49dGhpcy5yKXJldHVybiBDLldPCnJldHVybiBuZXcgUC5HaihQLldYKHRoaXMuZ3RQKCkpLHUu
+Vyl9LAprWDpmdW5jdGlvbihhKXt2YXIgdCxzPXRoaXMuZAppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJl
+dHVybiBzLmgoKQp0PXMrMQpyZXR1cm4gdCthLmxlbmd0aD09PXRoaXMuZSYmQy54Qi5RaSh0aGlzLmEs
+YSx0KX0sCk45OmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPXQucixyPXQuYQppZihzPj1yLmxlbmd0aCly
+ZXR1cm4gdApyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihyLDAscyksdC5iLHQuYyx0LmQsdC5lLHQuZixz
+LHQueCl9LApubTpmdW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxrLGo9dGhpcyxpPW51
+bGwKdS5YLmIobnVsbCkKdS5rLmIoYikKdD1qLmdGaSgpCnM9dD09PSJmaWxlIgpyPWouYwpxPXI+MD9D
+LnhCLk5qKGouYSxqLmIrMyxyKToiIgpwPWouZ3hBKCk/ai5ndHAoaik6aQpyPWouYwppZihyPjApbz1D
+LnhCLk5qKGouYSxyLGouZCkKZWxzZSBvPXEubGVuZ3RoIT09MHx8cCE9bnVsbHx8cz8iIjppCnI9ai5h
+Cm49Qy54Qi5OaihyLGouZSxqLmYpCmlmKCFzKW09byE9bnVsbCYmbi5sZW5ndGghPT0wCmVsc2UgbT0h
+MAppZihtJiYhQy54Qi5uKG4sIi8iKSluPSIvIituCmw9UC5sZShpLDAsMCxiKQptPWoucgprPW08ci5s
+ZW5ndGg/Qy54Qi5HKHIsbSsxKTppCnJldHVybiBuZXcgUC5Ebih0LHEsbyxwLG4sbCxrKX0sClpJOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLm1TKFAuaEsoYSkpfSwKbVM6ZnVuY3Rpb24oYSl7aWYoYSBpbnN0
+YW5jZW9mIFAuVWYpcmV0dXJuIHRoaXMudTEodGhpcyxhKQpyZXR1cm4gdGhpcy52cygpLm1TKGEpfSwK
+dTE6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsayxqLGksaCxnLGYsZT1iLmIKaWYo
+ZT4wKXJldHVybiBiCnQ9Yi5jCmlmKHQ+MCl7cz1hLmIKaWYoczw9MClyZXR1cm4gYgppZihhLmdOdygp
+KXI9Yi5lIT1iLmYKZWxzZSBpZihhLmd2aCgpKXI9IWIua1goIjgwIikKZWxzZSByPSFhLmdSZSgpfHwh
+Yi5rWCgiNDQzIikKaWYocil7cT1zKzEKcD1DLnhCLk5qKGEuYSwwLHEpK0MueEIuRyhiLmEsZSsxKQpl
+PWIuZAppZih0eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpvPWIuZQppZih0eXBlb2YgbyE9
+PSJudW1iZXIiKXJldHVybiBvLmgoKQpuPWIuZgppZih0eXBlb2YgbiE9PSJudW1iZXIiKXJldHVybiBu
+LmgoKQpyZXR1cm4gbmV3IFAuVWYocCxzLHQrcSxlK3EsbytxLG4rcSxiLnIrcSxhLngpfWVsc2UgcmV0
+dXJuIHRoaXMudnMoKS5tUyhiKX1tPWIuZQplPWIuZgppZihtPT1lKXt0PWIucgppZih0eXBlb2YgZSE9
+PSJudW1iZXIiKXJldHVybiBlLkooKQppZihlPHQpe3M9YS5mCmlmKHR5cGVvZiBzIT09Im51bWJlciIp
+cmV0dXJuIHMuSE4oKQpxPXMtZQpyZXR1cm4gbmV3IFAuVWYoQy54Qi5OaihhLmEsMCxzKStDLnhCLkco
+Yi5hLGUpLGEuYixhLmMsYS5kLGEuZSxlK3EsdCtxLGEueCl9ZT1iLmEKaWYodDxlLmxlbmd0aCl7cz1h
+LnIKcmV0dXJuIG5ldyBQLlVmKEMueEIuTmooYS5hLDAscykrQy54Qi5HKGUsdCksYS5iLGEuYyxhLmQs
+YS5lLGEuZix0KyhzLXQpLGEueCl9cmV0dXJuIGEuTjkoKX10PWIuYQppZihDLnhCLlFpKHQsIi8iLG0p
+KXtzPWEuZQppZih0eXBlb2YgcyE9PSJudW1iZXIiKXJldHVybiBzLkhOKCkKaWYodHlwZW9mIG0hPT0i
+bnVtYmVyIilyZXR1cm4gSC5wWShtKQpxPXMtbQpwPUMueEIuTmooYS5hLDAscykrQy54Qi5HKHQsbSkK
+aWYodHlwZW9mIGUhPT0ibnVtYmVyIilyZXR1cm4gZS5oKCkKcmV0dXJuIG5ldyBQLlVmKHAsYS5iLGEu
+YyxhLmQscyxlK3EsYi5yK3EsYS54KX1sPWEuZQprPWEuZgppZihsPT1rJiZhLmM+MCl7Zm9yKDtDLnhC
+LlFpKHQsIi4uLyIsbSk7KXtpZih0eXBlb2YgbSE9PSJudW1iZXIiKXJldHVybiBtLmgoKQptKz0zfWlm
+KHR5cGVvZiBsIT09Im51bWJlciIpcmV0dXJuIGwuSE4oKQppZih0eXBlb2YgbSE9PSJudW1iZXIiKXJl
+dHVybiBILnBZKG0pCnE9bC1tKzEKcD1DLnhCLk5qKGEuYSwwLGwpKyIvIitDLnhCLkcodCxtKQppZih0
+eXBlb2YgZSE9PSJudW1iZXIiKXJldHVybiBlLmgoKQpyZXR1cm4gbmV3IFAuVWYocCxhLmIsYS5jLGEu
+ZCxsLGUrcSxiLnIrcSxhLngpfWo9YS5hCmZvcihpPWw7Qy54Qi5RaShqLCIuLi8iLGkpOyl7aWYodHlw
+ZW9mIGkhPT0ibnVtYmVyIilyZXR1cm4gaS5oKCkKaSs9M31oPTAKd2hpbGUoITApe2lmKHR5cGVvZiBt
+IT09Im51bWJlciIpcmV0dXJuIG0uaCgpCmc9bSszCmlmKHR5cGVvZiBlIT09Im51bWJlciIpcmV0dXJu
+IEgucFkoZSkKaWYoIShnPD1lJiZDLnhCLlFpKHQsIi4uLyIsbSkpKWJyZWFrOysraAptPWd9Zj0iIgp3
+aGlsZSghMCl7aWYodHlwZW9mIGshPT0ibnVtYmVyIilyZXR1cm4gay5vcygpCmlmKHR5cGVvZiBpIT09
+Im51bWJlciIpcmV0dXJuIEgucFkoaSkKaWYoIShrPmkpKWJyZWFrOy0tawppZihDLnhCLm0oaixrKT09
+PTQ3KXtpZihoPT09MCl7Zj0iLyIKYnJlYWt9LS1oCmY9Ii8ifX1pZihrPT09aSYmYS5iPD0wJiYhQy54
+Qi5RaShqLCIvIixsKSl7bS09aCozCmY9IiJ9cT1rLW0rZi5sZW5ndGgKcmV0dXJuIG5ldyBQLlVmKEMu
+eEIuTmooaiwwLGspK2YrQy54Qi5HKHQsbSksYS5iLGEuYyxhLmQsbCxlK3EsYi5yK3EsYS54KX0sCnQ0
+OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscD10aGlzCmlmKHAuYj49MCYmIXAuZ053KCkpdGhyb3cgSC5i
+KFAuTDQoIkNhbm5vdCBleHRyYWN0IGEgZmlsZSBwYXRoIGZyb20gYSAiK0guZChwLmdGaSgpKSsiIFVS
+SSIpKQp0PXAuZgpzPXAuYQppZih0eXBlb2YgdCE9PSJudW1iZXIiKXJldHVybiB0LkooKQppZih0PHMu
+bGVuZ3RoKXtpZih0PHAucil0aHJvdyBILmIoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBmaWxlIHBhdGgg
+ZnJvbSBhIFVSSSB3aXRoIGEgcXVlcnkgY29tcG9uZW50IikpCnRocm93IEguYihQLkw0KCJDYW5ub3Qg
+ZXh0cmFjdCBhIGZpbGUgcGF0aCBmcm9tIGEgVVJJIHdpdGggYSBmcmFnbWVudCBjb21wb25lbnQiKSl9
+cj0kLndRKCkKaWYoSC5vVChyKSl0PVAubW4ocCkKZWxzZXtxPXAuZAppZih0eXBlb2YgcSE9PSJudW1i
+ZXIiKXJldHVybiBILnBZKHEpCmlmKHAuYzxxKUgudmgoUC5MNCgiQ2Fubm90IGV4dHJhY3QgYSBub24t
+V2luZG93cyBmaWxlIHBhdGggZnJvbSBhIGZpbGUgVVJJIHdpdGggYW4gYXV0aG9yaXR5IikpCnQ9Qy54
+Qi5OaihzLHAuZSx0KX1yZXR1cm4gdH0sCmdpTzpmdW5jdGlvbihhKXt2YXIgdD10aGlzLnkKcmV0dXJu
+IHQ9PW51bGw/dGhpcy55PUMueEIuZ2lPKHRoaXMuYSk6dH0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09
+bnVsbClyZXR1cm4hMQppZih0aGlzPT09YilyZXR1cm4hMApyZXR1cm4gdS52LmMoYikmJnRoaXMuYT09
+PWIudygwKX0sCnZzOmZ1bmN0aW9uKCl7dmFyIHQ9dGhpcyxzPW51bGwscj10LmdGaSgpLHE9dC5na3Uo
+KSxwPXQuYz4wP3QuZ0pmKHQpOnMsbz10Lmd4QSgpP3QuZ3RwKHQpOnMsbj10LmEsbT10LmYsbD1DLnhC
+Lk5qKG4sdC5lLG0pLGs9dC5yCmlmKHR5cGVvZiBtIT09Im51bWJlciIpcmV0dXJuIG0uSigpCm09bTxr
+P3QuZ3RQKCk6cwpyZXR1cm4gbmV3IFAuRG4ocixxLHAsbyxsLG0sazxuLmxlbmd0aD90LmdLYSgpOnMp
+fSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hfSwKJGlpRDoxfQpQLnFlLnByb3RvdHlwZT17fQpX
+LnFFLnByb3RvdHlwZT17fQpXLkdoLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJuIFN0cmlu
+ZyhhKX0sCiRpR2g6MX0KVy5mWS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiBTdHJpbmco
+YSl9fQpXLm5CLnByb3RvdHlwZT17JGluQjoxfQpXLkF6LnByb3RvdHlwZT17JGlBejoxfQpXLlFQLnBy
+b3RvdHlwZT17JGlRUDoxfQpXLm54LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxl
+bmd0aH19Clcub0oucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5p
+ZC5wcm90b3R5cGU9e30KVy5RRi5wcm90b3R5cGU9e30KVy5OaC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9u
+KGEpe3JldHVybiBTdHJpbmcoYSl9fQpXLklCLnByb3RvdHlwZT17Cnc6ZnVuY3Rpb24oYSl7cmV0dXJu
+IlJlY3RhbmdsZSAoIitILmQoYS5sZWZ0KSsiLCAiK0guZChhLnRvcCkrIikgIitILmQoYS53aWR0aCkr
+IiB4ICIrSC5kKGEuaGVpZ2h0KX0sCkROOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClyZXR1cm4hMQpy
+ZXR1cm4gdS5xLmMoYikmJmEubGVmdD09PWIubGVmdCYmYS50b3A9PT1iLnRvcCYmYS53aWR0aD09PWIu
+d2lkdGgmJmEuaGVpZ2h0PT09Yi5oZWlnaHR9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIFcuckUoQy5D
+RC5naU8oYS5sZWZ0KSxDLkNELmdpTyhhLnRvcCksQy5DRC5naU8oYS53aWR0aCksQy5DRC5naU8oYS5o
+ZWlnaHQpKX0sCiRpdG46MX0KVy5uNy5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+ZW5ndGh9fQpXLnd6LnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEubGVuZ3Ro
+fSwKcTpmdW5jdGlvbihhLGIpe3ZhciB0CkguU2MoYikKdD10aGlzLmEKaWYoYjwwfHxiPj10Lmxlbmd0
+aClyZXR1cm4gSC5PSCh0LGIpCnJldHVybiB0aGlzLiR0aS5kLmIodFtiXSl9LApZOmZ1bmN0aW9uKGEs
+YixjKXt0aGlzLiR0aS5kLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBtb2RpZnkgbGlzdCIpKX19
+ClcuY3YucHJvdG90eXBlPXsKZ1FnOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5pNyhhKX0sCmdQOmZ1
+bmN0aW9uKGEpe3JldHVybiBuZXcgVy5JNChhKX0sCnNQOmZ1bmN0aW9uKGEsYil7dmFyIHQKdS5YLmIo
+YikKdD10aGlzLmdQKGEpCnQuVjEoMCkKdC5GVigwLGIpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gYS5s
+b2NhbE5hbWV9LApGRjpmdW5jdGlvbihhKXt2YXIgdD0hIWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZApp
+Zih0KWEuc2Nyb2xsSW50b1ZpZXdJZk5lZWRlZCgpCmVsc2UgYS5zY3JvbGxJbnRvVmlldygpfSwKbno6
+ZnVuY3Rpb24oYSxiLGMsZCxlKXt2YXIgdCxzPXRoaXMucjYoYSxjLGQsZSkKc3dpdGNoKGIudG9Mb3dl
+ckNhc2UoKSl7Y2FzZSJiZWZvcmViZWdpbiI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzLGEpCmJy
+ZWFrCmNhc2UiYWZ0ZXJiZWdpbiI6dD1hLmNoaWxkTm9kZXMKYS5pbnNlcnRCZWZvcmUocyx0Lmxlbmd0
+aD4wP3RbMF06bnVsbCkKYnJlYWsKY2FzZSJiZWZvcmVlbmQiOmEuYXBwZW5kQ2hpbGQocykKYnJlYWsK
+Y2FzZSJhZnRlcmVuZCI6YS5wYXJlbnROb2RlLmluc2VydEJlZm9yZShzLGEubmV4dFNpYmxpbmcpCmJy
+ZWFrCmRlZmF1bHQ6SC52aChQLnhZKCJJbnZhbGlkIHBvc2l0aW9uICIrYikpfX0sCnI2OmZ1bmN0aW9u
+KGEsYixjLGQpe3ZhciB0LHMscixxCmlmKGM9PW51bGwpe2lmKGQ9PW51bGwpe3Q9JC5sdAppZih0PT1u
+dWxsKXt0PUguVk0oW10sdS5pKQpzPW5ldyBXLnZEKHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0u
+aSh0LFcuQmwoKSkKJC5sdD1zCmQ9c31lbHNlIGQ9dH10PSQuRVUKaWYodD09bnVsbCl7dD1uZXcgVy5L
+byhkKQokLkVVPXQKYz10fWVsc2V7dC5hPWQKYz10fX1lbHNlIGlmKGQhPW51bGwpdGhyb3cgSC5iKFAu
+eFkoInZhbGlkYXRvciBjYW4gb25seSBiZSBwYXNzZWQgaWYgdHJlZVNhbml0aXplciBpcyBudWxsIikp
+CmlmKCQueG89PW51bGwpe3Q9ZG9jdW1lbnQKcz10LmltcGxlbWVudGF0aW9uLmNyZWF0ZUhUTUxEb2N1
+bWVudCgiIikKJC54bz1zCiQuQk89cy5jcmVhdGVSYW5nZSgpCnM9JC54by5jcmVhdGVFbGVtZW50KCJi
+YXNlIikKdS5jUi5iKHMpCnMuaHJlZj10LmJhc2VVUkkKJC54by5oZWFkLmFwcGVuZENoaWxkKHMpfXQ9
+JC54bwppZih0LmJvZHk9PW51bGwpe3M9dC5jcmVhdGVFbGVtZW50KCJib2R5IikKdC5ib2R5PXUuWS5i
+KHMpfXQ9JC54bwppZih1LlkuYyhhKSlyPXQuYm9keQplbHNle3I9dC5jcmVhdGVFbGVtZW50KGEudGFn
+TmFtZSkKJC54by5ib2R5LmFwcGVuZENoaWxkKHIpfWlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQi
+IGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUmJiFDLk5tLnRnKEMuU3EsYS50YWdOYW1lKSl7JC5CTy5z
+ZWxlY3ROb2RlQ29udGVudHMocikKcT0kLkJPLmNyZWF0ZUNvbnRleHR1YWxGcmFnbWVudChiKX1lbHNl
+e3IuaW5uZXJIVE1MPWIKcT0kLnhvLmNyZWF0ZURvY3VtZW50RnJhZ21lbnQoKQpmb3IoO3Q9ci5maXJz
+dENoaWxkLHQhPW51bGw7KXEuYXBwZW5kQ2hpbGQodCl9dD0kLnhvLmJvZHkKaWYocj09bnVsbD90IT1u
+dWxsOnIhPT10KUouTHQocikKYy5QbihxKQpkb2N1bWVudC5hZG9wdE5vZGUocSkKcmV0dXJuIHF9LApB
+SDpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIHRoaXMucjYoYSxiLGMsbnVsbCl9LApzaGY6ZnVuY3Rpb24o
+YSxiKXt0aGlzLllDKGEsYil9LApwazpmdW5jdGlvbihhLGIsYyl7YS50ZXh0Q29udGVudD1udWxsCmEu
+YXBwZW5kQ2hpbGQodGhpcy5yNihhLGIsbnVsbCxjKSl9LApZQzpmdW5jdGlvbihhLGIpe3JldHVybiB0
+aGlzLnBrKGEsYixudWxsKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFcuZXUoYSwiY2xpY2si
+LCExLHUuUSl9LAokaWN2OjEsCmduczpmdW5jdGlvbihhKXtyZXR1cm4gYS50YWdOYW1lfX0KVy5Ddi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5oLmModS5BLmIoYSkpfSwKJFM6MjV9Clcu
+ZWEucHJvdG90eXBlPXskaWVhOjF9ClcuRDAucHJvdG90eXBlPXsKT246ZnVuY3Rpb24oYSxiLGMsZCl7
+dS5VLmIoYykKaWYoYyE9bnVsbCl0aGlzLnYoYSxiLGMsZCl9LApCOmZ1bmN0aW9uKGEsYixjKXtyZXR1
+cm4gdGhpcy5PbihhLGIsYyxudWxsKX0sCnY6ZnVuY3Rpb24oYSxiLGMsZCl7cmV0dXJuIGEuYWRkRXZl
+bnRMaXN0ZW5lcihiLEgudFIodS5VLmIoYyksMSksZCl9LAokaUQwOjF9ClcuaEgucHJvdG90eXBlPXsk
+aWhIOjF9ClcuaDQucHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofX0KVy5i
+ci5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9fQpXLlZiLnByb3RvdHlw
+ZT17fQpXLk83LnByb3RvdHlwZT17CmVvOmZ1bmN0aW9uKGEsYixjLGQpe3JldHVybiBhLm9wZW4oYixj
+LCEwKX0sCiRpTzc6MX0KVy53YS5wcm90b3R5cGU9e30KVy5TZy5wcm90b3R5cGU9eyRpU2c6MX0KVy51
+OC5wcm90b3R5cGU9ewpnRHI6ZnVuY3Rpb24oYSl7aWYoIm9yaWdpbiIgaW4gYSlyZXR1cm4gYS5vcmln
+aW4KcmV0dXJuIEguZChhLnByb3RvY29sKSsiLy8iK0guZChhLmhvc3QpfSwKdzpmdW5jdGlvbihhKXty
+ZXR1cm4gU3RyaW5nKGEpfSwKJGl1ODoxfQpXLkFqLnByb3RvdHlwZT17JGlBajoxfQpXLmU3LnByb3Rv
+dHlwZT17CmdyODpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEscz10LmNoaWxkTm9kZXMubGVuZ3RoCmlm
+KHM9PT0wKXRocm93IEguYihQLlBWKCJObyBlbGVtZW50cyIpKQppZihzPjEpdGhyb3cgSC5iKFAuUFYo
+Ik1vcmUgdGhhbiBvbmUgZWxlbWVudCIpKQpyZXR1cm4gdC5maXJzdENoaWxkfSwKRlY6ZnVuY3Rpb24o
+YSxiKXt2YXIgdCxzLHIscQp1LmVoLmIoYikKdD1iLmEKcz10aGlzLmEKaWYodCE9PXMpZm9yKHI9dC5j
+aGlsZE5vZGVzLmxlbmd0aCxxPTA7cTxyOysrcSlzLmFwcGVuZENoaWxkKHQuZmlyc3RDaGlsZCkKcmV0
+dXJufSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQscwp1LkEuYihjKQp0PXRoaXMuYQpzPXQuY2hpbGRO
+b2RlcwppZihiPDB8fGI+PXMubGVuZ3RoKXJldHVybiBILk9IKHMsYikKdC5yZXBsYWNlQ2hpbGQoYyxz
+W2JdKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLmEuY2hpbGROb2RlcwpyZXR1cm4gbmV3IFcu
+VzkodCx0Lmxlbmd0aCxILnpLKHQpLkMoIlc5PEdtLkU+IikpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJu
+IHRoaXMuYS5jaGlsZE5vZGVzLmxlbmd0aH0sCnE6ZnVuY3Rpb24oYSxiKXt2YXIgdApILlNjKGIpCnQ9
+dGhpcy5hLmNoaWxkTm9kZXMKaWYoYjwwfHxiPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LGIpCnJldHVy
+biB0W2JdfX0KVy51SC5wcm90b3R5cGU9ewp3ZzpmdW5jdGlvbihhKXt2YXIgdD1hLnBhcmVudE5vZGUK
+aWYodCE9bnVsbCl0LnJlbW92ZUNoaWxkKGEpfSwKRDQ6ZnVuY3Rpb24oYSl7dmFyIHQKZm9yKDt0PWEu
+Zmlyc3RDaGlsZCx0IT1udWxsOylhLnJlbW92ZUNoaWxkKHQpfSwKdzpmdW5jdGlvbihhKXt2YXIgdD1h
+Lm5vZGVWYWx1ZQpyZXR1cm4gdD09bnVsbD90aGlzLlUoYSk6dH0sCiRpdUg6MX0KVy5CSC5wcm90b3R5
+cGU9ewpnQTpmdW5jdGlvbihhKXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhi
+KQppZihiPj4+MCE9PWJ8fGI+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVs
+bCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5BLmIoYykKdGhyb3cgSC5iKFAuTDQo
+IkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0aW9uKGEs
+Yil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUTox
+LAokaVhqOjEsCiRpY1g6MSwKJGl6TToxfQpXLlNOLnByb3RvdHlwZT17fQpXLmV3LnByb3RvdHlwZT17
+JGlldzoxfQpXLmxwLnByb3RvdHlwZT17CmdBOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxlbmd0aH19Clcu
+VGIucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscwppZigiY3JlYXRlQ29udGV4
+dHVhbEZyYWdtZW50IiBpbiB3aW5kb3cuUmFuZ2UucHJvdG90eXBlKXJldHVybiB0aGlzLkRXKGEsYixj
+LGQpCnQ9Vy5VOSgiPHRhYmxlPiIrSC5kKGIpKyI8L3RhYmxlPiIsYyxkKQpzPWRvY3VtZW50LmNyZWF0
+ZURvY3VtZW50RnJhZ21lbnQoKQpzLnRvU3RyaW5nCnQudG9TdHJpbmcKbmV3IFcuZTcocykuRlYoMCxu
+ZXcgVy5lNyh0KSkKcmV0dXJuIHN9fQpXLkl2LnByb3RvdHlwZT17CnI2OmZ1bmN0aW9uKGEsYixjLGQp
+e3ZhciB0LHMscixxCmlmKCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5w
+cm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1l
+bnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9T
+dHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQu
+Z3I4KHQpCnMudG9TdHJpbmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHEpKQpy
+ZXR1cm4gc319ClcuV1AucHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmlm
 KCJjcmVhdGVDb250ZXh0dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJu
 IHRoaXMuRFcoYSxiLGMsZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9
 Qy5JZS5yNih0LmNyZWF0ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5l
-Nyh0KQpyPXQuZ3I4KHQpCnIudG9TdHJpbmcKdD1uZXcgVy5lNyhyKQpxPXQuZ3I4KHQpCnMudG9TdHJp
-bmcKcS50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHEpKQpyZXR1cm4gc319ClcuV1Au
-cHJvdG90eXBlPXsKcjY6ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCmlmKCJjcmVhdGVDb250ZXh0
-dWFsRnJhZ21lbnQiIGluIHdpbmRvdy5SYW5nZS5wcm90b3R5cGUpcmV0dXJuIHRoaXMuRFcoYSxiLGMs
-ZCkKdD1kb2N1bWVudApzPXQuY3JlYXRlRG9jdW1lbnRGcmFnbWVudCgpCnQ9Qy5JZS5yNih0LmNyZWF0
-ZUVsZW1lbnQoInRhYmxlIiksYixjLGQpCnQudG9TdHJpbmcKdD1uZXcgVy5lNyh0KQpyPXQuZ3I4KHQp
-CnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBXLmU3KHIpKQpyZXR1cm4g
-c319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0LHMKYS50ZXh0Q29udGVu
-dD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5iVCh0KQpzPXRoaXMucjYoYSxiLG51bGwsYykK
-YS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5wayhh
-LGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJvdG90eXBlPXsKUG86ZnVu
-Y3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0fSwKZ21XOmZ1bmN0aW9u
-KGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlLNToxLAokaXY2OjF9ClcuQ20ucHJvdG90eXBlPXskaUNt
-OjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9ClcudzQucHJvdG90eXBlPXsKWjpmdW5jdGlvbihhKXty
-ZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9wKSsiKSAiK0guZChhLndp
-ZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVy
-biExCnJldHVybiB1LnEuYihiKSYmYS5sZWZ0PT1iLmxlZnQmJmEudG9wPT1iLnRvcCYmYS53aWR0aD09
-Yi53aWR0aCYmYS5oZWlnaHQ9PWIuaGVpZ2h0fSwKZ2lPOmZ1bmN0aW9uKGEpe3JldHVybiBXLnJFKEou
-aGYoYS5sZWZ0KSxKLmhmKGEudG9wKSxKLmhmKGEud2lkdGgpLEouaGYoYS5oZWlnaHQpKX19Clcucmgu
-cHJvdG90eXBlPXsKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIGEubGVuZ3RofSwKcTpmdW5jdGlvbihhLGIp
-e0guV1koYikKaWYoYj4+PjAhPT1ifHxiPj1hLmxlbmd0aCl0aHJvdyBILmIoUC50KGIsYSxudWxsLG51
-bGwsbnVsbCkpCnJldHVybiBhW2JdfSwKWTpmdW5jdGlvbihhLGIsYyl7dS5BLmEoYykKdGhyb3cgSC5i
-KFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxlbWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0
-aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxlbmd0aClyZXR1cm4gSC5rKGEsYikKcmV0dXJuIGFbYl19LAok
-aWJROjEsCiRpWGo6MSwKJGljWDoxLAokaXpNOjF9ClcuY2YucHJvdG90eXBlPXsKSzpmdW5jdGlvbihh
-LGIpe3ZhciB0LHMscixxLHAKdS5lQS5hKGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhp
-cy5hLHE9MDtxPHQubGVuZ3RoO3QubGVuZ3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4k
-MihwLHIuZ2V0QXR0cmlidXRlKHApKX19LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5h
-LmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUucykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7Kyty
-KXtpZihyPj1wLmxlbmd0aClyZXR1cm4gSC5rKHAscikKcT1zLmEocFtyXSkKaWYocS5uYW1lc3BhY2VV
-Ukk9PW51bGwpQy5ObS5pKG8scS5uYW1lKX1yZXR1cm4gb30sCmdsMDpmdW5jdGlvbihhKXtyZXR1cm4g
-dGhpcy5nVigpLmxlbmd0aD09PTB9fQpXLmk3LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmEuaGFzQXR0cmlidXRlKGEpfSwKcTpmdW5jdGlvbihhLGIpe3JldHVybiB0aGlzLmEuZ2V0
-QXR0cmlidXRlKEguYyhiKSl9LApZOmZ1bmN0aW9uKGEsYixjKXt0aGlzLmEuc2V0QXR0cmlidXRlKGIs
-Yyl9LApnQTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nVigpLmxlbmd0aH19ClcuU3kucHJvdG90eXBl
-PXsKeDQ6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5hLmhhc0F0dHJpYnV0ZSgiZGF0YS0iK3RoaXMu
-TyhhKSl9LApxOmZ1bmN0aW9uKGEsYil7cmV0dXJuIHRoaXMuYS5hLmdldEF0dHJpYnV0ZSgiZGF0YS0i
-K3RoaXMuTyhILmMoYikpKX0sClk6ZnVuY3Rpb24oYSxiLGMpe3RoaXMuYS5hLnNldEF0dHJpYnV0ZSgi
-ZGF0YS0iK3RoaXMuTyhiKSxjKX0sCks6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuSygwLG5ldyBXLktTKHRo
-aXMsdS5lQS5hKGIpKSl9LApnVjpmdW5jdGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygw
-LG5ldyBXLkEzKHRoaXMsdCkpCnJldHVybiB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1Yo
-KS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfSwKazpm
-dW5jdGlvbihhKXt2YXIgdCxzLHI9SC5WTShhLnNwbGl0KCItIiksdS5zKQpmb3IodD0xO3Q8ci5sZW5n
-dGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5ndGg+MClDLk5tLlkocix0LHNbMF0udG9VcHBlckNhc2UoKStK
-LktWKHMsMSkpfXJldHVybiBDLk5tLkgociwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAK
-Zm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7czx0Oysrcyl7cT1hW3NdCnA9cS50b0xvd2VyQ2FzZSgpCnI9
-KHEhPT1wJiZzPjA/cisiLSI6cikrcH1yZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn19ClcuS1Mu
-cHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSl0aGlzLmIu
-JDIodGhpcy5hLmsoQy54Qi5HKGEsNSkpLGIpfSwKJFM6MTR9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVu
-Y3Rpb24oYSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5rKEMu
-eEIuRyhhLDUpKSl9LAokUzoxNH0KVy5JNC5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKCl7dmFyIHQscyxy
-LHEscD1QLkxzKHUuTikKZm9yKHQ9dGhpcy5hLmNsYXNzTmFtZS5zcGxpdCgiICIpLHM9dC5sZW5ndGgs
-cj0wO3I8czsrK3Ipe3E9Si5UMCh0W3JdKQppZihxLmxlbmd0aCE9PTApcC5pKDAscSl9cmV0dXJuIHB9
-LApYOmZ1bmN0aW9uKGEpe3RoaXMuYS5jbGFzc05hbWU9dS5DLmEoYSkuSCgwLCIgIil9LApnQTpmdW5j
-dGlvbihhKXtyZXR1cm4gdGhpcy5hLmNsYXNzTGlzdC5sZW5ndGh9LApWMTpmdW5jdGlvbihhKXt0aGlz
-LmEuY2xhc3NOYW1lPSIifSwKdGc6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LmNv
-bnRhaW5zKGIpCnJldHVybiB0fSwKaTpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYS5jbGFzc0xpc3Qs
-cz10LmNvbnRhaW5zKGIpCnQuYWRkKGIpCnJldHVybiFzfSwKUjpmdW5jdGlvbihhLGIpe3ZhciB0PXRo
-aXMuYS5jbGFzc0xpc3Qscz10LmNvbnRhaW5zKGIpCnQucmVtb3ZlKGIpCnJldHVybiBzfSwKRlY6ZnVu
-Y3Rpb24oYSxiKXtXLlROKHRoaXMuYSx1LlguYShiKSl9fQpXLkZrLnByb3RvdHlwZT17fQpXLlJPLnBy
-b3RvdHlwZT17fQpXLmV1LnByb3RvdHlwZT17fQpXLnhDLnByb3RvdHlwZT17fQpXLnZOLnByb3RvdHlw
-ZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmEuJDEodS5CLmEoYSkpfSwKJFM6Mjd9ClcuSlEu
-cHJvdG90eXBlPXsKQ1k6ZnVuY3Rpb24oYSl7dmFyIHQKaWYoJC5vci5hPT09MCl7Zm9yKHQ9MDt0PDI2
-MjsrK3QpJC5vci5ZKDAsQy5jbVt0XSxXLnBTKCkpCmZvcih0PTA7dDwxMjsrK3QpJC5vci5ZKDAsQy5C
-SVt0XSxXLlY0KCkpfX0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiAkLkFOKCkudGcoMCxXLnJTKGEpKX0s
-CkViOmZ1bmN0aW9uKGEsYixjKXt2YXIgdD0kLm9yLnEoMCxILmQoVy5yUyhhKSkrIjo6IitiKQppZih0
-PT1udWxsKXQ9JC5vci5xKDAsIio6OiIrYikKaWYodD09bnVsbClyZXR1cm4hMQpyZXR1cm4gSC5FOSh0
-LiQ0KGEsYixjLHRoaXMpKX0sCiRpa0Y6MX0KVy5HbS5wcm90b3R5cGU9ewpna3o6ZnVuY3Rpb24oYSl7
-cmV0dXJuIG5ldyBXLlc5KGEsdGhpcy5nQShhKSxILnEoYSkuQygiVzk8R20uRT4iKSl9fQpXLnZELnBy
-b3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLlZyKHRoaXMuYSxuZXcgVy5VdihhKSl9
-LApFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLkVnKGEsYixjKSl9
-LAokaWtGOjF9ClcuVXYucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZS5hKGEpLmkw
-KHRoaXMuYSl9LAokUzoxNX0KVy5FZy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5l
-LmEoYSkuRWIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MTV9ClcubTYucHJvdG90eXBlPXsKQ1k6
-ZnVuY3Rpb24oYSxiLGMsZCl7dmFyIHQscyxyCnRoaXMuYS5GVigwLGMpCnQ9Yi5ldigwLG5ldyBXLkVv
-KCkpCnM9Yi5ldigwLG5ldyBXLldrKCkpCnRoaXMuYi5GVigwLHQpCnI9dGhpcy5jCnIuRlYoMCxDLnhE
-KQpyLkZWKDAscyl9LAppMDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLnRnKDAsVy5yUyhhKSl9LApF
-YjpmdW5jdGlvbihhLGIsYyl7dmFyIHQ9dGhpcyxzPVcuclMoYSkscj10LmMKaWYoci50ZygwLEguZChz
-KSsiOjoiK2IpKXJldHVybiB0LmQuRHQoYykKZWxzZSBpZihyLnRnKDAsIio6OiIrYikpcmV0dXJuIHQu
-ZC5EdChjKQplbHNle3I9dC5iCmlmKHIudGcoMCxILmQocykrIjo6IitiKSlyZXR1cm4hMAplbHNlIGlm
-KHIudGcoMCwiKjo6IitiKSlyZXR1cm4hMAplbHNlIGlmKHIudGcoMCxILmQocykrIjo6KiIpKXJldHVy
-biEwCmVsc2UgaWYoci50ZygwLCIqOjoqIikpcmV0dXJuITB9cmV0dXJuITF9LAokaWtGOjF9ClcuRW8u
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIUMuTm0udGcoQy5CSSxILmMoYSkpfSwKJFM6
-N30KVy5Xay5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gQy5ObS50ZyhDLkJJLEguYyhh
-KSl9LAokUzo3fQpXLmN0LnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixjKXtpZih0aGlzLmpGKGEs
-YixjKSlyZXR1cm4hMAppZihiPT09InRlbXBsYXRlIiYmYz09PSIiKXJldHVybiEwCmlmKGEuZ2V0QXR0
-cmlidXRlKCJ0ZW1wbGF0ZSIpPT09IiIpcmV0dXJuIHRoaXMuZS50ZygwLGIpCnJldHVybiExfX0KVy5J
-QS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4iVEVNUExBVEU6OiIrSC5kKEguYyhhKSl9
-LAokUzo1fQpXLk93LnByb3RvdHlwZT17CmkwOmZ1bmN0aW9uKGEpe3ZhciB0CmlmKHUuYU8uYihhKSly
-ZXR1cm4hMQp0PXUuZzcuYihhKQppZih0JiZXLnJTKGEpPT09ImZvcmVpZ25PYmplY3QiKXJldHVybiEx
-CmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApFYjpmdW5jdGlvbihhLGIsYyl7aWYoYj09PSJpcyJ8fEMu
-eEIubihiLCJvbiIpKXJldHVybiExCnJldHVybiB0aGlzLmkwKGEpfSwKJGlrRjoxfQpXLlc5LnByb3Rv
-dHlwZT17CkY6ZnVuY3Rpb24oKXt2YXIgdD10aGlzLHM9dC5jKzEscj10LmIKaWYoczxyKXt0LnNwKEou
-eDkodC5hLHMpKQp0LmM9cwpyZXR1cm4hMH10LnNwKG51bGwpCnQuYz1yCnJldHVybiExfSwKZ2w6ZnVu
-Y3Rpb24oKXtyZXR1cm4gdGhpcy5kfSwKc3A6ZnVuY3Rpb24oYSl7dGhpcy5kPXRoaXMuJHRpLmMuYShh
-KX0sCiRpQW46MX0KVy5kVy5wcm90b3R5cGU9ewpnbVc6ZnVuY3Rpb24oYSl7cmV0dXJuIFcuSEgodGhp
-cy5hLmxvY2F0aW9uKX0sCiRpRDA6MSwKJGl2NjoxfQpXLkZiLnByb3RvdHlwZT17fQpXLmtGLnByb3Rv
-dHlwZT17fQpXLm1rLnByb3RvdHlwZT17JGl5MDoxfQpXLktvLnByb3RvdHlwZT17ClBuOmZ1bmN0aW9u
-KGEpe3ZhciB0PXRoaXMscz1uZXcgVy5mbSh0KQp0LmI9ITEKcy4kMihhLG51bGwpCmZvcig7dC5iOyl7
-dC5iPSExCnMuJDIoYSxudWxsKX19LApFUDpmdW5jdGlvbihhLGIpe3ZhciB0PXRoaXMuYj0hMAppZihi
-IT1udWxsP2IhPT1hLnBhcmVudE5vZGU6dClKLkx0KGEpCmVsc2UgYi5yZW1vdmVDaGlsZChhKX0sCkk0
-OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwKdHJ5e249Si5pZyhh
-KQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmEoYSkKdD1mdW5jdGlvbihjKXtpZighKGMuYXR0
-cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKaWYoYy5pZD09J2xhc3RD
-aGlsZCd8fGMubmFtZT09J2xhc3RDaGlsZCd8fGMuaWQ9PSdwcmV2aW91c1NpYmxpbmcnfHxjLm5hbWU9
-PSdwcmV2aW91c1NpYmxpbmcnfHxjLmlkPT0nY2hpbGRyZW4nfHxjLm5hbWU9PSdjaGlsZHJlbicpcmV0
-dXJuIHRydWUKdmFyIGw9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RDaGlsZCE9PWxb
-bC5sZW5ndGgtMV0pcmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRyZW4gaW5zdGFu
-Y2VvZiBIVE1MQ29sbGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0KSlyZXR1cm4g
-dHJ1ZQp2YXIgaz0wCmlmKGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3IodmFyIGo9MDtq
-PGs7aisrKXt2YXIgaT1jLmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8aS5uYW1lPT0n
-YXR0cmlidXRlcyd8fGkuaWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQnfHxpLmlkPT0n
-cHJldmlvdXNTaWJsaW5nJ3x8aS5uYW1lPT0ncHJldmlvdXNTaWJsaW5nJ3x8aS5pZD09J2NoaWxkcmVu
-J3x8aS5uYW1lPT0nY2hpbGRyZW4nKXJldHVybiB0cnVlfXJldHVybiBmYWxzZX0oYSkKbz1ILm9UKHQp
-PyEwOiEoYS5hdHRyaWJ1dGVzIGluc3RhbmNlb2YgTmFtZWROb2RlTWFwKX1jYXRjaChxKXtILlJ1KHEp
-fXM9ImVsZW1lbnQgdW5wcmludGFibGUiCnRyeXtzPUouQWMoYSl9Y2F0Y2gocSl7SC5SdShxKX10cnl7
-cj1XLnJTKGEpCnRoaXMua1IodS5oLmEoYSksYixvLHMscix1LkcuYShuKSxILmMobSkpfWNhdGNoKHEp
-e2lmKEguUnUocSkgaW5zdGFuY2VvZiBQLkFUKXRocm93IHEKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93
-CnA9IlJlbW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBjb25zb2xlIT0i
-dW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihhLGIsYyxkLGUs
-ZixnKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3Zp
-bmcgZWxlbWVudCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIKaWYodHlwZW9m
-IGNvbnNvbGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKCFuLmEu
-aTAoYSkpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVtZW50IDwiK0gu
-ZChlKSsiPiBmcm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cu
-Y29uc29sZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMiLGcpKXtuLkVQ
-KGEsYikKd2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5kKGUp
-KycgaXM9IicrZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29s
-ZS53YXJuKHQpCnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+
-IikpCmZvcihyPWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5sZW5ndGgpcmV0
-dXJuIEguayhzLHIpCnE9c1tyXQpwPW4uYQpvPUouY0gocSkKSC5jKHEpCmlmKCFwLkViKGEsbyx0Lmdl
-dEF0dHJpYnV0ZShxKSkpe3dpbmRvdwpwPSJSZW1vdmluZyBkaXNhbGxvd2VkIGF0dHJpYnV0ZSA8IitI
-LmQoZSkrIiAiK3ErJz0iJytILmQodC5nZXRBdHRyaWJ1dGUocSkpKyciPicKaWYodHlwZW9mIGNvbnNv
-bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4ocCkKdC5yZW1vdmVBdHRyaWJ1dGUocSl9
-fWlmKHUuYVcuYihhKSluLlBuKGEuY29udGVudCl9LAokaW9uOjF9ClcuZm0ucHJvdG90eXBlPXsKJDI6
-ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbj10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nh
-c2UgMTpuLkk0KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZh
-dWx0Om4uRVAoYSxiKX10PWEubGFzdENoaWxkCmZvcihyPXUuQTtudWxsIT10Oyl7cz1udWxsCnRyeXtz
-PXQucHJldmlvdXNTaWJsaW5nCmlmKHMhPW51bGwpe3E9cy5uZXh0U2libGluZwpwPXQKcD1xPT1udWxs
-P3AhPW51bGw6cSE9PXAKcT1wfWVsc2UgcT0hMQppZihxKXtxPVAuUFYoIkNvcnJ1cHQgSFRNTCIpCnRo
-cm93IEguYihxKX19Y2F0Y2gobyl7SC5SdShvKQpxPXIuYSh0KQpuLmI9ITAKcD1xLnBhcmVudE5vZGUK
-cD1hPT1udWxsP3AhPW51bGw6YSE9PXAKaWYocCl7cD1xLnBhcmVudE5vZGUKaWYocCE9bnVsbClwLnJl
-bW92ZUNoaWxkKHEpfWVsc2UgYS5yZW1vdmVDaGlsZChxKQp0PW51bGwKcz1hLmxhc3RDaGlsZH1pZih0
-IT1udWxsKXRoaXMuJDIodCxhKQp0PXN9fSwKJFM6MzB9ClcuTGUucHJvdG90eXBlPXt9ClcuSzcucHJv
-dG90eXBlPXt9ClcuckIucHJvdG90eXBlPXt9ClcuWFcucHJvdG90eXBlPXt9Clcub2EucHJvdG90eXBl
-PXt9ClAuaUoucHJvdG90eXBlPXsKVkg6ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLmEscj1zLmxlbmd0
-aApmb3IodD0wO3Q8cjsrK3QpaWYoc1t0XT09PWEpcmV0dXJuIHQKQy5ObS5pKHMsYSkKQy5ObS5pKHRo
-aXMuYixudWxsKQpyZXR1cm4gcn0sClB2OmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxPXRoaXMscD17fQpp
-ZihhPT1udWxsKXJldHVybiBhCmlmKEguclEoYSkpcmV0dXJuIGEKaWYodHlwZW9mIGE9PSJudW1iZXIi
-KXJldHVybiBhCmlmKHR5cGVvZiBhPT0ic3RyaW5nIilyZXR1cm4gYQppZihhIGluc3RhbmNlb2YgUC5p
-UClyZXR1cm4gbmV3IERhdGUoYS5hKQppZih1LmZ2LmIoYSkpdGhyb3cgSC5iKFAubigic3RydWN0dXJl
-ZCBjbG9uZSBvZiBSZWdFeHAiKSkKaWYodS5jOC5iKGEpKXJldHVybiBhCmlmKHUuZC5iKGEpKXJldHVy
-biBhCmlmKHUuSS5iKGEpKXJldHVybiBhCnQ9dS5kRC5iKGEpfHwhMQppZih0KXJldHVybiBhCmlmKHUu
-Ry5iKGEpKXtzPXEuVkgoYSkKdD1xLmIKaWYocz49dC5sZW5ndGgpcmV0dXJuIEguayh0LHMpCnI9cC5h
-PXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1yCkMuTm0uWSh0LHMscikKYS5LKDAsbmV3
-IFAuamcocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYihhKSl7cz1xLlZIKGEpCnA9cS5iCmlmKHM+PXAu
-bGVuZ3RoKXJldHVybiBILmsocCxzKQpyPXBbc10KaWYociE9bnVsbClyZXR1cm4gcgpyZXR1cm4gcS5l
-ayhhLHMpfWlmKHUuZUguYihhKSl7cz1xLlZIKGEpCnQ9cS5iCmlmKHM+PXQubGVuZ3RoKXJldHVybiBI
-LmsodCxzKQpyPXAuYj10W3NdCmlmKHIhPW51bGwpcmV0dXJuIHIKcj17fQpwLmI9cgpDLk5tLlkodCxz
-LHIpCnEuaW0oYSxuZXcgUC5UYShwLHEpKQpyZXR1cm4gcC5ifXRocm93IEguYihQLm4oInN0cnVjdHVy
-ZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1KLlU2KGEp
-LHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlkodGhpcy5iLGIscSkKZm9yKHQ9MDt0PHI7Kyt0
-KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJldHVybiBxfX0KUC5qZy5wcm90b3R5cGU9ewok
-MjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMuYi5QdihiKX0sCiRTOjR9ClAuVGEucHJvdG90
-eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlthXT10aGlzLmIuUHYoYil9LAokUzo0fQpQLkJm
-LnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEKdS5iOC5hKGIpCmZvcih0PU9i
-amVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsrK3Ipe3E9dFtyXQpiLiQyKHEsYVtxXSl9fX0K
-UC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3ZhciB0CkguYyhhKQp0PSQuaEcoKS5iCmlmKHR5
-cGVvZiBhIT0ic3RyaW5nIilILnZoKEguSShhKSkKaWYodC50ZXN0KGEpKXJldHVybiBhCnRocm93IEgu
-YihQLkwzKGEsInZhbHVlIiwiTm90IGEgdmFsaWQgY2xhc3MgdG9rZW4iKSl9LApaOmZ1bmN0aW9uKGEp
-e3JldHVybiB0aGlzLncoKS5IKDAsIiAiKX0sCmdrejpmdW5jdGlvbihhKXt2YXIgdD10aGlzLncoKQpy
-ZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMudygp
-LmF9LAp0ZzpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1cm4gdGhpcy53KCkudGcoMCxiKX0sCmk6
-ZnVuY3Rpb24oYSxiKXt0aGlzLlQoYikKcmV0dXJuIEguRTkodGhpcy5PUyhuZXcgUC5HRShiKSkpfSwK
-UjpmdW5jdGlvbihhLGIpe3ZhciB0LHMKdGhpcy5UKGIpCnQ9dGhpcy53KCkKcz10LlIoMCxiKQp0aGlz
-LlgodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlvbihhLGIpe3RoaXMuT1MobmV3IFAuTjcodGhpcyx1Llgu
-YShiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEp
-e3ZhciB0LHMKdS5iVS5hKGEpCnQ9dGhpcy53KCkKcz1hLiQxKHQpCnRoaXMuWCh0KQpyZXR1cm4gc319
-ClAuR0UucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuQy5hKGEpLmkoMCx0aGlzLmEp
-fSwKJFM6MzF9ClAuTjcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5iLHM9SC50
-Nih0KQpyZXR1cm4gdS5DLmEoYSkuRlYoMCxuZXcgSC5sSih0LHMuQygicVUoMSkiKS5hKHRoaXMuYS5n
-dU0oKSkscy5DKCJsSjwxLHFVPiIpKSl9LAokUzoxNn0KUC51US5wcm90b3R5cGU9ewokMTpmdW5jdGlv
-bihhKXt1LkMuYShhKQppZihhLmE+MCl7YS5iPWEuYz1hLmQ9YS5lPWEuZj1udWxsCmEuYT0wCmEuUygp
-fXJldHVybiBudWxsfSwKJFM6MTZ9ClAuaEYucHJvdG90eXBlPXskaWhGOjF9ClAuUEMucHJvdG90eXBl
-PXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5aLmEoYSkKdD1mdW5jdGlvbihiLGMsZCl7cmV0dXJuIGZ1
-bmN0aW9uKCl7cmV0dXJuIGIoYyxkLHRoaXMsQXJyYXkucHJvdG90eXBlLnNsaWNlLmFwcGx5KGFyZ3Vt
-ZW50cykpfX0oUC5SNCxhLCExKQpQLkRtKHQsJC53USgpLGEpCnJldHVybiB0fSwKJFM6MX0KUC5tdC5w
-cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjF9ClAuTnou
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6NDJ9ClAuUVMu
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9LAokUzozNH0K
-UC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAokUzozNX0K
-UC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9uKGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciJiZ0eXBl
-b2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAueFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmluZyBvciBu
-dW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2JdKX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBi
-IT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1iZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBu
-b3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMuYVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtp
-ZihiPT1udWxsKXJldHVybiExCnJldHVybiBiIGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwK
-WjpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0PVN0cmluZyh0aGlzLmEpCnJldHVybiB0fWNhdGNoKHMp
-e0guUnUocykKdD10aGlzLnhiKDApCnJldHVybiB0fX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10
-aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxzZXt0PUgudDYoYikKdD1QLkNIKG5ldyBILmxKKGIsdC5D
-KCJAKDEpIikuYShQLmlHKCkpLHQuQygibEo8MSxAPiIpKSwhMCx1LnopfXJldHVybiBQLkw3KHNbYV0u
-YXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24oYSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQ
-LlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+PXQuZ0EodCkK
-aWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5nQSh0KSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxi
-KXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9PT1DLmpuLnl1KGIpKXRoaXMuY1AoSC5XWShiKSkKcmV0
-dXJuIHRoaXMuJHRpLmMuYSh0aGlzLlVyKDAsYikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdGhp
-cy4kdGkuYy5hKGMpCnQ9Qy5qbi55dShiKQppZihiPT09dCl0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMp
-fSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhpcy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIi
-JiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cgSC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0s
-CiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAuY28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90eXBlPXsk
-aW5kOjF9ClAuS2UucHJvdG90eXBlPXsKdzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmdl
-dEF0dHJpYnV0ZSgiY2xhc3MiKSxvPVAuTHModS5OKQppZihwPT1udWxsKXJldHVybiBvCmZvcih0PXAu
-c3BsaXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFtyXSkKaWYocS5sZW5ndGgh
-PT0wKW8uaSgwLHEpfXJldHVybiBvfSwKWDpmdW5jdGlvbihhKXt0aGlzLmEuc2V0QXR0cmlidXRlKCJj
-bGFzcyIsYS5IKDAsIiAiKSl9fQpQLmQ1LnByb3RvdHlwZT17CmdQOmZ1bmN0aW9uKGEpe3JldHVybiBu
-ZXcgUC5LZShhKX0sCnNoZjpmdW5jdGlvbihhLGIpe3RoaXMuWUMoYSxiKX0sCnI2OmZ1bmN0aW9uKGEs
-YixjLGQpe3ZhciB0LHMscixxLHAsbwppZihkPT1udWxsKXt0PUguVk0oW10sdS5pKQpkPW5ldyBXLnZE
-KHQpCkMuTm0uaSh0LFcuVHcobnVsbCkpCkMuTm0uaSh0LFcuQmwoKSkKQy5ObS5pKHQsbmV3IFcuT3co
-KSl9Yz1uZXcgVy5LbyhkKQpzPSc8c3ZnIHZlcnNpb249IjEuMSI+JytILmQoYikrIjwvc3ZnPiIKdD1k
-b2N1bWVudApyPXQuYm9keQpxPShyJiZDLlJZKS5BSChyLHMsYykKcD10LmNyZWF0ZURvY3VtZW50RnJh
-Z21lbnQoKQpxLnRvU3RyaW5nCnQ9bmV3IFcuZTcocSkKbz10LmdyOCh0KQpmb3IoO3Q9by5maXJzdENo
-aWxkLHQhPW51bGw7KXAuYXBwZW5kQ2hpbGQodCkKcmV0dXJuIHB9LApuejpmdW5jdGlvbihhLGIsYyxk
-LGUpe3Rocm93IEguYihQLkw0KCJDYW5ub3QgaW52b2tlIGluc2VydEFkamFjZW50SHRtbCBvbiBTVkcu
-IikpfSwKZ1ZsOmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5ldShhLCJjbGljayIsITEsdS5RKX0sCiRp
-ZDU6MX0KUC5uNi5wcm90b3R5cGU9eyRpYlE6MSwkaWNYOjEsJGl6TToxLCRpZXE6MX0KTS5INy5wcm90
-b3R5cGU9ewpaOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpVLkxMLnByb3RvdHlwZT17Ckx0OmZ1
-bmN0aW9uKCl7cmV0dXJuIFAuRUYoWyJub2RlSWQiLHRoaXMuYiwia2luZCIsdGhpcy5hLmFdLHUuTix1
-LkspfX0KVS5NRC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5ncC5hKGEpLmE9PT10
-aGlzLmEucSgwLCJraW5kIil9LAokUzozNn0KVS5kMi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3Zh
-ciB0LHMscixxLHA9dGhpcyxvPXUuTixuPXUuSyxtPVAuRmwobyxuKSxsPXAuYQppZihsIT1udWxsKXt0
-PUguVk0oW10sdS5KKQpmb3Iocz1sLmxlbmd0aCxyPTA7cjxsLmxlbmd0aDtsLmxlbmd0aD09PXN8fCgw
-LEgubGspKGwpLCsrcil7cT1sW3JdCkMuTm0uaSh0LFAuRUYoWyJkZXNjcmlwdGlvbiIscS5hLCJocmVm
-IixxLmJdLG8sbikpfW0uWSgwLCJlZGl0cyIsdCl9bS5ZKDAsImV4cGxhbmF0aW9uIixwLmIpCm0uWSgw
-LCJsaW5lIixwLmMpCm0uWSgwLCJkaXNwbGF5UGF0aCIscC5kKQptLlkoMCwidXJpUGF0aCIscC5lKQpv
-PXAuZgppZihvIT1udWxsKXtuPUguVk0oW10sdS5KKQpmb3IobD1vLmxlbmd0aCxyPTA7cjxvLmxlbmd0
-aDtvLmxlbmd0aD09PWx8fCgwLEgubGspKG8pLCsrcilDLk5tLmkobixvW3JdLkx0KCkpCm0uWSgwLCJ0
-cmFjZXMiLG4pfXJldHVybiBtfX0KVS5TZS5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQ
-LkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiaHJlZiIsdGhpcy5iXSx1Lk4sdS5LKX19ClUuTWwucHJv
-dG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImhyZWYiLHRoaXMuYSwibGluZSIsdGhp
-cy5iLCJwYXRoIix0aGlzLmNdLHUuTix1LkspfX0KVS55RC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigp
-e3ZhciB0LHMscixxPUguVk0oW10sdS5KKQpmb3IodD10aGlzLmIscz10Lmxlbmd0aCxyPTA7cjx0Lmxl
-bmd0aDt0Lmxlbmd0aD09PXN8fCgwLEgubGspKHQpLCsrcilDLk5tLmkocSx0W3JdLkx0KCkpCnJldHVy
-biBQLkVGKFsiZGVzY3JpcHRpb24iLHRoaXMuYSwiZW50cmllcyIscV0sdS5OLHUuSyl9fQpVLndiLnBy
-b3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMscT1QLkZsKHUuTix1LkspCnEuWSgw
-LCJkZXNjcmlwdGlvbiIsci5hKQp0PXIuYgppZih0IT1udWxsKXEuWSgwLCJmdW5jdGlvbiIsdCkKdD1y
-LmMKaWYodCE9bnVsbClxLlkoMCwibGluayIsdC5MdCgpKQp0PXIuZAppZih0Lmxlbmd0aCE9PTApe3M9
-SC50Nih0KQpxLlkoMCwiaGludEFjdGlvbnMiLG5ldyBILmxKKHQscy5DKCJaMDxxVSxNaD4oMSkiKS5h
-KG5ldyBVLmIwKCkpLHMuQygibEo8MSxaMDxxVSxNaD4+IikpLmJyKDApKX1yZXR1cm4gcX19ClUuYU4u
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIFUubnoodS5TLmEoYSkpfSwKJFM6Mzd9ClUu
-YjAucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIHUuRS5hKGEpLkx0KCl9LAokUzozOH0K
-Qi5qOC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibGluZSIsdGhpcy5hLCJl
-eHBsYW5hdGlvbiIsdGhpcy5iLCJvZmZzZXQiLHRoaXMuY10sdS5OLHUuSyl9fQpCLnFwLnByb3RvdHlw
-ZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG4sbT10aGlzLGw9dS5OLGs9UC5GbChsLHUu
-ZDMpCmZvcih0PW0uZCx0PXQuZ1B1KHQpLHQ9dC5na3oodCkscz11Lksscj11Lko7dC5GKCk7KXtxPXQu
-Z2woKQpwPXEuYQpvPUguVk0oW10scikKZm9yKHE9Si5JVChxLmIpO3EuRigpOyl7bj1xLmdsKCkKQy5O
-bS5pKG8sUC5FRihbImxpbmUiLG4uYSwiZXhwbGFuYXRpb24iLG4uYiwib2Zmc2V0IixuLmNdLGwscykp
-fWsuWSgwLHAsbyl9cmV0dXJuIFAuRUYoWyJyZWdpb25zIixtLmEsIm5hdmlnYXRpb25Db250ZW50Iixt
-LmIsInNvdXJjZUNvZGUiLG0uYywiZWRpdHMiLGtdLGwscyl9fQpULm1RLnByb3RvdHlwZT17fQpMLmUu
-cHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4KdS5CLmEoYSkKdD13aW5k
-b3cubG9jYXRpb24ucGF0aG5hbWUKcz1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2lu
-ZG93LmxvY2F0aW9uLmhyZWYpCkwuR2UoKQppZih0IT09Ii8iJiZ0IT09Si5UMChkb2N1bWVudC5xdWVy
-eVNlbGVjdG9yKCIucm9vdCIpLnRleHRDb250ZW50KSlMLkc3KHQscyxyLCEwLG5ldyBMLlZXKHQscyxy
-KSkKcT1kb2N1bWVudApwPUoucUYocS5xdWVyeVNlbGVjdG9yKCIuYXBwbHktbWlncmF0aW9uIikpCm89
-cC4kdGkKbj1vLkMoIn4oMSkiKS5hKG5ldyBMLm9aKCkpCnUuTS5hKG51bGwpClcuSkUocC5hLHAuYixu
-LCExLG8uYykKbz1KLnFGKHEucXVlcnlTZWxlY3RvcigiLnJlcnVuLW1pZ3JhdGlvbiIpKQpuPW8uJHRp
-ClcuSkUoby5hLG8uYixuLkMoIn4oMSkiKS5hKG5ldyBMLnk4KCkpLCExLG4uYykKbj1KLnFGKHEucXVl
-cnlTZWxlY3RvcigiLnJlcG9ydC1wcm9ibGVtIikpCm89bi4kdGkKVy5KRShuLmEsbi5iLG8uQygifigx
-KSIpLmEobmV3IEwuSGkoKSksITEsby5jKQpxPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFu
-ZSAuY2xvc2UiKSkKbz1xLiR0aQpXLkpFKHEuYSxxLmIsby5DKCJ+KDEpIikuYShuZXcgTC5CVCgpKSwh
-MSxvLmMpfSwKJFM6MTd9CkwuVlcucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMuYSx0
-aGlzLmIsdGhpcy5jKX0sCiRTOjB9Ckwub1oucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQs
-cyxyLHEKdS5WLmEoYSkKaWYoSC5vVCh3aW5kb3cuY29uZmlybSgiVGhpcyB3aWxsIGFwcGx5IHRoZSBj
-aGFuZ2VzIHlvdSd2ZSBwcmV2aWV3ZWQgdG8geW91ciB3b3JraW5nIGRpcmVjdG9yeS4gSXQgaXMgcmVj
-b21tZW5kZWQgeW91IGNvbW1pdCBhbnkgY2hhbmdlcyB5b3UgbWFkZSBiZWZvcmUgZG9pbmcgdGhpcy4i
-KSkpe3Q9TC50eSgiL2FwcGx5LW1pZ3JhdGlvbiIsbnVsbCkuVzcobmV3IEwuanIoKSx1LlApCnM9bmV3
-IEwucWwoKQp1LmJmLmEobnVsbCkKcj10LiR0aQpxPSQuWDMKaWYocSE9PUMuTlUpcz1QLlZIKHMscSkK
-dC54ZihuZXcgUC5GZShuZXcgUC52cyhxLHIpLDIsbnVsbCxzLHIuQygiQDwxPiIpLktxKHIuYykuQygi
-RmU8MSwyPiIpKSl9fSwKJFM6M30KTC5qci5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdAp1
-LlMuYShhKQp0PWRvY3VtZW50LmJvZHkKdC5jbGFzc0xpc3QucmVtb3ZlKCJwcm9wb3NlZCIpCnQuY2xh
-c3NMaXN0LmFkZCgiYXBwbGllZCIpfSwKJFM6NDF9CkwucWwucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
-YSxiKXtMLkMyKCJDb3VsZCBub3QgYXBwbHkgbWlncmF0aW9uIixhLGIpfSwKJEM6IiQyIiwKJFI6MiwK
-JFM6NH0KTC55OC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy54bih1LlYuYShh
-KSl9LAp4bjpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbyxuLG0sbAp2
-YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGlsZSh0cnVl
-KXN3aXRjaCh0KXtjYXNlIDA6cj0zCmRvY3VtZW50LmJvZHkuY2xhc3NMaXN0LmFkZCgicmVydW5uaW5n
-IikKdD02CnJldHVybiBQLmpRKEwudHkoIi9yZXJ1bi1taWdyYXRpb24iLG51bGwpLCRhc3luYyQkMSkK
-Y2FzZSA2OndpbmRvdy5sb2NhdGlvbi5yZWxvYWQoKQpwLnB1c2goNSkKdD00CmJyZWFrCmNhc2UgMzpy
-PTIKbD1xCm89SC5SdShsKQpuPUgudHMobCkKTC5DMigiRmFpbGVkIHRvIHJlcnVuIG1pZ3JhdGlvbiIs
-byxuKQpwLnB1c2goNSkKdD00CmJyZWFrCmNhc2UgMjpwPVsxXQpjYXNlIDQ6cj0xCmRvY3VtZW50LmJv
-ZHkuY2xhc3NMaXN0LnJlbW92ZSgicmVydW5uaW5nIikKdD1wLnBvcCgpCmJyZWFrCmNhc2UgNTpyZXR1
-cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQLkRJKCRhc3lu
-YyQkMSxzKX0sCiRTOjExfQpMLkhpLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5h
-KGEpCnQ9dS5OCkMub2wuUG8od2luZG93LFAuWGQoImh0dHBzIiwiZ2l0aHViLmNvbSIsImRhcnQtbGFu
-Zy9zZGsvaXNzdWVzL25ldyIsUC5FRihbInRpdGxlIiwiQ3VzdG9tZXItcmVwb3J0ZWQgaXNzdWUgd2l0
-aCBOTkJEIG1pZ3JhdGlvbiB0b29sIiwibGFiZWxzIiwiYXJlYS1hbmFseXplcixhbmFseXplci1ubmJk
-LW1pZ3JhdGlvbix0eXBlLWJ1ZyIsImJvZHkiLCIjIyMjIFN0ZXBzIHRvIHJlcHJvZHVjZVxuXG4jIyMj
-IFdoYXQgZGlkIHlvdSBleHBlY3QgdG8gaGFwcGVuP1xuXG4jIyMjIFdoYXQgYWN0dWFsbHkgaGFwcGVu
-ZWQ/XG5cbl9TY3JlZW5zaG90cyBhcmUgYXBwcmVjaWF0ZWRfXG5cbioqRGFydCBTREsgdmVyc2lvbioq
-OiAiK0guZChkb2N1bWVudC5nZXRFbGVtZW50QnlJZCgic2RrLXZlcnNpb24iKS50ZXh0Q29udGVudCkr
-IlxuXG5UaGFua3MgZm9yIGZpbGluZyFcbiJdLHQsdCkpLlooMCksInJlcG9ydC1wcm9ibGVtIil9LAok
-UzozfQpMLkJULnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5hKGEpCnQ9ZG9jdW1l
-bnQucXVlcnlTZWxlY3RvcigiLnBvcHVwLXBhbmUiKS5zdHlsZQp0LmRpc3BsYXk9Im5vbmUiCnJldHVy
-biJub25lIn0sCiRTOjQzfQpMLkwucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUu
-Qi5hKGEpCnQ9d2luZG93LmxvY2F0aW9uLnBhdGhuYW1lCnM9TC5HNih3aW5kb3cubG9jYXRpb24uaHJl
-ZikKcj1MLmFLKHdpbmRvdy5sb2NhdGlvbi5ocmVmKQppZih0Lmxlbmd0aD4xKUwuRzcodCxzLHIsITEs
-bnVsbCkKZWxzZXtMLkJFKHQsbmV3IEIucXAoIiIsIiIsIiIsQy5DTSksITApCkwuQlgoIiZuYnNwOyIs
-bnVsbCl9fSwKJFM6MTd9CkwuV3gucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyLHE9
-ImNvbGxhcHNlZCIKdS5WLmEoYSkKdD10aGlzLmEKcz1KLlJFKHQpCnI9dGhpcy5iCmlmKCFzLmdQKHQp
-LnRnKDAscSkpe3MuZ1AodCkuaSgwLHEpCkouZFIocikuaSgwLHEpfWVsc2V7cy5nUCh0KS5SKDAscSkK
-Si5kUihyKS5SKDAscSl9fSwKJFM6M30KTC5BTy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIg
-dD1KLnFGKHUuaC5hKGEpKSxzPXQuJHRpLHI9cy5DKCJ+KDEpIikuYShuZXcgTC5kTih0aGlzLmEpKQp1
-Lk0uYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxzLmMpfSwKJFM6Nn0KTC5kTi5wcm90b3R5cGU9ewok
-MTpmdW5jdGlvbihhKXt2YXIgdAp1LlYuYShhKQp0PWRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoInRhYmxl
-W2RhdGEtcGF0aF0iKQp0LnRvU3RyaW5nCkwudDIoYSx0aGlzLmEsdC5nZXRBdHRyaWJ1dGUoImRhdGEt
-IituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygicGF0aCIpKSl9LAokUzozfQpMLkhvLnByb3RvdHlwZT17
-CiQxOmZ1bmN0aW9uKGEpe3ZhciB0LHMscgp1LmguYShhKQp0PUoucUYoYSkKcz10LiR0aQpyPXMuQygi
-figxKSIpLmEobmV3IEwueHooYSx0aGlzLmEpKQp1Lk0uYShudWxsKQpXLkpFKHQuYSx0LmIsciwhMSxz
-LmMpfSwKJFM6Nn0KTC54ei5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzPW51bGwKdS5W
-LmEoYSkKdD10aGlzLmEKTC5oWCh0aGlzLmIsUC5RQSh0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBX
-LlN5KG5ldyBXLmk3KHQpKS5PKCJvZmZzZXQiKSkscyxzKSxQLlFBKHQuZ2V0QXR0cmlidXRlKCJkYXRh
-LSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oImxpbmUiKSkscyxzKSl9LAokUzozfQpMLklDLnByb3Rv
-dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PUoucUYodS5oLmEoYSkpLHM9dC4kdGkKcy5DKCJ+KDEp
-IikuYShMLmlTKCkpCnUuTS5hKG51bGwpClcuSkUodC5hLHQuYixMLmlTKCksITEscy5jKX0sCiRTOjZ9
-CkwuZkMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5GLmEoYSkKdGhpcy5hLmFNKDAsdGhpcy5i
-KX0sCiRTOjQ1fQpMLm5ULnByb3RvdHlwZT17CiQwOmZ1bmN0aW9uKCl7TC5Gcih0aGlzLmEuYSx0aGlz
-LmIsdGhpcy5jKX0sCiRTOjB9CkwuQloucHJvdG90eXBlPXsKJDA6ZnVuY3Rpb24oKXtMLkZyKHRoaXMu
-YS5hLG51bGwsbnVsbCl9LAokUzowfQpMLkdILnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3UuaC5h
-KGEpCiQuekIoKS50b1N0cmluZwp1Lm0uYSgkLm93KCkucSgwLCJobGpzIikpLlY3KCJoaWdobGlnaHRC
-bG9jayIsW2FdKX0sCiRTOjZ9CkwuRUUucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscwp1
-LlYuYShhKQp0PXRoaXMuYQpzPXRoaXMuYgpMLmFmKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSx0LHMs
-ITAsbmV3IEwuUUwodCxzKSkKTC5oWCh0aGlzLmMsdCxzKX0sCiRTOjN9CkwuUUwucHJvdG90eXBlPXsK
-JDA6ZnVuY3Rpb24oKXtMLkZyKHdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZSx0aGlzLmEsdGhpcy5iKX0s
-CiRTOjB9CkwuVlMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscz0ic2VsZWN0ZWQtZmls
-ZSIKdS5oLmEoYSkKYS50b1N0cmluZwp0PUouUkUoYSkKaWYoYS5nZXRBdHRyaWJ1dGUoImRhdGEtIitu
-ZXcgVy5TeShuZXcgVy5pNyhhKSkuTygibmFtZSIpKT09PXRoaXMuYS5hKXQuZ1AoYSkuaSgwLHMpCmVs
-c2UgdC5nUChhKS5SKDAscyl9LAokUzo2fQpMLlRELnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3Jl
-dHVybiBMLnQyKHUuVi5hKGEpLCEwLG51bGwpfSwKJFM6MTh9CkwuQVMucHJvdG90eXBlPXsKJDE6ZnVu
-Y3Rpb24oYSl7cmV0dXJuIHRoaXMuUEwodS5WLmEoYSkpfSwKUEw6ZnVuY3Rpb24oYSl7dmFyIHQ9MCxz
-PVAuRlgodS5QKSxyPTEscSxwPVtdLG89dGhpcyxuLG0sbCxrLGoKdmFyICRhc3luYyQkMT1QLmx6KGZ1
-bmN0aW9uKGIsYyl7aWYoYj09PTEpe3E9Ywp0PXJ9d2hpbGUodHJ1ZSlzd2l0Y2godCl7Y2FzZSAwOnI9
-MwpsPXUuTgp0PTYKcmV0dXJuIFAualEoTC50eShMLlE0KCIvYXBwbHktaGludCIsUC5GbChsLGwpKSxv
-LmEuTHQoKSksJGFzeW5jJCQxKQpjYXNlIDY6bD1vLmIKTC5HNyhsLmMsbnVsbCxsLmIsITEsbnVsbCkK
-ZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QuYWRkKCJuZWVkcy1yZXJ1biIpCnI9MQp0PTUKYnJlYWsKY2Fz
-ZSAzOnI9MgpqPXEKbj1ILlJ1KGopCm09SC50cyhqKQpMLkMyKCJDb3VsZCBub3QgYXBwbHkgaGludCIs
-bixtKQp0PTUKYnJlYWsKY2FzZSAyOnQ9MQpicmVhawpjYXNlIDU6cmV0dXJuIFAueUMobnVsbCxzKQpj
-YXNlIDE6cmV0dXJuIFAuZjMocSxzKX19KQpyZXR1cm4gUC5ESSgkYXN5bmMkJDEscyl9LAokUzoxMX0K
-TC5YQS5wcm90b3R5cGU9ewpFYjpmdW5jdGlvbihhLGIsYyl7cmV0dXJuITB9LAppMDpmdW5jdGlvbihh
-KXtyZXR1cm4hMH0sCiRpa0Y6MX0KTC5aWi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3ZhciB0LHM9
-dGhpcyxyPVAuRmwodS5OLHUuSykKci5ZKDAsInR5cGUiLEwudnkocy5hKSkKci5ZKDAsIm5hbWUiLHMu
-YikKdD1zLmMKaWYodCE9bnVsbClyLlkoMCwic3VidHJlZSIsTC5WRCh0KSkKdD1zLmQKaWYodCE9bnVs
-bClyLlkoMCwicGF0aCIsdCkKdD1zLmUKaWYodCE9bnVsbClyLlkoMCwiaHJlZiIsdCkKdD1zLmYKaWYo
-dCE9bnVsbClyLlkoMCwiZWRpdENvdW50Iix0KQpyZXR1cm4gcn19CkwuTzkucHJvdG90eXBlPXsKWjpm
-dW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ifX0KTS5sSS5wcm90b3R5cGU9ewpXTzpmdW5jdGlvbihhLGIp
-e3ZhciB0LHM9bnVsbApNLllGKCJhYnNvbHV0ZSIsSC5WTShbYixudWxsLG51bGwsbnVsbCxudWxsLG51
-bGwsbnVsbF0sdS5zKSkKdD10aGlzLmEKdD10LllyKGIpPjAmJiF0LmhLKGIpCmlmKHQpcmV0dXJuIGIK
-dD1ELlJYKCkKcmV0dXJuIHRoaXMucTcoMCx0LGIscyxzLHMscyxzLHMpfSwKemY6ZnVuY3Rpb24oYSl7
-dmFyIHQscyxyPVguQ0woYSx0aGlzLmEpCnIuSVYoKQp0PXIuZApzPXQubGVuZ3RoCmlmKHM9PT0wKXt0
-PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZihzPT09MSl7dD1yLmIKcmV0dXJuIHQ9PW51bGw/Ii4i
-OnR9aWYoMD49cylyZXR1cm4gSC5rKHQsLTEpCnQucG9wKCkKQy5ObS5tdihyLmUpCnIuSVYoKQpyZXR1
-cm4gci5aKDApfSwKcTc6ZnVuY3Rpb24oYSxiLGMsZCxlLGYsZyxoLGkpe3ZhciB0PUguVk0oW2IsYyxk
-LGUsZixnLGgsaV0sdS5zKQpNLllGKCJqb2luIix0KQpyZXR1cm4gdGhpcy5JUChuZXcgSC5VNSh0LHUu
-YkIuYShuZXcgTS5NaSgpKSx1LmNjKSl9LApJUDpmdW5jdGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixt
-LGwsawp1LlguYShhKQpmb3IodD1hLiR0aSxzPXQuQygiYTIoY1guRSkiKS5hKG5ldyBNLnE3KCkpLHI9
-YS5na3ooYSksdD1uZXcgSC52RyhyLHMsdC5DKCJ2RzxjWC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9ITEs
-bz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikmJnApe209WC5DTChuLHMpCmw9by5jaGFyQ29k
-ZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3AobCwhMCkpCm0uYj1vCmlmKHMuZHMobykpQy5O
-bS5ZKG0uZSwwLHMuZ21JKCkpCm89bS5aKDApfWVsc2UgaWYocy5ZcihuKT4wKXtwPSFzLmhLKG4pCm89
-SC5kKG4pfWVsc2V7az1uLmxlbmd0aAppZihrIT09MCl7aWYoMD49aylyZXR1cm4gSC5rKG4sMCkKaz1z
-LlVkKG5bMF0pfWVsc2Ugaz0hMQppZighaylpZihxKW8rPXMuZ21JKCkKbys9bn1xPXMuZHMobil9cmV0
-dXJuIG8uY2hhckNvZGVBdCgwKT09MD9vOm99LApvNTpmdW5jdGlvbihhKXt2YXIgdAppZighdGhpcy55
-MyhhKSlyZXR1cm4gYQp0PVguQ0woYSx0aGlzLmEpCnQuclIoKQpyZXR1cm4gdC5aKDApfSwKeTM6ZnVu
-Y3Rpb24oYSl7dmFyIHQscyxyLHEscCxvLG4sbSxsLGsKYS50b1N0cmluZwp0PXRoaXMuYQpzPXQuWXIo
-YSkKaWYocyE9PTApe2lmKHQ9PT0kLktrKCkpZm9yKHI9MDtyPHM7KytyKWlmKEMueEIuVyhhLHIpPT09
-NDcpcmV0dXJuITAKcT1zCnA9NDd9ZWxzZXtxPTAKcD1udWxsfWZvcihvPW5ldyBILnFqKGEpLmEsbj1v
-Lmxlbmd0aCxyPXEsbT1udWxsO3I8bjsrK3IsbT1wLHA9bCl7bD1DLnhCLm0obyxyKQppZih0LnI0KGwp
-KXtpZih0PT09JC5LaygpJiZsPT09NDcpcmV0dXJuITAKaWYocCE9bnVsbCYmdC5yNChwKSlyZXR1cm4h
-MAppZihwPT09NDYpaz1tPT1udWxsfHxtPT09NDZ8fHQucjQobSkKZWxzZSBrPSExCmlmKGspcmV0dXJu
-ITB9fWlmKHA9PW51bGwpcmV0dXJuITAKaWYodC5yNChwKSlyZXR1cm4hMAppZihwPT09NDYpdD1tPT1u
-dWxsfHx0LnI0KG0pfHxtPT09NDYKZWxzZSB0PSExCmlmKHQpcmV0dXJuITAKcmV0dXJuITF9LApIUDpm
-dW5jdGlvbihhLGIpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcyxsPSdVbmFibGUgdG8gZmluZCBhIHBh
-dGggdG8gIicKYj1tLldPKDAsYikKdD1tLmEKaWYodC5ZcihiKTw9MCYmdC5ZcihhKT4wKXJldHVybiBt
-Lm81KGEpCmlmKHQuWXIoYSk8PTB8fHQuaEsoYSkpYT1tLldPKDAsYSkKaWYodC5ZcihhKTw9MCYmdC5Z
-cihiKT4wKXRocm93IEguYihYLkk3KGwrSC5kKGEpKyciIGZyb20gIicrSC5kKGIpKyciLicpKQpzPVgu
-Q0woYix0KQpzLnJSKCkKcj1YLkNMKGEsdCkKci5yUigpCnE9cy5kCnA9cS5sZW5ndGgKaWYocCE9PTAp
-e2lmKDA+PXApcmV0dXJuIEguayhxLDApCnE9Si5STShxWzBdLCIuIil9ZWxzZSBxPSExCmlmKHEpcmV0
-dXJuIHIuWigwKQpxPXMuYgpwPXIuYgppZihxIT1wKXE9cT09bnVsbHx8cD09bnVsbHx8IXQuTmMocSxw
-KQplbHNlIHE9ITEKaWYocSlyZXR1cm4gci5aKDApCndoaWxlKCEwKXtxPXMuZApwPXEubGVuZ3RoCmlm
-KHAhPT0wKXtvPXIuZApuPW8ubGVuZ3RoCmlmKG4hPT0wKXtpZigwPj1wKXJldHVybiBILmsocSwwKQpx
-PXFbMF0KaWYoMD49bilyZXR1cm4gSC5rKG8sMCkKbz10Lk5jKHEsb1swXSkKcT1vfWVsc2UgcT0hMX1l
-bHNlIHE9ITEKaWYoIXEpYnJlYWsKQy5ObS5XNChzLmQsMCkKQy5ObS5XNChzLmUsMSkKQy5ObS5XNChy
-LmQsMCkKQy5ObS5XNChyLmUsMSl9cT1zLmQKcD1xLmxlbmd0aAppZihwIT09MCl7aWYoMD49cClyZXR1
-cm4gSC5rKHEsMCkKcT1KLlJNKHFbMF0sIi4uIil9ZWxzZSBxPSExCmlmKHEpdGhyb3cgSC5iKFguSTco
-bCtILmQoYSkrJyIgZnJvbSAiJytILmQoYikrJyIuJykpCnE9dS5OCkMuTm0uVUcoci5kLDAsUC5POChz
-LmQubGVuZ3RoLCIuLiIscSkpCkMuTm0uWShyLmUsMCwiIikKQy5ObS5VRyhyLmUsMSxQLk84KHMuZC5s
-ZW5ndGgsdC5nbUkoKSxxKSkKdD1yLmQKcT10Lmxlbmd0aAppZihxPT09MClyZXR1cm4iLiIKaWYocT4x
-JiZKLlJNKEMuTm0uZ3JaKHQpLCIuIikpe3Q9ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILmsodCwt
-MSkKdC5wb3AoKQp0PXIuZQpDLk5tLm12KHQpCkMuTm0ubXYodCkKQy5ObS5pKHQsIiIpfXIuYj0iIgpy
-LklWKCkKcmV0dXJuIHIuWigwKX19Ck0uTWkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEguYyhhKSE9bnVsbH0sCiRTOjd9Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJu
-IEguYyhhKSE9PSIifSwKJFM6N30KTS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILmMoYSkK
-cmV0dXJuIGE9PW51bGw/Im51bGwiOiciJythKyciJ30sCiRTOjV9CkIuZnYucHJvdG90eXBlPXsKeFo6
-ZnVuY3Rpb24oYSl7dmFyIHQscz10aGlzLllyKGEpCmlmKHM+MClyZXR1cm4gSi5sZChhLDAscykKaWYo
-dGhpcy5oSyhhKSl7aWYoMD49YS5sZW5ndGgpcmV0dXJuIEguayhhLDApCnQ9YVswXX1lbHNlIHQ9bnVs
-bApyZXR1cm4gdH0sCk5jOmZ1bmN0aW9uKGEsYil7cmV0dXJuIGE9PWJ9fQpYLldELnByb3RvdHlwZT17
-CklWOmZ1bmN0aW9uKCl7dmFyIHQscyxyPXRoaXMKd2hpbGUoITApe3Q9ci5kCmlmKCEodC5sZW5ndGgh
-PT0wJiZKLlJNKEMuTm0uZ3JaKHQpLCIiKSkpYnJlYWsKdD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJu
-IEguayh0LC0xKQp0LnBvcCgpCkMuTm0ubXYoci5lKX10PXIuZQpzPXQubGVuZ3RoCmlmKHMhPT0wKUMu
-Tm0uWSh0LHMtMSwiIil9LApyUjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHAsbyxuLG09dGhpcyxsPUgu
-Vk0oW10sdS5zKQpmb3IodD1tLmQscz10Lmxlbmd0aCxyPTAscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9
-PT1zfHwoMCxILmxrKSh0KSwrK3Epe3A9dFtxXQpvPUouaWEocCkKaWYoIShvLkROKHAsIi4iKXx8by5E
-TihwLCIiKSkpaWYoby5ETihwLCIuLiIpKXtvPWwubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1vKXJldHVy
-biBILmsobCwtMSkKbC5wb3AoKX1lbHNlICsrcn1lbHNlIEMuTm0uaShsLHApfWlmKG0uYj09bnVsbClD
-Lk5tLlVHKGwsMCxQLk84KHIsIi4uIix1Lk4pKQppZihsLmxlbmd0aD09PTAmJm0uYj09bnVsbClDLk5t
-LmkobCwiLiIpCm49UC5kSChsLmxlbmd0aCxuZXcgWC5xUihtKSwhMCx1Lk4pCnQ9bS5iCnQ9dCE9bnVs
-bCYmbC5sZW5ndGghPT0wJiZtLmEuZHModCk/bS5hLmdtSSgpOiIiCkgudDYobikuYy5hKHQpCmlmKCEh
-bi5maXhlZCRsZW5ndGgpSC52aChQLkw0KCJpbnNlcnQiKSkKbi5zcGxpY2UoMCwwLHQpCm0uc25KKGwp
-Cm0uc1BoKG4pCnQ9bS5iCmlmKHQhPW51bGwmJm0uYT09PSQuS2soKSl7dC50b1N0cmluZwptLmI9SC55
-cyh0LCIvIiwiXFwiKX1tLklWKCl9LApaOmZ1bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9
-cSE9bnVsbD9xOiIiCmZvcih0PTA7dDxyLmQubGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgp
-cmV0dXJuIEguayhzLHQpCnM9cStILmQoc1t0XSkKcT1yLmQKaWYodD49cS5sZW5ndGgpcmV0dXJuIEgu
-ayhxLHQpCnE9cytILmQocVt0XSl9cSs9SC5kKEMuTm0uZ3JaKHIuZSkpCnJldHVybiBxLmNoYXJDb2Rl
-QXQoMCk9PTA/cTpxfSwKc25KOmZ1bmN0aW9uKGEpe3RoaXMuZD11LmEuYShhKX0sCnNQaDpmdW5jdGlv
-bihhKXt0aGlzLmU9dS5hLmEoYSl9fQpYLnFSLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVy
-biB0aGlzLmEuYS5nbUkoKX0sCiRTOjQ3fQpYLmR2LnByb3RvdHlwZT17Clo6ZnVuY3Rpb24oYSl7cmV0
-dXJuIlBhdGhFeGNlcHRpb246ICIrdGhpcy5hfSwKJGlSejoxfQpPLnpMLnByb3RvdHlwZT17Clo6ZnVu
-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
-dGF0aWNUZWFyT2ZmLHA9aHVua0hlbHBlcnMuX2luc3RhbmNlXzF1CnQoUCwiRVgiLCJaViIsOCkKdChQ
-LCJ5dCIsIm9BIiw4KQp0KFAsInFXIiwiQnoiLDgpCnMoUCwiVjkiLCJlTiIsMikKcihQLlBmLnByb3Rv
-dHlwZSwiZ1lKIiwwLDEsbnVsbCxbIiQyIiwiJDEiXSxbIncwIiwicG0iXSwyOCwwKQp0KFAsIkN5Iiwi
-TkMiLDEpCnQoUCwiUEgiLCJNdCIsNSkKcShXLCJwUyIsNCxudWxsLFsiJDQiXSxbInFEIl0sOSwwKQpx
-KFcsIlY0Iiw0LG51bGwsWyIkNCJdLFsiUVciXSw5LDApCnAoUC5Bcy5wcm90b3R5cGUsImd1TSIsIlQi
-LDUpCnQoUCwiaUciLCJ3WSIsMSkKdChQLCJ3MCIsIkw3IiwzMykKdChMLCJpUyIsImk2IiwxOCl9KSgp
-OyhmdW5jdGlvbiBpbmhlcml0YW5jZSgpe3ZhciB0PWh1bmtIZWxwZXJzLm1peGluLHM9aHVua0hlbHBl
-cnMuaW5oZXJpdCxyPWh1bmtIZWxwZXJzLmluaGVyaXRNYW55CnMoUC5NaCxudWxsKQpyKFAuTWgsW0gu
-RkssSi52QixKLm0xLFAublksUC5jWCxILmE3LFAuQW4sSC5TVSxILlJlLEgud3YsUC5QbixILldVLEgu
-TEksSC5UcCxILmY5LFAuWFMsSC5icSxILlhPLFAuWWssSC5kYixILk42LEguVlIsSC5FSyxILlBiLEgu
-dFEsSC5TZCxILkpjLEguRVQsUC5XMyxQLmloLFAuRnksUC5HVixQLmI4LFAuUGYsUC5GZSxQLnZzLFAu
-T00sUC5xaCxQLk1PLFAua1QsUC54SSxQLk9ILFAubTAsUC5YdixQLmJuLFAubG0sUC5sRCxQLktQLFAu
-TWEsUC5UQyxQLlVrLFAuU2gsUC5SdyxQLmJ6LFAuYTIsUC5pUCxQLmxmLFAuazUsUC5LWSxQLkNELFAu
-YUUsUC5FSCxQLnpNLFAuWjAsUC5OMyxQLmM4LFAuT2QsUC5pYixQLkd6LFAuWmQsUC5xVSxQLlJuLFAu
-R0QsUC5EbixQLlBFLFAuVWYsVy5pZCxXLkZrLFcuSlEsVy5HbSxXLnZELFcubTYsVy5PdyxXLlc5LFcu
-ZFcsVy5GYixXLmtGLFcubWssVy5LbyxQLmlKLFAuRTQsUC5uNixNLkg3LFUuTEwsVS5kMixVLlNlLFUu
-TWwsVS55RCxVLndiLEIuajgsQi5xcCxULm1RLEwuWEEsTC5aWixMLk85LE0ubEksTy56TCxYLldELFgu
-ZHZdKQpyKEoudkIsW0oueUUsSi5ZRSxKLk1GLEouamQsSi5xSSxKLkRyLEguZUgsVy5EMCxXLkF6LFcu
-TGUsVy5OaCxXLklCLFcubjcsVy5lYSxXLmJyLFcuU2csVy51OCxXLks3LFcuWFcsUC5oRl0pCnIoSi5N
-RixbSi5pQyxKLmtkLEouYzVdKQpzKEouUG8sSi5qZCkKcihKLnFJLFtKLmJVLEouVkFdKQpzKFAudXks
-UC5uWSkKcihQLnV5LFtILncyLFcud3osVy5lN10pCnMoSC5xaixILncyKQpyKFAuY1gsW0guYlEsSC5p
-MSxILlU1LEguWFIsUC5tVyxILk5GXSkKcihILmJRLFtILmFMLEguaTUsUC54dV0pCnIoSC5hTCxbSC5u
-SCxILmxKLFAuaThdKQpzKEgueHksSC5pMSkKcihQLkFuLFtILk1ILEgudkddKQpzKFAuUlUsUC5QbikK
-cyhQLkdqLFAuUlUpCnMoSC5QRCxQLkdqKQpzKEguTFAsSC5XVSkKcihILlRwLFtILkNqLEguQW0sSC5s
-YyxILnIsSC5kQyxILndOLFAudGgsUC5oYSxQLlZzLFAuRnQsUC55SCxQLldNLFAuU1gsUC5HcyxQLmRh
-LFAub1EsUC5wVixQLlU3LFAudnIsUC5ySCxQLktGLFAuWkwsUC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1
-LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5PUixQLnJhLFAueVEsUC50aSxQLldGLFAubjEsUC5jUyxQLlZD
-LFAuSlQsUC5lMSxQLk5ZLFAuUlosUC5NRSxQLnk1LFAucTMsUC55SSxQLmM2LFAucWQsVy5DdixXLktT
-LFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldrLFcuSUEsVy5mbSxQLmpnLFAuVGEsUC5HRSxQLk43
-LFAudVEsUC5QQyxQLm10LFAuTnosUC5RUyxQLm5wLFUuTUQsVS5hTixVLmIwLEwuZSxMLlZXLEwub1os
-TC5qcixMLnFsLEwueTgsTC5IaSxMLkJULEwuTCxMLld4LEwuQU8sTC5kTixMLkhvLEwueHosTC5JQyxM
-LmZDLEwublQsTC5CWixMLkdILEwuRUUsTC5RTCxMLlZTLEwuVEQsTC5BUyxNLk1pLE0ucTcsTS5ObyxY
-LnFSXSkKcihQLlhTLFtILlcwLEguYXosSC52VixILkVxLFAuQzYsSC51OSxQLlVkLFAuTEssUC5BVCxQ
-Lm1wLFAudWIsUC5kcyxQLmxqLFAuVVYsUC50N10pCnIoSC5sYyxbSC56eCxILmp5XSkKcyhILmtZLFAu
-QzYpCnMoUC5pbCxQLllrKQpyKFAuaWwsW0guTjUsUC51dyxXLmNmLFcuU3ldKQpyKFAubVcsW0guS1cs
-UC5xNF0pCnMoSC5MWixILmVIKQpyKEguTFosW0guUkcsSC5XQl0pCnMoSC5WUCxILlJHKQpzKEguRGcs
-SC5WUCkKcyhILlpHLEguV0IpCnMoSC5QZyxILlpHKQpyKEguUGcsW0gueGosSC5kRSxILlpBLEgud2Ys
-SC5QcSxILmVFLEguVjZdKQpzKEgueCxILnU5KQpzKFAuWmYsUC5QZikKcyhQLkppLFAubTApCnMoUC5i
-NixQLlh2KQpzKFAuVmosUC5UQykKcihQLlVrLFtQLkNWLFAuWmksUC5ieV0pCnMoUC53SSxQLmtUKQpy
-KFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMsUC5HWV0pCnMoUC5LOCxQLlVkKQpzKFAudHUsUC5TaCkK
-cyhQLnU1LFAuWmkpCnIoUC5sZixbUC5DUCxQLklmXSkKcihQLkFULFtQLmJKLFAuZVldKQpzKFAucWUs
-UC5EbikKcihXLkQwLFtXLnVILFcud2EsVy5LNSxXLkNtXSkKcihXLnVILFtXLmN2LFcubngsVy5RRixX
-LkNRXSkKcihXLmN2LFtXLnFFLFAuZDVdKQpyKFcucUUsW1cuR2gsVy5mWSxXLm5CLFcuUVAsVy5oNCxX
-LlNOLFcubHAsVy5UYixXLkl2LFcuV1AsVy55WV0pCnMoVy5vSixXLkxlKQpzKFcuaEgsVy5BeikKcyhX
-LlZiLFcuUUYpCnMoVy5mSixXLndhKQpyKFcuZWEsW1cudzYsVy5ld10pCnMoVy5PSyxXLnc2KQpzKFcu
-ckIsVy5LNykKcyhXLkJILFcuckIpCnMoVy53NCxXLklCKQpzKFcub2EsVy5YVykKcyhXLnJoLFcub2Ep
-CnMoVy5pNyxXLmNmKQpzKFAuQXMsUC5WaikKcihQLkFzLFtXLkk0LFAuS2VdKQpzKFcuUk8sUC5xaCkK
-cyhXLmV1LFcuUk8pCnMoVy54QyxQLk1PKQpzKFcuY3QsVy5tNikKcyhQLkJmLFAuaUopCnIoUC5FNCxb
-UC5yNyxQLmNvXSkKcyhQLlR6LFAuY28pCnMoUC5uZCxQLmQ1KQpzKEIuZnYsTy56TCkKcihCLmZ2LFtF
-Lk9GLEYucnUsTC5JVl0pCnQoSC53MixILlJlKQp0KEguUkcsUC5sRCkKdChILlZQLEguU1UpCnQoSC5X
-QixQLmxEKQp0KEguWkcsSC5TVSkKdChQLm5ZLFAubEQpCnQoUC5UQyxQLk1hKQp0KFAuUlUsUC5LUCkK
-dChXLkxlLFcuaWQpCnQoVy5LNyxQLmxEKQp0KFcuckIsVy5HbSkKdChXLlhXLFAubEQpCnQoVy5vYSxX
-LkdtKQp0KFAuY28sUC5sRCl9KSgpCnZhciB2PXt0eXBlVW5pdmVyc2U6e2VDOm5ldyBNYXAoKSx0Ujp7
-fSxlVDp7fSx0UFY6e30sc0VBOltdfSxtYW5nbGVkR2xvYmFsTmFtZXM6e0lmOiJpbnQiLENQOiJkb3Vi
-bGUiLGxmOiJudW0iLHFVOiJTdHJpbmciLGEyOiJib29sIixjODoiTnVsbCIsek06Ikxpc3QifSxtYW5n
-bGVkTmFtZXM6e30sZ2V0VHlwZUZyb21OYW1lOmdldEdsb2JhbEZyb21OYW1lLG1ldGFkYXRhOltdLHR5
-cGVzOlsiYzgoKSIsIkAoQCkiLCJ+KCkiLCJjOChPSykiLCJjOChALEApIiwicVUocVUpIiwiYzgoY3Yp
-IiwiYTIocVUpIiwifih+KCkpIiwiYTIoY3YscVUscVUsSlEpIiwiYzgoQCkiLCJiODxjOD4oT0spIiwi
-YzgocVUsQCkiLCJjOChxVSkiLCJjOChxVSxxVSkiLCJhMihrRikiLCJ+KHh1PHFVPikiLCJjOChlYSki
-LCJ+KE9LKSIsIn4ocVUsSWYpIiwiYzgofigpKSIsImM4KEAsR3opIiwifihxVSxxVSkiLCJuNihJZiki
-LCJuNihALEApIiwiYTIodUgpIiwiYzgoSWYsQCkiLCJAKGVhKSIsIn4oTWhbR3pdKSIsImM4KEBbR3pd
-KSIsIn4odUgsdUgpIiwiYTIoeHU8cVU+KSIsInZzPEA+KEApIiwiTWgoQCkiLCJUejxAPihAKSIsIkU0
-KEApIiwiYTIoSDcpIiwiTEwoQCkiLCJaMDxxVSxNaD4oTEwpIiwiQChxVSkiLCJjOChHRCxAKSIsImM4
-KFowPHFVLE1oPikiLCJyNyhAKSIsInFVKE9LKSIsIlowPHFVLHFVPihaMDxxVSxxVT4scVUpIiwiYzgo
-ZXcpIiwiQChALHFVKSIsInFVKElmKSIsIn4ocVVbQF0pIiwiSWYoSWYsSWYpIiwifihAKSJdLGludGVy
-Y2VwdG9yc0J5VGFnOm51bGwsbGVhZlRhZ3M6bnVsbCxhcnJheVJ0aTp0eXBlb2YgU3ltYm9sPT0iZnVu
-Y3Rpb24iJiZ0eXBlb2YgU3ltYm9sKCk9PSJzeW1ib2wiP1N5bWJvbCgiJHRpIik6IiR0aSJ9CkgueGIo
-di50eXBlVW5pdmVyc2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJy
-eCI6ImVhIiwiZTUiOiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwiRzgiOiJldyIsIk1yIjoicUUiLCJl
-TCI6InFFIiwiSTAiOiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJPSyIsInk0IjoidzYiLCJh
-UCI6IkNtIiwieGMiOiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJlSCIsInlFIjp7ImEyIjpb
-XX0sIllFIjp7ImM4IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJi
-USI6WyIxIl0sImNYIjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0s
-ImNYIjpbIjEiXX0sIm0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwibGYiOltdfSwiYlUiOnsi
-SWYiOltdLCJDUCI6W10sImxmIjpbXX0sIlZBIjp7IkNQIjpbXSwibGYiOltdfSwiRHIiOnsicVUiOltd
-LCJ2WCI6W119LCJxaiI6eyJSZSI6WyJJZiJdLCJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJiUSI6WyJJ
-ZiJdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYiLCJSZS5FIjoiSWYifSwiYlEiOnsiY1giOlsiMSJdfSwi
-YUwiOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1gi
-OlsiMSJdLCJhTC5FIjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpb
-IjIiXSwiY1guRSI6IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0s
-ImNYLkUiOiIyIn0sIk1IIjp7IkFuIjpbIjIiXX0sImxKIjp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJj
-WCI6WyIyIl0sImFMLkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9
-LCJ2RyI6eyJBbiI6WyIxIl19LCJ3MiI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJi
-USI6WyIxIl0sImNYIjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJV
-IjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJX
-VSI6eyJaMCI6WyIxIiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhS
-Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoi
-OnsiWFMiOltdfSwidlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwibGMi
-OnsiRUgiOltdfSwiengiOnsiRUgiOltdfSwiankiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwia1ki
-OnsiWFMiOltdfSwiTjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIi
-XSwiWWsuSyI6IjEiLCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1guRSI6
-IjEifSwiTjYiOnsiQW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6W10s
-Ik9kIjpbXX0sIktXIjp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJdfSwi
-dFEiOnsiT2QiOltdfSwiTkYiOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpbIk9k
-Il19LCJlSCI6eyJlcSI6W119LCJMWiI6eyJYaiI6WyJAIl0sImVIIjpbXSwiZXEiOltdfSwiRGciOnsi
-bEQiOlsiQ1AiXSwiWGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJlSCI6W10sImJRIjpbIkNQIl0sIlNVIjpb
-IkNQIl0sImVxIjpbXSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIklmIl0sInpN
-IjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10s
-ImNYIjpbIklmIl19LCJ4aiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJdLCJYaiI6WyJAIl0sImVIIjpb
-XSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJZiJdLCJsRC5FIjoiSWYifSwi
-ZEUiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJlSCI6W10sImJRIjpbIklmIl0s
-IlNVIjpbIklmIl0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6IklmIn0sIlpBIjp7ImxEIjpbIklm
-Il0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJTVSI6WyJJZiJdLCJl
-cSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ3ZiI6eyJsRCI6WyJJZiJdLCJ6TSI6WyJJZiJd
-LCJYaiI6WyJAIl0sImVIIjpbXSwiYlEiOlsiSWYiXSwiU1UiOlsiSWYiXSwiZXEiOltdLCJjWCI6WyJJ
-ZiJdLCJsRC5FIjoiSWYifSwiUHEiOnsibEQiOlsiSWYiXSwiek0iOlsiSWYiXSwiWGoiOlsiQCJdLCJl
-SCI6W10sImJRIjpbIklmIl0sIlNVIjpbIklmIl0sImVxIjpbXSwiY1giOlsiSWYiXSwibEQuRSI6Iklm
-In0sImVFIjp7ImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJ
-ZiJdLCJTVSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJWNiI6eyJuNiI6
-W10sImxEIjpbIklmIl0sInpNIjpbIklmIl0sIlhqIjpbIkAiXSwiZUgiOltdLCJiUSI6WyJJZiJdLCJT
-VSI6WyJJZiJdLCJlcSI6W10sImNYIjpbIklmIl0sImxELkUiOiJJZiJ9LCJ1OSI6eyJYUyI6W119LCJ4
-Ijp7IlhTIjpbXX0sIkdWIjp7IkFuIjpbIjEiXX0sInE0Ijp7ImNYIjpbIjEiXSwiY1guRSI6IjEifSwi
-WmYiOnsiUGYiOlsiMSJdfSwidnMiOnsiYjgiOlsiMSJdfSwiT0giOnsiWFMiOltdfSwibTAiOnsiSkIi
-OltdfSwiSmkiOnsiSkIiOltdfSwiYjYiOnsiWHYiOlsiMSJdLCJ4dSI6WyIxIl0sImJRIjpbIjEiXSwi
-Y1giOlsiMSJdfSwibG0iOnsiQW4iOlsiMSJdfSwibVciOnsiY1giOlsiMSJdfSwidXkiOnsibEQiOlsi
-MSJdLCJ6TSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwiaWwiOnsiWWsiOlsiMSIsIjIiXSwi
-WjAiOlsiMSIsIjIiXX0sIllrIjp7IlowIjpbIjEiLCIyIl19LCJQbiI6eyJaMCI6WyIxIiwiMiJdfSwi
-R2oiOnsiUlUiOlsiMSIsIjIiXSwiUG4iOlsiMSIsIjIiXSwiS1AiOlsiMSIsIjIiXSwiWjAiOlsiMSIs
-IjIiXX0sIlZqIjp7Ik1hIjpbIjEiXSwieHUiOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlh2
-Ijp7Inh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJ1dyI6eyJZayI6WyJxVSIsIkAiXSwi
-WjAiOlsicVUiLCJAIl0sIllrLksiOiJxVSIsIllrLlYiOiJAIn0sImk4Ijp7ImFMIjpbInFVIl0sImJR
-IjpbInFVIl0sImNYIjpbInFVIl0sImFMLkUiOiJxVSIsImNYLkUiOiJxVSJ9LCJDViI6eyJVayI6WyJ6
-TTxJZj4iLCJxVSJdLCJVay5TIjoiek08SWY+In0sIlU4Ijp7IndJIjpbInpNPElmPiIsInFVIl19LCJa
-aSI6eyJVayI6WyJxVSIsInpNPElmPiJdfSwiVWQiOnsiWFMiOltdfSwiSzgiOnsiWFMiOltdfSwiYnki
-OnsiVWsiOlsiTWgiLCJxVSJdLCJVay5TIjoiTWgifSwib2oiOnsid0kiOlsiTWgiLCJxVSJdfSwiTXgi
-Onsid0kiOlsicVUiLCJNaCJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxJZj4iXSwiVWsuUyI6InFVIn0s
-IkUzIjp7IndJIjpbInFVIiwiek08SWY+Il19LCJHWSI6eyJ3SSI6WyJ6TTxJZj4iLCJxVSJdfSwiQ1Ai
-OnsibGYiOltdfSwiQzYiOnsiWFMiOltdfSwiTEsiOnsiWFMiOltdfSwiQVQiOnsiWFMiOltdfSwiYkoi
-OnsiWFMiOltdfSwiZVkiOnsiWFMiOltdfSwibXAiOnsiWFMiOltdfSwidWIiOnsiWFMiOltdfSwiZHMi
-OnsiWFMiOltdfSwibGoiOnsiWFMiOltdfSwiVVYiOnsiWFMiOltdfSwiazUiOnsiWFMiOltdfSwiS1ki
-OnsiWFMiOltdfSwidDciOnsiWFMiOltdfSwiQ0QiOnsiUnoiOltdfSwiYUUiOnsiUnoiOltdfSwiSWYi
-OnsibGYiOltdfSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6
-eyJiUSI6WyIxIl0sImNYIjpbIjEiXX0sIlpkIjp7Ikd6IjpbXX0sInFVIjp7InZYIjpbXX0sIlJuIjp7
-IkJMIjpbXX0sIkRuIjp7ImlEIjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7ImlEIjpbXX0sInFFIjp7
-ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZlki
-OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJR
-UCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwibngiOnsidUgiOltdLCJEMCI6W119LCJRRiI6eyJ1
-SCI6W10sIkQwIjpbXX0sIklCIjp7InRuIjpbImxmIl19LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEi
-XSwiYlEiOlsiMSJdLCJjWCI6WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwi
-aEgiOnsiQXoiOltdfSwiaDQiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlZiIjp7InVIIjpbXSwi
-RDAiOltdfSwiZkoiOnsiRDAiOltdfSwid2EiOnsiRDAiOltdfSwiT0siOnsiZWEiOltdfSwiZTciOnsi
-bEQiOlsidUgiXSwiek0iOlsidUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIn0s
-InVIIjp7IkQwIjpbXX0sIkJIIjp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhq
-IjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJT
-TiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwibHAiOnsiY3YiOltdLCJ1
-SCI6W10sIkQwIjpbXX0sIlRiIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJJdiI6eyJjdiI6W10s
-InVIIjpbXSwiRDAiOltdfSwiV1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInlZIjp7ImN2Ijpb
-XSwidUgiOltdLCJEMCI6W119LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6W10sIkQwIjpbXX0sIkNt
-Ijp7IkQwIjpbXX0sIkNRIjp7InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4iOlsibGYiXX0sInJoIjp7
-IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0s
-ImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJjZiI6eyJZayI6WyJxVSIsInFVIl0s
-IlowIjpbInFVIiwicVUiXX0sImk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZ
-ay5LIjoicVUiLCJZay5WIjoicVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFV
-Il0sIllrLksiOiJxVSIsIllrLlYiOiJxVSJ9LCJJNCI6eyJNYSI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJi
-USI6WyJxVSJdLCJjWCI6WyJxVSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUiOnsiUk8iOlsiMSJdLCJx
-aCI6WyIxIl19LCJ4QyI6eyJNTyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJt
-NiI6eyJrRiI6W119LCJjdCI6eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19
-LCJkVyI6eyJ2NiI6W10sIkQwIjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7Im9uIjpbXX0sIkFzIjp7
-Ik1hIjpbInFVIl0sInh1IjpbInFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6
-W119LCJUeiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJFNCI6W10sImNYIjpbIjEi
-XSwibEQuRSI6IjEifSwibmQiOnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiS2UiOnsi
-TWEiOlsicVUiXSwieHUiOlsicVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1Ijp7ImN2Ijpb
-XSwidUgiOltdLCJEMCI6W119LCJuNiI6eyJ6TSI6WyJJZiJdLCJiUSI6WyJJZiJdLCJlcSI6W10sImNY
-IjpbIklmIl19LCJYQSI6eyJrRiI6W119LCJkdiI6eyJSeiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6
-eyJmdiI6W119LCJJViI6eyJmdiI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2Uo
-J3siYlEiOjEsIncyIjoxLCJNTyI6MSwia1QiOjIsIm1XIjoxLCJ1eSI6MSwiaWwiOjIsIlZqIjoxLCJu
-WSI6MSwiVEMiOjEsImNvIjoxfScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0
-dXJue2JxOnQoIkdoIiksbjp0KCJPSCIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLFk6dCgiUVAiKSxnRjp0
-KCJQRDxHRCxAPiIpLGd3OnQoImJRPEA+IiksaDp0KCJjdiIpLFc6dCgiWFMiKSxCOnQoImVhIikscjp0
-KCJEMCIpLGc4OnQoIlJ6IiksYzg6dCgiaEgiKSxaOnQoIkVIIiksYVE6dCgiYjg8Yzg+IiksYzp0KCJi
-ODxAPiIpLEU6dCgiTEwiKSxncDp0KCJINyIpLEk6dCgiU2ciKSxvOnQoInZRIiksZWg6dCgiY1g8dUg+
-IiksWDp0KCJjWDxxVT4iKSxSOnQoImNYPEA+IiksZkE6dCgiamQ8U2U+IiksZ2k6dCgiamQ8ajg+Iiks
-Sjp0KCJqZDxaMDxxVSxNaD4+IiksZmg6dCgiamQ8Wlo+IiksaTp0KCJqZDxrRj4iKSxzOnQoImpkPHFV
-PiIpLGhoOnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIpLGI6dCgiamQ8QD4iKSx0OnQoImpkPElmPiIp
-LGVIOnQoInZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxH
-RCxAPiIpLG06dCgiRTQiKSxkejp0KCJoRiIpLGY0OnQoInpNPGo4PiIpLGQzOnQoInpNPFowPHFVLE1o
-Pj4iKSxldzp0KCJ6TTxNaD4iKSxhOnQoInpNPHFVPiIpLGo6dCgiek08QD4iKSxMOnQoInpNPElmPiIp
-LGFfOnQoInU4IiksUzp0KCJaMDxxVSxNaD4iKSxmOnQoIlowPHFVLHFVPiIpLGs6dCgiWjA8cVUsQD4i
-KSxHOnQoIlowPEAsQD4iKSxkdjp0KCJsSjxxVSxxVT4iKSxkbzp0KCJsSjxxVSxAPiIpLFY6dCgiT0si
-KSxkRDp0KCJlSCIpLGJtOnQoIlY2IiksQTp0KCJ1SCIpLGU6dCgia0YiKSxQOnQoImM4IiksSzp0KCJN
-aCIpLEY6dCgiZXciKSxxOnQoInRuPGxmPiIpLGZ2OnQoIndMIiksYXY6dCgiSmMiKSxhTzp0KCJuZCIp
-LEM6dCgieHU8cVU+IiksbDp0KCJHeiIpLE46dCgicVUiKSxkRzp0KCJxVShxVSkiKSxnNzp0KCJkNSIp
-LGZvOnQoIkdEIiksYVc6dCgieVkiKSx1OnQoImVxIiksZ2M6dCgibjYiKSxhazp0KCJrZCIpLHY6dCgi
-R2o8cVUscVU+Iiksdzp0KCJpRCIpLGNjOnQoIlU1PHFVPiIpLGc0OnQoIks1IiksY2k6dCgidjYiKSxn
-Mjp0KCJDbSIpLGJqOnQoIlpmPGZKPiIpLGg5OnQoIkNRIiksYWM6dCgiZTciKSxROnQoImV1PE9LPiIp
-LFQ6dCgid3o8Y3Y+IikseDp0KCJGZTxALEA+IiksYW86dCgidnM8Zko+IiksXzp0KCJ2czxAPiIpLGZK
-OnQoInZzPElmPiIpLE86dCgiSlEiKSxEOnQoImJuIikseTp0KCJhMiIpLGFsOnQoImEyKE1oKSIpLGJC
-OnQoImEyKHFVKSIpLGJmOnQoImEyKEApIiksZ1I6dCgiQ1AiKSx6OnQoIkAiKSxmTzp0KCJAKCkiKSxV
-OnQoIkAoZWEpIiksYkk6dCgiQChNaCkiKSxlcDp0KCJAKE1oLE1oKSIpLGFnOnQoIkAoTWgsR3opIiks
-YlU6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiYzp0KCJAKEApIiksYjg6dCgiQChALEApIiks
-cDp0KCJJZiIpLGRpOnQoImxmIiksSDp0KCJ+IiksTTp0KCJ+KCkiKSxhbjp0KCJ+KGV3KSIpLGVBOnQo
-In4ocVUscVUpIiksY0E6dCgifihxVSxAKSIpfX0pKCk7KGZ1bmN0aW9uIGNvbnN0YW50cygpe3ZhciB0
-PWh1bmtIZWxwZXJzLm1ha2VDb25zdExpc3QKQy5SWT1XLlFQLnByb3RvdHlwZQpDLkJaPVcuVmIucHJv
-dG90eXBlCkMuRHQ9Vy5mSi5wcm90b3R5cGUKQy5Paz1KLnZCLnByb3RvdHlwZQpDLk5tPUouamQucHJv
-dG90eXBlCkMuam49Si5iVS5wcm90b3R5cGUKQy5DRD1KLnFJLnByb3RvdHlwZQpDLnhCPUouRHIucHJv
-dG90eXBlCkMuREc9Si5jNS5wcm90b3R5cGUKQy5FeD1XLnU4LnByb3RvdHlwZQpDLkx0PVcuU04ucHJv
-dG90eXBlCkMuWlE9Si5pQy5wcm90b3R5cGUKQy5JZT1XLlRiLnByb3RvdHlwZQpDLnZCPUoua2QucHJv
-dG90eXBlCkMub2w9Vy5LNS5wcm90b3R5cGUKQy55OD1uZXcgUC5VOCgpCkMuaDk9bmV3IFAuQ1YoKQpD
-LndiPWZ1bmN0aW9uIGdldFRhZ0ZhbGxiYWNrKG8pIHsKICB2YXIgcyA9IE9iamVjdC5wcm90b3R5cGUu
-dG9TdHJpbmcuY2FsbChvKTsKICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKfQpD
-Lk80PWZ1bmN0aW9uKCkgewogIHZhciB0b1N0cmluZ0Z1bmN0aW9uID0gT2JqZWN0LnByb3RvdHlwZS50
-b1N0cmluZzsKICBmdW5jdGlvbiBnZXRUYWcobykgewogICAgdmFyIHMgPSB0b1N0cmluZ0Z1bmN0aW9u
-LmNhbGwobyk7CiAgICByZXR1cm4gcy5zdWJzdHJpbmcoOCwgcy5sZW5ndGggLSAxKTsKICB9CiAgZnVu
-Y3Rpb24gZ2V0VW5rbm93blRhZyhvYmplY3QsIHRhZykgewogICAgaWYgKC9eSFRNTFtBLVpdLipFbGVt
-ZW50JC8udGVzdCh0YWcpKSB7CiAgICAgIHZhciBuYW1lID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxsKG9i
-amVjdCk7CiAgICAgIGlmIChuYW1lID09ICJbb2JqZWN0IE9iamVjdF0iKSByZXR1cm4gbnVsbDsKICAg
-ICAgcmV0dXJuICJIVE1MRWxlbWVudCI7CiAgICB9CiAgfQogIGZ1bmN0aW9uIGdldFVua25vd25UYWdH
-ZW5lcmljQnJvd3NlcihvYmplY3QsIHRhZykgewogICAgaWYgKHNlbGYuSFRNTEVsZW1lbnQgJiYgb2Jq
-ZWN0IGluc3RhbmNlb2YgSFRNTEVsZW1lbnQpIHJldHVybiAiSFRNTEVsZW1lbnQiOwogICAgcmV0dXJu
-IGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpOwogIH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWco
-dGFnKSB7CiAgICBpZiAodHlwZW9mIHdpbmRvdyA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAg
-ICBpZiAodHlwZW9mIHdpbmRvd1t0YWddID09ICJ1bmRlZmluZWQiKSByZXR1cm4gbnVsbDsKICAgIHZh
-ciBjb25zdHJ1Y3RvciA9IHdpbmRvd1t0YWddOwogICAgaWYgKHR5cGVvZiBjb25zdHJ1Y3RvciAhPSAi
-ZnVuY3Rpb24iKSByZXR1cm4gbnVsbDsKICAgIHJldHVybiBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAg
-fQogIGZ1bmN0aW9uIGRpc2NyaW1pbmF0b3IodGFnKSB7IHJldHVybiBudWxsOyB9CiAgdmFyIGlzQnJv
-d3NlciA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0gIm9iamVjdCI7CiAgcmV0dXJuIHsKICAgIGdldFRhZzog
-Z2V0VGFnLAogICAgZ2V0VW5rbm93blRhZzogaXNCcm93c2VyID8gZ2V0VW5rbm93blRhZ0dlbmVyaWNC
-cm93c2VyIDogZ2V0VW5rbm93blRhZywKICAgIHByb3RvdHlwZUZvclRhZzogcHJvdG90eXBlRm9yVGFn
-LAogICAgZGlzY3JpbWluYXRvcjogZGlzY3JpbWluYXRvciB9Owp9CkMuZGs9ZnVuY3Rpb24oZ2V0VGFn
-RmFsbGJhY2spIHsKICByZXR1cm4gZnVuY3Rpb24oaG9va3MpIHsKICAgIGlmICh0eXBlb2YgbmF2aWdh
-dG9yICE9ICJvYmplY3QiKSByZXR1cm4gaG9va3M7CiAgICB2YXIgdWEgPSBuYXZpZ2F0b3IudXNlckFn
-ZW50OwogICAgaWYgKHVhLmluZGV4T2YoIkR1bXBSZW5kZXJUcmVlIikgPj0gMCkgcmV0dXJuIGhvb2tz
-OwogICAgaWYgKHVhLmluZGV4T2YoIkNocm9tZSIpID49IDApIHsKICAgICAgZnVuY3Rpb24gY29uZmly
-bShwKSB7CiAgICAgICAgcmV0dXJuIHR5cGVvZiB3aW5kb3cgPT0gIm9iamVjdCIgJiYgd2luZG93W3Bd
-ICYmIHdpbmRvd1twXS5uYW1lID09IHA7CiAgICAgIH0KICAgICAgaWYgKGNvbmZpcm0oIldpbmRvdyIp
-ICYmIGNvbmZpcm0oIkhUTUxFbGVtZW50IikpIHJldHVybiBob29rczsKICAgIH0KICAgIGhvb2tzLmdl
-dFRhZyA9IGdldFRhZ0ZhbGxiYWNrOwogIH07Cn0KQy5ZcT1mdW5jdGlvbihob29rcykgewogIGlmICh0
-eXBlb2YgZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnICE9ICJmdW5jdGlvbiIpIHJldHVybiBob29r
-czsKICBob29rcy5nZXRUYWcgPSBkYXJ0RXhwZXJpbWVudGFsRml4dXBHZXRUYWcoaG9va3MuZ2V0VGFn
-KTsKfQpDLktVPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIGdldFRhZyA9IGhvb2tzLmdldFRhZzsKICB2
-YXIgcHJvdG90eXBlRm9yVGFnID0gaG9va3MucHJvdG90eXBlRm9yVGFnOwogIGZ1bmN0aW9uIGdldFRh
-Z0ZpeGVkKG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICBpZiAodGFnID09ICJEb2N1bWVu
-dCIpIHsKICAgICAgaWYgKCEhby54bWxWZXJzaW9uKSByZXR1cm4gIiFEb2N1bWVudCI7CiAgICAgIHJl
-dHVybiAiIUhUTUxEb2N1bWVudCI7CiAgICB9CiAgICByZXR1cm4gdGFnOwogIH0KICBmdW5jdGlvbiBw
-cm90b3R5cGVGb3JUYWdGaXhlZCh0YWcpIHsKICAgIGlmICh0YWcgPT0gIkRvY3VtZW50IikgcmV0dXJu
-IG51bGw7CiAgICByZXR1cm4gcHJvdG90eXBlRm9yVGFnKHRhZyk7CiAgfQogIGhvb2tzLmdldFRhZyA9
-IGdldFRhZ0ZpeGVkOwogIGhvb2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0ZpeGVk
-Owp9CkMueGk9ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRv
-ciA9PSAib2JqZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50Lmlu
-ZGV4T2YoIkZpcmVmb3giKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5n
-ZXRUYWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwK
-ICAgICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJHZW9HZW9sb2NhdGlvbiI6ICJHZW9s
-b2NhdGlvbiIsCiAgICAiTG9jYXRpb24iOiAiIUxvY2F0aW9uIiwKICAgICJXb3JrZXJNZXNzYWdlRXZl
-bnQiOiAiTWVzc2FnZUV2ZW50IiwKICAgICJYTUxEb2N1bWVudCI6ICIhRG9jdW1lbnQifTsKICBmdW5j
-dGlvbiBnZXRUYWdGaXJlZm94KG8pIHsKICAgIHZhciB0YWcgPSBnZXRUYWcobyk7CiAgICByZXR1cm4g
-cXVpY2tNYXBbdGFnXSB8fCB0YWc7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0ZpcmVmb3g7Cn0K
-Qy5pNz1mdW5jdGlvbihob29rcykgewogIHZhciB1c2VyQWdlbnQgPSB0eXBlb2YgbmF2aWdhdG9yID09
-ICJvYmplY3QiID8gbmF2aWdhdG9yLnVzZXJBZ2VudCA6ICIiOwogIGlmICh1c2VyQWdlbnQuaW5kZXhP
-ZigiVHJpZGVudC8iKSA9PSAtMSkgcmV0dXJuIGhvb2tzOwogIHZhciBnZXRUYWcgPSBob29rcy5nZXRU
-YWc7CiAgdmFyIHF1aWNrTWFwID0gewogICAgIkJlZm9yZVVubG9hZEV2ZW50IjogIkV2ZW50IiwKICAg
-ICJEYXRhVHJhbnNmZXIiOiAiQ2xpcGJvYXJkIiwKICAgICJIVE1MRERFbGVtZW50IjogIkhUTUxFbGVt
-ZW50IiwKICAgICJIVE1MRFRFbGVtZW50IjogIkhUTUxFbGVtZW50IiwKICAgICJIVE1MUGhyYXNlRWxl
-bWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiUG9zaXRpb24iOiAiR2VvcG9zaXRpb24iCiAgfTsKICBm
-dW5jdGlvbiBnZXRUYWdJRShvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgdmFyIG5ld1Rh
-ZyA9IHF1aWNrTWFwW3RhZ107CiAgICBpZiAobmV3VGFnKSByZXR1cm4gbmV3VGFnOwogICAgaWYgKHRh
-ZyA9PSAiT2JqZWN0IikgewogICAgICBpZiAod2luZG93LkRhdGFWaWV3ICYmIChvIGluc3RhbmNlb2Yg
-d2luZG93LkRhdGFWaWV3KSkgcmV0dXJuICJEYXRhVmlldyI7CiAgICB9CiAgICByZXR1cm4gdGFnOwog
-IH0KICBmdW5jdGlvbiBwcm90b3R5cGVGb3JUYWdJRSh0YWcpIHsKICAgIHZhciBjb25zdHJ1Y3RvciA9
-IHdpbmRvd1t0YWddOwogICAgaWYgKGNvbnN0cnVjdG9yID09IG51bGwpIHJldHVybiBudWxsOwogICAg
-cmV0dXJuIGNvbnN0cnVjdG9yLnByb3RvdHlwZTsKICB9CiAgaG9va3MuZ2V0VGFnID0gZ2V0VGFnSUU7
-CiAgaG9va3MucHJvdG90eXBlRm9yVGFnID0gcHJvdG90eXBlRm9yVGFnSUU7Cn0KQy5mUT1mdW5jdGlv
-bihob29rcykgeyByZXR1cm4gaG9va3M7IH0KCkMuQ3Q9bmV3IFAuYnkoKQpDLkVxPW5ldyBQLms1KCkK
-Qy54TT1uZXcgUC51NSgpCkMuUWs9bmV3IFAuRTMoKQpDLk5VPW5ldyBQLkppKCkKQy5wZD1uZXcgUC5a
-ZCgpCkMuQWQ9bmV3IE0uSDcoMCwiSGludEFjdGlvbktpbmQuYWRkTnVsbGFibGVIaW50IikKQy5uZT1u
-ZXcgTS5INygxLCJIaW50QWN0aW9uS2luZC5hZGROb25OdWxsYWJsZUhpbnQiKQpDLm15PW5ldyBNLkg3
-KDIsIkhpbnRBY3Rpb25LaW5kLmNoYW5nZVRvTnVsbGFibGVIaW50IikKQy5yeD1uZXcgTS5INygzLCJI
-aW50QWN0aW9uS2luZC5jaGFuZ2VUb05vbk51bGxhYmxlSGludCIpCkMud1Y9bmV3IE0uSDcoNCwiSGlu
-dEFjdGlvbktpbmQucmVtb3ZlTnVsbGFibGVIaW50IikKQy5mUj1uZXcgTS5INyg1LCJIaW50QWN0aW9u
-S2luZC5yZW1vdmVOb25OdWxsYWJsZUhpbnQiKQpDLkEzPW5ldyBQLk14KG51bGwpCkMublg9bmV3IFAu
-b2oobnVsbCkKQy5HYj1ILlZNKHQoWzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5W
-TSh0KFswLDAsMzI3NzYsMzM3OTIsMSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xh
-c3MiLCIqOjpkaXIiLCIqOjpkcmFnZ2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0Iiwi
-Kjo6aXRlbXByb3AiLCIqOjppdGVtcmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxs
-Y2hlY2siLCIqOjp0aXRsZSIsIio6OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIs
-IkE6OmhyZWZsYW5nIiwiQTo6bmFtZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQi
-LCJBOjp0eXBlIiwiQVJFQTo6YWNjZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJF
-QTo6bm9ocmVmIiwiQVJFQTo6c2hhcGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFV
-RElPOjpjb250cm9scyIsIkFVRElPOjpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0
-ZWQiLCJBVURJTzo6cHJlbG9hZCIsIkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9y
-IiwiQk9EWTo6bGluayIsIkJPRFk6OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRP
-Tjo6YWNjZXNza2V5IiwiQlVUVE9OOjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFi
-aW5kZXgiLCJCVVRUT046OnR5cGUiLCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5W
-QVM6OndpZHRoIiwiQ0FQVElPTjo6YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpj
-aGFyb2ZmIiwiQ09MOjpzcGFuIiwiQ09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFs
-aWduIiwiQ09MR1JPVVA6OmNoYXIiLCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwi
-Q09MR1JPVVA6OnZhbGlnbiIsIkNPTEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01N
-QU5EOjpjb21tYW5kIiwiQ09NTUFORDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6
-OnJhZGlvZ3JvdXAiLCJDT01NQU5EOjp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwi
-REVUQUlMUzo6b3BlbiIsIkRJUjo6Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJ
-RUxEU0VUOjpkaXNhYmxlZCIsIkZPTlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJG
-T1JNOjphY2NlcHQiLCJGT1JNOjphdXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0
-aG9kIiwiRk9STTo6bmFtZSIsIkZPUk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6
-bmFtZSIsIkgxOjphbGlnbiIsIkgyOjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1Ojph
-bGlnbiIsIkg2OjphbGlnbiIsIkhSOjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6
-d2lkdGgiLCJIVE1MOjp2ZXJzaW9uIiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIi
-LCJJRlJBTUU6OmhlaWdodCIsIklGUkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0
-aCIsIklGUkFNRTo6d2lkdGgiLCJJTUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklN
-Rzo6aGVpZ2h0IiwiSU1HOjpoc3BhY2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2Vt
-YXAiLCJJTUc6OnZzcGFjZSIsIklNRzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vz
-c2tleSIsIklOUFVUOjphbGlnbiIsIklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5Q
-VVQ6OmF1dG9mb2N1cyIsIklOUFVUOjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6Omlu
-cHV0bW9kZSIsIklOUFVUOjppc21hcCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjpt
-YXhsZW5ndGgiLCJJTlBVVDo6bWluIiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBV
-VDo6cGxhY2Vob2xkZXIiLCJJTlBVVDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6
-c2l6ZSIsIklOUFVUOjpzdGVwIiwiSU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6
-dXNlbWFwIiwiSU5QVVQ6OnZhbHVlIiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJL
-RVlHRU46OmtleXR5cGUiLCJLRVlHRU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZv
-ciIsIkxFR0VORDo6YWNjZXNza2V5IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVl
-IiwiTElOSzo6c2l6ZXMiLCJNQVA6Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJN
-RU5VOjp0eXBlIiwiTUVURVI6OmhpZ2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjpt
-aW4iLCJNRVRFUjo6dmFsdWUiLCJPQkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9M
-OjpyZXZlcnNlZCIsIk9MOjpzdGFydCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BU
-R1JPVVA6OmxhYmVsIiwiT1BUSU9OOjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNl
-bGVjdGVkIiwiT1BUSU9OOjp2YWx1ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxp
-Z24iLCJQUkU6OndpZHRoIiwiUFJPR1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6
-dmFsdWUiLCJTRUxFQ1Q6OmF1dG9jb21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11
-bHRpcGxlIiwiU0VMRUNUOjpuYW1lIiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNF
-TEVDVDo6dGFiaW5kZXgiLCJTT1VSQ0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xv
-ciIsIlRBQkxFOjpib3JkZXIiLCJUQUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmci
-LCJUQUJMRTo6ZnJhbWUiLCJUQUJMRTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0
-aCIsIlRCT0RZOjphbGlnbiIsIlRCT0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFs
-aWduIiwiVEQ6OmFiYnIiLCJURDo6YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNo
-YXIiLCJURDo6Y2hhcm9mZiIsIlREOjpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0Iiwi
-VEQ6Om5vd3JhcCIsIlREOjpyb3dzcGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0
-aCIsIlRFWFRBUkVBOjphY2Nlc3NrZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6
-OmNvbHMiLCJURVhUQVJFQTo6ZGlzYWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6
-Om5hbWUiLCJURVhUQVJFQTo6cGxhY2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJF
-QTo6cmVxdWlyZWQiLCJURVhUQVJFQTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVB
-Ojp3cmFwIiwiVEZPT1Q6OmFsaWduIiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09U
-Ojp2YWxpZ24iLCJUSDo6YWJiciIsIlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJU
-SDo6Y2hhciIsIlRIOjpjaGFyb2ZmIiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWln
-aHQiLCJUSDo6bm93cmFwIiwiVEg6OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6
-OndpZHRoIiwiVEhFQUQ6OmFsaWduIiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFE
-Ojp2YWxpZ24iLCJUUjo6YWxpZ24iLCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYi
-LCJUUjo6dmFsaWduIiwiVFJBQ0s6OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIs
-IlRSQUNLOjpzcmNsYW5nIiwiVUw6OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIs
-IlZJREVPOjpoZWlnaHQiLCJWSURFTzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11
-dGVkIiwiVklERU86OnByZWxvYWQiLCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCww
-LDY1NDkwLDQ1MDU1LDY1NTM1LDM0ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCww
-LDI2NjI0LDEwMjMsNjU1MzQsMjA0Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQi
-LCJBUkVBIiwiQkFTRSIsIkJBU0VGT05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJB
-TUUiLCJGUkFNRVNFVCIsIkhSIiwiSU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwi
-TUVUQSIsIlBBUkFNIiwiU09VUkNFIiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMuZG49SC5W
-TSh0KFtdKSxILk4wKCJqZDxMTD4iKSkKQy54RD1ILlZNKHQoW10pLHUucykKQy5oVT1ILlZNKHQoW10p
-LHUuYikKQy50bz1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
-LHUudCkKQy5yaz1ILlZNKHQoW0MuQWQsQy5uZSxDLm15LEMucngsQy53VixDLmZSXSksSC5OMCgiamQ8
-SDc+IikpCkMuRjM9SC5WTSh0KFswLDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
-LHUudCkKQy5lYT1ILlZNKHQoWzAsMCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0p
-LHUudCkKQy5aSj1ILlZNKHQoWzAsMCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0p
-LHUudCkKQy5XZD1ILlZNKHQoWzAsMCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0p
-LHUudCkKQy5ReD1ILlZNKHQoWyJiaW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5z
-KQpDLkJJPUguVk0odChbIkE6OmhyZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJP
-RFk6OmJhY2tncm91bmQiLCJDT01NQU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwi
-SU1HOjpzcmMiLCJJTlBVVDo6c3JjIiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIi
-XSksdS5zKQpDLkNNPW5ldyBILkxQKDAse30sQy54RCxILk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089
-bmV3IEguTFAoMCx7fSxDLnhELEguTjAoIkxQPHFVLHFVPiIpKQpDLmlIPUguVk0odChbXSksSC5OMCgi
-amQ8R0Q+IikpCkMuRHg9bmV3IEguTFAoMCx7fSxDLmlILEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3
-IEwuTzkoIk5hdmlnYXRpb25UcmVlTm9kZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2
-aWdhdGlvblRyZWVOb2RlVHlwZS5maWxlIikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAu
-RnkobnVsbCwyKX0pKCk7KGZ1bmN0aW9uIHN0YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5Q
-ND1udWxsCiQueT1udWxsCiQudT1udWxsCiQueDc9bnVsbAokLmo9bnVsbAokLnY9bnVsbAokLks9bnVs
-bAokLlM2PW51bGwKJC5rOD1udWxsCiQubWc9bnVsbAokLlVEPSExCiQuWDM9Qy5OVQokLnhnPVtdCiQu
-eG89bnVsbAokLkJPPW51bGwKJC5sdD1udWxsCiQuRVU9bnVsbAokLm9yPVAuRmwodS5OLHUuWikKJC5J
-Nj1udWxsCiQuRmY9bnVsbH0pKCk7KGZ1bmN0aW9uIGxhenlJbml0aWFsaXplcnMoKXt2YXIgdD1odW5r
-SGVscGVycy5sYXp5CnQoJCwiZmEiLCJ3USIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2Rh
-cnRDbG9zdXJlIil9KQp0KCQsIlkyIiwiQSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5ZZygiXyRkYXJ0X2pz
-Iil9KQp0KCQsIlUyIiwiU24iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyh7CnRvU3RyaW5nOmZ1
-bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0pCnQoJCwieHEiLCJscSIsZnVuY3Rpb24oKXty
-ZXR1cm4gSC5jTShILlM3KHskbWV0aG9kJDpudWxsLAp0b1N0cmluZzpmdW5jdGlvbigpe3JldHVybiIk
-cmVjZWl2ZXIkIn19KSl9KQp0KCQsIlIxIiwiTjkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5TNyhu
-dWxsKSl9KQp0KCQsImZOIiwiaUkiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt2YXIg
-JGFyZ3VtZW50c0V4cHIkPSckYXJndW1lbnRzJCcKdHJ5e251bGwuJG1ldGhvZCQoJGFyZ3VtZW50c0V4
-cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsInFpIiwiVU4iLGZ1bmN0aW9u
-KCl7cmV0dXJuIEguY00oSC5TNyh2b2lkIDApKX0pCnQoJCwicloiLCJaaCIsZnVuY3Rpb24oKXtyZXR1
-cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9JyRhcmd1bWVudHMkJwp0cnl7KHZv
-aWQgMCkuJG1ldGhvZCQoJGFyZ3VtZW50c0V4cHIkKX1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0o
-KSl9KQp0KCQsImtxIiwick4iLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oSC5NaihudWxsKSl9KQp0KCQs
-InR0IiwiYzMiLGZ1bmN0aW9uKCl7cmV0dXJuIEguY00oZnVuY3Rpb24oKXt0cnl7bnVsbC4kbWV0aG9k
-JH1jYXRjaChzKXtyZXR1cm4gcy5tZXNzYWdlfX0oKSl9KQp0KCQsImR0IiwiSEsiLGZ1bmN0aW9uKCl7
-cmV0dXJuIEguY00oSC5Naih2b2lkIDApKX0pCnQoJCwiQTciLCJyMSIsZnVuY3Rpb24oKXtyZXR1cm4g
-SC5jTShmdW5jdGlvbigpe3RyeXsodm9pZCAwKS4kbWV0aG9kJH1jYXRjaChzKXtyZXR1cm4gcy5tZXNz
-YWdlfX0oKSl9KQp0KCQsIldjIiwidXQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuT2ooKX0pCnQoJCwia2gi
-LCJ0TCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5XSSgpfSkKdCgkLCJidCIsIlY3IixmdW5jdGlvbigpe3Jl
-dHVybiBILkRRKEguWEYoSC5WTShbLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
-LTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIsLTIs
-LTIsLTIsLTIsLTIsLTEsLTIsLTIsLTIsLTIsLTIsNjIsLTIsNjIsLTIsNjMsNTIsNTMsNTQsNTUsNTYs
-NTcsNTgsNTksNjAsNjEsLTIsLTIsLTIsLTEsLTIsLTIsLTIsMCwxLDIsMyw0LDUsNiw3LDgsOSwxMCwx
-MSwxMiwxMywxNCwxNSwxNiwxNywxOCwxOSwyMCwyMSwyMiwyMywyNCwyNSwtMiwtMiwtMiwtMiw2Mywt
-MiwyNiwyNywyOCwyOSwzMCwzMSwzMiwzMywzNCwzNSwzNiwzNywzOCwzOSw0MCw0MSw0Miw0Myw0NCw0
-NSw0Niw0Nyw0OCw0OSw1MCw1MSwtMiwtMiwtMiwtMiwtMl0sdS50KSkpfSkKdCgkLCJNNSIsIk94Iixm
-dW5jdGlvbigpe3JldHVybiB0eXBlb2YgcHJvY2VzcyE9InVuZGVmaW5lZCImJk9iamVjdC5wcm90b3R5
-cGUudG9TdHJpbmcuY2FsbChwcm9jZXNzKT09IltvYmplY3QgcHJvY2Vzc10iJiZwcm9jZXNzLnBsYXRm
-b3JtPT0id2luMzIifSkKdCgkLCJtZiIsIno0IixmdW5jdGlvbigpe3JldHVybiBQLm51KCJeW1xcLVxc
-LjAtOUEtWl9hLXp+XSokIil9KQp0KCQsIkF2IiwicDYiLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBFcnJv
-cigpLnN0YWNrIT12b2lkIDB9KQp0KCQsIkpHIiwidloiLGZ1bmN0aW9uKCl7cmV0dXJuIFAuS04oKX0p
-CnQoJCwiU0MiLCJBTiIsZnVuY3Rpb24oKXtyZXR1cm4gUC50TShbIkEiLCJBQkJSIiwiQUNST05ZTSIs
-IkFERFJFU1MiLCJBUkVBIiwiQVJUSUNMRSIsIkFTSURFIiwiQVVESU8iLCJCIiwiQkRJIiwiQkRPIiwi
-QklHIiwiQkxPQ0tRVU9URSIsIkJSIiwiQlVUVE9OIiwiQ0FOVkFTIiwiQ0FQVElPTiIsIkNFTlRFUiIs
-IkNJVEUiLCJDT0RFIiwiQ09MIiwiQ09MR1JPVVAiLCJDT01NQU5EIiwiREFUQSIsIkRBVEFMSVNUIiwi
-REQiLCJERUwiLCJERVRBSUxTIiwiREZOIiwiRElSIiwiRElWIiwiREwiLCJEVCIsIkVNIiwiRklFTERT
-RVQiLCJGSUdDQVBUSU9OIiwiRklHVVJFIiwiRk9OVCIsIkZPT1RFUiIsIkZPUk0iLCJIMSIsIkgyIiwi
-SDMiLCJINCIsIkg1IiwiSDYiLCJIRUFERVIiLCJIR1JPVVAiLCJIUiIsIkkiLCJJRlJBTUUiLCJJTUci
-LCJJTlBVVCIsIklOUyIsIktCRCIsIkxBQkVMIiwiTEVHRU5EIiwiTEkiLCJNQVAiLCJNQVJLIiwiTUVO
-VSIsIk1FVEVSIiwiTkFWIiwiTk9CUiIsIk9MIiwiT1BUR1JPVVAiLCJPUFRJT04iLCJPVVRQVVQiLCJQ
-IiwiUFJFIiwiUFJPR1JFU1MiLCJRIiwiUyIsIlNBTVAiLCJTRUNUSU9OIiwiU0VMRUNUIiwiU01BTEwi
-LCJTT1VSQ0UiLCJTUEFOIiwiU1RSSUtFIiwiU1RST05HIiwiU1VCIiwiU1VNTUFSWSIsIlNVUCIsIlRB
-QkxFIiwiVEJPRFkiLCJURCIsIlRFWFRBUkVBIiwiVEZPT1QiLCJUSCIsIlRIRUFEIiwiVElNRSIsIlRS
-IiwiVFJBQ0siLCJUVCIsIlUiLCJVTCIsIlZBUiIsIlZJREVPIiwiV0JSIl0sdS5OKX0pCnQoJCwiWDQi
-LCJoRyIsZnVuY3Rpb24oKXtyZXR1cm4gUC5udSgiXlxcUyskIil9KQp0KCQsIndPIiwib3ciLGZ1bmN0
-aW9uKCl7cmV0dXJuIHUubS5hKFAuTkQoc2VsZikpfSkKdCgkLCJrdCIsIkNyIixmdW5jdGlvbigpe3Jl
-dHVybiBILllnKCJfJGRhcnRfZGFydE9iamVjdCIpfSkKdCgkLCJmSyIsImtJIixmdW5jdGlvbigpe3Jl
-dHVybiBmdW5jdGlvbiBEYXJ0T2JqZWN0KGEpe3RoaXMubz1hfX0pCnQoJCwicXQiLCJ6QiIsZnVuY3Rp
-b24oKXtyZXR1cm4gbmV3IFQubVEoKX0pCnQoJCwiT2wiLCJVRSIsZnVuY3Rpb24oKXtyZXR1cm4gUC5o
-SyhDLm9sLmdtVyhXLngzKCkpLmhyZWYpLmdoWSgpLnEoMCwiYXV0aFRva2VuIil9KQp0KCQsImhUIiwi
-eVAiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCIuZWRpdC1saXN0IC5wYW5l
-bC1jb250ZW50Iil9KQp0KCQsIlc2IiwiaEwiLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNl
-bGVjdG9yKCIuZWRpdC1wYW5lbCAucGFuZWwtY29udGVudCIpfSkKdCgkLCJUUiIsIkRXIixmdW5jdGlv
-bigpe3JldHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiZm9vdGVyIil9KQp0KCQsIkVZIiwiZmkiLGZ1
-bmN0aW9uKCl7cmV0dXJuIFcuWnIoKS5xdWVyeVNlbGVjdG9yKCJoZWFkZXIiKX0pCnQoJCwiYXYiLCJE
-OSIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIiN1bml0LW5hbWUiKX0pCnQo
-JCwiZmUiLCJLRyIsZnVuY3Rpb24oKXtyZXR1cm4gbmV3IEwuWEEoKX0pCnQoJCwiZW8iLCJuVSIsZnVu
-Y3Rpb24oKXtyZXR1cm4gbmV3IE0ubEkoJC5IaygpKX0pCnQoJCwieXIiLCJiRCIsZnVuY3Rpb24oKXty
-ZXR1cm4gbmV3IEUuT0YoUC5udSgiLyIpLFAubnUoIlteL10kIiksUC5udSgiXi8iKSl9KQp0KCQsIk1r
-IiwiS2siLGZ1bmN0aW9uKCl7cmV0dXJuIG5ldyBMLklWKFAubnUoIlsvXFxcXF0iKSxQLm51KCJbXi9c
-XFxcXSQiKSxQLm51KCJeKFxcXFxcXFxcW15cXFxcXStcXFxcW15cXFxcL10rfFthLXpBLVpdOlsvXFxc
-XF0pIiksUC5udSgiXlsvXFxcXF0oPyFbL1xcXFxdKSIpKX0pCnQoJCwiYWsiLCJFYiIsZnVuY3Rpb24o
-KXtyZXR1cm4gbmV3IEYucnUoUC5udSgiLyIpLFAubnUoIiheW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6
-Ly98W14vXSkkIiksUC5udSgiW2EtekEtWl1bLSsuYS16QS1aXFxkXSo6Ly9bXi9dKiIpLFAubnUoIl4v
-IikpfSkKdCgkLCJscyIsIkhrIixmdW5jdGlvbigpe3JldHVybiBPLlJoKCl9KX0pKCk7KGZ1bmN0aW9u
-IG5hdGl2ZVN1cHBvcnQoKXshZnVuY3Rpb24oKXt2YXIgdD1mdW5jdGlvbihhKXt2YXIgbj17fQpuW2Fd
-PTEKcmV0dXJuIE9iamVjdC5rZXlzKGh1bmtIZWxwZXJzLmNvbnZlcnRUb0Zhc3RPYmplY3QobikpWzBd
-fQp2LmdldElzb2xhdGVUYWc9ZnVuY3Rpb24oYSl7cmV0dXJuIHQoIl9fX2RhcnRfIithK3YuaXNvbGF0
-ZVRhZyl9CnZhciBzPSJfX19kYXJ0X2lzb2xhdGVfdGFnc18iCnZhciByPU9iamVjdFtzXXx8KE9iamVj
-dFtzXT1PYmplY3QuY3JlYXRlKG51bGwpKQp2YXIgcT0iX1p4WXhYIgpmb3IodmFyIHA9MDs7cCsrKXt2
-YXIgbz10KHErIl8iK3ArIl8iKQppZighKG8gaW4gcikpe3Jbb109MQp2Lmlzb2xhdGVUYWc9bwpicmVh
-a319di5kaXNwYXRjaFByb3BlcnR5TmFtZT12LmdldElzb2xhdGVUYWcoImRpc3BhdGNoX3JlY29yZCIp
-fSgpCmh1bmtIZWxwZXJzLnNldE9yVXBkYXRlSW50ZXJjZXB0b3JzQnlUYWcoe0RPTUVycm9yOkoudkIs
-RE9NSW1wbGVtZW50YXRpb246Si52QixNZWRpYUVycm9yOkoudkIsTmF2aWdhdG9yOkoudkIsTmF2aWdh
-dG9yQ29uY3VycmVudEhhcmR3YXJlOkoudkIsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6Si52QixPdmVy
-Y29uc3RyYWluZWRFcnJvcjpKLnZCLFBvc2l0aW9uRXJyb3I6Si52QixSYW5nZTpKLnZCLFNRTEVycm9y
-OkoudkIsRGF0YVZpZXc6SC5lSCxBcnJheUJ1ZmZlclZpZXc6SC5lSCxGbG9hdDMyQXJyYXk6SC5EZyxG
-bG9hdDY0QXJyYXk6SC5EZyxJbnQxNkFycmF5OkgueGosSW50MzJBcnJheTpILmRFLEludDhBcnJheTpI
-LlpBLFVpbnQxNkFycmF5Okgud2YsVWludDMyQXJyYXk6SC5QcSxVaW50OENsYW1wZWRBcnJheTpILmVF
-LENhbnZhc1BpeGVsQXJyYXk6SC5lRSxVaW50OEFycmF5OkguVjYsSFRNTEF1ZGlvRWxlbWVudDpXLnFF
-LEhUTUxCUkVsZW1lbnQ6Vy5xRSxIVE1MQnV0dG9uRWxlbWVudDpXLnFFLEhUTUxDYW52YXNFbGVtZW50
-OlcucUUsSFRNTENvbnRlbnRFbGVtZW50OlcucUUsSFRNTERMaXN0RWxlbWVudDpXLnFFLEhUTUxEYXRh
-RWxlbWVudDpXLnFFLEhUTUxEYXRhTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MRGV0YWlsc0VsZW1lbnQ6Vy5x
-RSxIVE1MRGlhbG9nRWxlbWVudDpXLnFFLEhUTUxEaXZFbGVtZW50OlcucUUsSFRNTEVtYmVkRWxlbWVu
-dDpXLnFFLEhUTUxGaWVsZFNldEVsZW1lbnQ6Vy5xRSxIVE1MSFJFbGVtZW50OlcucUUsSFRNTEhlYWRF
-bGVtZW50OlcucUUsSFRNTEhlYWRpbmdFbGVtZW50OlcucUUsSFRNTEh0bWxFbGVtZW50OlcucUUsSFRN
-TElGcmFtZUVsZW1lbnQ6Vy5xRSxIVE1MSW1hZ2VFbGVtZW50OlcucUUsSFRNTElucHV0RWxlbWVudDpX
-LnFFLEhUTUxMSUVsZW1lbnQ6Vy5xRSxIVE1MTGFiZWxFbGVtZW50OlcucUUsSFRNTExlZ2VuZEVsZW1l
-bnQ6Vy5xRSxIVE1MTGlua0VsZW1lbnQ6Vy5xRSxIVE1MTWFwRWxlbWVudDpXLnFFLEhUTUxNZWRpYUVs
-ZW1lbnQ6Vy5xRSxIVE1MTWVudUVsZW1lbnQ6Vy5xRSxIVE1MTWV0YUVsZW1lbnQ6Vy5xRSxIVE1MTWV0
-ZXJFbGVtZW50OlcucUUsSFRNTE1vZEVsZW1lbnQ6Vy5xRSxIVE1MT0xpc3RFbGVtZW50OlcucUUsSFRN
-TE9iamVjdEVsZW1lbnQ6Vy5xRSxIVE1MT3B0R3JvdXBFbGVtZW50OlcucUUsSFRNTE9wdGlvbkVsZW1l
-bnQ6Vy5xRSxIVE1MT3V0cHV0RWxlbWVudDpXLnFFLEhUTUxQYXJhbUVsZW1lbnQ6Vy5xRSxIVE1MUGlj
-dHVyZUVsZW1lbnQ6Vy5xRSxIVE1MUHJlRWxlbWVudDpXLnFFLEhUTUxQcm9ncmVzc0VsZW1lbnQ6Vy5x
-RSxIVE1MUXVvdGVFbGVtZW50OlcucUUsSFRNTFNjcmlwdEVsZW1lbnQ6Vy5xRSxIVE1MU2hhZG93RWxl
-bWVudDpXLnFFLEhUTUxTbG90RWxlbWVudDpXLnFFLEhUTUxTb3VyY2VFbGVtZW50OlcucUUsSFRNTFNw
-YW5FbGVtZW50OlcucUUsSFRNTFN0eWxlRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNhcHRpb25FbGVtZW50
-OlcucUUsSFRNTFRhYmxlQ2VsbEVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVEYXRhQ2VsbEVsZW1lbnQ6Vy5x
-RSxIVE1MVGFibGVIZWFkZXJDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUNvbEVsZW1lbnQ6Vy5xRSxI
-VE1MVGV4dEFyZWFFbGVtZW50OlcucUUsSFRNTFRpbWVFbGVtZW50OlcucUUsSFRNTFRpdGxlRWxlbWVu
-dDpXLnFFLEhUTUxUcmFja0VsZW1lbnQ6Vy5xRSxIVE1MVUxpc3RFbGVtZW50OlcucUUsSFRNTFVua25v
-d25FbGVtZW50OlcucUUsSFRNTFZpZGVvRWxlbWVudDpXLnFFLEhUTUxEaXJlY3RvcnlFbGVtZW50Olcu
-cUUsSFRNTEZvbnRFbGVtZW50OlcucUUsSFRNTEZyYW1lRWxlbWVudDpXLnFFLEhUTUxGcmFtZVNldEVs
-ZW1lbnQ6Vy5xRSxIVE1MTWFycXVlZUVsZW1lbnQ6Vy5xRSxIVE1MRWxlbWVudDpXLnFFLEhUTUxBbmNo
-b3JFbGVtZW50OlcuR2gsSFRNTEFyZWFFbGVtZW50OlcuZlksSFRNTEJhc2VFbGVtZW50OlcubkIsQmxv
-YjpXLkF6LEhUTUxCb2R5RWxlbWVudDpXLlFQLENEQVRBU2VjdGlvbjpXLm54LENoYXJhY3RlckRhdGE6
-Vy5ueCxDb21tZW50OlcubngsUHJvY2Vzc2luZ0luc3RydWN0aW9uOlcubngsVGV4dDpXLm54LENTU1N0
-eWxlRGVjbGFyYXRpb246Vy5vSixNU1N0eWxlQ1NTUHJvcGVydGllczpXLm9KLENTUzJQcm9wZXJ0aWVz
-Olcub0osWE1MRG9jdW1lbnQ6Vy5RRixEb2N1bWVudDpXLlFGLERPTUV4Y2VwdGlvbjpXLk5oLERPTVJl
-Y3RSZWFkT25seTpXLklCLERPTVRva2VuTGlzdDpXLm43LEVsZW1lbnQ6Vy5jdixBYm9ydFBheW1lbnRF
-dmVudDpXLmVhLEFuaW1hdGlvbkV2ZW50OlcuZWEsQW5pbWF0aW9uUGxheWJhY2tFdmVudDpXLmVhLEFw
-cGxpY2F0aW9uQ2FjaGVFcnJvckV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoQ2xpY2tFdmVudDpXLmVh
-LEJhY2tncm91bmRGZXRjaEV2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNoRmFpbEV2ZW50OlcuZWEsQmFj
-a2dyb3VuZEZldGNoZWRFdmVudDpXLmVhLEJlZm9yZUluc3RhbGxQcm9tcHRFdmVudDpXLmVhLEJlZm9y
-ZVVubG9hZEV2ZW50OlcuZWEsQmxvYkV2ZW50OlcuZWEsQ2FuTWFrZVBheW1lbnRFdmVudDpXLmVhLENs
-aXBib2FyZEV2ZW50OlcuZWEsQ2xvc2VFdmVudDpXLmVhLEN1c3RvbUV2ZW50OlcuZWEsRGV2aWNlTW90
-aW9uRXZlbnQ6Vy5lYSxEZXZpY2VPcmllbnRhdGlvbkV2ZW50OlcuZWEsRXJyb3JFdmVudDpXLmVhLEV4
-dGVuZGFibGVFdmVudDpXLmVhLEV4dGVuZGFibGVNZXNzYWdlRXZlbnQ6Vy5lYSxGZXRjaEV2ZW50Olcu
-ZWEsRm9udEZhY2VTZXRMb2FkRXZlbnQ6Vy5lYSxGb3JlaWduRmV0Y2hFdmVudDpXLmVhLEdhbWVwYWRF
-dmVudDpXLmVhLEhhc2hDaGFuZ2VFdmVudDpXLmVhLEluc3RhbGxFdmVudDpXLmVhLE1lZGlhRW5jcnlw
-dGVkRXZlbnQ6Vy5lYSxNZWRpYUtleU1lc3NhZ2VFdmVudDpXLmVhLE1lZGlhUXVlcnlMaXN0RXZlbnQ6
-Vy5lYSxNZWRpYVN0cmVhbUV2ZW50OlcuZWEsTWVkaWFTdHJlYW1UcmFja0V2ZW50OlcuZWEsTWVzc2Fn
-ZUV2ZW50OlcuZWEsTUlESUNvbm5lY3Rpb25FdmVudDpXLmVhLE1JRElNZXNzYWdlRXZlbnQ6Vy5lYSxN
-dXRhdGlvbkV2ZW50OlcuZWEsTm90aWZpY2F0aW9uRXZlbnQ6Vy5lYSxQYWdlVHJhbnNpdGlvbkV2ZW50
-OlcuZWEsUGF5bWVudFJlcXVlc3RFdmVudDpXLmVhLFBheW1lbnRSZXF1ZXN0VXBkYXRlRXZlbnQ6Vy5l
-YSxQb3BTdGF0ZUV2ZW50OlcuZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkF2YWlsYWJsZUV2ZW50Olcu
-ZWEsUHJlc2VudGF0aW9uQ29ubmVjdGlvbkNsb3NlRXZlbnQ6Vy5lYSxQcm9taXNlUmVqZWN0aW9uRXZl
-bnQ6Vy5lYSxQdXNoRXZlbnQ6Vy5lYSxSVENEYXRhQ2hhbm5lbEV2ZW50OlcuZWEsUlRDRFRNRlRvbmVD
-aGFuZ2VFdmVudDpXLmVhLFJUQ1BlZXJDb25uZWN0aW9uSWNlRXZlbnQ6Vy5lYSxSVENUcmFja0V2ZW50
-OlcuZWEsU2VjdXJpdHlQb2xpY3lWaW9sYXRpb25FdmVudDpXLmVhLFNlbnNvckVycm9yRXZlbnQ6Vy5l
-YSxTcGVlY2hSZWNvZ25pdGlvbkVycm9yOlcuZWEsU3BlZWNoUmVjb2duaXRpb25FdmVudDpXLmVhLFNw
-ZWVjaFN5bnRoZXNpc0V2ZW50OlcuZWEsU3RvcmFnZUV2ZW50OlcuZWEsU3luY0V2ZW50OlcuZWEsVHJh
-Y2tFdmVudDpXLmVhLFRyYW5zaXRpb25FdmVudDpXLmVhLFdlYktpdFRyYW5zaXRpb25FdmVudDpXLmVh
-LFZSRGV2aWNlRXZlbnQ6Vy5lYSxWUkRpc3BsYXlFdmVudDpXLmVhLFZSU2Vzc2lvbkV2ZW50OlcuZWEs
-TW9qb0ludGVyZmFjZVJlcXVlc3RFdmVudDpXLmVhLFVTQkNvbm5lY3Rpb25FdmVudDpXLmVhLElEQlZl
-cnNpb25DaGFuZ2VFdmVudDpXLmVhLEF1ZGlvUHJvY2Vzc2luZ0V2ZW50OlcuZWEsT2ZmbGluZUF1ZGlv
-Q29tcGxldGlvbkV2ZW50OlcuZWEsV2ViR0xDb250ZXh0RXZlbnQ6Vy5lYSxFdmVudDpXLmVhLElucHV0
-RXZlbnQ6Vy5lYSxFdmVudFRhcmdldDpXLkQwLEZpbGU6Vy5oSCxIVE1MRm9ybUVsZW1lbnQ6Vy5oNCxI
-aXN0b3J5OlcuYnIsSFRNTERvY3VtZW50OlcuVmIsWE1MSHR0cFJlcXVlc3Q6Vy5mSixYTUxIdHRwUmVx
-dWVzdEV2ZW50VGFyZ2V0Olcud2EsSW1hZ2VEYXRhOlcuU2csTG9jYXRpb246Vy51OCxNb3VzZUV2ZW50
-OlcuT0ssRHJhZ0V2ZW50OlcuT0ssUG9pbnRlckV2ZW50OlcuT0ssV2hlZWxFdmVudDpXLk9LLERvY3Vt
-ZW50RnJhZ21lbnQ6Vy51SCxTaGFkb3dSb290OlcudUgsRG9jdW1lbnRUeXBlOlcudUgsTm9kZTpXLnVI
-LE5vZGVMaXN0OlcuQkgsUmFkaW9Ob2RlTGlzdDpXLkJILEhUTUxQYXJhZ3JhcGhFbGVtZW50OlcuU04s
-UHJvZ3Jlc3NFdmVudDpXLmV3LFJlc291cmNlUHJvZ3Jlc3NFdmVudDpXLmV3LEhUTUxTZWxlY3RFbGVt
-ZW50OlcubHAsSFRNTFRhYmxlRWxlbWVudDpXLlRiLEhUTUxUYWJsZVJvd0VsZW1lbnQ6Vy5JdixIVE1M
-VGFibGVTZWN0aW9uRWxlbWVudDpXLldQLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6Vy55WSxDb21wb3NpdGlv
-bkV2ZW50OlcudzYsRm9jdXNFdmVudDpXLnc2LEtleWJvYXJkRXZlbnQ6Vy53NixUZXh0RXZlbnQ6Vy53
-NixUb3VjaEV2ZW50OlcudzYsVUlFdmVudDpXLnc2LFdpbmRvdzpXLks1LERPTVdpbmRvdzpXLks1LERl
-ZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOlcuQ20s
-U2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxXb3JrZXJHbG9iYWxTY29wZTpXLkNtLEF0dHI6Vy5D
-USxDbGllbnRSZWN0OlcudzQsRE9NUmVjdDpXLnc0LE5hbWVkTm9kZU1hcDpXLnJoLE1vek5hbWVkQXR0
-ck1hcDpXLnJoLElEQktleVJhbmdlOlAuaEYsU1ZHU2NyaXB0RWxlbWVudDpQLm5kLFNWR0FFbGVtZW50
-OlAuZDUsU1ZHQW5pbWF0ZUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDpQLmQ1LFNW
-R0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OlAuZDUsU1ZHQW5pbWF0aW9uRWxlbWVudDpQLmQ1LFNWR0Np
-cmNsZUVsZW1lbnQ6UC5kNSxTVkdDbGlwUGF0aEVsZW1lbnQ6UC5kNSxTVkdEZWZzRWxlbWVudDpQLmQ1
-LFNWR0Rlc2NFbGVtZW50OlAuZDUsU1ZHRGlzY2FyZEVsZW1lbnQ6UC5kNSxTVkdFbGxpcHNlRWxlbWVu
-dDpQLmQ1LFNWR0ZFQmxlbmRFbGVtZW50OlAuZDUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6UC5kNSxT
-VkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVudDpQLmQ1LFNWR0ZFQ29tcG9zaXRlRWxlbWVudDpQLmQ1
-LFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50OlAuZDUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50
-OlAuZDUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBFbGVtZW50OlAuZDUsU1ZHRkVEaXN0YW50TGlnaHRFbGVt
-ZW50OlAuZDUsU1ZHRkVGbG9vZEVsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNBRWxlbWVudDpQLmQ1LFNWR0ZF
-RnVuY0JFbGVtZW50OlAuZDUsU1ZHRkVGdW5jR0VsZW1lbnQ6UC5kNSxTVkdGRUZ1bmNSRWxlbWVudDpQ
-LmQ1LFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVudDpQLmQ1LFNWR0ZFSW1hZ2VFbGVtZW50OlAuZDUsU1ZH
-RkVNZXJnZUVsZW1lbnQ6UC5kNSxTVkdGRU1lcmdlTm9kZUVsZW1lbnQ6UC5kNSxTVkdGRU1vcnBob2xv
-Z3lFbGVtZW50OlAuZDUsU1ZHRkVPZmZzZXRFbGVtZW50OlAuZDUsU1ZHRkVQb2ludExpZ2h0RWxlbWVu
-dDpQLmQ1LFNWR0ZFU3BlY3VsYXJMaWdodGluZ0VsZW1lbnQ6UC5kNSxTVkdGRVNwb3RMaWdodEVsZW1l
-bnQ6UC5kNSxTVkdGRVRpbGVFbGVtZW50OlAuZDUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDpQLmQ1LFNW
-R0ZpbHRlckVsZW1lbnQ6UC5kNSxTVkdGb3JlaWduT2JqZWN0RWxlbWVudDpQLmQ1LFNWR0dFbGVtZW50
-OlAuZDUsU1ZHR2VvbWV0cnlFbGVtZW50OlAuZDUsU1ZHR3JhcGhpY3NFbGVtZW50OlAuZDUsU1ZHSW1h
-Z2VFbGVtZW50OlAuZDUsU1ZHTGluZUVsZW1lbnQ6UC5kNSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6
-UC5kNSxTVkdNYXJrZXJFbGVtZW50OlAuZDUsU1ZHTWFza0VsZW1lbnQ6UC5kNSxTVkdNZXRhZGF0YUVs
-ZW1lbnQ6UC5kNSxTVkdQYXRoRWxlbWVudDpQLmQ1LFNWR1BhdHRlcm5FbGVtZW50OlAuZDUsU1ZHUG9s
-eWdvbkVsZW1lbnQ6UC5kNSxTVkdQb2x5bGluZUVsZW1lbnQ6UC5kNSxTVkdSYWRpYWxHcmFkaWVudEVs
-ZW1lbnQ6UC5kNSxTVkdSZWN0RWxlbWVudDpQLmQ1LFNWR1NldEVsZW1lbnQ6UC5kNSxTVkdTdG9wRWxl
-bWVudDpQLmQ1LFNWR1N0eWxlRWxlbWVudDpQLmQ1LFNWR1NWR0VsZW1lbnQ6UC5kNSxTVkdTd2l0Y2hF
-bGVtZW50OlAuZDUsU1ZHU3ltYm9sRWxlbWVudDpQLmQ1LFNWR1RTcGFuRWxlbWVudDpQLmQ1LFNWR1Rl
-eHRDb250ZW50RWxlbWVudDpQLmQ1LFNWR1RleHRFbGVtZW50OlAuZDUsU1ZHVGV4dFBhdGhFbGVtZW50
-OlAuZDUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxlbWVudDpQLmQ1LFNWR1RpdGxlRWxlbWVudDpQLmQ1LFNW
-R1VzZUVsZW1lbnQ6UC5kNSxTVkdWaWV3RWxlbWVudDpQLmQ1LFNWR0dyYWRpZW50RWxlbWVudDpQLmQ1
-LFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rpb25FbGVtZW50OlAuZDUsU1ZHRkVEcm9wU2hhZG93RWxl
-bWVudDpQLmQ1LFNWR01QYXRoRWxlbWVudDpQLmQ1LFNWR0VsZW1lbnQ6UC5kNX0pCmh1bmtIZWxwZXJz
-LnNldE9yVXBkYXRlTGVhZlRhZ3Moe0RPTUVycm9yOnRydWUsRE9NSW1wbGVtZW50YXRpb246dHJ1ZSxN
-ZWRpYUVycm9yOnRydWUsTmF2aWdhdG9yOnRydWUsTmF2aWdhdG9yQ29uY3VycmVudEhhcmR3YXJlOnRy
-dWUsTmF2aWdhdG9yVXNlck1lZGlhRXJyb3I6dHJ1ZSxPdmVyY29uc3RyYWluZWRFcnJvcjp0cnVlLFBv
-c2l0aW9uRXJyb3I6dHJ1ZSxSYW5nZTp0cnVlLFNRTEVycm9yOnRydWUsRGF0YVZpZXc6dHJ1ZSxBcnJh
-eUJ1ZmZlclZpZXc6ZmFsc2UsRmxvYXQzMkFycmF5OnRydWUsRmxvYXQ2NEFycmF5OnRydWUsSW50MTZB
-cnJheTp0cnVlLEludDMyQXJyYXk6dHJ1ZSxJbnQ4QXJyYXk6dHJ1ZSxVaW50MTZBcnJheTp0cnVlLFVp
-bnQzMkFycmF5OnRydWUsVWludDhDbGFtcGVkQXJyYXk6dHJ1ZSxDYW52YXNQaXhlbEFycmF5OnRydWUs
-VWludDhBcnJheTpmYWxzZSxIVE1MQXVkaW9FbGVtZW50OnRydWUsSFRNTEJSRWxlbWVudDp0cnVlLEhU
-TUxCdXR0b25FbGVtZW50OnRydWUsSFRNTENhbnZhc0VsZW1lbnQ6dHJ1ZSxIVE1MQ29udGVudEVsZW1l
-bnQ6dHJ1ZSxIVE1MRExpc3RFbGVtZW50OnRydWUsSFRNTERhdGFFbGVtZW50OnRydWUsSFRNTERhdGFM
-aXN0RWxlbWVudDp0cnVlLEhUTUxEZXRhaWxzRWxlbWVudDp0cnVlLEhUTUxEaWFsb2dFbGVtZW50OnRy
-dWUsSFRNTERpdkVsZW1lbnQ6dHJ1ZSxIVE1MRW1iZWRFbGVtZW50OnRydWUsSFRNTEZpZWxkU2V0RWxl
-bWVudDp0cnVlLEhUTUxIUkVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZEVsZW1lbnQ6dHJ1ZSxIVE1MSGVhZGlu
-Z0VsZW1lbnQ6dHJ1ZSxIVE1MSHRtbEVsZW1lbnQ6dHJ1ZSxIVE1MSUZyYW1lRWxlbWVudDp0cnVlLEhU
-TUxJbWFnZUVsZW1lbnQ6dHJ1ZSxIVE1MSW5wdXRFbGVtZW50OnRydWUsSFRNTExJRWxlbWVudDp0cnVl
-LEhUTUxMYWJlbEVsZW1lbnQ6dHJ1ZSxIVE1MTGVnZW5kRWxlbWVudDp0cnVlLEhUTUxMaW5rRWxlbWVu
-dDp0cnVlLEhUTUxNYXBFbGVtZW50OnRydWUsSFRNTE1lZGlhRWxlbWVudDp0cnVlLEhUTUxNZW51RWxl
-bWVudDp0cnVlLEhUTUxNZXRhRWxlbWVudDp0cnVlLEhUTUxNZXRlckVsZW1lbnQ6dHJ1ZSxIVE1MTW9k
-RWxlbWVudDp0cnVlLEhUTUxPTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MT2JqZWN0RWxlbWVudDp0cnVlLEhU
-TUxPcHRHcm91cEVsZW1lbnQ6dHJ1ZSxIVE1MT3B0aW9uRWxlbWVudDp0cnVlLEhUTUxPdXRwdXRFbGVt
-ZW50OnRydWUsSFRNTFBhcmFtRWxlbWVudDp0cnVlLEhUTUxQaWN0dXJlRWxlbWVudDp0cnVlLEhUTUxQ
-cmVFbGVtZW50OnRydWUsSFRNTFByb2dyZXNzRWxlbWVudDp0cnVlLEhUTUxRdW90ZUVsZW1lbnQ6dHJ1
-ZSxIVE1MU2NyaXB0RWxlbWVudDp0cnVlLEhUTUxTaGFkb3dFbGVtZW50OnRydWUsSFRNTFNsb3RFbGVt
-ZW50OnRydWUsSFRNTFNvdXJjZUVsZW1lbnQ6dHJ1ZSxIVE1MU3BhbkVsZW1lbnQ6dHJ1ZSxIVE1MU3R5
-bGVFbGVtZW50OnRydWUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVDZWxsRWxl
-bWVudDp0cnVlLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDp0cnVlLEhUTUxUYWJsZUhlYWRlckNlbGxF
-bGVtZW50OnRydWUsSFRNTFRhYmxlQ29sRWxlbWVudDp0cnVlLEhUTUxUZXh0QXJlYUVsZW1lbnQ6dHJ1
-ZSxIVE1MVGltZUVsZW1lbnQ6dHJ1ZSxIVE1MVGl0bGVFbGVtZW50OnRydWUsSFRNTFRyYWNrRWxlbWVu
-dDp0cnVlLEhUTUxVTGlzdEVsZW1lbnQ6dHJ1ZSxIVE1MVW5rbm93bkVsZW1lbnQ6dHJ1ZSxIVE1MVmlk
-ZW9FbGVtZW50OnRydWUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6dHJ1ZSxIVE1MRm9udEVsZW1lbnQ6dHJ1
-ZSxIVE1MRnJhbWVFbGVtZW50OnRydWUsSFRNTEZyYW1lU2V0RWxlbWVudDp0cnVlLEhUTUxNYXJxdWVl
-RWxlbWVudDp0cnVlLEhUTUxFbGVtZW50OmZhbHNlLEhUTUxBbmNob3JFbGVtZW50OnRydWUsSFRNTEFy
-ZWFFbGVtZW50OnRydWUsSFRNTEJhc2VFbGVtZW50OnRydWUsQmxvYjpmYWxzZSxIVE1MQm9keUVsZW1l
-bnQ6dHJ1ZSxDREFUQVNlY3Rpb246dHJ1ZSxDaGFyYWN0ZXJEYXRhOnRydWUsQ29tbWVudDp0cnVlLFBy
-b2Nlc3NpbmdJbnN0cnVjdGlvbjp0cnVlLFRleHQ6dHJ1ZSxDU1NTdHlsZURlY2xhcmF0aW9uOnRydWUs
-TVNTdHlsZUNTU1Byb3BlcnRpZXM6dHJ1ZSxDU1MyUHJvcGVydGllczp0cnVlLFhNTERvY3VtZW50OnRy
-dWUsRG9jdW1lbnQ6ZmFsc2UsRE9NRXhjZXB0aW9uOnRydWUsRE9NUmVjdFJlYWRPbmx5OmZhbHNlLERP
-TVRva2VuTGlzdDp0cnVlLEVsZW1lbnQ6ZmFsc2UsQWJvcnRQYXltZW50RXZlbnQ6dHJ1ZSxBbmltYXRp
-b25FdmVudDp0cnVlLEFuaW1hdGlvblBsYXliYWNrRXZlbnQ6dHJ1ZSxBcHBsaWNhdGlvbkNhY2hlRXJy
-b3JFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaENsaWNrRXZlbnQ6dHJ1ZSxCYWNrZ3JvdW5kRmV0Y2hF
-dmVudDp0cnVlLEJhY2tncm91bmRGZXRjaEZhaWxFdmVudDp0cnVlLEJhY2tncm91bmRGZXRjaGVkRXZl
-bnQ6dHJ1ZSxCZWZvcmVJbnN0YWxsUHJvbXB0RXZlbnQ6dHJ1ZSxCZWZvcmVVbmxvYWRFdmVudDp0cnVl
-LEJsb2JFdmVudDp0cnVlLENhbk1ha2VQYXltZW50RXZlbnQ6dHJ1ZSxDbGlwYm9hcmRFdmVudDp0cnVl
-LENsb3NlRXZlbnQ6dHJ1ZSxDdXN0b21FdmVudDp0cnVlLERldmljZU1vdGlvbkV2ZW50OnRydWUsRGV2
-aWNlT3JpZW50YXRpb25FdmVudDp0cnVlLEVycm9yRXZlbnQ6dHJ1ZSxFeHRlbmRhYmxlRXZlbnQ6dHJ1
-ZSxFeHRlbmRhYmxlTWVzc2FnZUV2ZW50OnRydWUsRmV0Y2hFdmVudDp0cnVlLEZvbnRGYWNlU2V0TG9h
-ZEV2ZW50OnRydWUsRm9yZWlnbkZldGNoRXZlbnQ6dHJ1ZSxHYW1lcGFkRXZlbnQ6dHJ1ZSxIYXNoQ2hh
-bmdlRXZlbnQ6dHJ1ZSxJbnN0YWxsRXZlbnQ6dHJ1ZSxNZWRpYUVuY3J5cHRlZEV2ZW50OnRydWUsTWVk
-aWFLZXlNZXNzYWdlRXZlbnQ6dHJ1ZSxNZWRpYVF1ZXJ5TGlzdEV2ZW50OnRydWUsTWVkaWFTdHJlYW1F
-dmVudDp0cnVlLE1lZGlhU3RyZWFtVHJhY2tFdmVudDp0cnVlLE1lc3NhZ2VFdmVudDp0cnVlLE1JRElD
-b25uZWN0aW9uRXZlbnQ6dHJ1ZSxNSURJTWVzc2FnZUV2ZW50OnRydWUsTXV0YXRpb25FdmVudDp0cnVl
-LE5vdGlmaWNhdGlvbkV2ZW50OnRydWUsUGFnZVRyYW5zaXRpb25FdmVudDp0cnVlLFBheW1lbnRSZXF1
-ZXN0RXZlbnQ6dHJ1ZSxQYXltZW50UmVxdWVzdFVwZGF0ZUV2ZW50OnRydWUsUG9wU3RhdGVFdmVudDp0
-cnVlLFByZXNlbnRhdGlvbkNvbm5lY3Rpb25BdmFpbGFibGVFdmVudDp0cnVlLFByZXNlbnRhdGlvbkNv
-bm5lY3Rpb25DbG9zZUV2ZW50OnRydWUsUHJvbWlzZVJlamVjdGlvbkV2ZW50OnRydWUsUHVzaEV2ZW50
-OnRydWUsUlRDRGF0YUNoYW5uZWxFdmVudDp0cnVlLFJUQ0RUTUZUb25lQ2hhbmdlRXZlbnQ6dHJ1ZSxS
-VENQZWVyQ29ubmVjdGlvbkljZUV2ZW50OnRydWUsUlRDVHJhY2tFdmVudDp0cnVlLFNlY3VyaXR5UG9s
-aWN5VmlvbGF0aW9uRXZlbnQ6dHJ1ZSxTZW5zb3JFcnJvckV2ZW50OnRydWUsU3BlZWNoUmVjb2duaXRp
-b25FcnJvcjp0cnVlLFNwZWVjaFJlY29nbml0aW9uRXZlbnQ6dHJ1ZSxTcGVlY2hTeW50aGVzaXNFdmVu
-dDp0cnVlLFN0b3JhZ2VFdmVudDp0cnVlLFN5bmNFdmVudDp0cnVlLFRyYWNrRXZlbnQ6dHJ1ZSxUcmFu
-c2l0aW9uRXZlbnQ6dHJ1ZSxXZWJLaXRUcmFuc2l0aW9uRXZlbnQ6dHJ1ZSxWUkRldmljZUV2ZW50OnRy
-dWUsVlJEaXNwbGF5RXZlbnQ6dHJ1ZSxWUlNlc3Npb25FdmVudDp0cnVlLE1vam9JbnRlcmZhY2VSZXF1
-ZXN0RXZlbnQ6dHJ1ZSxVU0JDb25uZWN0aW9uRXZlbnQ6dHJ1ZSxJREJWZXJzaW9uQ2hhbmdlRXZlbnQ6
-dHJ1ZSxBdWRpb1Byb2Nlc3NpbmdFdmVudDp0cnVlLE9mZmxpbmVBdWRpb0NvbXBsZXRpb25FdmVudDp0
-cnVlLFdlYkdMQ29udGV4dEV2ZW50OnRydWUsRXZlbnQ6ZmFsc2UsSW5wdXRFdmVudDpmYWxzZSxFdmVu
-dFRhcmdldDpmYWxzZSxGaWxlOnRydWUsSFRNTEZvcm1FbGVtZW50OnRydWUsSGlzdG9yeTp0cnVlLEhU
-TUxEb2N1bWVudDp0cnVlLFhNTEh0dHBSZXF1ZXN0OnRydWUsWE1MSHR0cFJlcXVlc3RFdmVudFRhcmdl
-dDpmYWxzZSxJbWFnZURhdGE6dHJ1ZSxMb2NhdGlvbjp0cnVlLE1vdXNlRXZlbnQ6dHJ1ZSxEcmFnRXZl
-bnQ6dHJ1ZSxQb2ludGVyRXZlbnQ6dHJ1ZSxXaGVlbEV2ZW50OnRydWUsRG9jdW1lbnRGcmFnbWVudDp0
-cnVlLFNoYWRvd1Jvb3Q6dHJ1ZSxEb2N1bWVudFR5cGU6dHJ1ZSxOb2RlOmZhbHNlLE5vZGVMaXN0OnRy
-dWUsUmFkaW9Ob2RlTGlzdDp0cnVlLEhUTUxQYXJhZ3JhcGhFbGVtZW50OnRydWUsUHJvZ3Jlc3NFdmVu
-dDp0cnVlLFJlc291cmNlUHJvZ3Jlc3NFdmVudDp0cnVlLEhUTUxTZWxlY3RFbGVtZW50OnRydWUsSFRN
-TFRhYmxlRWxlbWVudDp0cnVlLEhUTUxUYWJsZVJvd0VsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVTZWN0aW9u
-RWxlbWVudDp0cnVlLEhUTUxUZW1wbGF0ZUVsZW1lbnQ6dHJ1ZSxDb21wb3NpdGlvbkV2ZW50OnRydWUs
-Rm9jdXNFdmVudDp0cnVlLEtleWJvYXJkRXZlbnQ6dHJ1ZSxUZXh0RXZlbnQ6dHJ1ZSxUb3VjaEV2ZW50
-OnRydWUsVUlFdmVudDpmYWxzZSxXaW5kb3c6dHJ1ZSxET01XaW5kb3c6dHJ1ZSxEZWRpY2F0ZWRXb3Jr
-ZXJHbG9iYWxTY29wZTp0cnVlLFNlcnZpY2VXb3JrZXJHbG9iYWxTY29wZTp0cnVlLFNoYXJlZFdvcmtl
-ckdsb2JhbFNjb3BlOnRydWUsV29ya2VyR2xvYmFsU2NvcGU6dHJ1ZSxBdHRyOnRydWUsQ2xpZW50UmVj
-dDp0cnVlLERPTVJlY3Q6dHJ1ZSxOYW1lZE5vZGVNYXA6dHJ1ZSxNb3pOYW1lZEF0dHJNYXA6dHJ1ZSxJ
-REJLZXlSYW5nZTp0cnVlLFNWR1NjcmlwdEVsZW1lbnQ6dHJ1ZSxTVkdBRWxlbWVudDp0cnVlLFNWR0Fu
-aW1hdGVFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZU1vdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdBbmltYXRlVHJh
-bnNmb3JtRWxlbWVudDp0cnVlLFNWR0FuaW1hdGlvbkVsZW1lbnQ6dHJ1ZSxTVkdDaXJjbGVFbGVtZW50
-OnRydWUsU1ZHQ2xpcFBhdGhFbGVtZW50OnRydWUsU1ZHRGVmc0VsZW1lbnQ6dHJ1ZSxTVkdEZXNjRWxl
-bWVudDp0cnVlLFNWR0Rpc2NhcmRFbGVtZW50OnRydWUsU1ZHRWxsaXBzZUVsZW1lbnQ6dHJ1ZSxTVkdG
-RUJsZW5kRWxlbWVudDp0cnVlLFNWR0ZFQ29sb3JNYXRyaXhFbGVtZW50OnRydWUsU1ZHRkVDb21wb25l
-bnRUcmFuc2ZlckVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvc2l0ZUVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbnZv
-bHZlTWF0cml4RWxlbWVudDp0cnVlLFNWR0ZFRGlmZnVzZUxpZ2h0aW5nRWxlbWVudDp0cnVlLFNWR0ZF
-RGlzcGxhY2VtZW50TWFwRWxlbWVudDp0cnVlLFNWR0ZFRGlzdGFudExpZ2h0RWxlbWVudDp0cnVlLFNW
-R0ZFRmxvb2RFbGVtZW50OnRydWUsU1ZHRkVGdW5jQUVsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNCRWxlbWVu
-dDp0cnVlLFNWR0ZFRnVuY0dFbGVtZW50OnRydWUsU1ZHRkVGdW5jUkVsZW1lbnQ6dHJ1ZSxTVkdGRUdh
-dXNzaWFuQmx1ckVsZW1lbnQ6dHJ1ZSxTVkdGRUltYWdlRWxlbWVudDp0cnVlLFNWR0ZFTWVyZ2VFbGVt
-ZW50OnRydWUsU1ZHRkVNZXJnZU5vZGVFbGVtZW50OnRydWUsU1ZHRkVNb3JwaG9sb2d5RWxlbWVudDp0
-cnVlLFNWR0ZFT2Zmc2V0RWxlbWVudDp0cnVlLFNWR0ZFUG9pbnRMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdG
-RVNwZWN1bGFyTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVTcG90TGlnaHRFbGVtZW50OnRydWUsU1ZH
-RkVUaWxlRWxlbWVudDp0cnVlLFNWR0ZFVHVyYnVsZW5jZUVsZW1lbnQ6dHJ1ZSxTVkdGaWx0ZXJFbGVt
-ZW50OnRydWUsU1ZHRm9yZWlnbk9iamVjdEVsZW1lbnQ6dHJ1ZSxTVkdHRWxlbWVudDp0cnVlLFNWR0dl
-b21ldHJ5RWxlbWVudDp0cnVlLFNWR0dyYXBoaWNzRWxlbWVudDp0cnVlLFNWR0ltYWdlRWxlbWVudDp0
-cnVlLFNWR0xpbmVFbGVtZW50OnRydWUsU1ZHTGluZWFyR3JhZGllbnRFbGVtZW50OnRydWUsU1ZHTWFy
-a2VyRWxlbWVudDp0cnVlLFNWR01hc2tFbGVtZW50OnRydWUsU1ZHTWV0YWRhdGFFbGVtZW50OnRydWUs
-U1ZHUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdQYXR0ZXJuRWxlbWVudDp0cnVlLFNWR1BvbHlnb25FbGVtZW50
-OnRydWUsU1ZHUG9seWxpbmVFbGVtZW50OnRydWUsU1ZHUmFkaWFsR3JhZGllbnRFbGVtZW50OnRydWUs
-U1ZHUmVjdEVsZW1lbnQ6dHJ1ZSxTVkdTZXRFbGVtZW50OnRydWUsU1ZHU3RvcEVsZW1lbnQ6dHJ1ZSxT
-VkdTdHlsZUVsZW1lbnQ6dHJ1ZSxTVkdTVkdFbGVtZW50OnRydWUsU1ZHU3dpdGNoRWxlbWVudDp0cnVl
-LFNWR1N5bWJvbEVsZW1lbnQ6dHJ1ZSxTVkdUU3BhbkVsZW1lbnQ6dHJ1ZSxTVkdUZXh0Q29udGVudEVs
-ZW1lbnQ6dHJ1ZSxTVkdUZXh0RWxlbWVudDp0cnVlLFNWR1RleHRQYXRoRWxlbWVudDp0cnVlLFNWR1Rl
-eHRQb3NpdGlvbmluZ0VsZW1lbnQ6dHJ1ZSxTVkdUaXRsZUVsZW1lbnQ6dHJ1ZSxTVkdVc2VFbGVtZW50
-OnRydWUsU1ZHVmlld0VsZW1lbnQ6dHJ1ZSxTVkdHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdDb21wb25l
-bnRUcmFuc2ZlckZ1bmN0aW9uRWxlbWVudDp0cnVlLFNWR0ZFRHJvcFNoYWRvd0VsZW1lbnQ6dHJ1ZSxT
-VkdNUGF0aEVsZW1lbnQ6dHJ1ZSxTVkdFbGVtZW50OmZhbHNlfSkKSC5MWi4kbmF0aXZlU3VwZXJjbGFz
-c1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlJHLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZl
-clZpZXciCkguVlAuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5EZy4kbmF0
-aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILldCLiRuYXRpdmVTdXBlcmNsYXNzVGFn
-PSJBcnJheUJ1ZmZlclZpZXciCkguWkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmll
-dyIKSC5QZy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3In0pKCkKY29udmVydEFs
-bFRvRmFzdE9iamVjdCh3KQpjb252ZXJ0VG9GYXN0T2JqZWN0KCQpOyhmdW5jdGlvbihhKXtpZih0eXBl
-b2YgZG9jdW1lbnQ9PT0idW5kZWZpbmVkIil7YShudWxsKQpyZXR1cm59aWYodHlwZW9mIGRvY3VtZW50
-LmN1cnJlbnRTY3JpcHQhPSd1bmRlZmluZWQnKXthKGRvY3VtZW50LmN1cnJlbnRTY3JpcHQpCnJldHVy
-bn12YXIgdD1kb2N1bWVudC5zY3JpcHRzCmZ1bmN0aW9uIG9uTG9hZChiKXtmb3IodmFyIHI9MDtyPHQu
-bGVuZ3RoOysrcil0W3JdLnJlbW92ZUV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxzZSkKYShi
-LnRhcmdldCl9Zm9yKHZhciBzPTA7czx0Lmxlbmd0aDsrK3MpdFtzXS5hZGRFdmVudExpc3RlbmVyKCJs
-b2FkIixvbkxvYWQsZmFsc2UpfSkoZnVuY3Rpb24oYSl7di5jdXJyZW50U2NyaXB0PWEKaWYodHlwZW9m
-IGRhcnRNYWluUnVubmVyPT09ImZ1bmN0aW9uIilkYXJ0TWFpblJ1bm5lcihMLklxLFtdKQplbHNlIEwu
-SXEoW10pfSl9KSgpCi8vIyBzb3VyY2VNYXBwaW5nVVJMPW1pZ3JhdGlvbi5qcy5tYXAK
+Nyh0KQpyPXQuZ3I4KHQpCnMudG9TdHJpbmcKci50b1N0cmluZwpuZXcgVy5lNyhzKS5GVigwLG5ldyBX
+LmU3KHIpKQpyZXR1cm4gc319ClcueVkucHJvdG90eXBlPXsKcGs6ZnVuY3Rpb24oYSxiLGMpe3ZhciB0
+LHMKYS50ZXh0Q29udGVudD1udWxsCnQ9YS5jb250ZW50CnQudG9TdHJpbmcKSi5iVCh0KQpzPXRoaXMu
+cjYoYSxiLG51bGwsYykKYS5jb250ZW50LmFwcGVuZENoaWxkKHMpfSwKWUM6ZnVuY3Rpb24oYSxiKXty
+ZXR1cm4gdGhpcy5wayhhLGIsbnVsbCl9LAokaXlZOjF9ClcudzYucHJvdG90eXBlPXt9ClcuSzUucHJv
+dG90eXBlPXsKUG86ZnVuY3Rpb24oYSxiLGMpe3ZhciB0PVcuUDEoYS5vcGVuKGIsYykpCnJldHVybiB0
+fSwKZ21XOmZ1bmN0aW9uKGEpe3JldHVybiBhLmxvY2F0aW9ufSwKJGlLNToxLAokaXY2OjF9ClcuQ20u
+cHJvdG90eXBlPXskaUNtOjF9ClcuQ1EucHJvdG90eXBlPXskaUNROjF9ClcudzQucHJvdG90eXBlPXsK
+dzpmdW5jdGlvbihhKXtyZXR1cm4iUmVjdGFuZ2xlICgiK0guZChhLmxlZnQpKyIsICIrSC5kKGEudG9w
+KSsiKSAiK0guZChhLndpZHRoKSsiIHggIitILmQoYS5oZWlnaHQpfSwKRE46ZnVuY3Rpb24oYSxiKXtp
+ZihiPT1udWxsKXJldHVybiExCnJldHVybiB1LnEuYyhiKSYmYS5sZWZ0PT09Yi5sZWZ0JiZhLnRvcD09
+PWIudG9wJiZhLndpZHRoPT09Yi53aWR0aCYmYS5oZWlnaHQ9PT1iLmhlaWdodH0sCmdpTzpmdW5jdGlv
+bihhKXtyZXR1cm4gVy5yRShDLkNELmdpTyhhLmxlZnQpLEMuQ0QuZ2lPKGEudG9wKSxDLkNELmdpTyhh
+LndpZHRoKSxDLkNELmdpTyhhLmhlaWdodCkpfX0KVy5yaC5wcm90b3R5cGU9ewpnQTpmdW5jdGlvbihh
+KXtyZXR1cm4gYS5sZW5ndGh9LApxOmZ1bmN0aW9uKGEsYil7SC5TYyhiKQppZihiPj4+MCE9PWJ8fGI+
+PWEubGVuZ3RoKXRocm93IEguYihQLkNmKGIsYSxudWxsLG51bGwsbnVsbCkpCnJldHVybiBhW2JdfSwK
+WTpmdW5jdGlvbihhLGIsYyl7dS5BLmIoYykKdGhyb3cgSC5iKFAuTDQoIkNhbm5vdCBhc3NpZ24gZWxl
+bWVudCBvZiBpbW11dGFibGUgTGlzdC4iKSl9LApFOmZ1bmN0aW9uKGEsYil7aWYoYjwwfHxiPj1hLmxl
+bmd0aClyZXR1cm4gSC5PSChhLGIpCnJldHVybiBhW2JdfSwKJGliUToxLAokaVhqOjEsCiRpY1g6MSwK
+JGl6TToxfQpXLmNmLnByb3RvdHlwZT17Cks6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwCnUuRi5i
+KGIpCmZvcih0PXRoaXMuZ1YoKSxzPXQubGVuZ3RoLHI9dGhpcy5hLHE9MDtxPHQubGVuZ3RoO3QubGVu
+Z3RoPT09c3x8KDAsSC5saykodCksKytxKXtwPXRbcV0KYi4kMihwLHIuZ2V0QXR0cmlidXRlKHApKX19
+LApnVjpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9dGhpcy5hLmF0dHJpYnV0ZXMsbz1ILlZNKFtdLHUu
+cykKZm9yKHQ9cC5sZW5ndGgscz11Lmg5LHI9MDtyPHQ7KytyKXtpZihyPj1wLmxlbmd0aClyZXR1cm4g
+SC5PSChwLHIpCnE9cy5iKHBbcl0pCmlmKHEubmFtZXNwYWNlVVJJPT1udWxsKUMuTm0uaShvLHEubmFt
+ZSl9cmV0dXJuIG99LApnbDA6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfX0K
+Vy5pNy5wcm90b3R5cGU9ewp4NDpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5hLmhhc0F0dHJpYnV0ZShh
+KX0sCnE6ZnVuY3Rpb24oYSxiKXtyZXR1cm4gdGhpcy5hLmdldEF0dHJpYnV0ZShILnkoYikpfSwKWTpm
+dW5jdGlvbihhLGIsYyl7dGhpcy5hLnNldEF0dHJpYnV0ZShiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0
+dXJuIHRoaXMuZ1YoKS5sZW5ndGh9fQpXLlN5LnByb3RvdHlwZT17Cng0OmZ1bmN0aW9uKGEpe3JldHVy
+biB0aGlzLmEuYS5oYXNBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYSkpfSwKcTpmdW5jdGlvbihhLGIp
+e3JldHVybiB0aGlzLmEuYS5nZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oSC55KGIpKSl9LApZOmZ1
+bmN0aW9uKGEsYixjKXt0aGlzLmEuYS5zZXRBdHRyaWJ1dGUoImRhdGEtIit0aGlzLk8oYiksYyl9LApL
+OmZ1bmN0aW9uKGEsYil7dGhpcy5hLksoMCxuZXcgVy5LUyh0aGlzLHUuRi5iKGIpKSl9LApnVjpmdW5j
+dGlvbigpe3ZhciB0PUguVk0oW10sdS5zKQp0aGlzLmEuSygwLG5ldyBXLkEzKHRoaXMsdCkpCnJldHVy
+biB0fSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGh9LApnbDA6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuZ1YoKS5sZW5ndGg9PT0wfSwKazpmdW5jdGlvbihhKXt2YXIgdCxzLHI9SC5W
+TShhLnNwbGl0KCItIiksdS5zKQpmb3IodD0xO3Q8ci5sZW5ndGg7Kyt0KXtzPXJbdF0KaWYocy5sZW5n
+dGg+MClDLk5tLlkocix0LHNbMF0udG9VcHBlckNhc2UoKStKLktWKHMsMSkpfXJldHVybiBDLk5tLkgo
+ciwiIil9LApPOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAKZm9yKHQ9YS5sZW5ndGgscz0wLHI9IiI7
+czx0Oysrcyl7cT1hW3NdCnA9cS50b0xvd2VyQ2FzZSgpCnI9KHEhPT1wJiZzPjA/cisiLSI6cikrcH1y
+ZXR1cm4gci5jaGFyQ29kZUF0KDApPT0wP3I6cn19ClcuS1MucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24o
+YSxiKXtpZihKLnJZKGEpLm4oYSwiZGF0YS0iKSl0aGlzLmIuJDIodGhpcy5hLmsoQy54Qi5HKGEsNSkp
+LGIpfSwKJFM6MTR9ClcuQTMucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXtpZihKLnJZKGEpLm4o
+YSwiZGF0YS0iKSlDLk5tLmkodGhpcy5iLHRoaXMuYS5rKEMueEIuRyhhLDUpKSl9LAokUzoxNH0KVy5J
+NC5wcm90b3R5cGU9ewpERzpmdW5jdGlvbigpe3ZhciB0LHMscixxLHA9UC5Mcyh1Lk4pCmZvcih0PXRo
+aXMuYS5jbGFzc05hbWUuc3BsaXQoIiAiKSxzPXQubGVuZ3RoLHI9MDtyPHM7KytyKXtxPUouVDAodFty
+XSkKaWYocS5sZW5ndGghPT0wKXAuaSgwLHEpfXJldHVybiBwfSwKWDpmdW5jdGlvbihhKXt0aGlzLmEu
+Y2xhc3NOYW1lPXUuQy5iKGEpLkgoMCwiICIpfSwKZ0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuYS5j
+bGFzc0xpc3QubGVuZ3RofSwKVjE6ZnVuY3Rpb24oYSl7dGhpcy5hLmNsYXNzTmFtZT0iIn0sCnRnOmZ1
+bmN0aW9uKGEsYil7dmFyIHQ9dGhpcy5hLmNsYXNzTGlzdC5jb250YWlucyhiKQpyZXR1cm4gdH0sCmk6
+ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250YWlucyhiKQp0LmFkZChi
+KQpyZXR1cm4hc30sClI6ZnVuY3Rpb24oYSxiKXt2YXIgdD10aGlzLmEuY2xhc3NMaXN0LHM9dC5jb250
+YWlucyhiKQp0LnJlbW92ZShiKQpyZXR1cm4gc30sCkZWOmZ1bmN0aW9uKGEsYil7Vy5UTih0aGlzLmEs
+dS5YLmIoYikpfX0KVy5Gay5wcm90b3R5cGU9e30KVy5STy5wcm90b3R5cGU9e30KVy5ldS5wcm90b3R5
+cGU9e30KVy54Qy5wcm90b3R5cGU9e30KVy52Ti5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5hLiQxKHUuQi5iKGEpKX0sCiRTOjI3fQpXLkpRLnByb3RvdHlwZT17CkNZOmZ1bmN0aW9u
+KGEpe3ZhciB0CmlmKCQub3IuYT09PTApe2Zvcih0PTA7dDwyNjI7Kyt0KSQub3IuWSgwLEMuY21bdF0s
+Vy5wUygpKQpmb3IodD0wO3Q8MTI7Kyt0KSQub3IuWSgwLEMuQklbdF0sVy5WNCgpKX19LAppMDpmdW5j
+dGlvbihhKXtyZXR1cm4gJC5BTigpLnRnKDAsVy5yUyhhKSl9LApFYjpmdW5jdGlvbihhLGIsYyl7dmFy
+IHQ9JC5vci5xKDAsSC5kKFcuclMoYSkpKyI6OiIrYikKaWYodD09bnVsbCl0PSQub3IucSgwLCIqOjoi
+K2IpCmlmKHQ9PW51bGwpcmV0dXJuITEKcmV0dXJuIEgueGQodC4kNChhLGIsYyx0aGlzKSl9LAokaWtG
+OjF9ClcuR20ucHJvdG90eXBlPXsKZ2t6OmZ1bmN0aW9uKGEpe3JldHVybiBuZXcgVy5XOShhLHRoaXMu
+Z0EoYSksSC56SyhhKS5DKCJXOTxHbS5FPiIpKX19ClcudkQucHJvdG90eXBlPXsKaTA6ZnVuY3Rpb24o
+YSl7cmV0dXJuIEMuTm0uVnIodGhpcy5hLG5ldyBXLlV2KGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXty
+ZXR1cm4gQy5ObS5Wcih0aGlzLmEsbmV3IFcuRWcoYSxiLGMpKX0sCiRpa0Y6MX0KVy5Vdi5wcm90b3R5
+cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdS5lLmIoYSkuaTAodGhpcy5hKX0sCiRTOjE1fQpXLkVn
+LnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3JldHVybiB1LmUuYihhKS5FYih0aGlzLmEsdGhpcy5i
+LHRoaXMuYyl9LAokUzoxNX0KVy5tNi5wcm90b3R5cGU9ewpDWTpmdW5jdGlvbihhLGIsYyxkKXt2YXIg
+dCxzLHIKdGhpcy5hLkZWKDAsYykKdD1iLmV2KDAsbmV3IFcuRW8oKSkKcz1iLmV2KDAsbmV3IFcuV2so
+KSkKdGhpcy5iLkZWKDAsdCkKcj10aGlzLmMKci5GVigwLEMueEQpCnIuRlYoMCxzKX0sCmkwOmZ1bmN0
+aW9uKGEpe3JldHVybiB0aGlzLmEudGcoMCxXLnJTKGEpKX0sCkViOmZ1bmN0aW9uKGEsYixjKXt2YXIg
+dD10aGlzLHM9Vy5yUyhhKSxyPXQuYwppZihyLnRnKDAsSC5kKHMpKyI6OiIrYikpcmV0dXJuIHQuZC5E
+dChjKQplbHNlIGlmKHIudGcoMCwiKjo6IitiKSlyZXR1cm4gdC5kLkR0KGMpCmVsc2V7cj10LmIKaWYo
+ci50ZygwLEguZChzKSsiOjoiK2IpKXJldHVybiEwCmVsc2UgaWYoci50ZygwLCIqOjoiK2IpKXJldHVy
+biEwCmVsc2UgaWYoci50ZygwLEguZChzKSsiOjoqIikpcmV0dXJuITAKZWxzZSBpZihyLnRnKDAsIio6
+OioiKSlyZXR1cm4hMH1yZXR1cm4hMX0sCiRpa0Y6MX0KVy5Fby5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4hQy5ObS50ZyhDLkJJLEgueShhKSl9LAokUzo3fQpXLldrLnByb3RvdHlwZT17CiQx
+OmZ1bmN0aW9uKGEpe3JldHVybiBDLk5tLnRnKEMuQkksSC55KGEpKX0sCiRTOjd9ClcuY3QucHJvdG90
+eXBlPXsKRWI6ZnVuY3Rpb24oYSxiLGMpe2lmKHRoaXMuakYoYSxiLGMpKXJldHVybiEwCmlmKGI9PT0i
+dGVtcGxhdGUiJiZjPT09IiIpcmV0dXJuITAKaWYoYS5nZXRBdHRyaWJ1dGUoInRlbXBsYXRlIik9PT0i
+IilyZXR1cm4gdGhpcy5lLnRnKDAsYikKcmV0dXJuITF9fQpXLklBLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3JldHVybiJURU1QTEFURTo6IitILmQoSC55KGEpKX0sCiRTOjV9ClcuT3cucHJvdG90eXBl
+PXsKaTA6ZnVuY3Rpb24oYSl7dmFyIHQKaWYodS5hTy5jKGEpKXJldHVybiExCnQ9dS5nNy5jKGEpCmlm
+KHQmJlcuclMoYSk9PT0iZm9yZWlnbk9iamVjdCIpcmV0dXJuITEKaWYodClyZXR1cm4hMApyZXR1cm4h
+MX0sCkViOmZ1bmN0aW9uKGEsYixjKXtpZihiPT09ImlzInx8Qy54Qi5uKGIsIm9uIikpcmV0dXJuITEK
+cmV0dXJuIHRoaXMuaTAoYSl9LAokaWtGOjF9ClcuVzkucHJvdG90eXBlPXsKRjpmdW5jdGlvbigpe3Zh
+ciB0PXRoaXMscz10LmMrMSxyPXQuYgppZihzPHIpe3Quc3AoSi53Mih0LmEscykpCnQuYz1zCnJldHVy
+biEwfXQuc3AobnVsbCkKdC5jPXIKcmV0dXJuITF9LApnbDpmdW5jdGlvbigpe3JldHVybiB0aGlzLmR9
+LApzcDpmdW5jdGlvbihhKXt0aGlzLmQ9dGhpcy4kdGkuZC5iKGEpfSwKJGlBbjoxfQpXLmRXLnByb3Rv
+dHlwZT17CmdtVzpmdW5jdGlvbihhKXtyZXR1cm4gVy5ISCh0aGlzLmEubG9jYXRpb24pfSwKJGlEMDox
+LAokaXY2OjF9ClcuRmIucHJvdG90eXBlPXt9Clcua0YucHJvdG90eXBlPXt9ClcubWsucHJvdG90eXBl
+PXskaXkwOjF9ClcuS28ucHJvdG90eXBlPXsKUG46ZnVuY3Rpb24oYSl7bmV3IFcuZm0odGhpcykuJDIo
+YSxudWxsKX0sCkVQOmZ1bmN0aW9uKGEsYil7aWYoYj09bnVsbClKLkx0KGEpCmVsc2UgYi5yZW1vdmVD
+aGlsZChhKX0sCkk0OmZ1bmN0aW9uKGEsYil7dmFyIHQscyxyLHEscCxvPSEwLG49bnVsbCxtPW51bGwK
+dHJ5e249Si5pZyhhKQptPW4uYS5nZXRBdHRyaWJ1dGUoImlzIikKdS5oLmIoYSkKdD1mdW5jdGlvbihj
+KXtpZighKGMuYXR0cmlidXRlcyBpbnN0YW5jZW9mIE5hbWVkTm9kZU1hcCkpcmV0dXJuIHRydWUKdmFy
+IGw9Yy5jaGlsZE5vZGVzCmlmKGMubGFzdENoaWxkJiZjLmxhc3RDaGlsZCE9PWxbbC5sZW5ndGgtMV0p
+cmV0dXJuIHRydWUKaWYoYy5jaGlsZHJlbilpZighKGMuY2hpbGRyZW4gaW5zdGFuY2VvZiBIVE1MQ29s
+bGVjdGlvbnx8Yy5jaGlsZHJlbiBpbnN0YW5jZW9mIE5vZGVMaXN0KSlyZXR1cm4gdHJ1ZQp2YXIgaz0w
+CmlmKGMuY2hpbGRyZW4paz1jLmNoaWxkcmVuLmxlbmd0aApmb3IodmFyIGo9MDtqPGs7aisrKXt2YXIg
+aT1jLmNoaWxkcmVuW2pdCmlmKGkuaWQ9PSdhdHRyaWJ1dGVzJ3x8aS5uYW1lPT0nYXR0cmlidXRlcyd8
+fGkuaWQ9PSdsYXN0Q2hpbGQnfHxpLm5hbWU9PSdsYXN0Q2hpbGQnfHxpLmlkPT0nY2hpbGRyZW4nfHxp
+Lm5hbWU9PSdjaGlsZHJlbicpcmV0dXJuIHRydWV9cmV0dXJuIGZhbHNlfShhKQpvPUgub1QodCk/ITA6
+IShhLmF0dHJpYnV0ZXMgaW5zdGFuY2VvZiBOYW1lZE5vZGVNYXApfWNhdGNoKHEpe0guUnUocSl9cz0i
+ZWxlbWVudCB1bnByaW50YWJsZSIKdHJ5e3M9Si5qKGEpfWNhdGNoKHEpe0guUnUocSl9dHJ5e3I9Vy5y
+UyhhKQp0aGlzLmtSKHUuaC5iKGEpLGIsbyxzLHIsdS5HLmIobiksSC55KG0pKX1jYXRjaChxKXtpZihI
+LlJ1KHEpIGluc3RhbmNlb2YgUC51KXRocm93IHEKZWxzZXt0aGlzLkVQKGEsYikKd2luZG93CnA9IlJl
+bW92aW5nIGNvcnJ1cHRlZCBlbGVtZW50ICIrSC5kKHMpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZp
+bmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApfX19LAprUjpmdW5jdGlvbihhLGIsYyxkLGUsZixnKXt2
+YXIgdCxzLHIscSxwLG8sbj10aGlzCmlmKGMpe24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZWxl
+bWVudCBkdWUgdG8gY29ycnVwdGVkIGF0dHJpYnV0ZXMgb24gPCIrZCsiPiIKaWYodHlwZW9mIGNvbnNv
+bGUhPSJ1bmRlZmluZWQiKXdpbmRvdy5jb25zb2xlLndhcm4odCkKcmV0dXJufWlmKCFuLmEuaTAoYSkp
+e24uRVAoYSxiKQp3aW5kb3cKdD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBlbGVtZW50IDwiK0guZChlKSsi
+PiBmcm9tICIrSC5kKGIpCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29s
+ZS53YXJuKHQpCnJldHVybn1pZihnIT1udWxsKWlmKCFuLmEuRWIoYSwiaXMiLGcpKXtuLkVQKGEsYikK
+d2luZG93CnQ9IlJlbW92aW5nIGRpc2FsbG93ZWQgdHlwZSBleHRlbnNpb24gPCIrSC5kKGUpKycgaXM9
+IicrZysnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0idW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJu
+KHQpCnJldHVybn10PWYuZ1YoKQpzPUguVk0odC5zbGljZSgwKSxILnQ2KHQpLkMoImpkPDE+IikpCmZv
+cihyPWYuZ1YoKS5sZW5ndGgtMSx0PWYuYTtyPj0wOy0tcil7aWYocj49cy5sZW5ndGgpcmV0dXJuIEgu
+T0gocyxyKQpxPXNbcl0KcD1uLmEKbz1KLmNIKHEpCkgueShxKQppZighcC5FYihhLG8sdC5nZXRBdHRy
+aWJ1dGUocSkpKXt3aW5kb3cKcD0iUmVtb3ZpbmcgZGlzYWxsb3dlZCBhdHRyaWJ1dGUgPCIrSC5kKGUp
+KyIgIitxKyc9IicrSC5kKHQuZ2V0QXR0cmlidXRlKHEpKSsnIj4nCmlmKHR5cGVvZiBjb25zb2xlIT0i
+dW5kZWZpbmVkIil3aW5kb3cuY29uc29sZS53YXJuKHApCnQucmVtb3ZlQXR0cmlidXRlKHEpfX1pZih1
+LmFXLmMoYSkpbi5QbihhLmNvbnRlbnQpfSwKJGlvbjoxfQpXLmZtLnByb3RvdHlwZT17CiQyOmZ1bmN0
+aW9uKGEsYil7dmFyIHQscyxyLHEscD10aGlzLmEKc3dpdGNoKGEubm9kZVR5cGUpe2Nhc2UgMTpwLkk0
+KGEsYikKYnJlYWsKY2FzZSA4OmNhc2UgMTE6Y2FzZSAzOmNhc2UgNDpicmVhawpkZWZhdWx0OnAuRVAo
+YSxiKX10PWEubGFzdENoaWxkCmZvcihwPXUuQTtudWxsIT10Oyl7cz1udWxsCnRyeXtzPXQucHJldmlv
+dXNTaWJsaW5nfWNhdGNoKHIpe0guUnUocikKcT1wLmIodCkKYS5yZW1vdmVDaGlsZChxKQp0PW51bGwK
+cz1hLmxhc3RDaGlsZH1pZih0IT1udWxsKXRoaXMuJDIodCxhKQp0PXAuYihzKX19LAokUzozMH0KVy5M
+ZS5wcm90b3R5cGU9e30KVy5LNy5wcm90b3R5cGU9e30KVy5yQi5wcm90b3R5cGU9e30KVy5YVy5wcm90
+b3R5cGU9e30KVy5vYS5wcm90b3R5cGU9e30KUC5pSi5wcm90b3R5cGU9ewpWSDpmdW5jdGlvbihhKXt2
+YXIgdCxzPXRoaXMuYSxyPXMubGVuZ3RoCmZvcih0PTA7dDxyOysrdClpZihzW3RdPT09YSlyZXR1cm4g
+dApDLk5tLmkocyxhKQpDLk5tLmkodGhpcy5iLG51bGwpCnJldHVybiByfSwKUHY6ZnVuY3Rpb24oYSl7
+dmFyIHQscyxyLHE9dGhpcyxwPXt9CmlmKGE9PW51bGwpcmV0dXJuIGEKaWYoSC5sKGEpKXJldHVybiBh
+CmlmKHR5cGVvZiBhPT0ibnVtYmVyIilyZXR1cm4gYQppZih0eXBlb2YgYT09InN0cmluZyIpcmV0dXJu
+IGEKaWYoYSBpbnN0YW5jZW9mIFAuaVApcmV0dXJuIG5ldyBEYXRlKGEuYSkKaWYodS5mdi5jKGEpKXRo
+cm93IEguYihQLlNZKCJzdHJ1Y3R1cmVkIGNsb25lIG9mIFJlZ0V4cCIpKQppZih1LmM4LmMoYSkpcmV0
+dXJuIGEKaWYodS5kLmMoYSkpcmV0dXJuIGEKaWYodS5JLmMoYSkpcmV0dXJuIGEKdD11LmRELmMoYSl8
+fCExCmlmKHQpcmV0dXJuIGEKaWYodS5HLmMoYSkpe3M9cS5WSChhKQp0PXEuYgppZihzPj10Lmxlbmd0
+aClyZXR1cm4gSC5PSCh0LHMpCnI9cC5hPXRbc10KaWYociE9bnVsbClyZXR1cm4gcgpyPXt9CnAuYT1y
+CkMuTm0uWSh0LHMscikKYS5LKDAsbmV3IFAubFIocCxxKSkKcmV0dXJuIHAuYX1pZih1LmouYyhhKSl7
+cz1xLlZIKGEpCnA9cS5iCmlmKHM+PXAubGVuZ3RoKXJldHVybiBILk9IKHAscykKcj1wW3NdCmlmKHIh
+PW51bGwpcmV0dXJuIHIKcmV0dXJuIHEuZWsoYSxzKX1pZih1LmVILmMoYSkpe3M9cS5WSChhKQp0PXEu
+YgppZihzPj10Lmxlbmd0aClyZXR1cm4gSC5PSCh0LHMpCnI9cC5iPXRbc10KaWYociE9bnVsbClyZXR1
+cm4gcgpyPXt9CnAuYj1yCkMuTm0uWSh0LHMscikKcS5pbShhLG5ldyBQLmpnKHAscSkpCnJldHVybiBw
+LmJ9dGhyb3cgSC5iKFAuU1koInN0cnVjdHVyZWQgY2xvbmUgb2Ygb3RoZXIgdHlwZSIpKX0sCmVrOmZ1
+bmN0aW9uKGEsYil7dmFyIHQscz1KLlU2KGEpLHI9cy5nQShhKSxxPW5ldyBBcnJheShyKQpDLk5tLlko
+dGhpcy5iLGIscSkKZm9yKHQ9MDt0PHI7Kyt0KUMuTm0uWShxLHQsdGhpcy5QdihzLnEoYSx0KSkpCnJl
+dHVybiBxfX0KUC5sUi5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe3RoaXMuYS5hW2FdPXRoaXMu
+Yi5QdihiKX0sCiRTOjR9ClAuamcucHJvdG90eXBlPXsKJDI6ZnVuY3Rpb24oYSxiKXt0aGlzLmEuYlth
+XT10aGlzLmIuUHYoYil9LAokUzo0fQpQLkJmLnByb3RvdHlwZT17CmltOmZ1bmN0aW9uKGEsYil7dmFy
+IHQscyxyLHEKdS5iOC5iKGIpCmZvcih0PU9iamVjdC5rZXlzKGEpLHM9dC5sZW5ndGgscj0wO3I8czsr
+K3Ipe3E9dFtyXQpiLiQyKHEsYVtxXSl9fX0KUC5Bcy5wcm90b3R5cGU9ewpUOmZ1bmN0aW9uKGEpe3Zh
+ciB0CkgueShhKQp0PSQuaEcoKS5iCmlmKHR5cGVvZiBhIT0ic3RyaW5nIilILnZoKEgudEwoYSkpCmlm
+KHQudGVzdChhKSlyZXR1cm4gYQp0aHJvdyBILmIoUC5MMyhhLCJ2YWx1ZSIsIk5vdCBhIHZhbGlkIGNs
+YXNzIHRva2VuIikpfSwKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5ERygpLkgoMCwiICIpfSwKZ2t6
+OmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuREcoKQpyZXR1cm4gUC5yaih0LHQucixILkxoKHQpLmQpfSwK
+Z0E6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuREcoKS5hfSwKdGc6ZnVuY3Rpb24oYSxiKXt0aGlzLlQo
+YikKcmV0dXJuIHRoaXMuREcoKS50ZygwLGIpfSwKaTpmdW5jdGlvbihhLGIpe3RoaXMuVChiKQpyZXR1
+cm4gSC54ZCh0aGlzLk9TKG5ldyBQLkdFKGIpKSl9LApSOmZ1bmN0aW9uKGEsYil7dmFyIHQscwp0aGlz
+LlQoYikKdD10aGlzLkRHKCkKcz10LlIoMCxiKQp0aGlzLlgodCkKcmV0dXJuIHN9LApGVjpmdW5jdGlv
+bihhLGIpe3RoaXMuT1MobmV3IFAuTjcodGhpcyx1LlguYihiKSkpfSwKVjE6ZnVuY3Rpb24oYSl7dGhp
+cy5PUyhuZXcgUC51USgpKX0sCk9TOmZ1bmN0aW9uKGEpe3ZhciB0LHMKdS5jaC5iKGEpCnQ9dGhpcy5E
+RygpCnM9YS4kMSh0KQp0aGlzLlgodCkKcmV0dXJuIHN9fQpQLkdFLnByb3RvdHlwZT17CiQxOmZ1bmN0
+aW9uKGEpe3JldHVybiB1LkMuYihhKS5pKDAsdGhpcy5hKX0sCiRTOjMxfQpQLk43LnByb3RvdHlwZT17
+CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PXRoaXMuYixzPUgudDYodCkKcmV0dXJuIHUuQy5iKGEpLkZWKDAs
+bmV3IEguQTgodCxzLkMoInFVKDEpIikuYih0aGlzLmEuZ3VNKCkpLHMuQygiQTg8MSxxVT4iKSkpfSwK
+JFM6MTF9ClAudVEucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5DLmIoYSkKaWYoYS5hPjApe2Eu
+Yj1hLmM9YS5kPWEuZT1hLmY9bnVsbAphLmE9MAphLlMoKX1yZXR1cm4gbnVsbH0sCiRTOjExfQpQLmhG
+LnByb3RvdHlwZT17JGloRjoxfQpQLlBDLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUu
+Wi5iKGEpCnQ9ZnVuY3Rpb24oYixjLGQpe3JldHVybiBmdW5jdGlvbigpe3JldHVybiBiKGMsZCx0aGlz
+LEFycmF5LnByb3RvdHlwZS5zbGljZS5hcHBseShhcmd1bWVudHMpKX19KFAuUjQsYSwhMSkKUC5EbSh0
+LCQudygpLGEpCnJldHVybiB0fSwKJFM6MX0KUC5tdC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
+ZXR1cm4gbmV3IHRoaXMuYShhKX0sCiRTOjF9ClAuTnoucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLnI3KGEpfSwKJFM6MzN9ClAuUVMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7
+cmV0dXJuIG5ldyBQLlR6KGEsdS5hbSl9LAokUzozNH0KUC5ucC5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXtyZXR1cm4gbmV3IFAuRTQoYSl9LAokUzozNX0KUC5FNC5wcm90b3R5cGU9ewpxOmZ1bmN0aW9u
+KGEsYil7aWYodHlwZW9mIGIhPSJzdHJpbmciJiZ0eXBlb2YgYiE9Im51bWJlciIpdGhyb3cgSC5iKFAu
+eFkoInByb3BlcnR5IGlzIG5vdCBhIFN0cmluZyBvciBudW0iKSkKcmV0dXJuIFAuTDcodGhpcy5hW2Jd
+KX0sClk6ZnVuY3Rpb24oYSxiLGMpe2lmKHR5cGVvZiBiIT0ic3RyaW5nIiYmdHlwZW9mIGIhPSJudW1i
+ZXIiKXRocm93IEguYihQLnhZKCJwcm9wZXJ0eSBpcyBub3QgYSBTdHJpbmcgb3IgbnVtIikpCnRoaXMu
+YVtiXT1QLndZKGMpfSwKRE46ZnVuY3Rpb24oYSxiKXtpZihiPT1udWxsKXJldHVybiExCnJldHVybiBi
+IGluc3RhbmNlb2YgUC5FNCYmdGhpcy5hPT09Yi5hfSwKdzpmdW5jdGlvbihhKXt2YXIgdCxzCnRyeXt0
+PVN0cmluZyh0aGlzLmEpCnJldHVybiB0fWNhdGNoKHMpe0guUnUocykKdD10aGlzLnhiKDApCnJldHVy
+biB0fX0sClY3OmZ1bmN0aW9uKGEsYil7dmFyIHQscz10aGlzLmEKaWYoYj09bnVsbCl0PW51bGwKZWxz
+ZXt0PUgudDYoYikKdD1QLkNIKG5ldyBILkE4KGIsdC5DKCJAKDEpIikuYihQLmlHKCkpLHQuQygiQTg8
+MSxAPiIpKSwhMCx1LnopfXJldHVybiBQLkw3KHNbYV0uYXBwbHkocyx0KSl9LApnaU86ZnVuY3Rpb24o
+YSl7cmV0dXJuIDB9fQpQLnI3LnByb3RvdHlwZT17fQpQLlR6LnByb3RvdHlwZT17CmNQOmZ1bmN0aW9u
+KGEpe3ZhciB0PXRoaXMscz1hPDB8fGE+PXQuZ0EodCkKaWYocyl0aHJvdyBILmIoUC5URShhLDAsdC5n
+QSh0KSxudWxsLG51bGwpKX0sCnE6ZnVuY3Rpb24oYSxiKXtpZih0eXBlb2YgYj09Im51bWJlciImJmI9
+PT1DLmpuLnl1KGIpKXRoaXMuY1AoSC5TYyhiKSkKcmV0dXJuIHRoaXMuJHRpLmQuYih0aGlzLlVyKDAs
+YikpfSwKWTpmdW5jdGlvbihhLGIsYyl7dmFyIHQKdGhpcy4kdGkuZC5iKGMpCnQ9Qy5qbi55dShiKQpp
+ZihiPT09dCl0aGlzLmNQKGIpCnRoaXMuZTQoMCxiLGMpfSwKZ0E6ZnVuY3Rpb24oYSl7dmFyIHQ9dGhp
+cy5hLmxlbmd0aAppZih0eXBlb2YgdD09PSJudW1iZXIiJiZ0Pj4+MD09PXQpcmV0dXJuIHQKdGhyb3cg
+SC5iKFAuUFYoIkJhZCBKc0FycmF5IGxlbmd0aCIpKX0sCiRpYlE6MSwKJGljWDoxLAokaXpNOjF9ClAu
+Y28ucHJvdG90eXBlPXt9ClAubmQucHJvdG90eXBlPXskaW5kOjF9ClAuS2UucHJvdG90eXBlPXsKREc6
+ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMuYS5nZXRBdHRyaWJ1dGUoImNsYXNzIiksbz1QLkxz
+KHUuTikKaWYocD09bnVsbClyZXR1cm4gbwpmb3IodD1wLnNwbGl0KCIgIikscz10Lmxlbmd0aCxyPTA7
+cjxzOysrcil7cT1KLlQwKHRbcl0pCmlmKHEubGVuZ3RoIT09MClvLmkoMCxxKX1yZXR1cm4gb30sClg6
+ZnVuY3Rpb24oYSl7dGhpcy5hLnNldEF0dHJpYnV0ZSgiY2xhc3MiLGEuSCgwLCIgIikpfX0KUC5kNS5w
+cm90b3R5cGU9ewpnUDpmdW5jdGlvbihhKXtyZXR1cm4gbmV3IFAuS2UoYSl9LApzaGY6ZnVuY3Rpb24o
+YSxiKXt0aGlzLllDKGEsYil9LApyNjpmdW5jdGlvbihhLGIsYyxkKXt2YXIgdCxzLHIscSxwLG8KaWYo
+ZD09bnVsbCl7dD1ILlZNKFtdLHUuaSkKZD1uZXcgVy52RCh0KQpDLk5tLmkodCxXLlR3KG51bGwpKQpD
+Lk5tLmkodCxXLkJsKCkpCkMuTm0uaSh0LG5ldyBXLk93KCkpfWM9bmV3IFcuS28oZCkKcz0nPHN2ZyB2
+ZXJzaW9uPSIxLjEiPicrSC5kKGIpKyI8L3N2Zz4iCnQ9ZG9jdW1lbnQKcj10LmJvZHkKcT0ociYmQy5S
+WSkuQUgocixzLGMpCnA9dC5jcmVhdGVEb2N1bWVudEZyYWdtZW50KCkKcS50b1N0cmluZwp0PW5ldyBX
+LmU3KHEpCm89dC5ncjgodCkKZm9yKDt0PW8uZmlyc3RDaGlsZCx0IT1udWxsOylwLmFwcGVuZENoaWxk
+KHQpCnJldHVybiBwfSwKbno6ZnVuY3Rpb24oYSxiLGMsZCxlKXt0aHJvdyBILmIoUC5MNCgiQ2Fubm90
+IGludm9rZSBpbnNlcnRBZGphY2VudEh0bWwgb24gU1ZHLiIpKX0sCmdWbDpmdW5jdGlvbihhKXtyZXR1
+cm4gbmV3IFcuZXUoYSwiY2xpY2siLCExLHUuUSl9LAokaWQ1OjF9ClAubjYucHJvdG90eXBlPXskaWJR
+OjEsJGljWDoxLCRpek06MSwkaWVxOjF9Ck0uSDcucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5ifX0KVS5MTC5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3JldHVybiBQLkVGKFsibm9k
+ZUlkIix0aGlzLmIsImtpbmQiLHRoaXMuYS5hXSx1Lk4sdS5LKX19ClUuTUQucHJvdG90eXBlPXsKJDE6
+ZnVuY3Rpb24oYSl7cmV0dXJuIHUuZ3AuYihhKS5hPT09dGhpcy5hLnEoMCwia2luZCIpfSwKJFM6MzZ9
+ClUuZDIucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscSxwPXRoaXMsbz11Lk4sbj11
+LkssbT1QLkZsKG8sbiksbD1wLmEKaWYobCE9bnVsbCl7dD1ILlZNKFtdLHUuSikKZm9yKHM9bC5sZW5n
+dGgscj0wO3I8bC5sZW5ndGg7bC5sZW5ndGg9PT1zfHwoMCxILmxrKShsKSwrK3Ipe3E9bFtyXQpDLk5t
+LmkodCxQLkVGKFsiZGVzY3JpcHRpb24iLHEuYSwiaHJlZiIscS5iXSxvLG4pKX1tLlkoMCwiZWRpdHMi
+LHQpfW0uWSgwLCJleHBsYW5hdGlvbiIscC5iKQptLlkoMCwibGluZSIscC5jKQptLlkoMCwiZGlzcGxh
+eVBhdGgiLHAuZCkKbS5ZKDAsInVyaVBhdGgiLHAuZSkKbz1wLmYKaWYobyE9bnVsbCl7bj1ILlZNKFtd
+LHUuSikKZm9yKGw9by5sZW5ndGgscj0wO3I8by5sZW5ndGg7by5sZW5ndGg9PT1sfHwoMCxILmxrKShv
+KSwrK3IpQy5ObS5pKG4sb1tyXS5MdCgpKQptLlkoMCwidHJhY2VzIixuKX1yZXR1cm4gbX19ClUuU2Uu
+cHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXtyZXR1cm4gUC5FRihbImRlc2NyaXB0aW9uIix0aGlzLmEs
+ImhyZWYiLHRoaXMuYl0sdS5OLHUuSyl9fQpVLk1sLnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9uKCl7cmV0
+dXJuIFAuRUYoWyJocmVmIix0aGlzLmEsImxpbmUiLHRoaXMuYiwicGF0aCIsdGhpcy5jXSx1Lk4sdS5L
+KX19ClUueUQucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIscT1ILlZNKFtdLHUuSikK
+Zm9yKHQ9dGhpcy5iLHM9dC5sZW5ndGgscj0wO3I8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxr
+KSh0KSwrK3IpQy5ObS5pKHEsdFtyXS5MdCgpKQpyZXR1cm4gUC5FRihbImRlc2NyaXB0aW9uIix0aGlz
+LmEsImVudHJpZXMiLHFdLHUuTix1LkspfX0KVS53Yi5wcm90b3R5cGU9ewpMdDpmdW5jdGlvbigpe3Zh
+ciB0LHMscj10aGlzLHE9UC5GbCh1Lk4sdS5LKQpxLlkoMCwiZGVzY3JpcHRpb24iLHIuYSkKdD1yLmIK
+aWYodCE9bnVsbClxLlkoMCwiZnVuY3Rpb24iLHQpCnQ9ci5jCmlmKHQhPW51bGwpcS5ZKDAsImxpbmsi
+LHQuTHQoKSkKdD1yLmQKaWYodC5sZW5ndGghPT0wKXtzPUgudDYodCkKcS5ZKDAsImhpbnRBY3Rpb25z
+IixuZXcgSC5BOCh0LHMuQygiWjA8cVUsaz4oMSkiKS5iKG5ldyBVLmIwKCkpLHMuQygiQTg8MSxaMDxx
+VSxrPj4iKSkuYnIoMCkpfXJldHVybiBxfX0KVS5hTi5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXty
+ZXR1cm4gVS5ueih1LlMuYShhKSl9LAokUzozN30KVS5iMC5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihh
+KXtyZXR1cm4gdS5ELmIoYSkuTHQoKX0sCiRTOjM4fQpCLmo4LnByb3RvdHlwZT17Ckx0OmZ1bmN0aW9u
+KCl7cmV0dXJuIFAuRUYoWyJsaW5lIix0aGlzLmEsImV4cGxhbmF0aW9uIix0aGlzLmIsIm9mZnNldCIs
+dGhpcy5jXSx1Lk4sdS5LKX19CkIucXAucHJvdG90eXBlPXsKTHQ6ZnVuY3Rpb24oKXt2YXIgdCxzLHIs
+cSxwLG8sbixtPXRoaXMsbD11Lk4saz1QLkZsKGwsdS5kMykKZm9yKHQ9bS5kLHQ9dC5nUHUodCksdD10
+Lmdreih0KSxzPXUuSyxyPXUuSjt0LkYoKTspe3E9dC5nbCgpCnA9cS5hCm89SC5WTShbXSxyKQpmb3Io
+cT1KLklUKHEuYik7cS5GKCk7KXtuPXEuZ2woKQpDLk5tLmkobyxQLkVGKFsibGluZSIsbi5hLCJleHBs
+YW5hdGlvbiIsbi5iLCJvZmZzZXQiLG4uY10sbCxzKSl9ay5ZKDAscCxvKX1yZXR1cm4gUC5FRihbInJl
+Z2lvbnMiLG0uYSwibmF2aWdhdGlvbkNvbnRlbnQiLG0uYiwic291cmNlQ29kZSIsbS5jLCJlZGl0cyIs
+a10sbCxzKX19ClQubVEucHJvdG90eXBlPXt9CkwuZS5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2
+YXIgdCxzLHIscSxwLG8sbgp1LkIuYihhKQp0PXdpbmRvdy5sb2NhdGlvbi5wYXRobmFtZQpzPUwuRzYo
+d2luZG93LmxvY2F0aW9uLmhyZWYpCnI9TC5hSyh3aW5kb3cubG9jYXRpb24uaHJlZikKTC5HZSgpCmlm
+KHQhPT0iLyImJnQhPT1KLlQwKGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoIi5yb290IikudGV4dENvbnRl
+bnQpKUwuRzcodCxzLHIsITAsbmV3IEwuVlcodCxzLHIpKQpxPWRvY3VtZW50CnA9Si5xRihxLnF1ZXJ5
+U2VsZWN0b3IoIi5hcHBseS1taWdyYXRpb24iKSkKbz1wLiR0aQpuPW8uQygifigxKSIpLmIobmV3IEwu
+b1ooKSkKdS5NLmIobnVsbCkKVy5KRShwLmEscC5iLG4sITEsby5kKQpvPUoucUYocS5xdWVyeVNlbGVj
+dG9yKCIucmVydW4tbWlncmF0aW9uIikpCm49by4kdGkKVy5KRShvLmEsby5iLG4uQygifigxKSIpLmIo
+bmV3IEwueTgoKSksITEsbi5kKQpuPUoucUYocS5xdWVyeVNlbGVjdG9yKCIucmVwb3J0LXByb2JsZW0i
+KSkKbz1uLiR0aQpXLkpFKG4uYSxuLmIsby5DKCJ+KDEpIikuYihuZXcgTC5IaSgpKSwhMSxvLmQpCnE9
+Si5xRihxLnF1ZXJ5U2VsZWN0b3IoIi5wb3B1cC1wYW5lIC5jbG9zZSIpKQpvPXEuJHRpClcuSkUocS5h
+LHEuYixvLkMoIn4oMSkiKS5iKG5ldyBMLkJUKCkpLCExLG8uZCl9LAokUzoxNn0KTC5WVy5wcm90b3R5
+cGU9ewokMDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5vWi5w
+cm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscQp1LlYuYihhKQppZihILm9UKHdpbmRv
+dy5jb25maXJtKCJUaGlzIHdpbGwgYXBwbHkgdGhlIGNoYW5nZXMgeW91J3ZlIHByZXZpZXdlZCB0byB5
+b3VyIHdvcmtpbmcgZGlyZWN0b3J5LiBJdCBpcyByZWNvbW1lbmRlZCB5b3UgY29tbWl0IGFueSBjaGFu
+Z2VzIHlvdSBtYWRlIGJlZm9yZSBkb2luZyB0aGlzLiIpKSl7dD1MLnR5KCIvYXBwbHktbWlncmF0aW9u
+IixudWxsKS5XNyhuZXcgTC5qcigpLHUuUCkKcz1uZXcgTC5xbCgpCnUuYmYuYihudWxsKQpyPXQuJHRp
+CnE9JC5YMwppZihxIT09Qy5OVSlzPVAuVkgocyxxKQp0LnhmKG5ldyBQLkZlKG5ldyBQLnZzKHEsciks
+MixudWxsLHMsci5DKCJAPDE+IikuS3Eoci5kKS5DKCJGZTwxLDI+IikpKX19LAokUzozfQpMLmpyLnBy
+b3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuUy5iKGEpCnQ9ZG9jdW1lbnQuYm9keQp0LmNs
+YXNzTGlzdC5yZW1vdmUoInByb3Bvc2VkIikKdC5jbGFzc0xpc3QuYWRkKCJhcHBsaWVkIil9LAokUzo0
+MX0KTC5xbC5wcm90b3R5cGU9ewokMjpmdW5jdGlvbihhLGIpe0wuQzIoIkNvdWxkIG5vdCBhcHBseSBt
+aWdyYXRpb24iLGEsYil9LAokQzoiJDIiLAokUjoyLAokUzo0fQpMLnk4LnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3JldHVybiB0aGlzLnhuKHUuVi5iKGEpKX0sCnhuOmZ1bmN0aW9uKGEpe3ZhciB0PTAs
+cz1QLkZYKHUuUCkscj0xLHEscD1bXSxvLG4sbSxsCnZhciAkYXN5bmMkJDE9UC5seihmdW5jdGlvbihi
+LGMpe2lmKGI9PT0xKXtxPWMKdD1yfXdoaWxlKHRydWUpc3dpdGNoKHQpe2Nhc2UgMDpyPTMKZG9jdW1l
+bnQuYm9keS5jbGFzc0xpc3QuYWRkKCJyZXJ1bm5pbmciKQp0PTYKcmV0dXJuIFAualEoTC50eSgiL3Jl
+cnVuLW1pZ3JhdGlvbiIsbnVsbCksJGFzeW5jJCQxKQpjYXNlIDY6d2luZG93LmxvY2F0aW9uLnJlbG9h
+ZCgpCnAucHVzaCg1KQp0PTQKYnJlYWsKY2FzZSAzOnI9MgpsPXEKbz1ILlJ1KGwpCm49SC50cyhsKQpM
+LkMyKCJGYWlsZWQgdG8gcmVydW4gbWlncmF0aW9uIixvLG4pCnAucHVzaCg1KQp0PTQKYnJlYWsKY2Fz
+ZSAyOnA9WzFdCmNhc2UgNDpyPTEKZG9jdW1lbnQuYm9keS5jbGFzc0xpc3QucmVtb3ZlKCJyZXJ1bm5p
+bmciKQp0PXAucG9wKCkKYnJlYWsKY2FzZSA1OnJldHVybiBQLnlDKG51bGwscykKY2FzZSAxOnJldHVy
+biBQLmYzKHEscyl9fSkKcmV0dXJuIFAuREkoJGFzeW5jJCQxLHMpfSwKJFM6MTd9CkwuSGkucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQKdS5WLmIoYSkKdD11Lk4KQy5vbC5Qbyh3aW5kb3csUC5Y
+ZCgiaHR0cHMiLCJnaXRodWIuY29tIiwiZGFydC1sYW5nL3Nkay9pc3N1ZXMvbmV3IixQLkVGKFsidGl0
+bGUiLCJDdXN0b21lci1yZXBvcnRlZCBpc3N1ZSB3aXRoIE5OQkQgbWlncmF0aW9uIHRvb2wiLCJsYWJl
+bHMiLCJhcmVhLWFuYWx5emVyLGFuYWx5emVyLW5uYmQtbWlncmF0aW9uLHR5cGUtYnVnIiwiYm9keSIs
+IiMjIyMgU3RlcHMgdG8gcmVwcm9kdWNlXG5cbiMjIyMgV2hhdCBkaWQgeW91IGV4cGVjdCB0byBoYXBw
+ZW4/XG5cbiMjIyMgV2hhdCBhY3R1YWxseSBoYXBwZW5lZD9cblxuX1NjcmVlbnNob3RzIGFyZSBhcHBy
+ZWNpYXRlZF9cblxuKipEYXJ0IFNESyB2ZXJzaW9uKio6ICIrSC5kKGRvY3VtZW50LmdldEVsZW1lbnRC
+eUlkKCJzZGstdmVyc2lvbiIpLnRleHRDb250ZW50KSsiXG5cblRoYW5rcyBmb3IgZmlsaW5nIVxuIl0s
+dCx0KSkudygwKSwicmVwb3J0LXByb2JsZW0iKX0sCiRTOjN9CkwuQlQucHJvdG90eXBlPXsKJDE6ZnVu
+Y3Rpb24oYSl7dmFyIHQKdS5WLmIoYSkKdD1kb2N1bWVudC5xdWVyeVNlbGVjdG9yKCIucG9wdXAtcGFu
+ZSIpLnN0eWxlCnJldHVybiB0LmRpc3BsYXk9Im5vbmUifSwKJFM6NDN9CkwuTC5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt2YXIgdCxzLHIKdS5CLmIoYSkKdD13aW5kb3cubG9jYXRpb24ucGF0aG5hbWUK
+cz1MLkc2KHdpbmRvdy5sb2NhdGlvbi5ocmVmKQpyPUwuYUsod2luZG93LmxvY2F0aW9uLmhyZWYpCmlm
+KHQubGVuZ3RoPjEpTC5HNyh0LHMsciwhMSxudWxsKQplbHNle0wuQkUodCxuZXcgQi5xcCgiIiwiIiwi
+IixDLkNNKSwhMCkKTC5CWCgiJm5ic3A7IixudWxsKX19LAokUzoxNn0KTC5XeC5wcm90b3R5cGU9ewok
+MTpmdW5jdGlvbihhKXt2YXIgdCxzLHIscT0iY29sbGFwc2VkIgp1LlYuYihhKQp0PXRoaXMuYQpzPUou
+UkUodCkKcj10aGlzLmIKaWYoIXMuZ1AodCkudGcoMCxxKSl7cy5nUCh0KS5pKDAscSkKSi5kUihyKS5p
+KDAscSl9ZWxzZXtzLmdQKHQpLlIoMCxxKQpKLmRSKHIpLlIoMCxxKX19LAokUzozfQpMLkFPLnByb3Rv
+dHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0PUoucUYodS5oLmIoYSkpLHM9dC4kdGkscj1zLkMoIn4o
+MSkiKS5iKG5ldyBMLmROKHRoaXMuYSkpCnUuTS5iKG51bGwpClcuSkUodC5hLHQuYixyLCExLHMuZCl9
+LAokUzo2fQpMLmROLnByb3RvdHlwZT17CiQxOmZ1bmN0aW9uKGEpe3ZhciB0CnUuVi5iKGEpCnQ9ZG9j
+dW1lbnQucXVlcnlTZWxlY3RvcigidGFibGVbZGF0YS1wYXRoXSIpCnQudG9TdHJpbmcKTC50MihhLHRo
+aXMuYSx0LmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KHQpKS5PKCJwYXRoIikp
+KX0sCiRTOjN9CkwuSG8ucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQscyxyCnUuaC5iKGEp
+CnQ9Si5xRihhKQpzPXQuJHRpCnI9cy5DKCJ+KDEpIikuYihuZXcgTC54eihhLHRoaXMuYSkpCnUuTS5i
+KG51bGwpClcuSkUodC5hLHQuYixyLCExLHMuZCl9LAokUzo2fQpMLnh6LnByb3RvdHlwZT17CiQxOmZ1
+bmN0aW9uKGEpe3ZhciB0LHM9bnVsbAp1LlYuYihhKQp0PXRoaXMuYQpMLmhYKHRoaXMuYixQLlFBKHQu
+Z2V0QXR0cmlidXRlKCJkYXRhLSIrbmV3IFcuU3kobmV3IFcuaTcodCkpLk8oIm9mZnNldCIpKSxzLHMp
+LFAuUUEodC5nZXRBdHRyaWJ1dGUoImRhdGEtIituZXcgVy5TeShuZXcgVy5pNyh0KSkuTygibGluZSIp
+KSxzLHMpKX0sCiRTOjN9CkwuSUMucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dmFyIHQ9Si5xRih1
+LmguYihhKSkscz10LiR0aQpzLkMoIn4oMSkiKS5iKEwuaVMoKSkKdS5NLmIobnVsbCkKVy5KRSh0LmEs
+dC5iLEwuaVMoKSwhMSxzLmQpfSwKJFM6Nn0KTC5mQy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXt1
+LnAuYihhKQp0aGlzLmEuYU0oMCx0aGlzLmIpfSwKJFM6NDV9CkwublQucHJvdG90eXBlPXsKJDA6ZnVu
+Y3Rpb24oKXtMLkZyKHRoaXMuYS5hLHRoaXMuYix0aGlzLmMpfSwKJFM6MH0KTC5CWi5wcm90b3R5cGU9
+ewokMDpmdW5jdGlvbigpe0wuRnIodGhpcy5hLmEsbnVsbCxudWxsKX0sCiRTOjB9CkwuR0gucHJvdG90
+eXBlPXsKJDE6ZnVuY3Rpb24oYSl7dS5oLmIoYSkKJC56QigpLnRvU3RyaW5nCnUubS5hKCQub3coKS5x
+KDAsImhsanMiKSkuVjcoImhpZ2hsaWdodEJsb2NrIixbYV0pfSwKJFM6Nn0KTC5FRS5wcm90b3R5cGU9
+ewokMTpmdW5jdGlvbihhKXt2YXIgdCxzCnUuVi5iKGEpCnQ9dGhpcy5hCnM9dGhpcy5iCkwuYWYod2lu
+ZG93LmxvY2F0aW9uLnBhdGhuYW1lLHQscywhMCxuZXcgTC5RTCh0LHMpKQpMLmhYKHRoaXMuYyx0LHMp
+fSwKJFM6M30KTC5RTC5wcm90b3R5cGU9ewokMDpmdW5jdGlvbigpe0wuRnIod2luZG93LmxvY2F0aW9u
+LnBhdGhuYW1lLHRoaXMuYSx0aGlzLmIpfSwKJFM6MH0KTC5WUy5wcm90b3R5cGU9ewokMTpmdW5jdGlv
+bihhKXt2YXIgdCxzPSJzZWxlY3RlZC1maWxlIgp1LmguYihhKQphLnRvU3RyaW5nCnQ9Si5SRShhKQpp
+ZihhLmdldEF0dHJpYnV0ZSgiZGF0YS0iK25ldyBXLlN5KG5ldyBXLmk3KGEpKS5PKCJuYW1lIikpPT09
+dGhpcy5hLmEpdC5nUChhKS5pKDAscykKZWxzZSB0LmdQKGEpLlIoMCxzKX0sCiRTOjZ9CkwuVEQucHJv
+dG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEwudDIodS5WLmIoYSksITAsbnVsbCl9LAokUzox
+OH0KTC5BUy5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5QTCh1LlYuYihhKSl9
+LApQTDpmdW5jdGlvbihhKXt2YXIgdD0wLHM9UC5GWCh1LlApLHI9MSxxLHA9W10sbz10aGlzLG4sbSxs
+LGssagp2YXIgJGFzeW5jJCQxPVAubHooZnVuY3Rpb24oYixjKXtpZihiPT09MSl7cT1jCnQ9cn13aGls
+ZSh0cnVlKXN3aXRjaCh0KXtjYXNlIDA6cj0zCmw9dS5OCnQ9NgpyZXR1cm4gUC5qUShMLnR5KEwuUTQo
+Ii9hcHBseS1oaW50IixQLkZsKGwsbCkpLG8uYS5MdCgpKSwkYXN5bmMkJDEpCmNhc2UgNjpsPW8uYgpM
+Lkc3KGwuYyxudWxsLGwuYiwhMSxudWxsKQpkb2N1bWVudC5ib2R5LmNsYXNzTGlzdC5hZGQoIm5lZWRz
+LXJlcnVuIikKcj0xCnQ9NQpicmVhawpjYXNlIDM6cj0yCmo9cQpuPUguUnUoaikKbT1ILnRzKGopCkwu
+QzIoIkNvdWxkIG5vdCBhcHBseSBoaW50IixuLG0pCnQ9NQpicmVhawpjYXNlIDI6dD0xCmJyZWFrCmNh
+c2UgNTpyZXR1cm4gUC55QyhudWxsLHMpCmNhc2UgMTpyZXR1cm4gUC5mMyhxLHMpfX0pCnJldHVybiBQ
+LkRJKCRhc3luYyQkMSxzKX0sCiRTOjE3fQpMLlhBLnByb3RvdHlwZT17CkViOmZ1bmN0aW9uKGEsYixj
+KXtyZXR1cm4hMH0sCmkwOmZ1bmN0aW9uKGEpe3JldHVybiEwfSwKJGlrRjoxfQpMLlpaLnByb3RvdHlw
+ZT17Ckx0OmZ1bmN0aW9uKCl7dmFyIHQscz10aGlzLHI9UC5GbCh1Lk4sdS5LKQpyLlkoMCwidHlwZSIs
+TC52eShzLmEpKQpyLlkoMCwibmFtZSIscy5iKQp0PXMuYwppZih0IT1udWxsKXIuWSgwLCJzdWJ0cmVl
+IixMLlZEKHQpKQp0PXMuZAppZih0IT1udWxsKXIuWSgwLCJwYXRoIix0KQp0PXMuZQppZih0IT1udWxs
+KXIuWSgwLCJocmVmIix0KQp0PXMuZgppZih0IT1udWxsKXIuWSgwLCJlZGl0Q291bnQiLHQpCnJldHVy
+biByfX0KTC5POS5wcm90b3R5cGU9ewp3OmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLmJ9fQpNLmxJLnBy
+b3RvdHlwZT17CldPOmZ1bmN0aW9uKGEsYil7dmFyIHQscz1udWxsCk0uWUYoImFic29sdXRlIixILlZN
+KFtiLG51bGwsbnVsbCxudWxsLG51bGwsbnVsbCxudWxsXSx1LnMpKQp0PXRoaXMuYQp0PXQuWXIoYik+
+MCYmIXQuaEsoYikKaWYodClyZXR1cm4gYgp0PUQuUlgoKQpyZXR1cm4gdGhpcy5xNygwLHQsYixzLHMs
+cyxzLHMscyl9LAp6ZjpmdW5jdGlvbihhKXt2YXIgdCxzLHI9WC5DTChhLHRoaXMuYSkKci5JVigpCnQ9
+ci5kCnM9dC5sZW5ndGgKaWYocz09PTApe3Q9ci5iCnJldHVybiB0PT1udWxsPyIuIjp0fWlmKHM9PT0x
+KXt0PXIuYgpyZXR1cm4gdD09bnVsbD8iLiI6dH1pZigwPj1zKXJldHVybiBILk9IKHQsLTEpCnQucG9w
+KCkKQy5ObS5tdihyLmUpCnIuSVYoKQpyZXR1cm4gci53KDApfSwKcTc6ZnVuY3Rpb24oYSxiLGMsZCxl
+LGYsZyxoLGkpe3ZhciB0PUguVk0oW2IsYyxkLGUsZixnLGgsaV0sdS5zKQpNLllGKCJqb2luIix0KQpy
+ZXR1cm4gdGhpcy5JUChuZXcgSC5VNSh0LHUuYkIuYihuZXcgTS5NaSgpKSx1LmNjKSl9LApJUDpmdW5j
+dGlvbihhKXt2YXIgdCxzLHIscSxwLG8sbixtLGwsawp1LlguYihhKQpmb3IodD1hLiR0aSxzPXQuQygi
+YTIoY1guRSkiKS5iKG5ldyBNLnE3KCkpLHI9YS5na3ooYSksdD1uZXcgSC5TTyhyLHMsdC5DKCJTTzxj
+WC5FPiIpKSxzPXRoaXMuYSxxPSExLHA9ITEsbz0iIjt0LkYoKTspe249ci5nbCgpCmlmKHMuaEsobikm
+JnApe209WC5DTChuLHMpCmw9by5jaGFyQ29kZUF0KDApPT0wP286bwpvPUMueEIuTmoobCwwLHMuU3Ao
+bCwhMCkpCm0uYj1vCmlmKHMuZHMobykpQy5ObS5ZKG0uZSwwLHMuZ21JKCkpCm89bS53KDApfWVsc2Ug
+aWYocy5ZcihuKT4wKXtwPSFzLmhLKG4pCm89SC5kKG4pfWVsc2V7az1uLmxlbmd0aAppZihrIT09MCl7
+aWYoMD49aylyZXR1cm4gSC5PSChuLDApCms9cy5VZChuWzBdKX1lbHNlIGs9ITEKaWYoIWspaWYocSlv
+Kz1zLmdtSSgpCm8rPW59cT1zLmRzKG4pfXJldHVybiBvLmNoYXJDb2RlQXQoMCk9PTA/bzpvfSwKbzU6
+ZnVuY3Rpb24oYSl7dmFyIHQKaWYoIXRoaXMueTMoYSkpcmV0dXJuIGEKdD1YLkNMKGEsdGhpcy5hKQp0
+LnJSKCkKcmV0dXJuIHQudygwKX0sCnkzOmZ1bmN0aW9uKGEpe3ZhciB0LHMscixxLHAsbyxuLG0sbCxr
+CmEudG9TdHJpbmcKdD10aGlzLmEKcz10LllyKGEpCmlmKHMhPT0wKXtpZih0PT09JC5LaygpKWZvcihy
+PTA7cjxzOysrcilpZihDLnhCLlcoYSxyKT09PTQ3KXJldHVybiEwCnE9cwpwPTQ3fWVsc2V7cT0wCnA9
+bnVsbH1mb3Iobz1uZXcgSC5xaihhKS5hLG49by5sZW5ndGgscj1xLG09bnVsbDtyPG47KytyLG09cCxw
+PWwpe2w9Qy54Qi5tKG8scikKaWYodC5yNChsKSl7aWYodD09PSQuS2soKSYmbD09PTQ3KXJldHVybiEw
+CmlmKHAhPW51bGwmJnQucjQocCkpcmV0dXJuITAKaWYocD09PTQ2KWs9bT09bnVsbHx8bT09PTQ2fHx0
+LnI0KG0pCmVsc2Ugaz0hMQppZihrKXJldHVybiEwfX1pZihwPT1udWxsKXJldHVybiEwCmlmKHQucjQo
+cCkpcmV0dXJuITAKaWYocD09PTQ2KXQ9bT09bnVsbHx8dC5yNChtKXx8bT09PTQ2CmVsc2UgdD0hMQpp
+Zih0KXJldHVybiEwCnJldHVybiExfSwKSFA6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwLG8sbixt
+PXRoaXMsbD0nVW5hYmxlIHRvIGZpbmQgYSBwYXRoIHRvICInCmI9bS5XTygwLGIpCnQ9bS5hCmlmKHQu
+WXIoYik8PTAmJnQuWXIoYSk+MClyZXR1cm4gbS5vNShhKQppZih0LllyKGEpPD0wfHx0LmhLKGEpKWE9
+bS5XTygwLGEpCmlmKHQuWXIoYSk8PTAmJnQuWXIoYik+MCl0aHJvdyBILmIoWC5JNyhsK0guZChhKSsn
+IiBmcm9tICInK0guZChiKSsnIi4nKSkKcz1YLkNMKGIsdCkKcy5yUigpCnI9WC5DTChhLHQpCnIuclIo
+KQpxPXMuZApwPXEubGVuZ3RoCmlmKHAhPT0wKXtpZigwPj1wKXJldHVybiBILk9IKHEsMCkKcT1KLlJN
+KHFbMF0sIi4iKX1lbHNlIHE9ITEKaWYocSlyZXR1cm4gci53KDApCnE9cy5iCnA9ci5iCmlmKHEhPXAp
+cT1xPT1udWxsfHxwPT1udWxsfHwhdC5OYyhxLHApCmVsc2UgcT0hMQppZihxKXJldHVybiByLncoMCkK
+d2hpbGUoITApe3E9cy5kCnA9cS5sZW5ndGgKaWYocCE9PTApe289ci5kCm49by5sZW5ndGgKaWYobiE9
+PTApe2lmKDA+PXApcmV0dXJuIEguT0gocSwwKQpxPXFbMF0KaWYoMD49bilyZXR1cm4gSC5PSChvLDAp
+Cm89dC5OYyhxLG9bMF0pCnE9b31lbHNlIHE9ITF9ZWxzZSBxPSExCmlmKCFxKWJyZWFrCkMuTm0uVzQo
+cy5kLDApCkMuTm0uVzQocy5lLDEpCkMuTm0uVzQoci5kLDApCkMuTm0uVzQoci5lLDEpfXE9cy5kCnA9
+cS5sZW5ndGgKaWYocCE9PTApe2lmKDA+PXApcmV0dXJuIEguT0gocSwwKQpxPUouUk0ocVswXSwiLi4i
+KX1lbHNlIHE9ITEKaWYocSl0aHJvdyBILmIoWC5JNyhsK0guZChhKSsnIiBmcm9tICInK0guZChiKSsn
+Ii4nKSkKcT11Lk4KQy5ObS5VRyhyLmQsMCxQLk84KHMuZC5sZW5ndGgsIi4uIiwhMSxxKSkKQy5ObS5Z
+KHIuZSwwLCIiKQpDLk5tLlVHKHIuZSwxLFAuTzgocy5kLmxlbmd0aCx0LmdtSSgpLCExLHEpKQp0PXIu
+ZApxPXQubGVuZ3RoCmlmKHE9PT0wKXJldHVybiIuIgppZihxPjEmJkouUk0oQy5ObS5ncloodCksIi4i
+KSl7dD1yLmQKaWYoMD49dC5sZW5ndGgpcmV0dXJuIEguT0godCwtMSkKdC5wb3AoKQp0PXIuZQpDLk5t
+Lm12KHQpCkMuTm0ubXYodCkKQy5ObS5pKHQsIiIpfXIuYj0iIgpyLklWKCkKcmV0dXJuIHIudygwKX19
+Ck0uTWkucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEgueShhKSE9bnVsbH0sCiRTOjd9
+Ck0ucTcucHJvdG90eXBlPXsKJDE6ZnVuY3Rpb24oYSl7cmV0dXJuIEgueShhKSE9PSIifSwKJFM6N30K
+TS5Oby5wcm90b3R5cGU9ewokMTpmdW5jdGlvbihhKXtILnkoYSkKcmV0dXJuIGE9PW51bGw/Im51bGwi
+OiciJythKyciJ30sCiRTOjV9CkIuZnYucHJvdG90eXBlPXsKeFo6ZnVuY3Rpb24oYSl7dmFyIHQscz10
+aGlzLllyKGEpCmlmKHM+MClyZXR1cm4gSi5sZChhLDAscykKaWYodGhpcy5oSyhhKSl7aWYoMD49YS5s
+ZW5ndGgpcmV0dXJuIEguT0goYSwwKQp0PWFbMF19ZWxzZSB0PW51bGwKcmV0dXJuIHR9LApOYzpmdW5j
+dGlvbihhLGIpe3JldHVybiBhPT1ifX0KWC5XRC5wcm90b3R5cGU9ewpJVjpmdW5jdGlvbigpe3ZhciB0
+LHMscj10aGlzCndoaWxlKCEwKXt0PXIuZAppZighKHQubGVuZ3RoIT09MCYmSi5STShDLk5tLmdyWih0
+KSwiIikpKWJyZWFrCnQ9ci5kCmlmKDA+PXQubGVuZ3RoKXJldHVybiBILk9IKHQsLTEpCnQucG9wKCkK
+Qy5ObS5tdihyLmUpfXQ9ci5lCnM9dC5sZW5ndGgKaWYocyE9PTApQy5ObS5ZKHQscy0xLCIiKX0sCnJS
+OmZ1bmN0aW9uKCl7dmFyIHQscyxyLHEscCxvLG49dGhpcyxtPUguVk0oW10sdS5zKQpmb3IodD1uLmQs
+cz10Lmxlbmd0aCxyPTAscT0wO3E8dC5sZW5ndGg7dC5sZW5ndGg9PT1zfHwoMCxILmxrKSh0KSwrK3Ep
+e3A9dFtxXQpvPUouaWEocCkKaWYoIShvLkROKHAsIi4iKXx8by5ETihwLCIiKSkpaWYoby5ETihwLCIu
+LiIpKXtvPW0ubGVuZ3RoCmlmKG8hPT0wKXtpZigwPj1vKXJldHVybiBILk9IKG0sLTEpCm0ucG9wKCl9
+ZWxzZSArK3J9ZWxzZSBDLk5tLmkobSxwKX1pZihuLmI9PW51bGwpQy5ObS5VRyhtLDAsUC5POChyLCIu
+LiIsITEsdS5OKSkKaWYobS5sZW5ndGg9PT0wJiZuLmI9PW51bGwpQy5ObS5pKG0sIi4iKQpuLnNuSiht
+KQp0PW4uYQpuLnNQaChQLk84KG0ubGVuZ3RoKzEsdC5nbUkoKSwhMCx1Lk4pKQpzPW4uYgppZihzPT1u
+dWxsfHxtLmxlbmd0aD09PTB8fCF0LmRzKHMpKUMuTm0uWShuLmUsMCwiIikKcz1uLmIKaWYocyE9bnVs
+bCYmdD09PSQuS2soKSl7cy50b1N0cmluZwpuLmI9SC55cyhzLCIvIiwiXFwiKX1uLklWKCl9LAp3OmZ1
+bmN0aW9uKGEpe3ZhciB0LHMscj10aGlzLHE9ci5iCnE9cSE9bnVsbD9xOiIiCmZvcih0PTA7dDxyLmQu
+bGVuZ3RoOysrdCl7cz1yLmUKaWYodD49cy5sZW5ndGgpcmV0dXJuIEguT0gocyx0KQpzPXErSC5kKHNb
+dF0pCnE9ci5kCmlmKHQ+PXEubGVuZ3RoKXJldHVybiBILk9IKHEsdCkKcT1zK0guZChxW3RdKX1xKz1I
+LmQoQy5ObS5nclooci5lKSkKcmV0dXJuIHEuY2hhckNvZGVBdCgwKT09MD9xOnF9LApzbko6ZnVuY3Rp
+b24oYSl7dGhpcy5kPXUuYS5iKGEpfSwKc1BoOmZ1bmN0aW9uKGEpe3RoaXMuZT11LmEuYihhKX19Clgu
+ZHYucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4iUGF0aEV4Y2VwdGlvbjogIit0aGlzLmF9
+LAokaVJ6OjF9Ck8uekwucHJvdG90eXBlPXsKdzpmdW5jdGlvbihhKXtyZXR1cm4gdGhpcy5nb2ModGhp
+cyl9fQpFLk9GLnByb3RvdHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0s
+CnI0OmZ1bmN0aW9uKGEpe3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0
+aApyZXR1cm4gdCE9PTAmJkMueEIubShhLHQtMSkhPT00N30sClNwOmZ1bmN0aW9uKGEsYil7aWYoYS5s
+ZW5ndGghPT0wJiZDLnhCLlcoYSwwKT09PTQ3KXJldHVybiAxCnJldHVybiAwfSwKWXI6ZnVuY3Rpb24o
+YSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1cm4hMX0sCmdvYzpmdW5j
+dGlvbigpe3JldHVybiJwb3NpeCJ9LApnbUk6ZnVuY3Rpb24oKXtyZXR1cm4iLyJ9fQpGLnJ1LnByb3Rv
+dHlwZT17ClVkOmZ1bmN0aW9uKGEpe3JldHVybiBDLnhCLnRnKGEsIi8iKX0sCnI0OmZ1bmN0aW9uKGEp
+e3JldHVybiBhPT09NDd9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1
+cm4hMQppZihDLnhCLm0oYSx0LTEpIT09NDcpcmV0dXJuITAKcmV0dXJuIEMueEIuVGMoYSwiOi8vIikm
+JnRoaXMuWXIoYSk9PT10fSwKU3A6ZnVuY3Rpb24oYSxiKXt2YXIgdCxzLHIscSxwPWEubGVuZ3RoCmlm
+KHA9PT0wKXJldHVybiAwCmlmKEMueEIuVyhhLDApPT09NDcpcmV0dXJuIDEKZm9yKHQ9MDt0PHA7Kyt0
+KXtzPUMueEIuVyhhLHQpCmlmKHM9PT00NylyZXR1cm4gMAppZihzPT09NTgpe2lmKHQ9PT0wKXJldHVy
+biAwCnI9Qy54Qi5YVShhLCIvIixDLnhCLlFpKGEsIi8vIix0KzEpP3QrMzp0KQppZihyPD0wKXJldHVy
+biBwCmlmKCFifHxwPHIrMylyZXR1cm4gcgppZighQy54Qi5uKGEsImZpbGU6Ly8iKSlyZXR1cm4gcgpp
+ZighQi5ZdShhLHIrMSkpcmV0dXJuIHIKcT1yKzMKcmV0dXJuIHA9PT1xP3E6cis0fX1yZXR1cm4gMH0s
+CllyOmZ1bmN0aW9uKGEpe3JldHVybiB0aGlzLlNwKGEsITEpfSwKaEs6ZnVuY3Rpb24oYSl7cmV0dXJu
+IGEubGVuZ3RoIT09MCYmQy54Qi5XKGEsMCk9PT00N30sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ1cmwi
+fSwKZ21JOmZ1bmN0aW9uKCl7cmV0dXJuIi8ifX0KTC5JVi5wcm90b3R5cGU9ewpVZDpmdW5jdGlvbihh
+KXtyZXR1cm4gQy54Qi50ZyhhLCIvIil9LApyNDpmdW5jdGlvbihhKXtyZXR1cm4gYT09PTQ3fHxhPT09
+OTJ9LApkczpmdW5jdGlvbihhKXt2YXIgdD1hLmxlbmd0aAppZih0PT09MClyZXR1cm4hMQp0PUMueEIu
+bShhLHQtMSkKcmV0dXJuISh0PT09NDd8fHQ9PT05Mil9LApTcDpmdW5jdGlvbihhLGIpe3ZhciB0LHMs
+cj1hLmxlbmd0aAppZihyPT09MClyZXR1cm4gMAp0PUMueEIuVyhhLDApCmlmKHQ9PT00NylyZXR1cm4g
+MQppZih0PT09OTIpe2lmKHI8Mnx8Qy54Qi5XKGEsMSkhPT05MilyZXR1cm4gMQpzPUMueEIuWFUoYSwi
+XFwiLDIpCmlmKHM+MCl7cz1DLnhCLlhVKGEsIlxcIixzKzEpCmlmKHM+MClyZXR1cm4gc31yZXR1cm4g
+cn1pZihyPDMpcmV0dXJuIDAKaWYoIUIuT1ModCkpcmV0dXJuIDAKaWYoQy54Qi5XKGEsMSkhPT01OCly
+ZXR1cm4gMApyPUMueEIuVyhhLDIpCmlmKCEocj09PTQ3fHxyPT09OTIpKXJldHVybiAwCnJldHVybiAz
+fSwKWXI6ZnVuY3Rpb24oYSl7cmV0dXJuIHRoaXMuU3AoYSwhMSl9LApoSzpmdW5jdGlvbihhKXtyZXR1
+cm4gdGhpcy5ZcihhKT09PTF9LApPdDpmdW5jdGlvbihhLGIpe3ZhciB0CmlmKGE9PT1iKXJldHVybiEw
+CmlmKGE9PT00NylyZXR1cm4gYj09PTkyCmlmKGE9PT05MilyZXR1cm4gYj09PTQ3CmlmKChhXmIpIT09
+MzIpcmV0dXJuITEKdD1hfDMyCnJldHVybiB0Pj05NyYmdDw9MTIyfSwKTmM6ZnVuY3Rpb24oYSxiKXt2
+YXIgdCxzLHIKaWYoYT09YilyZXR1cm4hMAp0PWEubGVuZ3RoCmlmKHQhPT1iLmxlbmd0aClyZXR1cm4h
+MQpmb3Iocz1KLnJZKGIpLHI9MDtyPHQ7KytyKWlmKCF0aGlzLk90KEMueEIuVyhhLHIpLHMuVyhiLHIp
+KSlyZXR1cm4hMQpyZXR1cm4hMH0sCmdvYzpmdW5jdGlvbigpe3JldHVybiJ3aW5kb3dzIn0sCmdtSTpm
+dW5jdGlvbigpe3JldHVybiJcXCJ9fTsoZnVuY3Rpb24gYWxpYXNlcygpe3ZhciB0PUoudkIucHJvdG90
+eXBlCnQuVT10LncKdC5Taj10LmU3CnQ9Si5NRi5wcm90b3R5cGUKdC50PXQudwp0PVAuY1gucHJvdG90
+eXBlCnQuR0c9dC5ldgp0PVAuay5wcm90b3R5cGUKdC54Yj10LncKdD1XLmN2LnByb3RvdHlwZQp0LkRX
+PXQucjYKdD1XLm02LnByb3RvdHlwZQp0LmpGPXQuRWIKdD1QLkU0LnByb3RvdHlwZQp0LlVyPXQucQp0
+LmU0PXQuWX0pKCk7KGZ1bmN0aW9uIGluc3RhbGxUZWFyT2Zmcygpe3ZhciB0PWh1bmtIZWxwZXJzLl9z
+dGF0aWNfMSxzPWh1bmtIZWxwZXJzLl9zdGF0aWNfMCxyPWh1bmtIZWxwZXJzLmluc3RhbGxJbnN0YW5j
+ZVRlYXJPZmYscT1odW5rSGVscGVycy5pbnN0YWxsU3RhdGljVGVhck9mZixwPWh1bmtIZWxwZXJzLl9p
+bnN0YW5jZV8xdQp0KFAsIkVYIiwiWlYiLDgpCnQoUCwieXQiLCJvQSIsOCkKdChQLCJxVyIsIkJ6Iiw4
+KQpzKFAsIlVJIiwiZU4iLDIpCnIoUC5QZi5wcm90b3R5cGUsImdZSiIsMCwxLG51bGwsWyIkMiIsIiQx
+Il0sWyJ3MCIsInBtIl0sMjgsMCkKdChQLCJDeSIsIk5DIiwxKQp0KFAsIlBIIiwiTXQiLDUpCnEoVywi
+cFMiLDQsbnVsbCxbIiQ0Il0sWyJxRCJdLDksMCkKcShXLCJWNCIsNCxudWxsLFsiJDQiXSxbIlFXIl0s
+OSwwKQpwKFAuQXMucHJvdG90eXBlLCJndU0iLCJUIiw1KQp0KFAsImlHIiwid1kiLDEpCnQoUCwidzAi
+LCJMNyIsMzIpCnQoTCwiaVMiLCJpNiIsMTgpfSkoKTsoZnVuY3Rpb24gaW5oZXJpdGFuY2UoKXt2YXIg
+dD1odW5rSGVscGVycy5taXhpbixzPWh1bmtIZWxwZXJzLmluaGVyaXQscj1odW5rSGVscGVycy5pbmhl
+cml0TWFueQpzKFAuayxudWxsKQpyKFAuayxbSC5lbyxKLnZCLEoubTEsUC5uWSxQLmNYLEguYTcsUC5B
+bixILlNVLEguUmUsSC53dixQLlBuLEguV1UsSC5MSSxILlRwLEguZjksUC5YUyxILmJxLEguWE8sUC5Z
+ayxILmRiLEguTjYsSC5WUixILkVLLEguUGIsSC50USxILlNkLEguSmMsSC5HLFAuVzMsUC5paCxQLkZ5
+LFAuR1YsUC5iOCxQLlBmLFAuRmUsUC52cyxQLk9NLFAucWgsUC5NTyxQLmtULFAueEksUC5DdyxQLm0w
+LFAuWHYsUC5ibixQLmxtLFAubEQsUC5LUCxQLmxmLFAuVEMsUC5VayxQLlNoLFAuUncsUC5ieixQLmEy
+LFAuaVAsUC5GSyxQLms1LFAuS1ksUC5DRCxQLmFFLFAuRUgsUC56TSxQLlowLFAuTjMsUC5jOCxQLk9k
+LFAuaWIsUC5HeixQLnFVLFAuUm4sUC5HRCxQLkRuLFAuUEUsUC5VZixXLmlkLFcuRmssVy5KUSxXLkdt
+LFcudkQsVy5tNixXLk93LFcuVzksVy5kVyxXLkZiLFcua0YsVy5tayxXLktvLFAuaUosUC5FNCxQLm42
+LE0uSDcsVS5MTCxVLmQyLFUuU2UsVS5NbCxVLnlELFUud2IsQi5qOCxCLnFwLFQubVEsTC5YQSxMLlpa
+LEwuTzksTS5sSSxPLnpMLFguV0QsWC5kdl0pCnIoSi52QixbSi55RSxKLllFLEouTUYsSi5qZCxKLnFJ
+LEouRHIsSC5FVCxXLkQwLFcuQXosVy5MZSxXLk5oLFcuSUIsVy5uNyxXLmVhLFcuYnIsVy5TZyxXLnU4
+LFcuSzcsVy5YVyxQLmhGXSkKcihKLk1GLFtKLmlDLEoua2QsSi5jNV0pCnMoSi5QbyxKLmpkKQpyKEou
+cUksW0ouYlUsSi5WQV0pCnMoUC51eSxQLm5ZKQpyKFAudXksW0guWEMsVy53eixXLmU3XSkKcyhILnFq
+LEguWEMpCnIoUC5jWCxbSC5iUSxILmkxLEguVTUsSC5YUixQLm1XLEgudW5dKQpyKEguYlEsW0guYUws
+SC5pNSxQLnh1XSkKcihILmFMLFtILm5ILEguQTgsUC5pOF0pCnMoSC54eSxILmkxKQpyKFAuQW4sW0gu
+TUgsSC5TT10pCnMoUC5SVSxQLlBuKQpzKFAuR2osUC5SVSkKcyhILlBELFAuR2opCnMoSC5MUCxILldV
+KQpyKEguVHAsW0guQ2osSC5BbSxILmxjLEguZEMsSC53TixILlZYLFAudGgsUC5oYSxQLlZzLFAuRnQs
+UC55SCxQLldNLFAuU1gsUC5HcyxQLmRhLFAub1EsUC5wVixQLlU3LFAudnIsUC5ySCxQLktGLFAuWkws
+UC5SVCxQLmpaLFAucnEsUC5SVyxQLkI1LFAudU8sUC5wSyxQLmhqLFAuVnAsUC5PUixQLnJhLFAueVEs
+UC50aSxQLldGLFAubjEsUC5jUyxQLlZDLFAuSlQsUC5lMSxQLk5ZLFAuUlosUC5NRSxQLnk1LFAucTMs
+UC55SSxQLmM2LFAucWQsVy5DdixXLktTLFcuQTMsVy52TixXLlV2LFcuRWcsVy5FbyxXLldrLFcuSUEs
+Vy5mbSxQLmxSLFAuamcsUC5HRSxQLk43LFAudVEsUC5QQyxQLm10LFAuTnosUC5RUyxQLm5wLFUuTUQs
+VS5hTixVLmIwLEwuZSxMLlZXLEwub1osTC5qcixMLnFsLEwueTgsTC5IaSxMLkJULEwuTCxMLld4LEwu
+QU8sTC5kTixMLkhvLEwueHosTC5JQyxMLmZDLEwublQsTC5CWixMLkdILEwuRUUsTC5RTCxMLlZTLEwu
+VEQsTC5BUyxNLk1pLE0ucTcsTS5Ob10pCnIoUC5YUyxbSC5XMCxILmF6LEgudlYsSC5FcSxQLkM2LEgu
+dTksUC5VZCxQLm4sUC51LFAubXAsUC51YixQLmRzLFAubGosUC5VVixQLmNdKQpyKEgubGMsW0guengs
+SC5yVF0pCnMoSC5rWSxQLkM2KQpzKFAuaWwsUC5ZaykKcihQLmlsLFtILk41LFAudXcsVy5jZixXLlN5
+XSkKcihQLm1XLFtILktXLFAucTRdKQpzKEguTFosSC5FVCkKcihILkxaLFtILlJHLEguV0JdKQpzKEgu
+VlAsSC5SRykKcyhILkRnLEguVlApCnMoSC5aRyxILldCKQpzKEguUGcsSC5aRykKcihILlBnLFtILnhq
+LEguZEUsSC5aQSxILndmLEguUHEsSC5lRSxILlY2XSkKcihILnU5LFtILmh6LEguaU1dKQpzKFAuWmYs
+UC5QZikKcyhQLkppLFAubTApCnMoUC5iNixQLlh2KQpzKFAuVmosUC5UQykKcihQLlVrLFtQLkNWLFAu
+WmksUC5ieV0pCnMoUC53SSxQLmtUKQpyKFAud0ksW1AuVTgsUC5vaixQLk14LFAuRTMsUC5HWV0pCnMo
+UC5LOCxQLlVkKQpzKFAudHUsUC5TaCkKcyhQLnU1LFAuWmkpCnIoUC5GSyxbUC5DUCxQLktOXSkKcihQ
+LnUsW1AuYkosUC5lWV0pCnMoUC5xZSxQLkRuKQpyKFcuRDAsW1cudUgsVy53YSxXLks1LFcuQ21dKQpy
+KFcudUgsW1cuY3YsVy5ueCxXLlFGLFcuQ1FdKQpyKFcuY3YsW1cucUUsUC5kNV0pCnIoVy5xRSxbVy5H
+aCxXLmZZLFcubkIsVy5RUCxXLmg0LFcuU04sVy5scCxXLlRiLFcuSXYsVy5XUCxXLnlZXSkKcyhXLm9K
+LFcuTGUpCnMoVy5oSCxXLkF6KQpzKFcuVmIsVy5RRikKcyhXLk83LFcud2EpCnIoVy5lYSxbVy53NixX
+LmV3XSkKcyhXLkFqLFcudzYpCnMoVy5yQixXLks3KQpzKFcuQkgsVy5yQikKcyhXLnc0LFcuSUIpCnMo
+Vy5vYSxXLlhXKQpzKFcucmgsVy5vYSkKcyhXLmk3LFcuY2YpCnMoUC5BcyxQLlZqKQpyKFAuQXMsW1cu
+STQsUC5LZV0pCnMoVy5STyxQLnFoKQpzKFcuZXUsVy5STykKcyhXLnhDLFAuTU8pCnMoVy5jdCxXLm02
+KQpzKFAuQmYsUC5pSikKcihQLkU0LFtQLnI3LFAuY29dKQpzKFAuVHosUC5jbykKcyhQLm5kLFAuZDUp
+CnMoQi5mdixPLnpMKQpyKEIuZnYsW0UuT0YsRi5ydSxMLklWXSkKdChILlhDLEguUmUpCnQoSC5SRyxQ
+LmxEKQp0KEguVlAsSC5TVSkKdChILldCLFAubEQpCnQoSC5aRyxILlNVKQp0KFAublksUC5sRCkKdChQ
+LlRDLFAubGYpCnQoUC5SVSxQLktQKQp0KFcuTGUsVy5pZCkKdChXLks3LFAubEQpCnQoVy5yQixXLkdt
+KQp0KFcuWFcsUC5sRCkKdChXLm9hLFcuR20pCnQoUC5jbyxQLmxEKX0pKCkKdmFyIHY9e3R5cGVVbml2
+ZXJzZTp7ZUM6bmV3IE1hcCgpLHRSOnt9LGVUOnt9LHRQVjp7fSxzRUE6W119LG1hbmdsZWRHbG9iYWxO
+YW1lczp7S046ImludCIsQ1A6ImRvdWJsZSIsRks6Im51bSIscVU6IlN0cmluZyIsYTI6ImJvb2wiLGM4
+OiJOdWxsIix6TToiTGlzdCJ9LG1hbmdsZWROYW1lczp7fSxnZXRUeXBlRnJvbU5hbWU6Z2V0R2xvYmFs
+RnJvbU5hbWUsbWV0YWRhdGE6W10sdHlwZXM6WyJjOCgpIiwiQChAKSIsIn4oKSIsImM4KEFqKSIsImM4
+KEAsQCkiLCJxVShxVSkiLCJjOChjdikiLCJhMihxVSkiLCJ+KH4oKSkiLCJhMihjdixxVSxxVSxKUSki
+LCJjOChAKSIsIn4oeHU8cVU+KSIsImM4KHFVLEApIiwiYzgocVUpIiwiYzgocVUscVUpIiwiYTIoa0Yp
+IiwiYzgoZWEpIiwiYjg8Yzg+KEFqKSIsIn4oQWopIiwiWjA8cVUscVU+KFowPHFVLHFVPixxVSkiLCJj
+OCh+KCkpIiwiYzgoQCxHeikiLCJ+KHFVLHFVKSIsIm42KEtOKSIsIm42KEAsQCkiLCJhMih1SCkiLCJj
+OChLTixAKSIsIkAoZWEpIiwifihrW0d6XSkiLCJjOChAW0d6XSkiLCJ+KHVILHVIKSIsImEyKHh1PHFV
+PikiLCJrKEApIiwicjcoQCkiLCJUejxAPihAKSIsIkU0KEApIiwiYTIoSDcpIiwiTEwoQCkiLCJaMDxx
+VSxrPihMTCkiLCJ2czxAPihAKSIsIkAocVUpIiwiYzgoWjA8cVUsaz4pIiwiYzgoR0QsQCkiLCJxVShB
+aikiLCJAKEAscVUpIiwiYzgoZXcpIiwifihxVSxLTikiLCJ+KHFVW0BdKSIsIktOKEtOLEtOKSIsIn4o
+QCkiXSxpbnRlcmNlcHRvcnNCeVRhZzpudWxsLGxlYWZUYWdzOm51bGx9CkgueGIodi50eXBlVW5pdmVy
+c2UsSlNPTi5wYXJzZSgneyJjNSI6Ik1GIiwiaUMiOiJNRiIsImtkIjoiTUYiLCJyeCI6ImVhIiwiZTUi
+OiJlYSIsIlkwIjoiZDUiLCJ0cCI6ImQ1IiwidjAiOiJldyIsIk1yIjoicUUiLCJlTCI6InFFIiwiSTAi
+OiJ1SCIsImhzIjoidUgiLCJYZyI6IlFGIiwibnIiOiJBaiIsInk0IjoidzYiLCJhUCI6IkNtIiwieGMi
+OiJueCIsImtKIjoibngiLCJ6VSI6IkRnIiwiZGYiOiJFVCIsInlFIjp7ImEyIjpbXX0sIllFIjp7ImM4
+IjpbXX0sIk1GIjp7InZtIjpbXSwiRUgiOltdfSwiamQiOnsiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
+IjpbIjEiXX0sIlBvIjp7ImpkIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0s
+Im0xIjp7IkFuIjpbIjEiXX0sInFJIjp7IkNQIjpbXSwiRksiOltdfSwiYlUiOnsiS04iOltdLCJDUCI6
+W10sIkZLIjpbXX0sIlZBIjp7IkNQIjpbXSwiRksiOltdfSwiRHIiOnsicVUiOltdLCJ2WCI6W119LCJx
+aiI6eyJSZSI6WyJLTiJdLCJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJiUSI6WyJLTiJdLCJjWCI6WyJL
+TiJdLCJsRC5FIjoiS04iLCJSZS5FIjoiS04ifSwiYlEiOnsiY1giOlsiMSJdfSwiYUwiOnsiYlEiOlsi
+MSJdLCJjWCI6WyIxIl19LCJuSCI6eyJhTCI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdLCJhTC5F
+IjoiMSIsImNYLkUiOiIxIn0sImE3Ijp7IkFuIjpbIjEiXX0sImkxIjp7ImNYIjpbIjIiXSwiY1guRSI6
+IjIifSwieHkiOnsiaTEiOlsiMSIsIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImNYLkUiOiIyIn0s
+Ik1IIjp7IkFuIjpbIjIiXX0sIkE4Ijp7ImFMIjpbIjIiXSwiYlEiOlsiMiJdLCJjWCI6WyIyIl0sImFM
+LkUiOiIyIiwiY1guRSI6IjIifSwiVTUiOnsiY1giOlsiMSJdLCJjWC5FIjoiMSJ9LCJTTyI6eyJBbiI6
+WyIxIl19LCJYQyI6eyJSZSI6WyIxIl0sImxEIjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNY
+IjpbIjEiXX0sInd2Ijp7IkdEIjpbXX0sIlBEIjp7IkdqIjpbIjEiLCIyIl0sIlJVIjpbIjEiLCIyIl0s
+IlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpbIjEiLCIyIl19LCJXVSI6eyJaMCI6WyIx
+IiwiMiJdfSwiTFAiOnsiV1UiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXX0sIlhSIjp7ImNYIjpbIjEi
+XSwiY1guRSI6IjEifSwiTEkiOnsidlEiOltdfSwiVzAiOnsiWFMiOltdfSwiYXoiOnsiWFMiOltdfSwi
+dlYiOnsiWFMiOltdfSwiWE8iOnsiR3oiOltdfSwiVHAiOnsiRUgiOltdfSwibGMiOnsiRUgiOltdfSwi
+engiOnsiRUgiOltdfSwiclQiOnsiRUgiOltdfSwiRXEiOnsiWFMiOltdfSwia1kiOnsiWFMiOltdfSwi
+TjUiOnsiRm8iOlsiMSIsIjIiXSwiWWsiOlsiMSIsIjIiXSwiWjAiOlsiMSIsIjIiXSwiWWsuSyI6IjEi
+LCJZay5WIjoiMiJ9LCJpNSI6eyJiUSI6WyIxIl0sImNYIjpbIjEiXSwiY1guRSI6IjEifSwiTjYiOnsi
+QW4iOlsiMSJdfSwiVlIiOnsid0wiOltdLCJ2WCI6W119LCJFSyI6eyJpYiI6W10sIk9kIjpbXX0sIktX
+Ijp7ImNYIjpbImliIl0sImNYLkUiOiJpYiJ9LCJQYiI6eyJBbiI6WyJpYiJdfSwidFEiOnsiT2QiOltd
+fSwidW4iOnsiY1giOlsiT2QiXSwiY1guRSI6Ik9kIn0sIlNkIjp7IkFuIjpbIk9kIl19LCJFVCI6eyJl
+cSI6W119LCJMWiI6eyJYaiI6WyJAIl0sIkVUIjpbXSwiZXEiOltdfSwiRGciOnsibEQiOlsiQ1AiXSwi
+WGoiOlsiQCJdLCJ6TSI6WyJDUCJdLCJFVCI6W10sImJRIjpbIkNQIl0sIlNVIjpbIkNQIl0sImVxIjpb
+XSwiY1giOlsiQ1AiXSwibEQuRSI6IkNQIn0sIlBnIjp7ImxEIjpbIktOIl0sInpNIjpbIktOIl0sIlhq
+IjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJlcSI6W10sImNYIjpbIktOIl19
+LCJ4aiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0sIkVUIjpbXSwiYlEiOlsiS04i
+XSwiU1UiOlsiS04iXSwiZXEiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoiS04ifSwiZEUiOnsibEQiOlsi
+S04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpbIktOIl0sIlNVIjpbIktOIl0s
+ImVxIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sIlpBIjp7ImxEIjpbIktOIl0sInpNIjpbIktO
+Il0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJlcSI6W10sImNYIjpb
+IktOIl0sImxELkUiOiJLTiJ9LCJ3ZiI6eyJsRCI6WyJLTiJdLCJ6TSI6WyJLTiJdLCJYaiI6WyJAIl0s
+IkVUIjpbXSwiYlEiOlsiS04iXSwiU1UiOlsiS04iXSwiZXEiOltdLCJjWCI6WyJLTiJdLCJsRC5FIjoi
+S04ifSwiUHEiOnsibEQiOlsiS04iXSwiek0iOlsiS04iXSwiWGoiOlsiQCJdLCJFVCI6W10sImJRIjpb
+IktOIl0sIlNVIjpbIktOIl0sImVxIjpbXSwiY1giOlsiS04iXSwibEQuRSI6IktOIn0sImVFIjp7ImxE
+IjpbIktOIl0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJL
+TiJdLCJlcSI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJWNiI6eyJuNiI6W10sImxEIjpbIktO
+Il0sInpNIjpbIktOIl0sIlhqIjpbIkAiXSwiRVQiOltdLCJiUSI6WyJLTiJdLCJTVSI6WyJLTiJdLCJl
+cSI6W10sImNYIjpbIktOIl0sImxELkUiOiJLTiJ9LCJ1OSI6eyJYUyI6W119LCJoeiI6eyJYUyI6W119
+LCJpTSI6eyJYUyI6W119LCJHViI6eyJBbiI6WyIxIl19LCJxNCI6eyJjWCI6WyIxIl0sImNYLkUiOiIx
+In0sIlpmIjp7IlBmIjpbIjEiXX0sInZzIjp7ImI4IjpbIjEiXX0sIkN3Ijp7IlhTIjpbXX0sIm0wIjp7
+IkpCIjpbXX0sIkppIjp7IkpCIjpbXX0sImI2Ijp7Ilh2IjpbIjEiXSwieHUiOlsiMSJdLCJiUSI6WyIx
+Il0sImNYIjpbIjEiXX0sImxtIjp7IkFuIjpbIjEiXX0sIm1XIjp7ImNYIjpbIjEiXX0sInV5Ijp7ImxE
+IjpbIjEiXSwiek0iOlsiMSJdLCJiUSI6WyIxIl0sImNYIjpbIjEiXX0sImlsIjp7IllrIjpbIjEiLCIy
+Il0sIlowIjpbIjEiLCIyIl19LCJZayI6eyJaMCI6WyIxIiwiMiJdfSwiUG4iOnsiWjAiOlsiMSIsIjIi
+XX0sIkdqIjp7IlJVIjpbIjEiLCIyIl0sIlBuIjpbIjEiLCIyIl0sIktQIjpbIjEiLCIyIl0sIlowIjpb
+IjEiLCIyIl19LCJWaiI6eyJsZiI6WyIxIl0sInh1IjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6WyIxIl19
+LCJYdiI6eyJ4dSI6WyIxIl0sImJRIjpbIjEiXSwiY1giOlsiMSJdfSwidXciOnsiWWsiOlsicVUiLCJA
+Il0sIlowIjpbInFVIiwiQCJdLCJZay5LIjoicVUiLCJZay5WIjoiQCJ9LCJpOCI6eyJhTCI6WyJxVSJd
+LCJiUSI6WyJxVSJdLCJjWCI6WyJxVSJdLCJhTC5FIjoicVUiLCJjWC5FIjoicVUifSwiQ1YiOnsiVWsi
+Olsiek08S04+IiwicVUiXSwiVWsuUyI6InpNPEtOPiJ9LCJVOCI6eyJ3SSI6WyJ6TTxLTj4iLCJxVSJd
+fSwiWmkiOnsiVWsiOlsicVUiLCJ6TTxLTj4iXX0sIlVkIjp7IlhTIjpbXX0sIks4Ijp7IlhTIjpbXX0s
+ImJ5Ijp7IlVrIjpbImsiLCJxVSJdLCJVay5TIjoiayJ9LCJvaiI6eyJ3SSI6WyJrIiwicVUiXX0sIk14
+Ijp7IndJIjpbInFVIiwiayJdfSwidTUiOnsiVWsiOlsicVUiLCJ6TTxLTj4iXSwiVWsuUyI6InFVIn0s
+IkUzIjp7IndJIjpbInFVIiwiek08S04+Il19LCJHWSI6eyJ3SSI6WyJ6TTxLTj4iLCJxVSJdfSwiQ1Ai
+OnsiRksiOltdfSwiQzYiOnsiWFMiOltdfSwibiI6eyJYUyI6W119LCJ1Ijp7IlhTIjpbXX0sImJKIjp7
+IlhTIjpbXX0sImVZIjp7IlhTIjpbXX0sIm1wIjp7IlhTIjpbXX0sInViIjp7IlhTIjpbXX0sImRzIjp7
+IlhTIjpbXX0sImxqIjp7IlhTIjpbXX0sIlVWIjp7IlhTIjpbXX0sIms1Ijp7IlhTIjpbXX0sIktZIjp7
+IlhTIjpbXX0sImMiOnsiWFMiOltdfSwiQ0QiOnsiUnoiOltdfSwiYUUiOnsiUnoiOltdfSwiS04iOnsi
+RksiOltdfSwiek0iOnsiYlEiOlsiMSJdLCJjWCI6WyIxIl19LCJpYiI6eyJPZCI6W119LCJ4dSI6eyJi
+USI6WyIxIl0sImNYIjpbIjEiXX0sInFVIjp7InZYIjpbXX0sIlJuIjp7IkJMIjpbXX0sIkRuIjp7ImlE
+IjpbXX0sIlVmIjp7ImlEIjpbXX0sInFlIjp7ImlEIjpbXX0sInFFIjp7ImN2IjpbXSwidUgiOltdLCJE
+MCI6W119LCJHaCI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiZlkiOnsiY3YiOltdLCJ1SCI6W10s
+IkQwIjpbXX0sIm5CIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJRUCI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwibngiOnsidUgiOltdLCJEMCI6W119LCJRRiI6eyJ1SCI6W10sIkQwIjpbXX0sIklC
+Ijp7InRuIjpbIkZLIl19LCJ3eiI6eyJsRCI6WyIxIl0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJjWCI6
+WyIxIl0sImxELkUiOiIxIn0sImN2Ijp7InVIIjpbXSwiRDAiOltdfSwiaEgiOnsiQXoiOltdfSwiaDQi
+OnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlZiIjp7InVIIjpbXSwiRDAiOltdfSwiTzciOnsiRDAi
+OltdfSwid2EiOnsiRDAiOltdfSwiQWoiOnsiZWEiOltdfSwiZTciOnsibEQiOlsidUgiXSwiek0iOlsi
+dUgiXSwiYlEiOlsidUgiXSwiY1giOlsidUgiXSwibEQuRSI6InVIIn0sInVIIjp7IkQwIjpbXX0sIkJI
+Ijp7IkdtIjpbInVIIl0sImxEIjpbInVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVI
+Il0sImNYIjpbInVIIl0sImxELkUiOiJ1SCIsIkdtLkUiOiJ1SCJ9LCJTTiI6eyJjdiI6W10sInVIIjpb
+XSwiRDAiOltdfSwiZXciOnsiZWEiOltdfSwibHAiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sIlRi
+Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119LCJJdiI6eyJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwi
+V1AiOnsiY3YiOltdLCJ1SCI6W10sIkQwIjpbXX0sInlZIjp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJ3NiI6eyJlYSI6W119LCJLNSI6eyJ2NiI6W10sIkQwIjpbXX0sIkNtIjp7IkQwIjpbXX0sIkNRIjp7
+InVIIjpbXSwiRDAiOltdfSwidzQiOnsidG4iOlsiRksiXX0sInJoIjp7IkdtIjpbInVIIl0sImxEIjpb
+InVIIl0sInpNIjpbInVIIl0sIlhqIjpbInVIIl0sImJRIjpbInVIIl0sImNYIjpbInVIIl0sImxELkUi
+OiJ1SCIsIkdtLkUiOiJ1SCJ9LCJjZiI6eyJZayI6WyJxVSIsInFVIl0sIlowIjpbInFVIiwicVUiXX0s
+Imk3Ijp7IllrIjpbInFVIiwicVUiXSwiWjAiOlsicVUiLCJxVSJdLCJZay5LIjoicVUiLCJZay5WIjoi
+cVUifSwiU3kiOnsiWWsiOlsicVUiLCJxVSJdLCJaMCI6WyJxVSIsInFVIl0sIllrLksiOiJxVSIsIllr
+LlYiOiJxVSJ9LCJJNCI6eyJsZiI6WyJxVSJdLCJ4dSI6WyJxVSJdLCJiUSI6WyJxVSJdLCJjWCI6WyJx
+VSJdfSwiUk8iOnsicWgiOlsiMSJdfSwiZXUiOnsiUk8iOlsiMSJdLCJxaCI6WyIxIl19LCJ4QyI6eyJN
+TyI6WyIxIl19LCJKUSI6eyJrRiI6W119LCJ2RCI6eyJrRiI6W119LCJtNiI6eyJrRiI6W119LCJjdCI6
+eyJrRiI6W119LCJPdyI6eyJrRiI6W119LCJXOSI6eyJBbiI6WyIxIl19LCJkVyI6eyJ2NiI6W10sIkQw
+IjpbXX0sIm1rIjp7InkwIjpbXX0sIktvIjp7Im9uIjpbXX0sIkFzIjp7ImxmIjpbInFVIl0sInh1Ijpb
+InFVIl0sImJRIjpbInFVIl0sImNYIjpbInFVIl19LCJyNyI6eyJFNCI6W119LCJUeiI6eyJsRCI6WyIx
+Il0sInpNIjpbIjEiXSwiYlEiOlsiMSJdLCJFNCI6W10sImNYIjpbIjEiXSwibEQuRSI6IjEifSwibmQi
+OnsiZDUiOltdLCJjdiI6W10sInVIIjpbXSwiRDAiOltdfSwiS2UiOnsibGYiOlsicVUiXSwieHUiOlsi
+cVUiXSwiYlEiOlsicVUiXSwiY1giOlsicVUiXX0sImQ1Ijp7ImN2IjpbXSwidUgiOltdLCJEMCI6W119
+LCJuNiI6eyJ6TSI6WyJLTiJdLCJiUSI6WyJLTiJdLCJlcSI6W10sImNYIjpbIktOIl19LCJYQSI6eyJr
+RiI6W119LCJkdiI6eyJSeiI6W119LCJPRiI6eyJmdiI6W119LCJydSI6eyJmdiI6W119LCJJViI6eyJm
+diI6W119fScpKQpILkZGKHYudHlwZVVuaXZlcnNlLEpTT04ucGFyc2UoJ3siYlEiOjEsIlhDIjoxLCJN
+TyI6MSwia1QiOjIsIm1XIjoxLCJ1eSI6MSwiaWwiOjIsIlZqIjoxLCJuWSI6MSwiVEMiOjEsImNvIjox
+fScpKQp2YXIgdT0oZnVuY3Rpb24gcnRpaSgpe3ZhciB0PUguTjAKcmV0dXJue2JxOnQoIkdoIiksbjp0
+KCJDdyIpLGNSOnQoIm5CIiksZDp0KCJBeiIpLFk6dCgiUVAiKSxnRjp0KCJQRDxHRCxAPiIpLGd3OnQo
+ImJRPEA+IiksaDp0KCJjdiIpLGJVOnQoIlhTIiksQjp0KCJlYSIpLHI6dCgiRDAiKSxnODp0KCJSeiIp
+LGM4OnQoImhIIiksWjp0KCJFSCIpLGM6dCgiYjg8QD4iKSxEOnQoIkxMIiksZ3A6dCgiSDciKSxJOnQo
+IlNnIiksbzp0KCJ2USIpLGVoOnQoImNYPHVIPiIpLFg6dCgiY1g8cVU+IiksUjp0KCJjWDxAPiIpLGZB
+OnQoImpkPFNlPiIpLGdpOnQoImpkPGo4PiIpLEo6dCgiamQ8WjA8cVUsaz4+IiksZmg6dCgiamQ8Wlo+
+IiksaTp0KCJqZDxrRj4iKSxzOnQoImpkPHFVPiIpLGhoOnQoImpkPHlEPiIpLGFKOnQoImpkPHdiPiIp
+LGI6dCgiamQ8QD4iKSx0OnQoImpkPEtOPiIpLGVIOnQoInZtIiksZzp0KCJjNSIpLGFVOnQoIlhqPEA+
+IiksYW06dCgiVHo8QD4iKSxlbzp0KCJONTxHRCxAPiIpLG06dCgiRTQiKSxkejp0KCJoRiIpLGY0OnQo
+InpNPGo4PiIpLGQzOnQoInpNPFowPHFVLGs+PiIpLGV3OnQoInpNPGs+IiksYTp0KCJ6TTxxVT4iKSxq
+OnQoInpNPEA+IiksTDp0KCJ6TTxLTj4iKSxhXzp0KCJ1OCIpLFM6dCgiWjA8cVUsaz4iKSxmOnQoIlow
+PHFVLHFVPiIpLGs6dCgiWjA8cVUsQD4iKSxHOnQoIlowPEAsQD4iKSxkdjp0KCJBODxxVSxxVT4iKSxk
+bzp0KCJBODxxVSxAPiIpLFY6dCgiQWoiKSxkRDp0KCJFVCIpLGJtOnQoIlY2IiksQTp0KCJ1SCIpLGU6
+dCgia0YiKSxQOnQoImM4IiksSzp0KCJrIikscDp0KCJldyIpLHE6dCgidG48Rks+IiksZnY6dCgid0wi
+KSxhdjp0KCJKYyIpLGFPOnQoIm5kIiksQzp0KCJ4dTxxVT4iKSxsOnQoIkd6IiksTjp0KCJxVSIpLGRH
+OnQoInFVKHFVKSIpLGc3OnQoImQ1IiksZm86dCgiR0QiKSxhVzp0KCJ5WSIpLHU6dCgiZXEiKSxnYzp0
+KCJuNiIpLGFrOnQoImtkIiksVzp0KCJHajxxVSxxVT4iKSx2OnQoImlEIiksY2M6dCgiVTU8cVU+Iiks
+ZzQ6dCgiSzUiKSxjaTp0KCJ2NiIpLGcyOnQoIkNtIiksYmo6dCgiWmY8Tzc+IiksaDk6dCgiQ1EiKSxh
+Yzp0KCJlNyIpLFE6dCgiZXU8QWo+IiksVDp0KCJ3ejxjdj4iKSx4OnQoIkZlPEAsQD4iKSxhbzp0KCJ2
+czxPNz4iKSxfOnQoInZzPEA+IiksZko6dCgidnM8S04+IiksTzp0KCJKUSIpLHk6dCgiYm4iKSxjSjp0
+KCJhMiIpLGFsOnQoImEyKGspIiksYkI6dCgiYTIocVUpIiksYmY6dCgiYTIoQCkiKSx6OnQoIkAiKSxm
+Tzp0KCJAKCkiKSxVOnQoIkAoZWEpIiksdzp0KCJAKGspIiksZXA6dCgiQChrLGspIiksRTp0KCJAKGss
+R3opIiksY2g6dCgiQCh4dTxxVT4pIiksZE86dCgiQChxVSkiKSxiYzp0KCJAKEApIiksYjg6dCgiQChA
+LEApIiksZWc6dCgiS04iKSxIOnQoIn4iKSxNOnQoIn4oKSIpLGFuOnQoIn4oZXcpIiksRjp0KCJ+KHFV
+LHFVKSIpLGNBOnQoIn4ocVUsQCkiKX19KSgpOyhmdW5jdGlvbiBjb25zdGFudHMoKXt2YXIgdD1odW5r
+SGVscGVycy5tYWtlQ29uc3RMaXN0CkMuUlk9Vy5RUC5wcm90b3R5cGUKQy5CWj1XLlZiLnByb3RvdHlw
+ZQpDLkR0PVcuTzcucHJvdG90eXBlCkMuT2s9Si52Qi5wcm90b3R5cGUKQy5ObT1KLmpkLnByb3RvdHlw
+ZQpDLmpuPUouYlUucHJvdG90eXBlCkMuQ0Q9Si5xSS5wcm90b3R5cGUKQy54Qj1KLkRyLnByb3RvdHlw
+ZQpDLkRHPUouYzUucHJvdG90eXBlCkMuRXg9Vy51OC5wcm90b3R5cGUKQy5MdD1XLlNOLnByb3RvdHlw
+ZQpDLlpRPUouaUMucHJvdG90eXBlCkMuSWU9Vy5UYi5wcm90b3R5cGUKQy52Qj1KLmtkLnByb3RvdHlw
+ZQpDLm9sPVcuSzUucHJvdG90eXBlCkMueTg9bmV3IFAuVTgoKQpDLmg5PW5ldyBQLkNWKCkKQy5PND1m
+dW5jdGlvbiBnZXRUYWdGYWxsYmFjayhvKSB7CiAgdmFyIHMgPSBPYmplY3QucHJvdG90eXBlLnRvU3Ry
+aW5nLmNhbGwobyk7CiAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7Cn0KQy5ZcT1m
+dW5jdGlvbigpIHsKICB2YXIgdG9TdHJpbmdGdW5jdGlvbiA9IE9iamVjdC5wcm90b3R5cGUudG9TdHJp
+bmc7CiAgZnVuY3Rpb24gZ2V0VGFnKG8pIHsKICAgIHZhciBzID0gdG9TdHJpbmdGdW5jdGlvbi5jYWxs
+KG8pOwogICAgcmV0dXJuIHMuc3Vic3RyaW5nKDgsIHMubGVuZ3RoIC0gMSk7CiAgfQogIGZ1bmN0aW9u
+IGdldFVua25vd25UYWcob2JqZWN0LCB0YWcpIHsKICAgIGlmICgvXkhUTUxbQS1aXS4qRWxlbWVudCQv
+LnRlc3QodGFnKSkgewogICAgICB2YXIgbmFtZSA9IHRvU3RyaW5nRnVuY3Rpb24uY2FsbChvYmplY3Qp
+OwogICAgICBpZiAobmFtZSA9PSAiW29iamVjdCBPYmplY3RdIikgcmV0dXJuIG51bGw7CiAgICAgIHJl
+dHVybiAiSFRNTEVsZW1lbnQiOwogICAgfQogIH0KICBmdW5jdGlvbiBnZXRVbmtub3duVGFnR2VuZXJp
+Y0Jyb3dzZXIob2JqZWN0LCB0YWcpIHsKICAgIGlmIChzZWxmLkhUTUxFbGVtZW50ICYmIG9iamVjdCBp
+bnN0YW5jZW9mIEhUTUxFbGVtZW50KSByZXR1cm4gIkhUTUxFbGVtZW50IjsKICAgIHJldHVybiBnZXRV
+bmtub3duVGFnKG9iamVjdCwgdGFnKTsKICB9CiAgZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnKHRhZykg
+ewogICAgaWYgKHR5cGVvZiB3aW5kb3cgPT0gInVuZGVmaW5lZCIpIHJldHVybiBudWxsOwogICAgaWYg
+KHR5cGVvZiB3aW5kb3dbdGFnXSA9PSAidW5kZWZpbmVkIikgcmV0dXJuIG51bGw7CiAgICB2YXIgY29u
+c3RydWN0b3IgPSB3aW5kb3dbdGFnXTsKICAgIGlmICh0eXBlb2YgY29uc3RydWN0b3IgIT0gImZ1bmN0
+aW9uIikgcmV0dXJuIG51bGw7CiAgICByZXR1cm4gY29uc3RydWN0b3IucHJvdG90eXBlOwogIH0KICBm
+dW5jdGlvbiBkaXNjcmltaW5hdG9yKHRhZykgeyByZXR1cm4gbnVsbDsgfQogIHZhciBpc0Jyb3dzZXIg
+PSB0eXBlb2YgbmF2aWdhdG9yID09ICJvYmplY3QiOwogIHJldHVybiB7CiAgICBnZXRUYWc6IGdldFRh
+ZywKICAgIGdldFVua25vd25UYWc6IGlzQnJvd3NlciA/IGdldFVua25vd25UYWdHZW5lcmljQnJvd3Nl
+ciA6IGdldFVua25vd25UYWcsCiAgICBwcm90b3R5cGVGb3JUYWc6IHByb3RvdHlwZUZvclRhZywKICAg
+IGRpc2NyaW1pbmF0b3I6IGRpc2NyaW1pbmF0b3IgfTsKfQpDLndiPWZ1bmN0aW9uKGdldFRhZ0ZhbGxi
+YWNrKSB7CiAgcmV0dXJuIGZ1bmN0aW9uKGhvb2tzKSB7CiAgICBpZiAodHlwZW9mIG5hdmlnYXRvciAh
+PSAib2JqZWN0IikgcmV0dXJuIGhvb2tzOwogICAgdmFyIHVhID0gbmF2aWdhdG9yLnVzZXJBZ2VudDsK
+ICAgIGlmICh1YS5pbmRleE9mKCJEdW1wUmVuZGVyVHJlZSIpID49IDApIHJldHVybiBob29rczsKICAg
+IGlmICh1YS5pbmRleE9mKCJDaHJvbWUiKSA+PSAwKSB7CiAgICAgIGZ1bmN0aW9uIGNvbmZpcm0ocCkg
+ewogICAgICAgIHJldHVybiB0eXBlb2Ygd2luZG93ID09ICJvYmplY3QiICYmIHdpbmRvd1twXSAmJiB3
+aW5kb3dbcF0ubmFtZSA9PSBwOwogICAgICB9CiAgICAgIGlmIChjb25maXJtKCJXaW5kb3ciKSAmJiBj
+b25maXJtKCJIVE1MRWxlbWVudCIpKSByZXR1cm4gaG9va3M7CiAgICB9CiAgICBob29rcy5nZXRUYWcg
+PSBnZXRUYWdGYWxsYmFjazsKICB9Owp9CkMuS1U9ZnVuY3Rpb24oaG9va3MpIHsKICBpZiAodHlwZW9m
+IGRhcnRFeHBlcmltZW50YWxGaXh1cEdldFRhZyAhPSAiZnVuY3Rpb24iKSByZXR1cm4gaG9va3M7CiAg
+aG9va3MuZ2V0VGFnID0gZGFydEV4cGVyaW1lbnRhbEZpeHVwR2V0VGFnKGhvb2tzLmdldFRhZyk7Cn0K
+Qy5mUT1mdW5jdGlvbihob29rcykgewogIHZhciBnZXRUYWcgPSBob29rcy5nZXRUYWc7CiAgdmFyIHBy
+b3RvdHlwZUZvclRhZyA9IGhvb2tzLnByb3RvdHlwZUZvclRhZzsKICBmdW5jdGlvbiBnZXRUYWdGaXhl
+ZChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgaWYgKHRhZyA9PSAiRG9jdW1lbnQiKSB7
+CiAgICAgIGlmICghIW8ueG1sVmVyc2lvbikgcmV0dXJuICIhRG9jdW1lbnQiOwogICAgICByZXR1cm4g
+IiFIVE1MRG9jdW1lbnQiOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAgZnVuY3Rpb24gcHJvdG90
+eXBlRm9yVGFnRml4ZWQodGFnKSB7CiAgICBpZiAodGFnID09ICJEb2N1bWVudCIpIHJldHVybiBudWxs
+OwogICAgcmV0dXJuIHByb3RvdHlwZUZvclRhZyh0YWcpOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRU
+YWdGaXhlZDsKICBob29rcy5wcm90b3R5cGVGb3JUYWcgPSBwcm90b3R5cGVGb3JUYWdGaXhlZDsKfQpD
+LmRrPWZ1bmN0aW9uKGhvb2tzKSB7CiAgdmFyIHVzZXJBZ2VudCA9IHR5cGVvZiBuYXZpZ2F0b3IgPT0g
+Im9iamVjdCIgPyBuYXZpZ2F0b3IudXNlckFnZW50IDogIiI7CiAgaWYgKHVzZXJBZ2VudC5pbmRleE9m
+KCJGaXJlZm94IikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFn
+OwogIHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAi
+RGF0YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiR2VvR2VvbG9jYXRpb24iOiAiR2VvbG9jYXRp
+b24iLAogICAgIkxvY2F0aW9uIjogIiFMb2NhdGlvbiIsCiAgICAiV29ya2VyTWVzc2FnZUV2ZW50Ijog
+Ik1lc3NhZ2VFdmVudCIsCiAgICAiWE1MRG9jdW1lbnQiOiAiIURvY3VtZW50In07CiAgZnVuY3Rpb24g
+Z2V0VGFnRmlyZWZveChvKSB7CiAgICB2YXIgdGFnID0gZ2V0VGFnKG8pOwogICAgcmV0dXJuIHF1aWNr
+TWFwW3RhZ10gfHwgdGFnOwogIH0KICBob29rcy5nZXRUYWcgPSBnZXRUYWdGaXJlZm94Owp9CkMueGk9
+ZnVuY3Rpb24oaG9va3MpIHsKICB2YXIgdXNlckFnZW50ID0gdHlwZW9mIG5hdmlnYXRvciA9PSAib2Jq
+ZWN0IiA/IG5hdmlnYXRvci51c2VyQWdlbnQgOiAiIjsKICBpZiAodXNlckFnZW50LmluZGV4T2YoIlRy
+aWRlbnQvIikgPT0gLTEpIHJldHVybiBob29rczsKICB2YXIgZ2V0VGFnID0gaG9va3MuZ2V0VGFnOwog
+IHZhciBxdWlja01hcCA9IHsKICAgICJCZWZvcmVVbmxvYWRFdmVudCI6ICJFdmVudCIsCiAgICAiRGF0
+YVRyYW5zZmVyIjogIkNsaXBib2FyZCIsCiAgICAiSFRNTERERWxlbWVudCI6ICJIVE1MRWxlbWVudCIs
+CiAgICAiSFRNTERURWxlbWVudCI6ICJIVE1MRWxlbWVudCIsCiAgICAiSFRNTFBocmFzZUVsZW1lbnQi
+OiAiSFRNTEVsZW1lbnQiLAogICAgIlBvc2l0aW9uIjogIkdlb3Bvc2l0aW9uIgogIH07CiAgZnVuY3Rp
+b24gZ2V0VGFnSUUobykgewogICAgdmFyIHRhZyA9IGdldFRhZyhvKTsKICAgIHZhciBuZXdUYWcgPSBx
+dWlja01hcFt0YWddOwogICAgaWYgKG5ld1RhZykgcmV0dXJuIG5ld1RhZzsKICAgIGlmICh0YWcgPT0g
+Ik9iamVjdCIpIHsKICAgICAgaWYgKHdpbmRvdy5EYXRhVmlldyAmJiAobyBpbnN0YW5jZW9mIHdpbmRv
+dy5EYXRhVmlldykpIHJldHVybiAiRGF0YVZpZXciOwogICAgfQogICAgcmV0dXJuIHRhZzsKICB9CiAg
+ZnVuY3Rpb24gcHJvdG90eXBlRm9yVGFnSUUodGFnKSB7CiAgICB2YXIgY29uc3RydWN0b3IgPSB3aW5k
+b3dbdGFnXTsKICAgIGlmIChjb25zdHJ1Y3RvciA9PSBudWxsKSByZXR1cm4gbnVsbDsKICAgIHJldHVy
+biBjb25zdHJ1Y3Rvci5wcm90b3R5cGU7CiAgfQogIGhvb2tzLmdldFRhZyA9IGdldFRhZ0lFOwogIGhv
+b2tzLnByb3RvdHlwZUZvclRhZyA9IHByb3RvdHlwZUZvclRhZ0lFOwp9CkMuaTc9ZnVuY3Rpb24oaG9v
+a3MpIHsgcmV0dXJuIGhvb2tzOyB9CgpDLkN0PW5ldyBQLmJ5KCkKQy5FcT1uZXcgUC5rNSgpCkMueE09
+bmV3IFAudTUoKQpDLlFrPW5ldyBQLkUzKCkKQy5OVT1uZXcgUC5KaSgpCkMuQWQ9bmV3IE0uSDcoMCwi
+SGludEFjdGlvbktpbmQuYWRkTnVsbGFibGVIaW50IikKQy5uZT1uZXcgTS5INygxLCJIaW50QWN0aW9u
+S2luZC5hZGROb25OdWxsYWJsZUhpbnQiKQpDLm15PW5ldyBNLkg3KDIsIkhpbnRBY3Rpb25LaW5kLmNo
+YW5nZVRvTnVsbGFibGVIaW50IikKQy5yeD1uZXcgTS5INygzLCJIaW50QWN0aW9uS2luZC5jaGFuZ2VU
+b05vbk51bGxhYmxlSGludCIpCkMud1Y9bmV3IE0uSDcoNCwiSGludEFjdGlvbktpbmQucmVtb3ZlTnVs
+bGFibGVIaW50IikKQy5mUj1uZXcgTS5INyg1LCJIaW50QWN0aW9uS2luZC5yZW1vdmVOb25OdWxsYWJs
+ZUhpbnQiKQpDLkEzPW5ldyBQLk14KG51bGwpCkMublg9bmV3IFAub2oobnVsbCkKQy5HYj1ILlZNKHQo
+WzEyNywyMDQ3LDY1NTM1LDExMTQxMTFdKSx1LnQpCkMuYWs9SC5WTSh0KFswLDAsMzI3NzYsMzM3OTIs
+MSwxMDI0MCwwLDBdKSx1LnQpCkMuY209SC5WTSh0KFsiKjo6Y2xhc3MiLCIqOjpkaXIiLCIqOjpkcmFn
+Z2FibGUiLCIqOjpoaWRkZW4iLCIqOjppZCIsIio6OmluZXJ0IiwiKjo6aXRlbXByb3AiLCIqOjppdGVt
+cmVmIiwiKjo6aXRlbXNjb3BlIiwiKjo6bGFuZyIsIio6OnNwZWxsY2hlY2siLCIqOjp0aXRsZSIsIio6
+OnRyYW5zbGF0ZSIsIkE6OmFjY2Vzc2tleSIsIkE6OmNvb3JkcyIsIkE6OmhyZWZsYW5nIiwiQTo6bmFt
+ZSIsIkE6OnNoYXBlIiwiQTo6dGFiaW5kZXgiLCJBOjp0YXJnZXQiLCJBOjp0eXBlIiwiQVJFQTo6YWNj
+ZXNza2V5IiwiQVJFQTo6YWx0IiwiQVJFQTo6Y29vcmRzIiwiQVJFQTo6bm9ocmVmIiwiQVJFQTo6c2hh
+cGUiLCJBUkVBOjp0YWJpbmRleCIsIkFSRUE6OnRhcmdldCIsIkFVRElPOjpjb250cm9scyIsIkFVRElP
+Ojpsb29wIiwiQVVESU86Om1lZGlhZ3JvdXAiLCJBVURJTzo6bXV0ZWQiLCJBVURJTzo6cHJlbG9hZCIs
+IkJETzo6ZGlyIiwiQk9EWTo6YWxpbmsiLCJCT0RZOjpiZ2NvbG9yIiwiQk9EWTo6bGluayIsIkJPRFk6
+OnRleHQiLCJCT0RZOjp2bGluayIsIkJSOjpjbGVhciIsIkJVVFRPTjo6YWNjZXNza2V5IiwiQlVUVE9O
+OjpkaXNhYmxlZCIsIkJVVFRPTjo6bmFtZSIsIkJVVFRPTjo6dGFiaW5kZXgiLCJCVVRUT046OnR5cGUi
+LCJCVVRUT046OnZhbHVlIiwiQ0FOVkFTOjpoZWlnaHQiLCJDQU5WQVM6OndpZHRoIiwiQ0FQVElPTjo6
+YWxpZ24iLCJDT0w6OmFsaWduIiwiQ09MOjpjaGFyIiwiQ09MOjpjaGFyb2ZmIiwiQ09MOjpzcGFuIiwi
+Q09MOjp2YWxpZ24iLCJDT0w6OndpZHRoIiwiQ09MR1JPVVA6OmFsaWduIiwiQ09MR1JPVVA6OmNoYXIi
+LCJDT0xHUk9VUDo6Y2hhcm9mZiIsIkNPTEdST1VQOjpzcGFuIiwiQ09MR1JPVVA6OnZhbGlnbiIsIkNP
+TEdST1VQOjp3aWR0aCIsIkNPTU1BTkQ6OmNoZWNrZWQiLCJDT01NQU5EOjpjb21tYW5kIiwiQ09NTUFO
+RDo6ZGlzYWJsZWQiLCJDT01NQU5EOjpsYWJlbCIsIkNPTU1BTkQ6OnJhZGlvZ3JvdXAiLCJDT01NQU5E
+Ojp0eXBlIiwiREFUQTo6dmFsdWUiLCJERUw6OmRhdGV0aW1lIiwiREVUQUlMUzo6b3BlbiIsIkRJUjo6
+Y29tcGFjdCIsIkRJVjo6YWxpZ24iLCJETDo6Y29tcGFjdCIsIkZJRUxEU0VUOjpkaXNhYmxlZCIsIkZP
+TlQ6OmNvbG9yIiwiRk9OVDo6ZmFjZSIsIkZPTlQ6OnNpemUiLCJGT1JNOjphY2NlcHQiLCJGT1JNOjph
+dXRvY29tcGxldGUiLCJGT1JNOjplbmN0eXBlIiwiRk9STTo6bWV0aG9kIiwiRk9STTo6bmFtZSIsIkZP
+Uk06Om5vdmFsaWRhdGUiLCJGT1JNOjp0YXJnZXQiLCJGUkFNRTo6bmFtZSIsIkgxOjphbGlnbiIsIkgy
+OjphbGlnbiIsIkgzOjphbGlnbiIsIkg0OjphbGlnbiIsIkg1OjphbGlnbiIsIkg2OjphbGlnbiIsIkhS
+OjphbGlnbiIsIkhSOjpub3NoYWRlIiwiSFI6OnNpemUiLCJIUjo6d2lkdGgiLCJIVE1MOjp2ZXJzaW9u
+IiwiSUZSQU1FOjphbGlnbiIsIklGUkFNRTo6ZnJhbWVib3JkZXIiLCJJRlJBTUU6OmhlaWdodCIsIklG
+UkFNRTo6bWFyZ2luaGVpZ2h0IiwiSUZSQU1FOjptYXJnaW53aWR0aCIsIklGUkFNRTo6d2lkdGgiLCJJ
+TUc6OmFsaWduIiwiSU1HOjphbHQiLCJJTUc6OmJvcmRlciIsIklNRzo6aGVpZ2h0IiwiSU1HOjpoc3Bh
+Y2UiLCJJTUc6OmlzbWFwIiwiSU1HOjpuYW1lIiwiSU1HOjp1c2VtYXAiLCJJTUc6OnZzcGFjZSIsIklN
+Rzo6d2lkdGgiLCJJTlBVVDo6YWNjZXB0IiwiSU5QVVQ6OmFjY2Vzc2tleSIsIklOUFVUOjphbGlnbiIs
+IklOUFVUOjphbHQiLCJJTlBVVDo6YXV0b2NvbXBsZXRlIiwiSU5QVVQ6OmF1dG9mb2N1cyIsIklOUFVU
+OjpjaGVja2VkIiwiSU5QVVQ6OmRpc2FibGVkIiwiSU5QVVQ6OmlucHV0bW9kZSIsIklOUFVUOjppc21h
+cCIsIklOUFVUOjpsaXN0IiwiSU5QVVQ6Om1heCIsIklOUFVUOjptYXhsZW5ndGgiLCJJTlBVVDo6bWlu
+IiwiSU5QVVQ6Om11bHRpcGxlIiwiSU5QVVQ6Om5hbWUiLCJJTlBVVDo6cGxhY2Vob2xkZXIiLCJJTlBV
+VDo6cmVhZG9ubHkiLCJJTlBVVDo6cmVxdWlyZWQiLCJJTlBVVDo6c2l6ZSIsIklOUFVUOjpzdGVwIiwi
+SU5QVVQ6OnRhYmluZGV4IiwiSU5QVVQ6OnR5cGUiLCJJTlBVVDo6dXNlbWFwIiwiSU5QVVQ6OnZhbHVl
+IiwiSU5TOjpkYXRldGltZSIsIktFWUdFTjo6ZGlzYWJsZWQiLCJLRVlHRU46OmtleXR5cGUiLCJLRVlH
+RU46Om5hbWUiLCJMQUJFTDo6YWNjZXNza2V5IiwiTEFCRUw6OmZvciIsIkxFR0VORDo6YWNjZXNza2V5
+IiwiTEVHRU5EOjphbGlnbiIsIkxJOjp0eXBlIiwiTEk6OnZhbHVlIiwiTElOSzo6c2l6ZXMiLCJNQVA6
+Om5hbWUiLCJNRU5VOjpjb21wYWN0IiwiTUVOVTo6bGFiZWwiLCJNRU5VOjp0eXBlIiwiTUVURVI6Omhp
+Z2giLCJNRVRFUjo6bG93IiwiTUVURVI6Om1heCIsIk1FVEVSOjptaW4iLCJNRVRFUjo6dmFsdWUiLCJP
+QkpFQ1Q6OnR5cGVtdXN0bWF0Y2giLCJPTDo6Y29tcGFjdCIsIk9MOjpyZXZlcnNlZCIsIk9MOjpzdGFy
+dCIsIk9MOjp0eXBlIiwiT1BUR1JPVVA6OmRpc2FibGVkIiwiT1BUR1JPVVA6OmxhYmVsIiwiT1BUSU9O
+OjpkaXNhYmxlZCIsIk9QVElPTjo6bGFiZWwiLCJPUFRJT046OnNlbGVjdGVkIiwiT1BUSU9OOjp2YWx1
+ZSIsIk9VVFBVVDo6Zm9yIiwiT1VUUFVUOjpuYW1lIiwiUDo6YWxpZ24iLCJQUkU6OndpZHRoIiwiUFJP
+R1JFU1M6Om1heCIsIlBST0dSRVNTOjptaW4iLCJQUk9HUkVTUzo6dmFsdWUiLCJTRUxFQ1Q6OmF1dG9j
+b21wbGV0ZSIsIlNFTEVDVDo6ZGlzYWJsZWQiLCJTRUxFQ1Q6Om11bHRpcGxlIiwiU0VMRUNUOjpuYW1l
+IiwiU0VMRUNUOjpyZXF1aXJlZCIsIlNFTEVDVDo6c2l6ZSIsIlNFTEVDVDo6dGFiaW5kZXgiLCJTT1VS
+Q0U6OnR5cGUiLCJUQUJMRTo6YWxpZ24iLCJUQUJMRTo6Ymdjb2xvciIsIlRBQkxFOjpib3JkZXIiLCJU
+QUJMRTo6Y2VsbHBhZGRpbmciLCJUQUJMRTo6Y2VsbHNwYWNpbmciLCJUQUJMRTo6ZnJhbWUiLCJUQUJM
+RTo6cnVsZXMiLCJUQUJMRTo6c3VtbWFyeSIsIlRBQkxFOjp3aWR0aCIsIlRCT0RZOjphbGlnbiIsIlRC
+T0RZOjpjaGFyIiwiVEJPRFk6OmNoYXJvZmYiLCJUQk9EWTo6dmFsaWduIiwiVEQ6OmFiYnIiLCJURDo6
+YWxpZ24iLCJURDo6YXhpcyIsIlREOjpiZ2NvbG9yIiwiVEQ6OmNoYXIiLCJURDo6Y2hhcm9mZiIsIlRE
+Ojpjb2xzcGFuIiwiVEQ6OmhlYWRlcnMiLCJURDo6aGVpZ2h0IiwiVEQ6Om5vd3JhcCIsIlREOjpyb3dz
+cGFuIiwiVEQ6OnNjb3BlIiwiVEQ6OnZhbGlnbiIsIlREOjp3aWR0aCIsIlRFWFRBUkVBOjphY2Nlc3Nr
+ZXkiLCJURVhUQVJFQTo6YXV0b2NvbXBsZXRlIiwiVEVYVEFSRUE6OmNvbHMiLCJURVhUQVJFQTo6ZGlz
+YWJsZWQiLCJURVhUQVJFQTo6aW5wdXRtb2RlIiwiVEVYVEFSRUE6Om5hbWUiLCJURVhUQVJFQTo6cGxh
+Y2Vob2xkZXIiLCJURVhUQVJFQTo6cmVhZG9ubHkiLCJURVhUQVJFQTo6cmVxdWlyZWQiLCJURVhUQVJF
+QTo6cm93cyIsIlRFWFRBUkVBOjp0YWJpbmRleCIsIlRFWFRBUkVBOjp3cmFwIiwiVEZPT1Q6OmFsaWdu
+IiwiVEZPT1Q6OmNoYXIiLCJURk9PVDo6Y2hhcm9mZiIsIlRGT09UOjp2YWxpZ24iLCJUSDo6YWJiciIs
+IlRIOjphbGlnbiIsIlRIOjpheGlzIiwiVEg6OmJnY29sb3IiLCJUSDo6Y2hhciIsIlRIOjpjaGFyb2Zm
+IiwiVEg6OmNvbHNwYW4iLCJUSDo6aGVhZGVycyIsIlRIOjpoZWlnaHQiLCJUSDo6bm93cmFwIiwiVEg6
+OnJvd3NwYW4iLCJUSDo6c2NvcGUiLCJUSDo6dmFsaWduIiwiVEg6OndpZHRoIiwiVEhFQUQ6OmFsaWdu
+IiwiVEhFQUQ6OmNoYXIiLCJUSEVBRDo6Y2hhcm9mZiIsIlRIRUFEOjp2YWxpZ24iLCJUUjo6YWxpZ24i
+LCJUUjo6Ymdjb2xvciIsIlRSOjpjaGFyIiwiVFI6OmNoYXJvZmYiLCJUUjo6dmFsaWduIiwiVFJBQ0s6
+OmRlZmF1bHQiLCJUUkFDSzo6a2luZCIsIlRSQUNLOjpsYWJlbCIsIlRSQUNLOjpzcmNsYW5nIiwiVUw6
+OmNvbXBhY3QiLCJVTDo6dHlwZSIsIlZJREVPOjpjb250cm9scyIsIlZJREVPOjpoZWlnaHQiLCJWSURF
+Tzo6bG9vcCIsIlZJREVPOjptZWRpYWdyb3VwIiwiVklERU86Om11dGVkIiwiVklERU86OnByZWxvYWQi
+LCJWSURFTzo6d2lkdGgiXSksdS5zKQpDLlZDPUguVk0odChbMCwwLDY1NDkwLDQ1MDU1LDY1NTM1LDM0
+ODE1LDY1NTM0LDE4NDMxXSksdS50KQpDLm1LPUguVk0odChbMCwwLDI2NjI0LDEwMjMsNjU1MzQsMjA0
+Nyw2NTUzNCwyMDQ3XSksdS50KQpDLlNxPUguVk0odChbIkhFQUQiLCJBUkVBIiwiQkFTRSIsIkJBU0VG
+T05UIiwiQlIiLCJDT0wiLCJDT0xHUk9VUCIsIkVNQkVEIiwiRlJBTUUiLCJGUkFNRVNFVCIsIkhSIiwi
+SU1BR0UiLCJJTUciLCJJTlBVVCIsIklTSU5ERVgiLCJMSU5LIiwiTUVUQSIsIlBBUkFNIiwiU09VUkNF
+IiwiU1RZTEUiLCJUSVRMRSIsIldCUiJdKSx1LnMpCkMuZG49SC5WTSh0KFtdKSxILk4wKCJqZDxMTD4i
+KSkKQy54RD1ILlZNKHQoW10pLHUucykKQy5oVT1ILlZNKHQoW10pLHUuYikKQy50bz1ILlZNKHQoWzAs
+MCwzMjcyMiwxMjI4Nyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5yaz1ILlZNKHQoW0Mu
+QWQsQy5uZSxDLm15LEMucngsQy53VixDLmZSXSksSC5OMCgiamQ8SDc+IikpCkMuRjM9SC5WTSh0KFsw
+LDAsMjQ1NzYsMTAyMyw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5lYT1ILlZNKHQoWzAs
+MCwzMjc1NCwxMTI2Myw2NTUzNCwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5aSj1ILlZNKHQoWzAs
+MCwzMjcyMiwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5XZD1ILlZNKHQoWzAs
+MCw2NTQ5MCwxMjI4Nyw2NTUzNSwzNDgxNSw2NTUzNCwxODQzMV0pLHUudCkKQy5ReD1ILlZNKHQoWyJi
+aW5kIiwiaWYiLCJyZWYiLCJyZXBlYXQiLCJzeW50YXgiXSksdS5zKQpDLkJJPUguVk0odChbIkE6Omhy
+ZWYiLCJBUkVBOjpocmVmIiwiQkxPQ0tRVU9URTo6Y2l0ZSIsIkJPRFk6OmJhY2tncm91bmQiLCJDT01N
+QU5EOjppY29uIiwiREVMOjpjaXRlIiwiRk9STTo6YWN0aW9uIiwiSU1HOjpzcmMiLCJJTlBVVDo6c3Jj
+IiwiSU5TOjpjaXRlIiwiUTo6Y2l0ZSIsIlZJREVPOjpwb3N0ZXIiXSksdS5zKQpDLkNNPW5ldyBILkxQ
+KDAse30sQy54RCxILk4wKCJMUDxxVSx6TTxqOD4+IikpCkMuV089bmV3IEguTFAoMCx7fSxDLnhELEgu
+TjAoIkxQPHFVLHFVPiIpKQpDLmlIPUguVk0odChbXSksSC5OMCgiamQ8R0Q+IikpCkMuRHg9bmV3IEgu
+TFAoMCx7fSxDLmlILEguTjAoIkxQPEdELEA+IikpCkMuWTI9bmV3IEwuTzkoIk5hdmlnYXRpb25UcmVl
+Tm9kZVR5cGUuZGlyZWN0b3J5IikKQy5yZj1uZXcgTC5POSgiTmF2aWdhdGlvblRyZWVOb2RlVHlwZS5m
+aWxlIikKQy5UZT1uZXcgSC53digiY2FsbCIpCkMud1E9bmV3IFAuRnkobnVsbCwyKX0pKCk7KGZ1bmN0
+aW9uIHN0YXRpY0ZpZWxkcygpeyQueWo9MAokLm1KPW51bGwKJC5QND1udWxsCiQuTkY9bnVsbAokLlRY
+PW51bGwKJC54Nz1udWxsCiQubnc9bnVsbAokLnZ2PW51bGwKJC5Cdj1udWxsCiQuUzY9bnVsbAokLms4
+PW51bGwKJC5tZz1udWxsCiQuVUQ9ITEKJC5YMz1DLk5VCiQueGc9W10KJC54bz1udWxsCiQuQk89bnVs
+bAokLmx0PW51bGwKJC5FVT1udWxsCiQub3I9UC5GbCh1Lk4sdS5aKQokLkk2PW51bGwKJC5GZj1udWxs
+fSkoKTsoZnVuY3Rpb24gbGF6eUluaXRpYWxpemVycygpe3ZhciB0PWh1bmtIZWxwZXJzLmxhenkKdCgk
+LCJmYSIsInciLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFydF9kYXJ0Q2xvc3VyZSIpfSkKdCgk
+LCJZMiIsIlVOIixmdW5jdGlvbigpe3JldHVybiBILllnKCJfJGRhcnRfanMiKX0pCnQoJCwiVTIiLCJT
+biIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KHsKdG9TdHJpbmc6ZnVuY3Rpb24oKXtyZXR1cm4i
+JHJlY2VpdmVyJCJ9fSkpfSkKdCgkLCJ4cSIsImxxIixmdW5jdGlvbigpe3JldHVybiBILmNNKEguUzco
+eyRtZXRob2QkOm51bGwsCnRvU3RyaW5nOmZ1bmN0aW9uKCl7cmV0dXJuIiRyZWNlaXZlciQifX0pKX0p
+CnQoJCwiUjEiLCJOOSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILlM3KG51bGwpKX0pCnQoJCwiZk4i
+LCJpSSIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3ZhciAkYXJndW1lbnRzRXhwciQ9
+JyRhcmd1bWVudHMkJwp0cnl7bnVsbC4kbWV0aG9kJCgkYXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3Jl
+dHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwicWkiLCJLZiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShI
+LlM3KHZvaWQgMCkpfSkKdCgkLCJyWiIsIlpoIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9u
+KCl7dmFyICRhcmd1bWVudHNFeHByJD0nJGFyZ3VtZW50cyQnCnRyeXsodm9pZCAwKS4kbWV0aG9kJCgk
+YXJndW1lbnRzRXhwciQpfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwia3EiLCJy
+TiIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1qKG51bGwpKX0pCnQoJCwidHQiLCJjMyIsZnVuY3Rp
+b24oKXtyZXR1cm4gSC5jTShmdW5jdGlvbigpe3RyeXtudWxsLiRtZXRob2QkfWNhdGNoKHMpe3JldHVy
+biBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwiZHQiLCJISyIsZnVuY3Rpb24oKXtyZXR1cm4gSC5jTShILk1q
+KHZvaWQgMCkpfSkKdCgkLCJBNyIsInIxIixmdW5jdGlvbigpe3JldHVybiBILmNNKGZ1bmN0aW9uKCl7
+dHJ5eyh2b2lkIDApLiRtZXRob2QkfWNhdGNoKHMpe3JldHVybiBzLm1lc3NhZ2V9fSgpKX0pCnQoJCwi
+V2MiLCJ1dCIsZnVuY3Rpb24oKXtyZXR1cm4gUC5PaigpfSkKdCgkLCJraCIsInJmIixmdW5jdGlvbigp
+e3JldHVybiBQLldJKCl9KQp0KCQsImJ0IiwiVjciLGZ1bmN0aW9uKCl7cmV0dXJuIEguRFEoSC5YRihI
+LlZNKFstMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwt
+MiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMiwtMSwt
+MiwtMiwtMiwtMiwtMiw2MiwtMiw2MiwtMiw2Myw1Miw1Myw1NCw1NSw1Niw1Nyw1OCw1OSw2MCw2MSwt
+MiwtMiwtMiwtMSwtMiwtMiwtMiwwLDEsMiwzLDQsNSw2LDcsOCw5LDEwLDExLDEyLDEzLDE0LDE1LDE2
+LDE3LDE4LDE5LDIwLDIxLDIyLDIzLDI0LDI1LC0yLC0yLC0yLC0yLDYzLC0yLDI2LDI3LDI4LDI5LDMw
+LDMxLDMyLDMzLDM0LDM1LDM2LDM3LDM4LDM5LDQwLDQxLDQyLDQzLDQ0LDQ1LDQ2LDQ3LDQ4LDQ5LDUw
+LDUxLC0yLC0yLC0yLC0yLC0yXSx1LnQpKSl9KQp0KCQsIk01Iiwid1EiLGZ1bmN0aW9uKCl7cmV0dXJu
+IHR5cGVvZiBwcm9jZXNzIT0idW5kZWZpbmVkIiYmT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxs
+KHByb2Nlc3MpPT0iW29iamVjdCBwcm9jZXNzXSImJnByb2Nlc3MucGxhdGZvcm09PSJ3aW4zMiJ9KQp0
+KCQsIm1mIiwiejQiLGZ1bmN0aW9uKCl7cmV0dXJuIFAubnUoIl5bXFwtXFwuMC05QS1aX2Eten5dKiQi
+KX0pCnQoJCwiSkciLCJ2WiIsZnVuY3Rpb24oKXtyZXR1cm4gUC51eCgpfSkKdCgkLCJTQyIsIkFOIixm
+dW5jdGlvbigpe3JldHVybiBQLnRNKFsiQSIsIkFCQlIiLCJBQ1JPTllNIiwiQUREUkVTUyIsIkFSRUEi
+LCJBUlRJQ0xFIiwiQVNJREUiLCJBVURJTyIsIkIiLCJCREkiLCJCRE8iLCJCSUciLCJCTE9DS1FVT1RF
+IiwiQlIiLCJCVVRUT04iLCJDQU5WQVMiLCJDQVBUSU9OIiwiQ0VOVEVSIiwiQ0lURSIsIkNPREUiLCJD
+T0wiLCJDT0xHUk9VUCIsIkNPTU1BTkQiLCJEQVRBIiwiREFUQUxJU1QiLCJERCIsIkRFTCIsIkRFVEFJ
+TFMiLCJERk4iLCJESVIiLCJESVYiLCJETCIsIkRUIiwiRU0iLCJGSUVMRFNFVCIsIkZJR0NBUFRJT04i
+LCJGSUdVUkUiLCJGT05UIiwiRk9PVEVSIiwiRk9STSIsIkgxIiwiSDIiLCJIMyIsIkg0IiwiSDUiLCJI
+NiIsIkhFQURFUiIsIkhHUk9VUCIsIkhSIiwiSSIsIklGUkFNRSIsIklNRyIsIklOUFVUIiwiSU5TIiwi
+S0JEIiwiTEFCRUwiLCJMRUdFTkQiLCJMSSIsIk1BUCIsIk1BUksiLCJNRU5VIiwiTUVURVIiLCJOQVYi
+LCJOT0JSIiwiT0wiLCJPUFRHUk9VUCIsIk9QVElPTiIsIk9VVFBVVCIsIlAiLCJQUkUiLCJQUk9HUkVT
+UyIsIlEiLCJTIiwiU0FNUCIsIlNFQ1RJT04iLCJTRUxFQ1QiLCJTTUFMTCIsIlNPVVJDRSIsIlNQQU4i
+LCJTVFJJS0UiLCJTVFJPTkciLCJTVUIiLCJTVU1NQVJZIiwiU1VQIiwiVEFCTEUiLCJUQk9EWSIsIlRE
+IiwiVEVYVEFSRUEiLCJURk9PVCIsIlRIIiwiVEhFQUQiLCJUSU1FIiwiVFIiLCJUUkFDSyIsIlRUIiwi
+VSIsIlVMIiwiVkFSIiwiVklERU8iLCJXQlIiXSx1Lk4pfSkKdCgkLCJYNCIsImhHIixmdW5jdGlvbigp
+e3JldHVybiBQLm51KCJeXFxTKyQiKX0pCnQoJCwid08iLCJvdyIsZnVuY3Rpb24oKXtyZXR1cm4gdS5t
+LmIoUC5ORChzZWxmKSl9KQp0KCQsImt0IiwiUjgiLGZ1bmN0aW9uKCl7cmV0dXJuIEguWWcoIl8kZGFy
+dF9kYXJ0T2JqZWN0Iil9KQp0KCQsImZLIiwia0kiLGZ1bmN0aW9uKCl7cmV0dXJuIGZ1bmN0aW9uIERh
+cnRPYmplY3QoYSl7dGhpcy5vPWF9fSkKdCgkLCJxdCIsInpCIixmdW5jdGlvbigpe3JldHVybiBuZXcg
+VC5tUSgpfSkKdCgkLCJPbCIsIlVFIixmdW5jdGlvbigpe3JldHVybiBQLmhLKEMub2wuZ21XKFcueDMo
+KSkuaHJlZikuZ2hZKCkucSgwLCJhdXRoVG9rZW4iKX0pCnQoJCwiaFQiLCJ5UCIsZnVuY3Rpb24oKXty
+ZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LWxpc3QgLnBhbmVsLWNvbnRlbnQiKX0pCnQo
+JCwiVzYiLCJoTCIsZnVuY3Rpb24oKXtyZXR1cm4gVy5acigpLnF1ZXJ5U2VsZWN0b3IoIi5lZGl0LXBh
+bmVsIC5wYW5lbC1jb250ZW50Iil9KQp0KCQsIlRSIiwiRFciLGZ1bmN0aW9uKCl7cmV0dXJuIFcuWnIo
+KS5xdWVyeVNlbGVjdG9yKCJmb290ZXIiKX0pCnQoJCwiRVkiLCJmaSIsZnVuY3Rpb24oKXtyZXR1cm4g
+Vy5acigpLnF1ZXJ5U2VsZWN0b3IoImhlYWRlciIpfSkKdCgkLCJhdiIsIkQ5IixmdW5jdGlvbigpe3Jl
+dHVybiBXLlpyKCkucXVlcnlTZWxlY3RvcigiI3VuaXQtbmFtZSIpfSkKdCgkLCJmZSIsIktHIixmdW5j
+dGlvbigpe3JldHVybiBuZXcgTC5YQSgpfSkKdCgkLCJtTSIsIm5VIixmdW5jdGlvbigpe3JldHVybiBu
+ZXcgTS5sSSgkLkhrKCkpfSkKdCgkLCJ5ciIsImJEIixmdW5jdGlvbigpe3JldHVybiBuZXcgRS5PRihQ
+Lm51KCIvIiksUC5udSgiW14vXSQiKSxQLm51KCJeLyIpKX0pCnQoJCwiTWsiLCJLayIsZnVuY3Rpb24o
+KXtyZXR1cm4gbmV3IEwuSVYoUC5udSgiWy9cXFxcXSIpLFAubnUoIlteL1xcXFxdJCIpLFAubnUoIl4o
+XFxcXFxcXFxbXlxcXFxdK1xcXFxbXlxcXFwvXSt8W2EtekEtWl06Wy9cXFxcXSkiKSxQLm51KCJeWy9c
+XFxcXSg/IVsvXFxcXF0pIikpfSkKdCgkLCJhayIsIkViIixmdW5jdGlvbigpe3JldHVybiBuZXcgRi5y
+dShQLm51KCIvIiksUC5udSgiKF5bYS16QS1aXVstKy5hLXpBLVpcXGRdKjovL3xbXi9dKSQiKSxQLm51
+KCJbYS16QS1aXVstKy5hLXpBLVpcXGRdKjovL1teL10qIiksUC5udSgiXi8iKSl9KQp0KCQsImxzIiwi
+SGsiLGZ1bmN0aW9uKCl7cmV0dXJuIE8uUmgoKX0pfSkoKTsoZnVuY3Rpb24gbmF0aXZlU3VwcG9ydCgp
+eyFmdW5jdGlvbigpe3ZhciB0PWZ1bmN0aW9uKGEpe3ZhciBuPXt9Cm5bYV09MQpyZXR1cm4gT2JqZWN0
+LmtleXMoaHVua0hlbHBlcnMuY29udmVydFRvRmFzdE9iamVjdChuKSlbMF19CnYuZ2V0SXNvbGF0ZVRh
+Zz1mdW5jdGlvbihhKXtyZXR1cm4gdCgiX19fZGFydF8iK2Erdi5pc29sYXRlVGFnKX0KdmFyIHM9Il9f
+X2RhcnRfaXNvbGF0ZV90YWdzXyIKdmFyIHI9T2JqZWN0W3NdfHwoT2JqZWN0W3NdPU9iamVjdC5jcmVh
+dGUobnVsbCkpCnZhciBxPSJfWnhZeFgiCmZvcih2YXIgcD0wOztwKyspe3ZhciBvPXQocSsiXyIrcCsi
+XyIpCmlmKCEobyBpbiByKSl7cltvXT0xCnYuaXNvbGF0ZVRhZz1vCmJyZWFrfX12LmRpc3BhdGNoUHJv
+cGVydHlOYW1lPXYuZ2V0SXNvbGF0ZVRhZygiZGlzcGF0Y2hfcmVjb3JkIil9KCkKaHVua0hlbHBlcnMu
+c2V0T3JVcGRhdGVJbnRlcmNlcHRvcnNCeVRhZyh7RE9NRXJyb3I6Si52QixET01JbXBsZW1lbnRhdGlv
+bjpKLnZCLE1lZGlhRXJyb3I6Si52QixOYXZpZ2F0b3I6Si52QixOYXZpZ2F0b3JDb25jdXJyZW50SGFy
+ZHdhcmU6Si52QixOYXZpZ2F0b3JVc2VyTWVkaWFFcnJvcjpKLnZCLE92ZXJjb25zdHJhaW5lZEVycm9y
+OkoudkIsUG9zaXRpb25FcnJvcjpKLnZCLFJhbmdlOkoudkIsU1FMRXJyb3I6Si52QixEYXRhVmlldzpI
+LkVULEFycmF5QnVmZmVyVmlldzpILkVULEZsb2F0MzJBcnJheTpILkRnLEZsb2F0NjRBcnJheTpILkRn
+LEludDE2QXJyYXk6SC54aixJbnQzMkFycmF5OkguZEUsSW50OEFycmF5OkguWkEsVWludDE2QXJyYXk6
+SC53ZixVaW50MzJBcnJheTpILlBxLFVpbnQ4Q2xhbXBlZEFycmF5OkguZUUsQ2FudmFzUGl4ZWxBcnJh
+eTpILmVFLFVpbnQ4QXJyYXk6SC5WNixIVE1MQXVkaW9FbGVtZW50OlcucUUsSFRNTEJSRWxlbWVudDpX
+LnFFLEhUTUxCdXR0b25FbGVtZW50OlcucUUsSFRNTENhbnZhc0VsZW1lbnQ6Vy5xRSxIVE1MQ29udGVu
+dEVsZW1lbnQ6Vy5xRSxIVE1MRExpc3RFbGVtZW50OlcucUUsSFRNTERhdGFFbGVtZW50OlcucUUsSFRN
+TERhdGFMaXN0RWxlbWVudDpXLnFFLEhUTUxEZXRhaWxzRWxlbWVudDpXLnFFLEhUTUxEaWFsb2dFbGVt
+ZW50OlcucUUsSFRNTERpdkVsZW1lbnQ6Vy5xRSxIVE1MRW1iZWRFbGVtZW50OlcucUUsSFRNTEZpZWxk
+U2V0RWxlbWVudDpXLnFFLEhUTUxIUkVsZW1lbnQ6Vy5xRSxIVE1MSGVhZEVsZW1lbnQ6Vy5xRSxIVE1M
+SGVhZGluZ0VsZW1lbnQ6Vy5xRSxIVE1MSHRtbEVsZW1lbnQ6Vy5xRSxIVE1MSUZyYW1lRWxlbWVudDpX
+LnFFLEhUTUxJbWFnZUVsZW1lbnQ6Vy5xRSxIVE1MSW5wdXRFbGVtZW50OlcucUUsSFRNTExJRWxlbWVu
+dDpXLnFFLEhUTUxMYWJlbEVsZW1lbnQ6Vy5xRSxIVE1MTGVnZW5kRWxlbWVudDpXLnFFLEhUTUxMaW5r
+RWxlbWVudDpXLnFFLEhUTUxNYXBFbGVtZW50OlcucUUsSFRNTE1lZGlhRWxlbWVudDpXLnFFLEhUTUxN
+ZW51RWxlbWVudDpXLnFFLEhUTUxNZXRhRWxlbWVudDpXLnFFLEhUTUxNZXRlckVsZW1lbnQ6Vy5xRSxI
+VE1MTW9kRWxlbWVudDpXLnFFLEhUTUxPTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MT2JqZWN0RWxlbWVudDpX
+LnFFLEhUTUxPcHRHcm91cEVsZW1lbnQ6Vy5xRSxIVE1MT3B0aW9uRWxlbWVudDpXLnFFLEhUTUxPdXRw
+dXRFbGVtZW50OlcucUUsSFRNTFBhcmFtRWxlbWVudDpXLnFFLEhUTUxQaWN0dXJlRWxlbWVudDpXLnFF
+LEhUTUxQcmVFbGVtZW50OlcucUUsSFRNTFByb2dyZXNzRWxlbWVudDpXLnFFLEhUTUxRdW90ZUVsZW1l
+bnQ6Vy5xRSxIVE1MU2NyaXB0RWxlbWVudDpXLnFFLEhUTUxTaGFkb3dFbGVtZW50OlcucUUsSFRNTFNs
+b3RFbGVtZW50OlcucUUsSFRNTFNvdXJjZUVsZW1lbnQ6Vy5xRSxIVE1MU3BhbkVsZW1lbnQ6Vy5xRSxI
+VE1MU3R5bGVFbGVtZW50OlcucUUsSFRNTFRhYmxlQ2FwdGlvbkVsZW1lbnQ6Vy5xRSxIVE1MVGFibGVD
+ZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZURhdGFDZWxsRWxlbWVudDpXLnFFLEhUTUxUYWJsZUhlYWRl
+ckNlbGxFbGVtZW50OlcucUUsSFRNTFRhYmxlQ29sRWxlbWVudDpXLnFFLEhUTUxUZXh0QXJlYUVsZW1l
+bnQ6Vy5xRSxIVE1MVGltZUVsZW1lbnQ6Vy5xRSxIVE1MVGl0bGVFbGVtZW50OlcucUUsSFRNTFRyYWNr
+RWxlbWVudDpXLnFFLEhUTUxVTGlzdEVsZW1lbnQ6Vy5xRSxIVE1MVW5rbm93bkVsZW1lbnQ6Vy5xRSxI
+VE1MVmlkZW9FbGVtZW50OlcucUUsSFRNTERpcmVjdG9yeUVsZW1lbnQ6Vy5xRSxIVE1MRm9udEVsZW1l
+bnQ6Vy5xRSxIVE1MRnJhbWVFbGVtZW50OlcucUUsSFRNTEZyYW1lU2V0RWxlbWVudDpXLnFFLEhUTUxN
+YXJxdWVlRWxlbWVudDpXLnFFLEhUTUxFbGVtZW50OlcucUUsSFRNTEFuY2hvckVsZW1lbnQ6Vy5HaCxI
+VE1MQXJlYUVsZW1lbnQ6Vy5mWSxIVE1MQmFzZUVsZW1lbnQ6Vy5uQixCbG9iOlcuQXosSFRNTEJvZHlF
+bGVtZW50OlcuUVAsQ0RBVEFTZWN0aW9uOlcubngsQ2hhcmFjdGVyRGF0YTpXLm54LENvbW1lbnQ6Vy5u
+eCxQcm9jZXNzaW5nSW5zdHJ1Y3Rpb246Vy5ueCxUZXh0OlcubngsQ1NTU3R5bGVEZWNsYXJhdGlvbjpX
+Lm9KLE1TU3R5bGVDU1NQcm9wZXJ0aWVzOlcub0osQ1NTMlByb3BlcnRpZXM6Vy5vSixYTUxEb2N1bWVu
+dDpXLlFGLERvY3VtZW50OlcuUUYsRE9NRXhjZXB0aW9uOlcuTmgsRE9NUmVjdFJlYWRPbmx5OlcuSUIs
+RE9NVG9rZW5MaXN0OlcubjcsRWxlbWVudDpXLmN2LEFib3J0UGF5bWVudEV2ZW50OlcuZWEsQW5pbWF0
+aW9uRXZlbnQ6Vy5lYSxBbmltYXRpb25QbGF5YmFja0V2ZW50OlcuZWEsQXBwbGljYXRpb25DYWNoZUVy
+cm9yRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hDbGlja0V2ZW50OlcuZWEsQmFja2dyb3VuZEZldGNo
+RXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hGYWlsRXZlbnQ6Vy5lYSxCYWNrZ3JvdW5kRmV0Y2hlZEV2
+ZW50OlcuZWEsQmVmb3JlSW5zdGFsbFByb21wdEV2ZW50OlcuZWEsQmVmb3JlVW5sb2FkRXZlbnQ6Vy5l
+YSxCbG9iRXZlbnQ6Vy5lYSxDYW5NYWtlUGF5bWVudEV2ZW50OlcuZWEsQ2xpcGJvYXJkRXZlbnQ6Vy5l
+YSxDbG9zZUV2ZW50OlcuZWEsQ3VzdG9tRXZlbnQ6Vy5lYSxEZXZpY2VNb3Rpb25FdmVudDpXLmVhLERl
+dmljZU9yaWVudGF0aW9uRXZlbnQ6Vy5lYSxFcnJvckV2ZW50OlcuZWEsRXh0ZW5kYWJsZUV2ZW50Olcu
+ZWEsRXh0ZW5kYWJsZU1lc3NhZ2VFdmVudDpXLmVhLEZldGNoRXZlbnQ6Vy5lYSxGb250RmFjZVNldExv
+YWRFdmVudDpXLmVhLEZvcmVpZ25GZXRjaEV2ZW50OlcuZWEsR2FtZXBhZEV2ZW50OlcuZWEsSGFzaENo
+YW5nZUV2ZW50OlcuZWEsSW5zdGFsbEV2ZW50OlcuZWEsTWVkaWFFbmNyeXB0ZWRFdmVudDpXLmVhLE1l
+ZGlhS2V5TWVzc2FnZUV2ZW50OlcuZWEsTWVkaWFRdWVyeUxpc3RFdmVudDpXLmVhLE1lZGlhU3RyZWFt
+RXZlbnQ6Vy5lYSxNZWRpYVN0cmVhbVRyYWNrRXZlbnQ6Vy5lYSxNZXNzYWdlRXZlbnQ6Vy5lYSxNSURJ
+Q29ubmVjdGlvbkV2ZW50OlcuZWEsTUlESU1lc3NhZ2VFdmVudDpXLmVhLE11dGF0aW9uRXZlbnQ6Vy5l
+YSxOb3RpZmljYXRpb25FdmVudDpXLmVhLFBhZ2VUcmFuc2l0aW9uRXZlbnQ6Vy5lYSxQYXltZW50UmVx
+dWVzdEV2ZW50OlcuZWEsUGF5bWVudFJlcXVlc3RVcGRhdGVFdmVudDpXLmVhLFBvcFN0YXRlRXZlbnQ6
+Vy5lYSxQcmVzZW50YXRpb25Db25uZWN0aW9uQXZhaWxhYmxlRXZlbnQ6Vy5lYSxQcmVzZW50YXRpb25D
+b25uZWN0aW9uQ2xvc2VFdmVudDpXLmVhLFByb21pc2VSZWplY3Rpb25FdmVudDpXLmVhLFB1c2hFdmVu
+dDpXLmVhLFJUQ0RhdGFDaGFubmVsRXZlbnQ6Vy5lYSxSVENEVE1GVG9uZUNoYW5nZUV2ZW50OlcuZWEs
+UlRDUGVlckNvbm5lY3Rpb25JY2VFdmVudDpXLmVhLFJUQ1RyYWNrRXZlbnQ6Vy5lYSxTZWN1cml0eVBv
+bGljeVZpb2xhdGlvbkV2ZW50OlcuZWEsU2Vuc29yRXJyb3JFdmVudDpXLmVhLFNwZWVjaFJlY29nbml0
+aW9uRXJyb3I6Vy5lYSxTcGVlY2hSZWNvZ25pdGlvbkV2ZW50OlcuZWEsU3BlZWNoU3ludGhlc2lzRXZl
+bnQ6Vy5lYSxTdG9yYWdlRXZlbnQ6Vy5lYSxTeW5jRXZlbnQ6Vy5lYSxUcmFja0V2ZW50OlcuZWEsVHJh
+bnNpdGlvbkV2ZW50OlcuZWEsV2ViS2l0VHJhbnNpdGlvbkV2ZW50OlcuZWEsVlJEZXZpY2VFdmVudDpX
+LmVhLFZSRGlzcGxheUV2ZW50OlcuZWEsVlJTZXNzaW9uRXZlbnQ6Vy5lYSxNb2pvSW50ZXJmYWNlUmVx
+dWVzdEV2ZW50OlcuZWEsVVNCQ29ubmVjdGlvbkV2ZW50OlcuZWEsSURCVmVyc2lvbkNoYW5nZUV2ZW50
+OlcuZWEsQXVkaW9Qcm9jZXNzaW5nRXZlbnQ6Vy5lYSxPZmZsaW5lQXVkaW9Db21wbGV0aW9uRXZlbnQ6
+Vy5lYSxXZWJHTENvbnRleHRFdmVudDpXLmVhLEV2ZW50OlcuZWEsSW5wdXRFdmVudDpXLmVhLEV2ZW50
+VGFyZ2V0OlcuRDAsRmlsZTpXLmhILEhUTUxGb3JtRWxlbWVudDpXLmg0LEhpc3Rvcnk6Vy5icixIVE1M
+RG9jdW1lbnQ6Vy5WYixYTUxIdHRwUmVxdWVzdDpXLk83LFhNTEh0dHBSZXF1ZXN0RXZlbnRUYXJnZXQ6
+Vy53YSxJbWFnZURhdGE6Vy5TZyxMb2NhdGlvbjpXLnU4LE1vdXNlRXZlbnQ6Vy5BaixEcmFnRXZlbnQ6
+Vy5BaixQb2ludGVyRXZlbnQ6Vy5BaixXaGVlbEV2ZW50OlcuQWosRG9jdW1lbnRGcmFnbWVudDpXLnVI
+LFNoYWRvd1Jvb3Q6Vy51SCxEb2N1bWVudFR5cGU6Vy51SCxOb2RlOlcudUgsTm9kZUxpc3Q6Vy5CSCxS
+YWRpb05vZGVMaXN0OlcuQkgsSFRNTFBhcmFncmFwaEVsZW1lbnQ6Vy5TTixQcm9ncmVzc0V2ZW50Olcu
+ZXcsUmVzb3VyY2VQcm9ncmVzc0V2ZW50OlcuZXcsSFRNTFNlbGVjdEVsZW1lbnQ6Vy5scCxIVE1MVGFi
+bGVFbGVtZW50OlcuVGIsSFRNTFRhYmxlUm93RWxlbWVudDpXLkl2LEhUTUxUYWJsZVNlY3Rpb25FbGVt
+ZW50OlcuV1AsSFRNTFRlbXBsYXRlRWxlbWVudDpXLnlZLENvbXBvc2l0aW9uRXZlbnQ6Vy53NixGb2N1
+c0V2ZW50OlcudzYsS2V5Ym9hcmRFdmVudDpXLnc2LFRleHRFdmVudDpXLnc2LFRvdWNoRXZlbnQ6Vy53
+NixVSUV2ZW50OlcudzYsV2luZG93OlcuSzUsRE9NV2luZG93OlcuSzUsRGVkaWNhdGVkV29ya2VyR2xv
+YmFsU2NvcGU6Vy5DbSxTZXJ2aWNlV29ya2VyR2xvYmFsU2NvcGU6Vy5DbSxTaGFyZWRXb3JrZXJHbG9i
+YWxTY29wZTpXLkNtLFdvcmtlckdsb2JhbFNjb3BlOlcuQ20sQXR0cjpXLkNRLENsaWVudFJlY3Q6Vy53
+NCxET01SZWN0OlcudzQsTmFtZWROb2RlTWFwOlcucmgsTW96TmFtZWRBdHRyTWFwOlcucmgsSURCS2V5
+UmFuZ2U6UC5oRixTVkdTY3JpcHRFbGVtZW50OlAubmQsU1ZHQUVsZW1lbnQ6UC5kNSxTVkdBbmltYXRl
+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
+VGFncyh7RE9NRXJyb3I6dHJ1ZSxET01JbXBsZW1lbnRhdGlvbjp0cnVlLE1lZGlhRXJyb3I6dHJ1ZSxO
+YXZpZ2F0b3I6dHJ1ZSxOYXZpZ2F0b3JDb25jdXJyZW50SGFyZHdhcmU6dHJ1ZSxOYXZpZ2F0b3JVc2Vy
+TWVkaWFFcnJvcjp0cnVlLE92ZXJjb25zdHJhaW5lZEVycm9yOnRydWUsUG9zaXRpb25FcnJvcjp0cnVl
+LFJhbmdlOnRydWUsU1FMRXJyb3I6dHJ1ZSxEYXRhVmlldzp0cnVlLEFycmF5QnVmZmVyVmlldzpmYWxz
+ZSxGbG9hdDMyQXJyYXk6dHJ1ZSxGbG9hdDY0QXJyYXk6dHJ1ZSxJbnQxNkFycmF5OnRydWUsSW50MzJB
+cnJheTp0cnVlLEludDhBcnJheTp0cnVlLFVpbnQxNkFycmF5OnRydWUsVWludDMyQXJyYXk6dHJ1ZSxV
+aW50OENsYW1wZWRBcnJheTp0cnVlLENhbnZhc1BpeGVsQXJyYXk6dHJ1ZSxVaW50OEFycmF5OmZhbHNl
+LEhUTUxBdWRpb0VsZW1lbnQ6dHJ1ZSxIVE1MQlJFbGVtZW50OnRydWUsSFRNTEJ1dHRvbkVsZW1lbnQ6
+dHJ1ZSxIVE1MQ2FudmFzRWxlbWVudDp0cnVlLEhUTUxDb250ZW50RWxlbWVudDp0cnVlLEhUTUxETGlz
+dEVsZW1lbnQ6dHJ1ZSxIVE1MRGF0YUVsZW1lbnQ6dHJ1ZSxIVE1MRGF0YUxpc3RFbGVtZW50OnRydWUs
+SFRNTERldGFpbHNFbGVtZW50OnRydWUsSFRNTERpYWxvZ0VsZW1lbnQ6dHJ1ZSxIVE1MRGl2RWxlbWVu
+dDp0cnVlLEhUTUxFbWJlZEVsZW1lbnQ6dHJ1ZSxIVE1MRmllbGRTZXRFbGVtZW50OnRydWUsSFRNTEhS
+RWxlbWVudDp0cnVlLEhUTUxIZWFkRWxlbWVudDp0cnVlLEhUTUxIZWFkaW5nRWxlbWVudDp0cnVlLEhU
+TUxIdG1sRWxlbWVudDp0cnVlLEhUTUxJRnJhbWVFbGVtZW50OnRydWUsSFRNTEltYWdlRWxlbWVudDp0
+cnVlLEhUTUxJbnB1dEVsZW1lbnQ6dHJ1ZSxIVE1MTElFbGVtZW50OnRydWUsSFRNTExhYmVsRWxlbWVu
+dDp0cnVlLEhUTUxMZWdlbmRFbGVtZW50OnRydWUsSFRNTExpbmtFbGVtZW50OnRydWUsSFRNTE1hcEVs
+ZW1lbnQ6dHJ1ZSxIVE1MTWVkaWFFbGVtZW50OnRydWUsSFRNTE1lbnVFbGVtZW50OnRydWUsSFRNTE1l
+dGFFbGVtZW50OnRydWUsSFRNTE1ldGVyRWxlbWVudDp0cnVlLEhUTUxNb2RFbGVtZW50OnRydWUsSFRN
+TE9MaXN0RWxlbWVudDp0cnVlLEhUTUxPYmplY3RFbGVtZW50OnRydWUsSFRNTE9wdEdyb3VwRWxlbWVu
+dDp0cnVlLEhUTUxPcHRpb25FbGVtZW50OnRydWUsSFRNTE91dHB1dEVsZW1lbnQ6dHJ1ZSxIVE1MUGFy
+YW1FbGVtZW50OnRydWUsSFRNTFBpY3R1cmVFbGVtZW50OnRydWUsSFRNTFByZUVsZW1lbnQ6dHJ1ZSxI
+VE1MUHJvZ3Jlc3NFbGVtZW50OnRydWUsSFRNTFF1b3RlRWxlbWVudDp0cnVlLEhUTUxTY3JpcHRFbGVt
+ZW50OnRydWUsSFRNTFNoYWRvd0VsZW1lbnQ6dHJ1ZSxIVE1MU2xvdEVsZW1lbnQ6dHJ1ZSxIVE1MU291
+cmNlRWxlbWVudDp0cnVlLEhUTUxTcGFuRWxlbWVudDp0cnVlLEhUTUxTdHlsZUVsZW1lbnQ6dHJ1ZSxI
+VE1MVGFibGVDYXB0aW9uRWxlbWVudDp0cnVlLEhUTUxUYWJsZUNlbGxFbGVtZW50OnRydWUsSFRNTFRh
+YmxlRGF0YUNlbGxFbGVtZW50OnRydWUsSFRNTFRhYmxlSGVhZGVyQ2VsbEVsZW1lbnQ6dHJ1ZSxIVE1M
+VGFibGVDb2xFbGVtZW50OnRydWUsSFRNTFRleHRBcmVhRWxlbWVudDp0cnVlLEhUTUxUaW1lRWxlbWVu
+dDp0cnVlLEhUTUxUaXRsZUVsZW1lbnQ6dHJ1ZSxIVE1MVHJhY2tFbGVtZW50OnRydWUsSFRNTFVMaXN0
+RWxlbWVudDp0cnVlLEhUTUxVbmtub3duRWxlbWVudDp0cnVlLEhUTUxWaWRlb0VsZW1lbnQ6dHJ1ZSxI
+VE1MRGlyZWN0b3J5RWxlbWVudDp0cnVlLEhUTUxGb250RWxlbWVudDp0cnVlLEhUTUxGcmFtZUVsZW1l
+bnQ6dHJ1ZSxIVE1MRnJhbWVTZXRFbGVtZW50OnRydWUsSFRNTE1hcnF1ZWVFbGVtZW50OnRydWUsSFRN
+TEVsZW1lbnQ6ZmFsc2UsSFRNTEFuY2hvckVsZW1lbnQ6dHJ1ZSxIVE1MQXJlYUVsZW1lbnQ6dHJ1ZSxI
+VE1MQmFzZUVsZW1lbnQ6dHJ1ZSxCbG9iOmZhbHNlLEhUTUxCb2R5RWxlbWVudDp0cnVlLENEQVRBU2Vj
+dGlvbjp0cnVlLENoYXJhY3RlckRhdGE6dHJ1ZSxDb21tZW50OnRydWUsUHJvY2Vzc2luZ0luc3RydWN0
+aW9uOnRydWUsVGV4dDp0cnVlLENTU1N0eWxlRGVjbGFyYXRpb246dHJ1ZSxNU1N0eWxlQ1NTUHJvcGVy
+dGllczp0cnVlLENTUzJQcm9wZXJ0aWVzOnRydWUsWE1MRG9jdW1lbnQ6dHJ1ZSxEb2N1bWVudDpmYWxz
+ZSxET01FeGNlcHRpb246dHJ1ZSxET01SZWN0UmVhZE9ubHk6ZmFsc2UsRE9NVG9rZW5MaXN0OnRydWUs
+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
+RXZlbnQ6dHJ1ZSxFdmVudDpmYWxzZSxJbnB1dEV2ZW50OmZhbHNlLEV2ZW50VGFyZ2V0OmZhbHNlLEZp
+bGU6dHJ1ZSxIVE1MRm9ybUVsZW1lbnQ6dHJ1ZSxIaXN0b3J5OnRydWUsSFRNTERvY3VtZW50OnRydWUs
+WE1MSHR0cFJlcXVlc3Q6dHJ1ZSxYTUxIdHRwUmVxdWVzdEV2ZW50VGFyZ2V0OmZhbHNlLEltYWdlRGF0
+YTp0cnVlLExvY2F0aW9uOnRydWUsTW91c2VFdmVudDp0cnVlLERyYWdFdmVudDp0cnVlLFBvaW50ZXJF
+dmVudDp0cnVlLFdoZWVsRXZlbnQ6dHJ1ZSxEb2N1bWVudEZyYWdtZW50OnRydWUsU2hhZG93Um9vdDp0
+cnVlLERvY3VtZW50VHlwZTp0cnVlLE5vZGU6ZmFsc2UsTm9kZUxpc3Q6dHJ1ZSxSYWRpb05vZGVMaXN0
+OnRydWUsSFRNTFBhcmFncmFwaEVsZW1lbnQ6dHJ1ZSxQcm9ncmVzc0V2ZW50OnRydWUsUmVzb3VyY2VQ
+cm9ncmVzc0V2ZW50OnRydWUsSFRNTFNlbGVjdEVsZW1lbnQ6dHJ1ZSxIVE1MVGFibGVFbGVtZW50OnRy
+dWUsSFRNTFRhYmxlUm93RWxlbWVudDp0cnVlLEhUTUxUYWJsZVNlY3Rpb25FbGVtZW50OnRydWUsSFRN
+TFRlbXBsYXRlRWxlbWVudDp0cnVlLENvbXBvc2l0aW9uRXZlbnQ6dHJ1ZSxGb2N1c0V2ZW50OnRydWUs
+S2V5Ym9hcmRFdmVudDp0cnVlLFRleHRFdmVudDp0cnVlLFRvdWNoRXZlbnQ6dHJ1ZSxVSUV2ZW50OmZh
+bHNlLFdpbmRvdzp0cnVlLERPTVdpbmRvdzp0cnVlLERlZGljYXRlZFdvcmtlckdsb2JhbFNjb3BlOnRy
+dWUsU2VydmljZVdvcmtlckdsb2JhbFNjb3BlOnRydWUsU2hhcmVkV29ya2VyR2xvYmFsU2NvcGU6dHJ1
+ZSxXb3JrZXJHbG9iYWxTY29wZTp0cnVlLEF0dHI6dHJ1ZSxDbGllbnRSZWN0OnRydWUsRE9NUmVjdDp0
+cnVlLE5hbWVkTm9kZU1hcDp0cnVlLE1vek5hbWVkQXR0ck1hcDp0cnVlLElEQktleVJhbmdlOnRydWUs
+U1ZHU2NyaXB0RWxlbWVudDp0cnVlLFNWR0FFbGVtZW50OnRydWUsU1ZHQW5pbWF0ZUVsZW1lbnQ6dHJ1
+ZSxTVkdBbmltYXRlTW90aW9uRWxlbWVudDp0cnVlLFNWR0FuaW1hdGVUcmFuc2Zvcm1FbGVtZW50OnRy
+dWUsU1ZHQW5pbWF0aW9uRWxlbWVudDp0cnVlLFNWR0NpcmNsZUVsZW1lbnQ6dHJ1ZSxTVkdDbGlwUGF0
+aEVsZW1lbnQ6dHJ1ZSxTVkdEZWZzRWxlbWVudDp0cnVlLFNWR0Rlc2NFbGVtZW50OnRydWUsU1ZHRGlz
+Y2FyZEVsZW1lbnQ6dHJ1ZSxTVkdFbGxpcHNlRWxlbWVudDp0cnVlLFNWR0ZFQmxlbmRFbGVtZW50OnRy
+dWUsU1ZHRkVDb2xvck1hdHJpeEVsZW1lbnQ6dHJ1ZSxTVkdGRUNvbXBvbmVudFRyYW5zZmVyRWxlbWVu
+dDp0cnVlLFNWR0ZFQ29tcG9zaXRlRWxlbWVudDp0cnVlLFNWR0ZFQ29udm9sdmVNYXRyaXhFbGVtZW50
+OnRydWUsU1ZHRkVEaWZmdXNlTGlnaHRpbmdFbGVtZW50OnRydWUsU1ZHRkVEaXNwbGFjZW1lbnRNYXBF
+bGVtZW50OnRydWUsU1ZHRkVEaXN0YW50TGlnaHRFbGVtZW50OnRydWUsU1ZHRkVGbG9vZEVsZW1lbnQ6
+dHJ1ZSxTVkdGRUZ1bmNBRWxlbWVudDp0cnVlLFNWR0ZFRnVuY0JFbGVtZW50OnRydWUsU1ZHRkVGdW5j
+R0VsZW1lbnQ6dHJ1ZSxTVkdGRUZ1bmNSRWxlbWVudDp0cnVlLFNWR0ZFR2F1c3NpYW5CbHVyRWxlbWVu
+dDp0cnVlLFNWR0ZFSW1hZ2VFbGVtZW50OnRydWUsU1ZHRkVNZXJnZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1l
+cmdlTm9kZUVsZW1lbnQ6dHJ1ZSxTVkdGRU1vcnBob2xvZ3lFbGVtZW50OnRydWUsU1ZHRkVPZmZzZXRF
+bGVtZW50OnRydWUsU1ZHRkVQb2ludExpZ2h0RWxlbWVudDp0cnVlLFNWR0ZFU3BlY3VsYXJMaWdodGlu
+Z0VsZW1lbnQ6dHJ1ZSxTVkdGRVNwb3RMaWdodEVsZW1lbnQ6dHJ1ZSxTVkdGRVRpbGVFbGVtZW50OnRy
+dWUsU1ZHRkVUdXJidWxlbmNlRWxlbWVudDp0cnVlLFNWR0ZpbHRlckVsZW1lbnQ6dHJ1ZSxTVkdGb3Jl
+aWduT2JqZWN0RWxlbWVudDp0cnVlLFNWR0dFbGVtZW50OnRydWUsU1ZHR2VvbWV0cnlFbGVtZW50OnRy
+dWUsU1ZHR3JhcGhpY3NFbGVtZW50OnRydWUsU1ZHSW1hZ2VFbGVtZW50OnRydWUsU1ZHTGluZUVsZW1l
+bnQ6dHJ1ZSxTVkdMaW5lYXJHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdNYXJrZXJFbGVtZW50OnRydWUs
+U1ZHTWFza0VsZW1lbnQ6dHJ1ZSxTVkdNZXRhZGF0YUVsZW1lbnQ6dHJ1ZSxTVkdQYXRoRWxlbWVudDp0
+cnVlLFNWR1BhdHRlcm5FbGVtZW50OnRydWUsU1ZHUG9seWdvbkVsZW1lbnQ6dHJ1ZSxTVkdQb2x5bGlu
+ZUVsZW1lbnQ6dHJ1ZSxTVkdSYWRpYWxHcmFkaWVudEVsZW1lbnQ6dHJ1ZSxTVkdSZWN0RWxlbWVudDp0
+cnVlLFNWR1NldEVsZW1lbnQ6dHJ1ZSxTVkdTdG9wRWxlbWVudDp0cnVlLFNWR1N0eWxlRWxlbWVudDp0
+cnVlLFNWR1NWR0VsZW1lbnQ6dHJ1ZSxTVkdTd2l0Y2hFbGVtZW50OnRydWUsU1ZHU3ltYm9sRWxlbWVu
+dDp0cnVlLFNWR1RTcGFuRWxlbWVudDp0cnVlLFNWR1RleHRDb250ZW50RWxlbWVudDp0cnVlLFNWR1Rl
+eHRFbGVtZW50OnRydWUsU1ZHVGV4dFBhdGhFbGVtZW50OnRydWUsU1ZHVGV4dFBvc2l0aW9uaW5nRWxl
+bWVudDp0cnVlLFNWR1RpdGxlRWxlbWVudDp0cnVlLFNWR1VzZUVsZW1lbnQ6dHJ1ZSxTVkdWaWV3RWxl
+bWVudDp0cnVlLFNWR0dyYWRpZW50RWxlbWVudDp0cnVlLFNWR0NvbXBvbmVudFRyYW5zZmVyRnVuY3Rp
+b25FbGVtZW50OnRydWUsU1ZHRkVEcm9wU2hhZG93RWxlbWVudDp0cnVlLFNWR01QYXRoRWxlbWVudDp0
+cnVlLFNWR0VsZW1lbnQ6ZmFsc2V9KQpILkxaLiRuYXRpdmVTdXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZl
+clZpZXciCkguUkcuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmlldyIKSC5WUC4kbmF0
+aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILkRnLiRuYXRpdmVTdXBlcmNsYXNzVGFn
+PSJBcnJheUJ1ZmZlclZpZXciCkguV0IuJG5hdGl2ZVN1cGVyY2xhc3NUYWc9IkFycmF5QnVmZmVyVmll
+dyIKSC5aRy4kbmF0aXZlU3VwZXJjbGFzc1RhZz0iQXJyYXlCdWZmZXJWaWV3IgpILlBnLiRuYXRpdmVT
+dXBlcmNsYXNzVGFnPSJBcnJheUJ1ZmZlclZpZXcifSkoKQpjb252ZXJ0QWxsVG9GYXN0T2JqZWN0KHcp
+CmNvbnZlcnRUb0Zhc3RPYmplY3QoJCk7KGZ1bmN0aW9uKGEpe2lmKHR5cGVvZiBkb2N1bWVudD09PSJ1
+bmRlZmluZWQiKXthKG51bGwpCnJldHVybn1pZih0eXBlb2YgZG9jdW1lbnQuY3VycmVudFNjcmlwdCE9
+J3VuZGVmaW5lZCcpe2EoZG9jdW1lbnQuY3VycmVudFNjcmlwdCkKcmV0dXJufXZhciB0PWRvY3VtZW50
+LnNjcmlwdHMKZnVuY3Rpb24gb25Mb2FkKGIpe2Zvcih2YXIgcj0wO3I8dC5sZW5ndGg7KytyKXRbcl0u
+cmVtb3ZlRXZlbnRMaXN0ZW5lcigibG9hZCIsb25Mb2FkLGZhbHNlKQphKGIudGFyZ2V0KX1mb3IodmFy
+IHM9MDtzPHQubGVuZ3RoOysrcyl0W3NdLmFkZEV2ZW50TGlzdGVuZXIoImxvYWQiLG9uTG9hZCxmYWxz
+ZSl9KShmdW5jdGlvbihhKXt2LmN1cnJlbnRTY3JpcHQ9YQppZih0eXBlb2YgZGFydE1haW5SdW5uZXI9
+PT0iZnVuY3Rpb24iKWRhcnRNYWluUnVubmVyKEwuSXEsW10pCmVsc2UgTC5JcShbXSl9KX0pKCkKLy8j
+IHNvdXJjZU1hcHBpbmdVUkw9bWlncmF0aW9uLmpzLm1hcAo=
 ''';
diff --git a/pkg/nnbd_migration/lib/src/messages.dart b/pkg/nnbd_migration/lib/src/messages.dart
index 3a32d14..41497f2 100644
--- a/pkg/nnbd_migration/lib/src/messages.dart
+++ b/pkg/nnbd_migration/lib/src/messages.dart
@@ -7,3 +7,6 @@
 const String nnbdExperimentOff =
     'Analyzer seems to need the nnbd experiment on in the SDK.';
 const String sdkNnbdOff = 'Analysis seems to have an SDK without NNBD enabled.';
+const String sdkPathEnvironmentVariableSet =
+    r'Note: $SDK_PATH environment variable is set and may point to outdated '
+    'dart:core sources';
diff --git a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
index 5028a7a..39e6c85 100644
--- a/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
+++ b/pkg/nnbd_migration/lib/src/nullability_migration_impl.dart
@@ -2,7 +2,6 @@
 // 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:analyzer/dart/analysis/features.dart';
 import 'package:analyzer/dart/analysis/results.dart';
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/src/dart/analysis/session.dart';
@@ -15,9 +14,9 @@
 import 'package:nnbd_migration/src/decorated_type.dart';
 import 'package:nnbd_migration/src/edge_builder.dart';
 import 'package:nnbd_migration/src/edit_plan.dart';
+import 'package:nnbd_migration/src/exceptions.dart';
 import 'package:nnbd_migration/src/fix_aggregator.dart';
 import 'package:nnbd_migration/src/fix_builder.dart';
-import 'package:nnbd_migration/src/messages.dart';
 import 'package:nnbd_migration/src/node_builder.dart';
 import 'package:nnbd_migration/src/nullability_node.dart';
 import 'package:nnbd_migration/src/postmortem_file.dart';
@@ -104,7 +103,7 @@
 
   @override
   void finalizeInput(ResolvedUnitResult result) {
-    _sanityCheck(result);
+    ExperimentStatusException.sanityCheck(result);
     if (!_propagated) {
       _propagated = true;
       _graph.propagate(_postmortemFileWriter);
@@ -160,7 +159,7 @@
   }
 
   void prepareInput(ResolvedUnitResult result) {
-    _sanityCheck(result);
+    ExperimentStatusException.sanityCheck(result);
     if (_variables == null) {
       _variables = Variables(_graph, result.typeProvider, _getLineInfo,
           instrumentation: _instrumentation,
@@ -184,7 +183,7 @@
   }
 
   void processInput(ResolvedUnitResult result) {
-    _sanityCheck(result);
+    ExperimentStatusException.sanityCheck(result);
     var unit = result.unit;
     try {
       DecoratedTypeParameterBounds.current = _decoratedTypeParameterBounds;
@@ -207,26 +206,6 @@
     _graph.update(_postmortemFileWriter);
   }
 
-  void _sanityCheck(ResolvedUnitResult result) {
-    final equalsParamType = result.typeProvider.objectType
-        .getMethod('==')
-        .parameters[0]
-        .type
-        .getDisplayString(withNullability: true);
-    if (equalsParamType == 'Object*') {
-      throw StateError(nnbdExperimentOff);
-    }
-
-    if (equalsParamType != 'Object') {
-      throw StateError(sdkNnbdOff);
-    }
-
-    if (result.unit.featureSet.isEnabled(Feature.non_nullable)) {
-      // TODO(jcollins-g): Allow for skipping already migrated compilation units.
-      throw StateError('$migratedAlready: ${result.path}');
-    }
-  }
-
   static Location _computeLocation(
       LineInfo lineInfo, SourceEdit edit, Source source) {
     final locationInfo = lineInfo.getLocation(edit.offset);
diff --git a/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart b/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart
index 7f5bdbe..199eb9a 100644
--- a/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart
+++ b/pkg/nnbd_migration/lib/src/utilities/completeness_tracker.dart
@@ -19,11 +19,15 @@
 
   @override
   T visitAnnotation(Annotation node) {
+    annotationVisited(node);
+    return super.visitAnnotation(node);
+  }
+
+  void annotationVisited(Annotation node) {
     assert(() {
       _annotationTracker.nodeVisited(node);
       return true;
     }());
-    return super.visitAnnotation(node);
   }
 
   void typeNameVisited(TypeName node) {
diff --git a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
index 7b5e9ca..fdc03f1 100644
--- a/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
+++ b/pkg/nnbd_migration/test/already_migrated_code_decorator_test.dart
@@ -118,6 +118,11 @@
         decoratedType.typeArguments[0], 'type argument 0 of $displayName');
   }
 
+  void checkNever(DecoratedType decoratedType, String displayName) {
+    expect(decoratedType.type, same(typeProvider.neverType));
+    checkExplicitlyNonNullable(decoratedType.node, displayName);
+  }
+
   void checkNum(
       DecoratedType decoratedType,
       void Function(NullabilityNode, String) checkNullability,
@@ -356,6 +361,10 @@
         decorated, checkExplicitlyNonNullable, checkDynamic, 'test type');
   }
 
+  void test_decorate_never() {
+    checkNever(decorate(typeProvider.neverType), 'test type');
+  }
+
   void test_decorate_typeParameterType_question() {
     var element = TypeParameterElementImpl.synthetic('T');
     checkTypeParameter(
diff --git a/pkg/nnbd_migration/test/api_test.dart b/pkg/nnbd_migration/test/api_test.dart
index 70c1d2d..7fed545 100644
--- a/pkg/nnbd_migration/test/api_test.dart
+++ b/pkg/nnbd_migration/test/api_test.dart
@@ -207,6 +207,22 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/42327')
+  // When fixing this issue, probably convert this to an edge builder test.
+  Future<void> test_migratedMethod_namedParameter() async {
+    var content = '''
+void f(Iterable<int> a) {
+  a.toList(growable: false);
+}
+''';
+    var expected = '''
+void f(Iterable<int> a) {
+  a.toList(growable: false);
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_add_required() async {
     var content = '''
 int f({String s}) => s.length;
@@ -2082,6 +2098,48 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_extension_on_type_param_implementation() async {
+    var content = '''
+abstract class C {
+  C _clone();
+}
+extension Cloner<T extends C> on T {
+  T clone() => _clone() as T;
+}
+''';
+    var expected = '''
+abstract class C {
+  C _clone();
+}
+extension Cloner<T extends C> on T {
+  T clone() => _clone() as T;
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
+  Future<void> test_extension_on_type_param_usage() async {
+    var content = '''
+abstract class C {
+  C _clone();
+}
+extension Cloner<T extends C> on T {
+  T clone() => throw Exception();
+}
+C f(C c) => c.clone();
+''';
+    var expected = '''
+abstract class C {
+  C _clone();
+}
+extension Cloner<T extends C> on T {
+  T clone() => throw Exception();
+}
+C f(C c) => c.clone();
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_field_final_uninitalized_used() async {
     var content = '''
 class C {
@@ -3485,6 +3543,27 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  @FailingTest(issue: 'https://github.com/dart-lang/sdk/issues/41397')
+  Future<void> test_issue_41397() async {
+    var content = '''
+void repro(){
+  List<dynamic> l = <dynamic>[];
+  for(final dynamic e in l) {
+    final List<String> a = (e['query'] as String).split('&');
+  }
+}
+''';
+    var expected = '''
+void repro(){
+  List<dynamic> l = <dynamic>[];
+  for(final dynamic e in l) {
+    final List<String> a = (e['query'] as String).split('&');
+  }
+}
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_late_hint_instance_field_with_constructor() async {
     var content = '''
 class C {
@@ -4045,6 +4124,20 @@
     await _checkSingleFileChanges(content, expected);
   }
 
+  Future<void> test_migrate_reference_to_never() async {
+    var content = '''
+import 'dart:io';
+int f() =>
+  exit(1); // this returns `Never` which used to cause a crash.
+''';
+    var expected = '''
+import 'dart:io';
+int f() =>
+  exit(1); // this returns `Never` which used to cause a crash.
+''';
+    await _checkSingleFileChanges(content, expected);
+  }
+
   Future<void> test_multiDeclaration_innerUsage() async {
     var content = '''
 void test() {
diff --git a/pkg/nnbd_migration/test/edge_builder_test.dart b/pkg/nnbd_migration/test/edge_builder_test.dart
index c4825b1..0d6105f 100644
--- a/pkg/nnbd_migration/test/edge_builder_test.dart
+++ b/pkg/nnbd_migration/test/edge_builder_test.dart
@@ -7508,6 +7508,16 @@
     expect(edge.sourceNode.displayName, 'throw expression (test.dart:2:10)');
   }
 
+  Future<void> test_top_level_annotation_begins_flow_analysis() async {
+    await analyze('''
+class C {
+  const C(bool x);
+}
+@C(true)
+int x;
+''');
+  }
+
   Future<void> test_topLevelSetter() async {
     await analyze('''
 void set x(int value) {}
diff --git a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
index 76d4c1c..972c478 100644
--- a/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
+++ b/pkg/nnbd_migration/test/front_end/nnbd_migration_test_base.dart
@@ -201,7 +201,7 @@
     // Compute the analysis results.
     var server = DriverProviderImpl(resourceProvider, driver.analysisContext);
     // Run the migration engine.
-    var listener = DartFixListener(server);
+    var listener = DartFixListener(server, _exceptionReported);
     var instrumentationListener = InstrumentationListener();
     var adapter = NullabilityMigrationAdapter(listener);
     var migration = NullabilityMigration(adapter, getLineInfo,
@@ -227,4 +227,8 @@
         resourceProvider, includedRoot, info, listener, migration, nodeMapper);
     infos = await builder.explainMigration();
   }
+
+  void _exceptionReported(String detail) {
+    fail('Unexpected error during migration: $detail');
+  }
 }
diff --git a/pkg/nnbd_migration/test/migration_cli_test.dart b/pkg/nnbd_migration/test/migration_cli_test.dart
index 2e521ee..c282fc0 100644
--- a/pkg/nnbd_migration/test/migration_cli_test.dart
+++ b/pkg/nnbd_migration/test/migration_cli_test.dart
@@ -25,6 +25,7 @@
 import 'package:nnbd_migration/src/front_end/web/edit_details.dart';
 import 'package:nnbd_migration/src/front_end/web/file_details.dart';
 import 'package:nnbd_migration/src/front_end/web/navigation_tree.dart';
+import 'package:nnbd_migration/src/messages.dart' as messages;
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -60,12 +61,10 @@
       ResourceProvider resourceProvider, LineInfo Function(String) getLineInfo,
       {List<String> included = const <String>[],
       int preferredPort,
-      bool enablePreview = true,
       String summaryPath})
       : super(listener, resourceProvider, getLineInfo,
             included: included,
             preferredPort: preferredPort,
-            enablePreview: enablePreview,
             summaryPath: summaryPath);
 
   @override
@@ -83,14 +82,16 @@
   Future<void> Function() _runWhilePreviewServerActive;
 
   _MigrationCli(_MigrationCliTestBase test,
-      {this.injectArtificialException = false})
+      {this.injectArtificialException = false,
+      Map<String, String> environmentVariables})
       : super(
             binaryName: 'nnbd_migration',
             loggerFactory: (isVerbose) => test.logger = _TestLogger(isVerbose),
             defaultSdkPathOverride:
                 test.resourceProvider.convertPath(mock_sdk.sdkRoot),
             resourceProvider: test.resourceProvider,
-            processManager: test.processManager);
+            processManager: test.processManager,
+            environmentVariables: environmentVariables);
 
   @override
   Future<void> blockUntilSignalInterrupt() async {
@@ -106,20 +107,17 @@
       ResourceProvider resourceProvider, LineInfo getLineInfo(String path),
       {List<String> included = const <String>[],
       int preferredPort,
-      bool enablePreview = true,
       String summaryPath}) {
     if (injectArtificialException) {
       return _ExceptionGeneratingNonNullableFix(
           listener, resourceProvider, getLineInfo,
           included: included,
           preferredPort: preferredPort,
-          enablePreview: enablePreview,
           summaryPath: summaryPath);
     } else {
       return super.createNonNullableFix(listener, resourceProvider, getLineInfo,
           included: included,
           preferredPort: preferredPort,
-          enablePreview: enablePreview,
           summaryPath: summaryPath);
     }
   }
@@ -146,6 +144,8 @@
   @override
   /*late*/ _TestLogger logger;
 
+  Map<String, String> environmentVariables = {};
+
   final hasVerboseHelpMessage = contains('for verbose help output');
 
   final hasUsageText = contains('Usage: nnbd_migration');
@@ -159,6 +159,7 @@
   }
 
   String assertErrorExit(MigrationCli cli, {bool withUsage = true}) {
+    expect(cli.isPreviewServerRunning, isFalse);
     expect(cli.exitCode, isNotNull);
     expect(cli.exitCode, isNot(0));
     var stderrText = logger.stderrBuffer.toString();
@@ -183,6 +184,11 @@
     expect(response.statusCode, 200);
   }
 
+  void assertNormalExit(MigrationCli cli) {
+    expect(cli.isPreviewServerRunning, isFalse);
+    expect(cli.exitCode, 0);
+  }
+
   Future<String> assertParseArgsFailure(List<String> args) async {
     try {
       MigrationCli.createParser().parse(args);
@@ -280,6 +286,7 @@
 
   void setUp() {
     resourceProvider.newFolder(resourceProvider.pathContext.current);
+    environmentVariables.clear();
   }
 
   Map<String, String> simpleProject(
@@ -342,10 +349,30 @@
     await cli.run(MigrationCli.createParser().parse([projectDir]));
     assertErrorExit(cli, withUsage: false);
     var output = logger.stdoutBuffer.toString();
-    expect(
-        output,
-        contains(
-            'Bad state: Analysis seems to have an SDK without NNBD enabled'));
+    expect(output, contains(messages.sdkNnbdOff));
+  }
+
+  test_detect_old_sdk_environment_variable() async {
+    environmentVariables['SDK_PATH'] = '/fake-old-sdk-path';
+    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(MigrationCli.createParser().parse([projectDir]));
+    assertErrorExit(cli, withUsage: false);
+    var output = logger.stdoutBuffer.toString();
+    expect(output, contains(messages.sdkNnbdOff));
+    expect(output, contains(messages.sdkPathEnvironmentVariableSet));
+    expect(output, contains(environmentVariables['SDK_PATH']));
   }
 
   test_flag_apply_changes_default() {
@@ -393,6 +420,25 @@
     expect(assertParseArgsSuccess(['--ignore-errors']).ignoreErrors, isTrue);
   }
 
+  test_flag_ignore_exceptions_default() {
+    expect(assertParseArgsSuccess([]).ignoreExceptions, isFalse);
+  }
+
+  test_flag_ignore_exceptions_disable() async {
+    await assertParseArgsFailure(['--no-ignore-exceptions']);
+  }
+
+  test_flag_ignore_exceptions_enable() {
+    expect(assertParseArgsSuccess(['--ignore-exceptions']).ignoreExceptions,
+        isTrue);
+  }
+
+  test_flag_ignore_exceptions_hidden() async {
+    var flagName = '--ignore-exceptions';
+    expect(await _getHelpText(verbose: false), isNot(contains(flagName)));
+    expect(await _getHelpText(verbose: true), contains(flagName));
+  }
+
   test_flag_skip_pub_outdated_default() {
     expect(assertParseArgsSuccess([]).skipPubOutdated, isFalse);
   }
@@ -425,6 +471,7 @@
     var cli = _createCli();
     await cli
         .run(_parseArgs(['--no-web-preview', '--apply-changes', projectDir]));
+    assertNormalExit(cli);
     // Check that a summary was printed
     expect(logger.stdoutBuffer.toString(), contains('Applying changes'));
     // And that it refers to test.dart and pubspec.yaml
@@ -454,6 +501,7 @@
     var projectDir = await createProjectDir(projectContents);
     var cli = _createCli();
     await cli.run(_parseArgs(['--no-web-preview', projectDir]));
+    assertNormalExit(cli);
     expect(cli.hasMultipleAnalysisContext, true);
     expect(cli.analysisContext, isNotNull);
     var output = logger.stdoutBuffer.toString();
@@ -465,6 +513,7 @@
     var projectDir = await createProjectDir(projectContents);
     var cli = _createCli();
     await cli.run(_parseArgs(['--no-web-preview', projectDir]));
+    assertNormalExit(cli);
     expect(cli.hasMultipleAnalysisContext, false);
     expect(cli.analysisContext, isNotNull);
   }
@@ -473,10 +522,61 @@
     var projectContents = simpleProject(sourceText: 'main() { print(0); }');
     var projectDir = await createProjectDir(projectContents);
     var cli = _createCli(injectArtificialException: true);
+    await cli.run(_parseArgs([projectDir]));
+    assertErrorExit(cli, withUsage: false);
+    var errorOutput = logger.stderrBuffer.toString();
+    expect(errorOutput, contains('Artificial exception triggered'));
     expect(
-        () async => runWithPreviewServer(cli, [projectDir], (url) async {}),
-        throwsA(TypeMatcher<Error>().having((e) => e.toString(), 'toString',
-            contains('Artificial exception triggered'))));
+        errorOutput, isNot(contains('try to fix errors in the source code')));
+    expect(errorOutput, contains('re-run with\n--ignore-exceptions'));
+  }
+
+  test_lifecycle_exception_handling_ignore() async {
+    var projectContents = simpleProject(sourceText: 'main() { print(0); }');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli(injectArtificialException: true);
+    await runWithPreviewServer(cli, ['--ignore-exceptions', projectDir],
+        (url) async {
+      var output = logger.stdoutBuffer.toString();
+      expect(output, contains('No analysis issues found'));
+      expect(output, isNot(contains('Artificial exception triggered')));
+      expect(
+          output,
+          contains('Attempting to perform\nmigration anyway due to the use'
+              ' of --ignore-exceptions.'));
+      expect(output, contains('re-run without --ignore-exceptions'));
+      await assertPreviewServerResponsive(url);
+    });
+    assertNormalExit(cli);
+    expect(logger.stderrBuffer.toString(), isEmpty);
+  }
+
+  test_lifecycle_exception_handling_multiple() async {
+    var projectContents =
+        simpleProject(sourceText: 'main() { print(0); print(1); }');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli(injectArtificialException: true);
+    await cli.run(_parseArgs([projectDir]));
+    assertErrorExit(cli, withUsage: false);
+    var errorOutput = logger.stderrBuffer.toString();
+    expect(
+        'Artificial exception triggered'.allMatches(errorOutput), hasLength(1));
+    expect(
+        errorOutput, isNot(contains('try to fix errors in the source code')));
+    expect(errorOutput, contains('re-run with\n--ignore-exceptions'));
+  }
+
+  test_lifecycle_exception_handling_with_error() async {
+    var projectContents =
+        simpleProject(sourceText: 'main() { print(0); unresolved; }');
+    var projectDir = await createProjectDir(projectContents);
+    var cli = _createCli(injectArtificialException: true);
+    await cli.run(_parseArgs(['--ignore-errors', projectDir]));
+    assertErrorExit(cli, withUsage: false);
+    var errorOutput = logger.stderrBuffer.toString();
+    expect(errorOutput, contains('Artificial exception triggered'));
+    expect(errorOutput, contains('try to fix errors in the source code'));
+    expect(errorOutput, contains('re-run with\n--ignore-exceptions'));
   }
 
   test_lifecycle_ignore_errors_disable() async {
@@ -517,6 +617,7 @@
               '--ignore-errors.'));
       await assertPreviewServerResponsive(url);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_no_preview() async {
@@ -524,6 +625,7 @@
     var projectDir = await createProjectDir(projectContents);
     var cli = _createCli();
     await cli.run(_parseArgs(['--no-web-preview', projectDir]));
+    assertNormalExit(cli);
     // Check that a summary was printed
     var output = logger.stdoutBuffer.toString();
     expect(output, contains('Summary'));
@@ -547,6 +649,7 @@
           logger.stdoutBuffer.toString(), contains('No analysis issues found'));
       await assertPreviewServerResponsive(url);
     });
+    assertNormalExit(cli);
     // No changes should have been made.
     assertProjectContents(projectDir, projectContents);
   }
@@ -578,6 +681,7 @@
       assertProjectContents(
           projectDir, simpleProject(sourceText: 'int/*!*/ x;'));
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_extra_forward_slash() async {
@@ -588,6 +692,7 @@
       await assertPreviewServerResponsive(
           uri.replace(path: uri.path + '/').toString());
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_navigation_links() async {
@@ -623,6 +728,7 @@
         assertHttpSuccess(contentsResponse);
       }
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_navigation_tree() async {
@@ -656,6 +762,7 @@
         }
       }
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_region_link() async {
@@ -697,6 +804,7 @@
           .getChildAssumingFile(displayPath);
       expect(file.exists, isTrue);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_region_table_path() async {
@@ -729,6 +837,7 @@
           headers: {'Content-Type': 'application/json; charset=UTF-8'});
       assertHttpSuccess(contentsResponse);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_rerun() async {
@@ -752,6 +861,7 @@
       // Now that we've rerun, the server should yield the new source text
       expect(await getSourceFromServer(uri, testPath), newSourceText);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_rerun_added_file() async {
@@ -775,6 +885,7 @@
       // Now that we've rerun, the server should yield the new source text
       expect(await getSourceFromServer(uri, test2Path), newSourceText);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_rerun_deleted_file() async {
@@ -811,6 +922,7 @@
       expect(summaryData['changes']['byPath'],
           isNot(contains('lib${separator}test.dart')));
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_serves_only_from_project_dir() async {
@@ -844,6 +956,7 @@
       // And check that we didn't leak any info through the 404 response.
       expect(response.body, isNot(contains(crazyFunctionName)));
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_stack_hint_action() async {
@@ -879,6 +992,7 @@
       assertProjectContents(
           projectDir, simpleProject(sourceText: 'int/*?*/ x;'));
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_preview_stacktrace_link() async {
@@ -914,6 +1028,7 @@
           headers: {'Content-Type': 'application/json; charset=UTF-8'});
       assertHttpSuccess(contentsResponse);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_skip_pub_outdated_disable() async {
@@ -934,7 +1049,7 @@
         '' /* stderr */);
     var cli = _createCli();
     await cli.run(_parseArgs([projectDir]));
-    var output = logger.stderrBuffer.toString();
+    var output = assertErrorExit(cli, withUsage: false);
     expect(output, contains('Warning: dependencies are outdated.'));
     expect(cli.exitCode, 1);
   }
@@ -960,6 +1075,7 @@
         (url) async {
       await assertPreviewServerResponsive(url);
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_summary() async {
@@ -973,6 +1089,7 @@
         jsonDecode(resourceProvider.getFile(summaryPath).readAsStringSync());
     expect(summaryData, TypeMatcher<Map>());
     expect(summaryData, contains('changes'));
+    assertNormalExit(cli);
   }
 
   test_lifecycle_summary_does_not_double_count_hint_removals() async {
@@ -982,6 +1099,7 @@
     var summaryPath = resourceProvider.convertPath('/summary.json');
     await cli.run(
         _parseArgs(['--no-web-preview', '--summary', summaryPath, projectDir]));
+    assertNormalExit(cli);
     var summaryData =
         jsonDecode(resourceProvider.getFile(summaryPath).readAsStringSync());
     var separator = resourceProvider.pathContext.separator;
@@ -1019,6 +1137,7 @@
         'checkExpression': 1
       });
     });
+    assertNormalExit(cli);
   }
 
   test_lifecycle_uri_error() async {
@@ -1454,7 +1573,8 @@
   _MigrationCli _createCli({bool injectArtificialException = false}) {
     mock_sdk.MockSdk(resourceProvider: resourceProvider);
     return _MigrationCli(this,
-        injectArtificialException: injectArtificialException);
+        injectArtificialException: injectArtificialException,
+        environmentVariables: environmentVariables);
   }
 
   Future<String> _getHelpText({@required bool verbose}) async {
@@ -1518,7 +1638,7 @@
       ProcessResult(
         123 /* pid */,
         0 /* exitCode */,
-        '' /* stdout */,
+        jsonEncode({'packages': []}) /* stdout */,
         '' /* stderr */,
       );
 }
diff --git a/pkg/nnbd_migration/test/preview/preview_site_test.dart b/pkg/nnbd_migration/test/preview/preview_site_test.dart
index 7aeda69..607fb30 100644
--- a/pkg/nnbd_migration/test/preview/preview_site_test.dart
+++ b/pkg/nnbd_migration/test/preview/preview_site_test.dart
@@ -36,7 +36,7 @@
   }
 
   void setUp() {
-    dartfixListener = DartFixListener(null);
+    dartfixListener = DartFixListener(null, _exceptionReported);
     resourceProvider = MemoryResourceProvider();
     final migrationInfo = MigrationInfo({}, {}, null, null);
     state = MigrationState(null, null, dartfixListener, null);
@@ -165,6 +165,10 @@
     expect(file.readAsStringSync(), currentContent);
     expect(state.hasBeenApplied, false);
   }
+
+  void _exceptionReported(String detail) {
+    fail('Unexpected error during migration: $detail');
+  }
 }
 
 mixin PreviewSiteTestMixin {
@@ -186,7 +190,7 @@
   @override
   void setUp() {
     super.setUp();
-    dartfixListener = DartFixListener(null);
+    dartfixListener = DartFixListener(null, _exceptionReported);
     final migrationInfo = MigrationInfo({}, {}, null, null);
     state = MigrationState(null, null, dartfixListener, null);
     nodeMapper = state.nodeMapper;
@@ -246,55 +250,6 @@
     expect(state.needsRerun, true);
   }
 
-  void test_performEdit_multiple() async {
-    final path = convertPath('/test.dart');
-    final file = getFile(path);
-    final content = r'''
-int x;
-int y = x;
-''';
-    file.writeAsStringSync(content);
-    final migratedContent = '''
-int? x;
-int? y = x;
-''';
-    final unitInfo = await buildInfoForSingleTestFile(content,
-        migratedContent: migratedContent);
-    site.unitInfoMap[path] = unitInfo;
-    final firstEditOffset = unitInfo.regions[0].edits[0].offset;
-    performEdit(path, firstEditOffset, '/*?*/');
-    final secondEditOffset = unitInfo.regions[1].edits[0].offset;
-    performEdit(path, secondEditOffset, '/*?*/');
-    expect(file.readAsStringSync(), '''
-int/*?*/ x;
-int/*?*/ y = x;
-''');
-    expect(unitInfo.content, '''
-int/*?*/? x;
-int/*?*/? y = x;
-''');
-    assertRegion(
-        region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
-    assertRegion(
-        region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
-    final targets = List<NavigationTarget>.from(unitInfo.targets);
-    assertInTargets(
-        targets: targets,
-        offset: unitInfo.content.indexOf('x'),
-        offsetMapper: unitInfo.offsetMapper);
-    assertInTargets(
-        targets: targets,
-        offset: unitInfo.content.indexOf('y'),
-        offsetMapper: unitInfo.offsetMapper);
-    var trace = unitInfo.regions[1].traces[0];
-    assertTraceEntry(unitInfo, trace.entries[0], 'y',
-        unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
-    assertTraceEntry(unitInfo, trace.entries[1], 'y',
-        unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
-    expect(state.hasBeenApplied, false);
-    expect(state.needsRerun, true);
-  }
-
   void test_applyHintAction_removeHint() async {
     final path = convertPath('/home/tests/bin/test.dart');
     final file = getFile(path);
@@ -333,4 +288,57 @@
     expect(state.hasBeenApplied, false);
     expect(state.needsRerun, true);
   }
+
+  void test_performEdit_multiple() async {
+    final path = convertPath('/test.dart');
+    final file = getFile(path);
+    final content = r'''
+int x;
+int y = x;
+''';
+    file.writeAsStringSync(content);
+    final migratedContent = '''
+int? x;
+int? y = x;
+''';
+    final unitInfo = await buildInfoForSingleTestFile(content,
+        migratedContent: migratedContent);
+    site.unitInfoMap[path] = unitInfo;
+    final firstEditOffset = unitInfo.regions[0].edits[0].offset;
+    performEdit(path, firstEditOffset, '/*?*/');
+    final secondEditOffset = unitInfo.regions[1].edits[0].offset;
+    performEdit(path, secondEditOffset, '/*?*/');
+    expect(file.readAsStringSync(), '''
+int/*?*/ x;
+int/*?*/ y = x;
+''');
+    expect(unitInfo.content, '''
+int/*?*/? x;
+int/*?*/? y = x;
+''');
+    assertRegion(
+        region: unitInfo.regions[0], offset: unitInfo.content.indexOf('? x'));
+    assertRegion(
+        region: unitInfo.regions[1], offset: unitInfo.content.indexOf('? y'));
+    final targets = List<NavigationTarget>.from(unitInfo.targets);
+    assertInTargets(
+        targets: targets,
+        offset: unitInfo.content.indexOf('x'),
+        offsetMapper: unitInfo.offsetMapper);
+    assertInTargets(
+        targets: targets,
+        offset: unitInfo.content.indexOf('y'),
+        offsetMapper: unitInfo.offsetMapper);
+    var trace = unitInfo.regions[1].traces[0];
+    assertTraceEntry(unitInfo, trace.entries[0], 'y',
+        unitInfo.content.indexOf('int/*?*/? y'), contains('y (test.dart:2:1)'));
+    assertTraceEntry(unitInfo, trace.entries[1], 'y',
+        unitInfo.content.indexOf('= x;') + '= '.length, contains('data flow'));
+    expect(state.hasBeenApplied, false);
+    expect(state.needsRerun, true);
+  }
+
+  void _exceptionReported(String detail) {
+    fail('Unexpected error during migration: $detail');
+  }
 }
diff --git a/pkg/test_runner/lib/src/options.dart b/pkg/test_runner/lib/src/options.dart
index be713c5..79222af 100644
--- a/pkg/test_runner/lib/src/options.dart
+++ b/pkg/test_runner/lib/src/options.dart
@@ -353,7 +353,7 @@
 
   /// For printing out reproducing command lines, we don't want to add these
   /// options.
-  static final _blacklistedOptions = {
+  static final _denylistedOptions = {
     'build_directory',
     'chrome',
     'clean_exit',
@@ -585,7 +585,7 @@
     for (var option in _options) {
       var name = option.name;
       if (!data.containsKey(name) ||
-          _blacklistedOptions.contains(name) ||
+          _denylistedOptions.contains(name) ||
           (usingNamedConfiguration &&
               _namedConfigurationOptions.contains(name))) {
         continue;
diff --git a/pkg/test_runner/lib/src/static_error.dart b/pkg/test_runner/lib/src/static_error.dart
index 202564b..38bfe0b 100644
--- a/pkg/test_runner/lib/src/static_error.dart
+++ b/pkg/test_runner/lib/src/static_error.dart
@@ -456,7 +456,7 @@
   _ErrorExpectationParser(String source) : _lines = source.split("\n");
 
   List<StaticError> _parse() {
-    while (!_isAtEnd) {
+    while (_canPeek(0)) {
       var sourceLine = _peek(0);
 
       var match = _caretLocationRegExp.firstMatch(sourceLine);
@@ -504,7 +504,7 @@
 
     var startLine = _currentLine;
 
-    while (!_isAtEnd) {
+    while (_canPeek(1)) {
       var match = _errorMessageRegExp.firstMatch(_peek(1));
       if (match == null) break;
 
@@ -516,7 +516,7 @@
       _advance();
 
       // Consume as many additional error message lines as we find.
-      while (!_isAtEnd) {
+      while (_canPeek(1)) {
         var nextLine = _peek(1);
 
         // A location line shouldn't be treated as part of the message.
@@ -585,7 +585,7 @@
         markerEndLine: _currentLine));
   }
 
-  bool get _isAtEnd => _currentLine >= _lines.length;
+  bool _canPeek(int offset) => _currentLine + offset < _lines.length;
 
   void _advance() {
     _currentLine++;
diff --git a/pkg/test_runner/lib/src/test_configurations.dart b/pkg/test_runner/lib/src/test_configurations.dart
index 7eac32a..8bfdced 100644
--- a/pkg/test_runner/lib/src/test_configurations.dart
+++ b/pkg/test_runner/lib/src/test_configurations.dart
@@ -35,6 +35,7 @@
   Path('tests/compiler/dartdevc_native'),
   Path('tests/corelib'),
   Path('tests/corelib_2'),
+  Path('tests/dart2js'),
   Path('tests/dart2js_2'),
   Path('tests/kernel'),
   Path('tests/language'),
diff --git a/pkg/test_runner/test/update_errors_test.dart b/pkg/test_runner/test/update_errors_test.dart
index 8d50b29..cf51646 100644
--- a/pkg/test_runner/test/update_errors_test.dart
+++ b/pkg/test_runner/test/update_errors_test.dart
@@ -287,6 +287,17 @@
 /\/ [cfe] Wrong 1.
 """);
 
+  // Don't crash with RangeError.
+  expectUpdate("""
+x
+// [error line 1, column 1, length 0]
+// [cfe] Whatever""", errors: [
+    makeError(line: 1, column: 1, length: 0, cfeError: "Foo"),
+  ], expected: """
+x
+// [error line 1, column 1, length 0]
+// [cfe] Foo""");
+
   regression();
 }
 
diff --git a/pkg/vm/bin/kernel_service.dart b/pkg/vm/bin/kernel_service.dart
index 0216c27..021c858 100644
--- a/pkg/vm/bin/kernel_service.dart
+++ b/pkg/vm/bin/kernel_service.dart
@@ -28,7 +28,6 @@
 import 'dart:typed_data' show Uint8List;
 
 import 'package:build_integration/file_system/multi_root.dart';
-import 'package:front_end/src/api_prototype/experimental_flags.dart';
 import 'package:front_end/src/api_prototype/front_end.dart' as fe
     show CompilerResult;
 import 'package:front_end/src/api_prototype/memory_file_system.dart';
@@ -78,6 +77,7 @@
 const int kCompileExpressionTag = 4;
 const int kListDependenciesTag = 5;
 const int kNotifyIsolateShutdownTag = 6;
+const int kDetectNullabilityTag = 7;
 
 bool allowDartInternalImport = false;
 
@@ -92,6 +92,62 @@
 const int kNullSafetyOptionWeak = 1;
 const int kNullSafetyOptionStrong = 2;
 
+CompilerOptions setupCompilerOptions(
+    FileSystem fileSystem,
+    Uri platformKernelPath,
+    bool suppressWarnings,
+    bool enableAsserts,
+    int nullSafety,
+    List<String> experimentalFlags,
+    bool bytecode,
+    Uri packagesUri,
+    List<String> errors) {
+  final expFlags = <String>[];
+  if (experimentalFlags != null) {
+    for (String flag in experimentalFlags) {
+      expFlags.addAll(flag.split(","));
+    }
+  }
+
+  return new CompilerOptions()
+    ..fileSystem = fileSystem
+    ..target = new VmTarget(new TargetFlags(
+        enableNullSafety: nullSafety == kNullSafetyOptionStrong))
+    ..packagesFileUri = packagesUri
+    ..sdkSummary = platformKernelPath
+    ..verbose = verbose
+    ..omitPlatform = true
+    ..bytecode = bytecode
+    ..experimentalFlags = parseExperimentalFlags(
+        parseExperimentalArguments(expFlags),
+        onError: (msg) => errors.add(msg))
+    ..environmentDefines = new EnvironmentMap()
+    ..nnbdMode = (nullSafety == kNullSafetyOptionStrong)
+        ? NnbdMode.Strong
+        : NnbdMode.Weak
+    ..onDiagnostic = (DiagnosticMessage message) {
+      bool printMessage;
+      switch (message.severity) {
+        case Severity.error:
+        case Severity.internalProblem:
+          // TODO(sigmund): support emitting code with errors as long as they
+          // are handled in the generated code.
+          printMessage = false; // errors are printed by VM
+          errors.addAll(message.plainTextFormatted);
+          break;
+        case Severity.warning:
+          printMessage = !suppressWarnings;
+          break;
+        case Severity.context:
+        case Severity.ignored:
+          throw "Unexpected severity: ${message.severity}";
+      }
+      if (printMessage) {
+        printDiagnosticMessage(message, stderr.writeln);
+      }
+    };
+}
+
 abstract class Compiler {
   final int isolateId;
   final FileSystem fileSystem;
@@ -135,50 +191,16 @@
       print("DFE: platformKernelPath: ${platformKernelPath}");
     }
 
-    var expFlags = List<String>();
-    if (experimentalFlags != null) {
-      for (String flag in experimentalFlags) {
-        expFlags.addAll(flag.split(","));
-      }
-    }
-
-    options = new CompilerOptions()
-      ..fileSystem = fileSystem
-      ..target = new VmTarget(new TargetFlags(
-          enableNullSafety: nullSafety == kNullSafetyOptionStrong))
-      ..packagesFileUri = packagesUri
-      ..sdkSummary = platformKernelPath
-      ..verbose = verbose
-      ..omitPlatform = true
-      ..bytecode = bytecode
-      ..experimentalFlags = parseExperimentalFlags(
-          parseExperimentalArguments(expFlags),
-          onError: (msg) => errors.add(msg))
-      ..environmentDefines = new EnvironmentMap()
-      ..nnbdMode = (nullSafety == kNullSafetyOptionStrong)
-          ? NnbdMode.Strong
-          : NnbdMode.Weak
-      ..onDiagnostic = (DiagnosticMessage message) {
-        bool printMessage;
-        switch (message.severity) {
-          case Severity.error:
-          case Severity.internalProblem:
-            // TODO(sigmund): support emitting code with errors as long as they
-            // are handled in the generated code.
-            printMessage = false; // errors are printed by VM
-            errors.addAll(message.plainTextFormatted);
-            break;
-          case Severity.warning:
-            printMessage = !suppressWarnings;
-            break;
-          case Severity.context:
-          case Severity.ignored:
-            throw "Unexpected severity: ${message.severity}";
-        }
-        if (printMessage) {
-          printDiagnosticMessage(message, stderr.writeln);
-        }
-      };
+    options = setupCompilerOptions(
+        fileSystem,
+        platformKernelPath,
+        suppressWarnings,
+        enableAsserts,
+        nullSafety,
+        experimentalFlags,
+        bytecode,
+        packagesUri,
+        errors);
   }
 
   Future<CompilerResult> compile(Uri script) {
@@ -352,13 +374,6 @@
   @override
   Future<CompilerResult> compileInternal(Uri script) async {
     if (generator == null) {
-      if ((nullSafety == kNullSafetyOptionUnspecified) &&
-          options.experimentalFlags[ExperimentalFlag.nonNullable]) {
-        await autoDetectNullSafetyMode(script, options);
-        // Reinitialize target to set correct null safety mode.
-        options.target = new VmTarget(new TargetFlags(
-            enableNullSafety: options.nnbdMode == NnbdMode.Strong));
-      }
       generator = new IncrementalCompiler(options, script);
     }
     errors.clear();
@@ -420,13 +435,6 @@
 
   @override
   Future<CompilerResult> compileInternal(Uri script) async {
-    if ((nullSafety == kNullSafetyOptionUnspecified) &&
-        options.experimentalFlags[ExperimentalFlag.nonNullable]) {
-      await autoDetectNullSafetyMode(script, options);
-      // Reinitialize target to set correct null safety mode.
-      options.target = new VmTarget(new TargetFlags(
-          enableNullSafety: options.nnbdMode == NnbdMode.Strong));
-    }
     fe.CompilerResult compilerResult = requireMain
         ? await kernelForProgram(script, options)
         : await kernelForModule([script], options);
@@ -768,6 +776,7 @@
   final String packageConfig = request[12];
   final String multirootFilepaths = request[13];
   final String multirootScheme = request[14];
+  final String workingDirectory = request[15];
 
   Uri platformKernelPath = null;
   List<int> platformKernel = null;
@@ -810,6 +819,30 @@
     }
     port.send(new CompilationResult.ok(null).toResponse());
     return;
+  } else if (tag == kDetectNullabilityTag) {
+    FileSystem fileSystem = _buildFileSystem(
+        sourceFiles, platformKernel, multirootFilepaths, multirootScheme);
+    Uri packagesUri = null;
+    if (packageConfig != null) {
+      packagesUri = Uri.parse(packageConfig);
+    } else if (Platform.packageConfig != null) {
+      packagesUri = Uri.parse(Platform.packageConfig);
+    }
+    if (packagesUri != null && packagesUri.scheme == '') {
+      // Script does not have a scheme, assume that it is a path,
+      // resolve it against the working directory.
+      packagesUri = Uri.directory(workingDirectory).resolveUri(packagesUri);
+    }
+    final List<String> errors = <String>[];
+    var options = setupCompilerOptions(fileSystem, platformKernelPath, false,
+        false, nullSafety, experimentalFlags, false, packagesUri, errors);
+
+    // script should only be null for kUpdateSourcesTag.
+    assert(script != null);
+    await autoDetectNullSafetyMode(script, options);
+    bool value = options.nnbdMode == NnbdMode.Strong;
+    port.send(new CompilationResult.nullSafety(value).toResponse());
+    return;
   }
 
   // script should only be null for kUpdateSourcesTag.
@@ -997,6 +1030,7 @@
     null /* package_config */,
     null /* multirootFilepaths */,
     null /* multirootScheme */,
+    null /* original working directory */,
   ];
   await _processLoadRequest(request);
 }
@@ -1044,6 +1078,8 @@
 
   factory CompilationResult.ok(Uint8List bytes) = _CompilationOk;
 
+  factory CompilationResult.nullSafety(bool val) = _CompilationNullSafety;
+
   factory CompilationResult.errors(List<String> errors, Uint8List bytes) =
       _CompilationError;
 
@@ -1075,6 +1111,20 @@
   String toString() => "_CompilationOk(${bytes.length} bytes)";
 }
 
+class _CompilationNullSafety extends CompilationResult {
+  final bool _null_safety;
+
+  _CompilationNullSafety(this._null_safety) : super._() {}
+
+  @override
+  Status get status => Status.ok;
+
+  @override
+  get payload => _null_safety;
+
+  String toString() => "_CompilationNullSafety($_null_safety)";
+}
+
 abstract class _CompilationFail extends CompilationResult {
   _CompilationFail() : super._();
 
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index afb12fc..24760e7 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -123,6 +123,11 @@
       help:
           'Split resulting kernel file into multiple files (one per package).',
       defaultsTo: false);
+  args.addOption('component-name',
+      help: 'Name of the Fuchsia component', defaultsTo: null);
+  args.addOption('data-dir',
+      help: 'Name of the subdirectory of //data for output files');
+  args.addOption('manifest', help: 'Path to output Fuchsia package manifest');
   args.addFlag('gen-bytecode', help: 'Generate bytecode', defaultsTo: false);
   args.addMultiOption('bytecode-options',
       help: 'Specify options for bytecode generation:',
@@ -181,6 +186,9 @@
   final bool nullSafety = options['null-safety'];
   final bool useProtobufTreeShaker = options['protobuf-tree-shaker'];
   final bool splitOutputByPackages = options['split-output-by-packages'];
+  final String manifestFilename = options['manifest'];
+  final String dataDir = options['component-name'] ?? options['data-dir'];
+
   final bool minimalKernel = options['minimal-kernel'];
   final bool treeShakeWriteOnlyFields = options['tree-shake-write-only-fields'];
   final List<String> experimentalFlags = options['enable-experiment'];
@@ -305,6 +313,10 @@
     );
   }
 
+  if (manifestFilename != null) {
+    await createFarManifest(outputFileName, dataDir, manifestFilename);
+  }
+
   return successExitCode;
 }
 
diff --git a/pkg/vm/lib/snapshot/compare.dart b/pkg/vm/lib/snapshot/compare.dart
index 47d65b6..cacf41b 100644
--- a/pkg/vm/lib/snapshot/compare.dart
+++ b/pkg/vm/lib/snapshot/compare.dart
@@ -7,12 +7,14 @@
 /// and which symbols decreased in size.
 library vm.snapshot.compare;
 
-import 'dart:convert';
 import 'dart:io';
 import 'dart:math' as math;
 
 import 'package:args/command_runner.dart';
 
+import 'package:vm/snapshot/instruction_sizes.dart';
+import 'package:vm/snapshot/program_info.dart';
+
 class CompareCommand extends Command<void> {
   @override
   final String name = 'compare';
@@ -32,10 +34,26 @@
       super.invocation.replaceAll('[arguments]', '<old.json> <new.json>');
 
   CompareCommand() {
-    argParser.addOption('column-width',
-        help: 'Truncate column content to the given width'
-            ' (${AsciiTable.unlimitedWidth} means do not truncate).',
-        defaultsTo: AsciiTable.unlimitedWidth.toString());
+    argParser
+      ..addOption('column-width',
+          help: 'Truncate column content to the given width'
+              ' (${AsciiTable.unlimitedWidth} means do not truncate).',
+          defaultsTo: AsciiTable.unlimitedWidth.toString())
+      ..addOption('granularity',
+          help: 'Choose the granularity of the output.',
+          allowed: ['method', 'class', 'library', 'package'],
+          defaultsTo: 'method')
+      ..addFlag('collapse-anonymous-closures', help: '''
+Collapse all anonymous closures from the same scope into a single entry.
+When comparing size of AOT snapshots for two different versions of a
+program there is no reliable way to precisely establish which two anonymous
+closures are the same and should be compared in size - so
+comparison might produce a noisy output. This option reduces confusion
+by collapsing different anonymous closures within the same scope into a
+single entry. Note that when comparing the same application compiled
+with two different versions of an AOT compiler closures can be distinguished
+precisely based on their source position (which is included in their name).
+''');
   }
 
   @override
@@ -53,110 +71,103 @@
 
     final oldJsonPath = _checkExists(argResults.rest[0]);
     final newJsonPath = _checkExists(argResults.rest[1]);
-    printComparison(oldJsonPath, newJsonPath, maxWidth: maxWidth);
+    printComparison(oldJsonPath, newJsonPath,
+        maxWidth: maxWidth,
+        granularity: _parseHistogramType(argResults['granularity']),
+        collapseAnonymousClosures: argResults['collapse-anonymous-closures']);
   }
 
-  String _checkExists(String path) {
-    if (!File(path).existsSync()) {
+  HistogramType _parseHistogramType(String value) {
+    switch (value) {
+      case 'method':
+        return HistogramType.bySymbol;
+      case 'class':
+        return HistogramType.byClass;
+      case 'library':
+        return HistogramType.byLibrary;
+      case 'package':
+        return HistogramType.byPackage;
+    }
+  }
+
+  File _checkExists(String path) {
+    final file = File(path);
+    if (!file.existsSync()) {
       usageException('File $path does not exist!');
     }
-    return path;
+    return file;
   }
 }
 
-void printComparison(String oldJsonPath, String newJsonPath,
-    {int maxWidth: 0}) {
-  final oldSizes = loadSymbolSizes(oldJsonPath);
-  final newSizes = loadSymbolSizes(newJsonPath);
+void printComparison(File oldJson, File newJson,
+    {int maxWidth: 0,
+    bool collapseAnonymousClosures = false,
+    HistogramType granularity = HistogramType.bySymbol}) async {
+  final oldSizes = await loadProgramInfo(oldJson,
+      collapseAnonymousClosures: collapseAnonymousClosures);
+  final newSizes = await loadProgramInfo(newJson,
+      collapseAnonymousClosures: collapseAnonymousClosures);
+  final diff = computeDiff(oldSizes, newSizes);
 
+  // Compute total sizes.
   var totalOld = 0;
+  oldSizes.visit((_, __, ___, size) {
+    totalOld += size;
+  });
+
   var totalNew = 0;
+  newSizes.visit((_, __, ___, size) {
+    totalNew += size;
+  });
+
   var totalDiff = 0;
-  final diffBySymbol = <String, int>{};
+  diff.visit((_, __, ___, size) {
+    totalDiff += size.inBytes;
+  });
 
-  // Process all symbols (from both old and new results) and compute the change
-  // in size. If symbol is not present in the compilation assume its size to be
-  // zero.
-  for (var key in Set<String>()..addAll(newSizes.keys)..addAll(oldSizes.keys)) {
-    final oldSize = oldSizes[key] ?? 0;
-    final newSize = newSizes[key] ?? 0;
-    final diff = newSize - oldSize;
-    if (diff != 0) diffBySymbol[key] = diff;
-    totalOld += oldSize;
-    totalNew += newSize;
-    totalDiff += diff;
-  }
-
-  // Compute the list of changed symbols sorted by difference (descending).
-  final changedSymbolsBySize = diffBySymbol.keys.toList();
-  changedSymbolsBySize.sort((a, b) => diffBySymbol[b] - diffBySymbol[a]);
+  // Compute histogram.
+  final histogram = SizesHistogram.from<SymbolDiff>(
+      diff, (diff) => diff.inBytes, granularity);
 
   // Now produce the report table.
   const numLargerSymbolsToReport = 30;
   const numSmallerSymbolsToReport = 10;
   final table = AsciiTable(header: [
-    Text.left('Library'),
-    Text.left('Method'),
+    for (var col in histogram.bucketing.nameComponents) Text.left(col),
     Text.right('Diff (Bytes)')
   ], maxWidth: maxWidth);
 
   // Report [numLargerSymbolsToReport] symbols that increased in size most.
-  for (var key in changedSymbolsBySize
-      .where((k) => diffBySymbol[k] > 0)
+  for (var key in histogram.bySize
+      .where((k) => histogram.buckets[k] > 0)
       .take(numLargerSymbolsToReport)) {
-    final name = key.split(librarySeparator);
-    table.addRow([name[0], name[1], '+${diffBySymbol[key]}']);
+    table.addRow([
+      ...histogram.bucketing.namesFromBucket(key),
+      '+${histogram.buckets[key]}'
+    ]);
   }
   table.addSeparator(Separator.Wave);
 
   // Report [numSmallerSymbolsToReport] symbols that decreased in size most.
-  for (var key in changedSymbolsBySize.reversed
-      .where((k) => diffBySymbol[k] < 0)
+  for (var key in histogram.bySize.reversed
+      .where((k) => histogram.buckets[k] < 0)
       .take(numSmallerSymbolsToReport)
       .toList()
       .reversed) {
-    final name = key.split(librarySeparator);
-    table.addRow([name[0], name[1], '${diffBySymbol[key]}']);
+    table.addRow([
+      ...histogram.bucketing.namesFromBucket(key),
+      '${histogram.buckets[key]}'
+    ]);
   }
   table.addSeparator();
 
   table.render();
-  print('Comparing ${oldJsonPath} (old) to ${newJsonPath} (new)');
+  print('Comparing ${oldJson.path} (old) to ${newJson.path} (new)');
   print('Old   : ${totalOld} bytes.');
   print('New   : ${totalNew} bytes.');
   print('Change: ${totalDiff > 0 ? '+' : ''}${totalDiff} bytes.');
 }
 
-/// A combination of characters that is unlikely to occur in the symbol name.
-const String librarySeparator = ',';
-
-/// Load --print-instructions-sizes-to output as a mapping from symbol names
-/// to their sizes.
-///
-/// Note: we produce a single symbol name from function name and library name
-/// by concatenating them with [librarySeparator].
-Map<String, int> loadSymbolSizes(String name) {
-  final symbols = jsonDecode(File(name).readAsStringSync());
-  final result = new Map<String, int>();
-  final regexp = new RegExp(r"0x[a-fA-F0-9]+");
-  for (int i = 0, n = symbols.length; i < n; i++) {
-    final e = symbols[i];
-    // Obtain a key by combining library and method name. Strip anything
-    // after the library separator to make sure we can easily decode later.
-    // For method names, also remove non-deterministic parts to avoid
-    // reporting non-existing differences against the same layout.
-    String lib = ((e['l'] ?? '').split(librarySeparator))[0];
-    String name = (e['n'].split(librarySeparator))[0]
-        .replaceAll('[Optimized] ', '')
-        .replaceAll(regexp, '');
-    String key = lib + librarySeparator + name;
-    int val = e['s'];
-    result[key] =
-        (result[key] ?? 0) + val; // add (key,val), accumulate if exists
-  }
-  return result;
-}
-
 /// A row in the [AsciiTable].
 abstract class Row {
   String render(List<int> widths, List<AlignmentDirection> alignments);
diff --git a/pkg/vm/lib/snapshot/instruction_sizes.dart b/pkg/vm/lib/snapshot/instruction_sizes.dart
index e73ec00..7efa3a1 100644
--- a/pkg/vm/lib/snapshot/instruction_sizes.dart
+++ b/pkg/vm/lib/snapshot/instruction_sizes.dart
@@ -9,6 +9,7 @@
 import 'dart:io';
 
 import 'package:vm/snapshot/name.dart';
+import 'package:vm/snapshot/program_info.dart';
 
 /// Parse the output of `--print-instructions-sizes-to` saved in the given
 /// file [input].
@@ -24,6 +25,22 @@
       .toList(growable: false);
 }
 
+/// Parse the output of `--print-instructions-sizes-to` saved in the given
+/// file [input] into [ProgramInfo<int>] structure representing the sizes
+/// of individual functions.
+///
+/// If [collapseAnonymousClosures] is set to [true] then all anonymous closures
+/// within the same scopes are collapsed together. Collapsing closures is
+/// helpful when comparing symbol sizes between two versions of the same
+/// program because in general there is no reliable way to recognize the same
+/// anonymous closures into two independent compilations.
+Future<ProgramInfo<int>> loadProgramInfo(File input,
+    {bool collapseAnonymousClosures = false}) async {
+  final symbols = await load(input);
+  return toProgramInfo(symbols,
+      collapseAnonymousClosures: collapseAnonymousClosures);
+}
+
 /// Information about the size of the instruction object.
 class SymbolInfo {
   /// Name of the code object (`Code::QualifiedName`) owning these instructions.
@@ -51,3 +68,43 @@
         size: map['s']);
   }
 }
+
+/// Restore hierarchical [ProgramInfo<int>] representation from the list of
+/// symbols by parsing function names.
+///
+/// If [collapseAnonymousClosures] is set to [true] then all anonymous closures
+/// within the same scopes are collapsed together. Collapsing closures is
+/// helpful when comparing symbol sizes between two versions of the same
+/// program because in general there is no reliable way to recognize the same
+/// anonymous closures into two independent compilations.
+ProgramInfo<int> toProgramInfo(List<SymbolInfo> symbols,
+    {bool collapseAnonymousClosures = false}) {
+  final program = ProgramInfo<int>();
+  for (var sym in symbols) {
+    final scrubbed = sym.name.scrubbed;
+    if (sym.libraryUri == null) {
+      assert(sym.name.isStub);
+      assert(
+          !program.stubs.containsKey(scrubbed) || sym.name.isTypeTestingStub);
+      program.stubs[scrubbed] = (program.stubs[scrubbed] ?? 0) + sym.size;
+    } else {
+      // Split the name into components (names of individual functions).
+      final path = sym.name.components;
+
+      final lib =
+          program.libraries.putIfAbsent(sym.libraryUri, () => LibraryInfo());
+      final cls = lib.classes.putIfAbsent(sym.className, () => ClassInfo());
+      var fun = cls.functions.putIfAbsent(path.first, () => FunctionInfo());
+      for (var name in path.skip(1)) {
+        if (collapseAnonymousClosures &&
+            name.startsWith('<anonymous closure @')) {
+          name = '<anonymous closure>';
+        }
+        fun = fun.closures.putIfAbsent(name, () => FunctionInfo());
+      }
+      fun.info = (fun.info ?? 0) + sym.size;
+    }
+  }
+
+  return program;
+}
diff --git a/pkg/vm/lib/snapshot/name.dart b/pkg/vm/lib/snapshot/name.dart
index e14e1a4..dba2c9f 100644
--- a/pkg/vm/lib/snapshot/name.dart
+++ b/pkg/vm/lib/snapshot/name.dart
@@ -15,20 +15,45 @@
   /// Raw textual representation of the name as it occurred in the output
   /// of the AOT compiler.
   final String raw;
+  String _scrubbed;
 
   Name(this.raw);
 
   /// Pretty version of the name, with some of the irrelevant information
   /// removed from it.
+  ///
   /// Note: we still expect this name to be unique within compilation,
   /// so we are not removing any details that are used for disambiguation.
-  String get scrubbed => raw.replaceAll(_scrubbingRe, '');
+  /// The only exception are type testing stubs, these refer to type names
+  /// and types names are not bound to be unique between compilations.
+  String get scrubbed => _scrubbed ??=
+      raw.replaceAll(isStub ? _stubScrubbingRe : _scrubbingRe, '');
 
   /// Returns true if this name refers to a stub.
   bool get isStub => raw.startsWith('[Stub] ');
 
   /// Returns true if this name refers to an allocation stub.
   bool get isAllocationStub => raw.startsWith('[Stub] Allocate ');
+
+  /// Returns ture if this name refers to a type testing stub.
+  bool get isTypeTestingStub => raw.startsWith('[Stub] Type Test ');
+
+  /// Split this name into individual '.' separated components (e.g. names of
+  /// its parent functions).
+  List<String> get components {
+    // Break the rest of the name into components.
+    final result = scrubbed.split('.');
+
+    // Constructor names look like this 'new <ClassName>.<CtorName>' so
+    // we need to concatenate the first two components back to form
+    // the constructor name.
+    if (result.first.startsWith('new ')) {
+      result[0] = '${result[0]}${result[1]}';
+      result.removeAt(1);
+    }
+
+    return result;
+  }
 }
 
 // Remove useless prefixes and private library suffixes from the raw name.
@@ -37,3 +62,7 @@
 // still, these names are formatted as '<anonymous closure @\d+>'.
 final _scrubbingRe =
     RegExp(r'\[(Optimized|Unoptimized|Stub)\]\s*|@\d+(?![>\d])');
+
+// Remove useless prefixes and private library suffixes from the raw name
+// for stubs.
+final _stubScrubbingRe = RegExp(r'\[Stub\]\s*|@\d+|\(H[a-f\d]+\) ');
diff --git a/pkg/vm/lib/snapshot/program_info.dart b/pkg/vm/lib/snapshot/program_info.dart
new file mode 100644
index 0000000..3094ee2
--- /dev/null
+++ b/pkg/vm/lib/snapshot/program_info.dart
@@ -0,0 +1,286 @@
+// 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.
+
+/// Classes for representing information about the program structure.
+library vm.snapshot.program_info;
+
+/// Represents information about compiled program.
+class ProgramInfo<T> {
+  final Map<String, LibraryInfo<T>> libraries = {};
+  final Map<String, T> stubs = {};
+
+  /// Recursively visit all function nodes, which have [FunctionInfo.info]
+  /// populated.
+  void visit(
+      void Function(String lib, String cls, String fun, T info) callback) {
+    void recurse(String lib, String cls, String name, FunctionInfo<T> fun) {
+      if (fun.info != null) {
+        callback(lib, cls, name, fun.info);
+      }
+
+      for (var clo in fun.closures.entries) {
+        recurse(lib, cls, '$name.${clo.key}', clo.value);
+      }
+    }
+
+    for (var stub in stubs.entries) {
+      callback(null, null, stub.key, stub.value);
+    }
+
+    for (var lib in libraries.entries) {
+      for (var cls in lib.value.classes.entries) {
+        for (var fun in cls.value.functions.entries) {
+          recurse(lib.key, cls.key, fun.key, fun.value);
+        }
+      }
+    }
+  }
+
+  /// Convert this program info to a JSON map using [infoToJson] to convert
+  /// data attached to [FunctioInfo] nodes into its JSON representation.
+  Map<String, dynamic> toJson(Object Function(T) infoToJson) {
+    Map<String, dynamic> recurse(FunctionInfo<T> fun) {
+      return {
+        if (fun.info != null) 'info': infoToJson(fun.info),
+        if (fun.closures.isNotEmpty)
+          'closures': {
+            for (var clo in fun.closures.entries) clo.key: recurse(clo.value)
+          }
+      };
+    }
+
+    return {
+      'stubs': {
+        for (var stub in stubs.entries) stub.key: infoToJson(stub.value)
+      },
+      'libraries': {
+        for (var lib in libraries.entries)
+          lib.key: {
+            for (var cls in lib.value.classes.entries)
+              cls.key: {
+                for (var fun in cls.value.functions.entries)
+                  fun.key: recurse(fun.value)
+              }
+          }
+      }
+    };
+  }
+}
+
+class LibraryInfo<T> {
+  final Map<String, ClassInfo<T>> classes = {};
+}
+
+class ClassInfo<T> {
+  final Map<String, FunctionInfo<T>> functions = {};
+}
+
+class FunctionInfo<T> {
+  final Map<String, FunctionInfo<T>> closures = {};
+
+  T info;
+}
+
+/// Computes the size difference between two [ProgramInfo<int>].
+ProgramInfo<SymbolDiff> computeDiff(
+    ProgramInfo<int> oldInfo, ProgramInfo<int> newInfo) {
+  final programDiff = ProgramInfo<SymbolDiff>();
+
+  void recursiveDiff(FunctionInfo<SymbolDiff> Function() functionInfo,
+      String fun, FunctionInfo<int> newFun, FunctionInfo<int> oldFun) {
+    if (newFun?.info != oldFun?.info) {
+      final funDiff = functionInfo();
+      final diff = funDiff.info ??= SymbolDiff();
+      diff.oldTotal += oldFun?.info ?? 0;
+      diff.newTotal += newFun?.info ?? 0;
+    }
+
+    for (var clo in _allKeys(newFun?.closures, oldFun?.closures)) {
+      final newClo = newFun != null ? newFun.closures[clo] : null;
+      final oldClo = oldFun != null ? oldFun.closures[clo] : null;
+      recursiveDiff(() {
+        return functionInfo().closures.putIfAbsent(clo, () => FunctionInfo());
+      }, clo, newClo, oldClo);
+    }
+  }
+
+  for (var stub in _allKeys(newInfo.stubs, oldInfo.stubs)) {
+    final newSize = newInfo.stubs[stub];
+    final oldSize = oldInfo.stubs[stub];
+    if (newSize != oldSize) {
+      programDiff.stubs[stub] = SymbolDiff()
+        ..oldTotal = oldSize ?? 0
+        ..newTotal = newSize ?? 0;
+    }
+  }
+
+  for (var lib in _allKeys(newInfo.libraries, oldInfo.libraries)) {
+    final newLib = newInfo.libraries[lib];
+    final oldLib = oldInfo.libraries[lib];
+    for (var cls in _allKeys(newLib?.classes, oldLib?.classes)) {
+      final newCls = newLib != null ? newLib.classes[cls] : null;
+      final oldCls = oldLib != null ? oldLib.classes[cls] : null;
+      for (var fun in _allKeys(newCls?.functions, oldCls?.functions)) {
+        final newFun = newCls != null ? newCls.functions[fun] : null;
+        final oldFun = oldCls != null ? oldCls.functions[fun] : null;
+        recursiveDiff(() {
+          return programDiff.libraries
+              .putIfAbsent(lib, () => LibraryInfo())
+              .classes
+              .putIfAbsent(cls, () => ClassInfo())
+              .functions
+              .putIfAbsent(fun, () => FunctionInfo());
+        }, fun, newFun, oldFun);
+      }
+    }
+  }
+
+  return programDiff;
+}
+
+class SymbolDiff {
+  int oldTotal = 0;
+  int newTotal = 0;
+
+  int get inBytes {
+    return newTotal - oldTotal;
+  }
+}
+
+Iterable<T> _allKeys<T>(Map<T, dynamic> a, Map<T, dynamic> b) {
+  return <T>{...?a?.keys, ...?b?.keys};
+}
+
+/// Histogram of sizes based on a [ProgramInfo] bucketted using one of the
+/// [HistogramType] rules.
+class SizesHistogram {
+  /// Rule used to produce this histogram. Specifies how bucket names
+  /// are constructed given (library-uri,class-name,function-name) tuples and
+  /// how these bucket names can be deconstructed back into human readable form.
+  final Bucketing bucketing;
+
+  /// Histogram buckets.
+  final Map<String, int> buckets;
+
+  /// Bucket names sorted by the size of the corresponding bucket in descending
+  /// order.
+  final List<String> bySize;
+
+  SizesHistogram._(this.bucketing, this.buckets, this.bySize);
+
+  /// Construct the histogram of specific [type] given a [ProgramInfo<T>] and
+  /// function [toSize] for  computing an integer value based on the datum of
+  /// type [T] attached to program nodes.
+  static SizesHistogram from<T>(
+      ProgramInfo<T> info, int Function(T) toSize, HistogramType type) {
+    final buckets = <String, int>{};
+    final bucketing = Bucketing._forType[type];
+
+    info.visit((lib, cls, fun, info) {
+      final bucket = bucketing.bucketFor(lib ?? '<stubs>', cls ?? '', fun);
+      buckets[bucket] = (buckets[bucket] ?? 0) + toSize(info);
+    });
+
+    final bySize = buckets.keys.toList(growable: false);
+    bySize.sort((a, b) => buckets[b] - buckets[a]);
+
+    return SizesHistogram._(bucketing, buckets, bySize);
+  }
+}
+
+enum HistogramType {
+  bySymbol,
+  byClass,
+  byLibrary,
+  byPackage,
+}
+
+abstract class Bucketing {
+  /// Specifies which human readable name components can be extracted from
+  /// the bucket name.
+  List<String> get nameComponents;
+
+  /// Constructs the bucket name from the given library name [lib], class name
+  /// [cls] and function name [fun].
+  String bucketFor(String lib, String cls, String fun);
+
+  /// Deconstructs bucket name into human readable components (the order matches
+  /// one returned by [nameComponents]).
+  List<String> namesFromBucket(String bucket);
+
+  const Bucketing();
+
+  static const _forType = {
+    HistogramType.bySymbol: _BucketBySymbol(),
+    HistogramType.byClass: _BucketByClass(),
+    HistogramType.byLibrary: _BucketByLibrary(),
+    HistogramType.byPackage: _BucketByPackage(),
+  };
+}
+
+/// A combination of characters that is unlikely to occur in the symbol name.
+const String _nameSeparator = ';;;';
+
+class _BucketBySymbol extends Bucketing {
+  @override
+  List<String> get nameComponents => const ['Library', 'Method'];
+
+  @override
+  String bucketFor(String lib, String cls, String fun) =>
+      '$lib${_nameSeparator}${cls}${cls != '' ? '.' : ''}${fun}';
+
+  @override
+  List<String> namesFromBucket(String bucket) => bucket.split(_nameSeparator);
+
+  const _BucketBySymbol();
+}
+
+class _BucketByClass extends Bucketing {
+  @override
+  List<String> get nameComponents => ['Library', 'Class'];
+
+  @override
+  String bucketFor(String lib, String cls, String fun) =>
+      '$lib${_nameSeparator}${cls}';
+
+  @override
+  List<String> namesFromBucket(String bucket) => bucket.split(_nameSeparator);
+
+  const _BucketByClass();
+}
+
+class _BucketByLibrary extends Bucketing {
+  @override
+  List<String> get nameComponents => ['Library'];
+
+  @override
+  String bucketFor(String lib, String cls, String fun) => '$lib';
+
+  @override
+  List<String> namesFromBucket(String bucket) => [bucket];
+
+  const _BucketByLibrary();
+}
+
+class _BucketByPackage extends Bucketing {
+  @override
+  List<String> get nameComponents => ['Package'];
+
+  @override
+  String bucketFor(String lib, String cls, String fun) => _packageOf(lib);
+
+  @override
+  List<String> namesFromBucket(String bucket) => [bucket];
+
+  const _BucketByPackage();
+
+  String _packageOf(String lib) {
+    if (lib.startsWith('package:')) {
+      final separatorPos = lib.indexOf('/');
+      return lib.substring(0, separatorPos);
+    } else {
+      return lib;
+    }
+  }
+}
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index 3f67eee..e8ad442 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -34,7 +34,8 @@
   kFloat,
   kDouble,
   kVoid,
-  kStruct
+  kStruct,
+  kHandle,
 }
 
 const NativeType kNativeTypeIntStart = NativeType.kInt8;
@@ -59,7 +60,8 @@
   'Float',
   'Double',
   'Void',
-  'Struct'
+  'Struct',
+  'Handle'
 ];
 
 const int UNKNOWN = 0;
@@ -85,6 +87,7 @@
   8, // Double
   UNKNOWN, // Void
   UNKNOWN, // Struct
+  WORD_SIZE, // Handle
 ];
 
 /// The struct layout in various ABIs.
@@ -181,6 +184,7 @@
   final DiagnosticReporter diagnosticReporter;
   final ReferenceFromIndex referenceFromIndex;
 
+  final Class objectClass;
   final Class intClass;
   final Class doubleClass;
   final Class listClass;
@@ -219,6 +223,7 @@
   FfiTransformer(this.index, this.coreTypes, this.hierarchy,
       this.diagnosticReporter, this.referenceFromIndex)
       : env = new TypeEnvironment(coreTypes, hierarchy),
+        objectClass = coreTypes.objectClass,
         intClass = coreTypes.intClass,
         doubleClass = coreTypes.doubleClass,
         listClass = coreTypes.listClass,
@@ -288,9 +293,11 @@
   /// [Void]                               -> [void]
   /// [Pointer]<T>                         -> [Pointer]<T>
   /// T extends [Pointer]                  -> T
+  /// [Handle]                             -> [Object]
   /// [NativeFunction]<T1 Function(T2, T3) -> S1 Function(S2, S3)
   ///    where DartRepresentationOf(Tn) -> Sn
-  DartType convertNativeTypeToDartType(DartType nativeType, bool allowStructs) {
+  DartType convertNativeTypeToDartType(
+      DartType nativeType, bool allowStructs, bool allowHandle) {
     if (nativeType is! InterfaceType) {
       return null;
     }
@@ -317,6 +324,9 @@
     if (nativeType_ == NativeType.kVoid) {
       return VoidType();
     }
+    if (nativeType_ == NativeType.kHandle && allowHandle) {
+      return InterfaceType(objectClass, Nullability.legacy);
+    }
     if (nativeType_ != NativeType.kNativeFunction ||
         native.typeArguments[0] is! FunctionType) {
       return null;
@@ -329,11 +339,12 @@
     }
     if (fun.typeParameters.length != 0) return null;
     // TODO(36730): Structs cannot appear in native function signatures.
-    final DartType returnType =
-        convertNativeTypeToDartType(fun.returnType, /*allowStructs=*/ false);
+    final DartType returnType = convertNativeTypeToDartType(
+        fun.returnType, /*allowStructs=*/ false, /*allowHandle=*/ true);
     if (returnType == null) return null;
     final List<DartType> argumentTypes = fun.positionalParameters
-        .map((t) => convertNativeTypeToDartType(t, /*allowStructs=*/ false))
+        .map((t) => convertNativeTypeToDartType(
+            t, /*allowStructs=*/ false, /*allowHandle=*/ true))
         .toList();
     if (argumentTypes.contains(null)) return null;
     return FunctionType(argumentTypes, returnType, Nullability.legacy);
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 1c11b71..9ba04b2 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -230,8 +230,8 @@
             nativeTypesClasses[nativeTypeAnnos.first.index],
             Nullability.legacy);
         // TODO(36730): Support structs inside structs.
-        final DartType shouldBeDartType =
-            convertNativeTypeToDartType(nativeType, /*allowStructs=*/ false);
+        final DartType shouldBeDartType = convertNativeTypeToDartType(
+            nativeType, /*allowStructs=*/ false, /*allowHandle=*/ false);
         if (shouldBeDartType == null ||
             !env.isSubtypeOf(type, shouldBeDartType,
                 SubtypeCheckMode.ignoringNullabilities)) {
diff --git a/pkg/vm/lib/transformations/ffi_use_sites.dart b/pkg/vm/lib/transformations/ffi_use_sites.dart
index aec594f..96830bf 100644
--- a/pkg/vm/lib/transformations/ffi_use_sites.dart
+++ b/pkg/vm/lib/transformations/ffi_use_sites.dart
@@ -202,7 +202,8 @@
                 .classNode);
 
         if (expectedReturn == NativeType.kVoid ||
-            expectedReturn == NativeType.kPointer) {
+            expectedReturn == NativeType.kPointer ||
+            expectedReturn == NativeType.kHandle) {
           if (node.arguments.positional.length > 1) {
             diagnosticReporter.report(
                 templateFfiExpectedNoExceptionalReturn.withArguments(
@@ -380,9 +381,9 @@
 
   void _ensureNativeTypeToDartType(
       DartType nativeType, DartType dartType, Expression node,
-      {bool allowStructs: false}) {
+      {bool allowStructs: false, bool allowHandle: false}) {
     final DartType correspondingDartType =
-        convertNativeTypeToDartType(nativeType, allowStructs);
+        convertNativeTypeToDartType(nativeType, allowStructs, allowHandle);
     if (dartType == correspondingDartType) return;
     if (env.isSubtypeOf(correspondingDartType, dartType,
         SubtypeCheckMode.ignoringNullabilities)) {
@@ -398,8 +399,9 @@
   }
 
   void _ensureNativeTypeValid(DartType nativeType, Expression node,
-      {bool allowStructs: false}) {
-    if (!_nativeTypeValid(nativeType, allowStructs: allowStructs)) {
+      {bool allowStructs: false, bool allowHandle: false}) {
+    if (!_nativeTypeValid(nativeType,
+        allowStructs: allowStructs, allowHandle: allowHandle)) {
       diagnosticReporter.report(
           templateFfiTypeInvalid.withArguments(
               nativeType, currentLibrary.isNonNullableByDefault),
@@ -412,8 +414,10 @@
 
   /// The Dart type system does not enforce that NativeFunction return and
   /// parameter types are only NativeTypes, so we need to check this.
-  bool _nativeTypeValid(DartType nativeType, {bool allowStructs: false}) {
-    return convertNativeTypeToDartType(nativeType, allowStructs) != null;
+  bool _nativeTypeValid(DartType nativeType,
+      {bool allowStructs: false, allowHandle: false}) {
+    return convertNativeTypeToDartType(nativeType, allowStructs, allowHandle) !=
+        null;
   }
 
   void _ensureIsStaticFunction(Expression node) {
diff --git a/pkg/vm/test/kernel_front_end_test.dart b/pkg/vm/test/kernel_front_end_test.dart
index 6aef35e..56dfc69 100644
--- a/pkg/vm/test/kernel_front_end_test.dart
+++ b/pkg/vm/test/kernel_front_end_test.dart
@@ -37,6 +37,7 @@
   });
 
   String outputDill() => new File('${tempDir.path}/foo.dill').path;
+  String outputManifest() => new File('${tempDir.path}/foo.manifest').path;
 
   test('compile-simple', () async {
     await testCompile([
@@ -91,6 +92,10 @@
       '--output',
       outputDill(),
       '--split-output-by-packages',
+      '--manifest',
+      outputManifest(),
+      '--component-name',
+      'foo_component',
       '$sdkDir/$mainScript',
     ]);
   }, timeout: Timeout.none);
@@ -120,6 +125,10 @@
       '--gen-bytecode',
       '--drop-ast',
       '--split-output-by-packages',
+      '--manifest',
+      outputManifest(),
+      '--component-name',
+      'foo_component',
       '$sdkDir/$mainScript',
     ]);
   }, timeout: Timeout.none);
diff --git a/pkg/vm/test/snapshot/instruction_sizes_test.dart b/pkg/vm/test/snapshot/instruction_sizes_test.dart
index 0a66a9a..60bd343 100644
--- a/pkg/vm/test/snapshot/instruction_sizes_test.dart
+++ b/pkg/vm/test/snapshot/instruction_sizes_test.dart
@@ -8,13 +8,9 @@
 import 'package:test/test.dart';
 
 import 'package:vm/snapshot/instruction_sizes.dart' as instruction_sizes;
+import 'package:vm/snapshot/program_info.dart';
 
-void main() async {
-  if (!Platform.executable.contains('dart-sdk')) {
-    // If we are not running from the prebuilt SDK then this test does nothing.
-    return;
-  }
-
+final dart2native = () {
   final sdkBin = path.dirname(Platform.executable);
   final dart2native =
       path.join(sdkBin, Platform.isWindows ? 'dart2native.bat' : 'dart2native');
@@ -23,15 +19,18 @@
     throw 'Failed to locate dart2native in the SDK';
   }
 
-  group('instruction-sizes', () {
-    test('basic-parsing', () async {
-      await withTempDir('basic-parsing', (dir) async {
-        final inputDart = path.join(dir, 'input.dart');
-        final outputBinary = path.join(dir, 'output.exe');
-        final sizesJson = path.join(dir, 'sizes.json');
+  return path.canonicalize(dart2native);
+}();
 
-        // Create test input.
-        await File(inputDart).writeAsString("""
+void main() async {
+  if (!Platform.executable.contains('dart-sdk')) {
+    // If we are not running from the prebuilt SDK then this test does nothing.
+    return;
+  }
+
+  group('instruction-sizes', () {
+    final testSource = {
+      'input.dart': """
 @pragma('vm:never-inline')
 dynamic makeSomeClosures() {
   return [
@@ -73,23 +72,105 @@
   print(tearOff(args.isEmpty ? A() : B()));
   print(C.tornOff);
 }
-""");
+"""
+    };
 
-        // Compile input.dart to native and output instruction sizes.
-        final result = await Process.run(dart2native, [
-          '-o',
-          outputBinary,
-          '--extra-gen-snapshot-options=--print_instructions_sizes_to=$sizesJson',
-          inputDart,
-        ]);
+    // Almost exactly the same source as above, but with few modifications
+    // marked with a 'modified' comment.
+    final testSourceModified = {
+      'input.dart': """
+@pragma('vm:never-inline')
+dynamic makeSomeClosures() {
+  return [
+    () => true,
+    () => false,
+    () => 11,
+    () => {},  // modified
+  ];
+}
 
-        expect(result.exitCode, equals(0),
-            reason: 'Compilation completed successfully');
-        expect(File(outputBinary).existsSync(), isTrue,
-            reason: 'Output binary exists');
-        expect(File(sizesJson).existsSync(), isTrue,
-            reason: 'Instruction sizes output exists');
+class A {
+  @pragma('vm:never-inline')
+  dynamic tornOff() {
+    for (var cl in makeSomeClosures()) {  // modified
+      print(cl());                        // modified
+    }                                     // modified
+    return true;
+  }
+}
 
+class B {
+  @pragma('vm:never-inline')
+  dynamic tornOff() {
+    return false;
+  }
+}
+
+class C {
+  static dynamic tornOff() async {
+    return true;
+  }
+}
+
+@pragma('vm:never-inline')
+Function tearOff(dynamic o) {
+  return o.tornOff;
+}
+
+void main(List<String> args) {
+  // modified
+  print(tearOff(args.isEmpty ? A() : B()));
+  print(C.tornOff);
+}
+"""
+    };
+
+    final testSourceModified2 = {
+      'input.dart': """
+@pragma('vm:never-inline')
+dynamic makeSomeClosures() {
+  return [
+    () => 0,
+  ];
+}
+
+class A {
+  @pragma('vm:never-inline')
+  dynamic tornOff() {
+    return true;
+  }
+}
+
+class B {
+  @pragma('vm:never-inline')
+  dynamic tornOff() {
+    return false;
+  }
+}
+
+class C {
+  static dynamic tornOff() async {
+    return true;
+  }
+}
+
+@pragma('vm:never-inline')
+Function tearOff(dynamic o) {
+  return o.tornOff;
+}
+
+void main(List<String> args) {
+  for (var cl in makeSomeClosures()) {
+    print(cl());
+  }
+  print(tearOff(args.isEmpty ? A() : B()));
+  print(C.tornOff);
+}
+"""
+    };
+
+    test('basic-parsing', () async {
+      await withSymbolSizes('basic-parsing', testSource, (sizesJson) async {
         final symbols = await instruction_sizes.load(File(sizesJson));
         expect(symbols, isNotNull,
             reason: 'Sizes file was successfully parsed');
@@ -97,70 +178,301 @@
             reason: 'Sizes file is non-empty');
 
         // Check for duplicated symbols (using both raw and scrubbed names).
-        final symbolRawNamesByLibrary = Map<String, Set<String>>();
-        final symbolScrubbedNamesByLibrary = Map<String, Set<String>>();
+        // Maps below contain mappings library-uri -> class-name -> names.
+        final symbolRawNames = <String, Map<String, Set<String>>>{};
+        final symbolScrubbedNames = <String, Map<String, Set<String>>>{};
 
-        Set<String> getSetOfNames(
-            Map<String, Set<String>> map, String libraryUri) {
-          // For file uris make sure to canonicalize the path. This prevents
-          // issues with mismatching case on Windows which has case insensitive
-          // file system.
-          if (libraryUri != null) {
-            final uri = Uri.parse(libraryUri);
-            if (uri.scheme == 'file') {
-              libraryUri =
-                  Uri.file(path.canonicalize(uri.toFilePath())).toString();
-            }
-          }
-          return map.putIfAbsent(libraryUri ?? '', () => {});
+        Set<String> getSetOfNames(Map<String, Map<String, Set<String>>> map,
+            String libraryUri, String className) {
+          return map
+              .putIfAbsent(libraryUri ?? '', () => {})
+              .putIfAbsent(className ?? '', () => {});
         }
 
         for (var sym in symbols) {
           expect(
-              getSetOfNames(symbolRawNamesByLibrary, sym.libraryUri)
+              getSetOfNames(symbolRawNames, sym.libraryUri, sym.className)
                   .add(sym.name.raw),
               isTrue,
               reason:
                   'All symbols should have unique names (within libraries): ${sym.name.raw}');
           expect(
-              getSetOfNames(symbolScrubbedNamesByLibrary, sym.libraryUri)
+              getSetOfNames(symbolScrubbedNames, sym.libraryUri, sym.className)
                   .add(sym.name.scrubbed),
               isTrue,
               reason: 'Scrubbing the name should not make it non-unique');
         }
 
         // Check for expected names which should appear in the output.
-        final inputDartSymbolNames = symbolScrubbedNamesByLibrary[
-            Uri.file(path.canonicalize(inputDart)).toString()];
+        final inputDartSymbolNames =
+            symbolScrubbedNames['package:input/input.dart'];
         expect(inputDartSymbolNames, isNotNull,
             reason: 'Symbols from input.dart are included into sizes output');
 
-        expect(inputDartSymbolNames, contains('makeSomeClosures'));
-        final closures = inputDartSymbolNames.where(
+        expect(inputDartSymbolNames[''], isNotNull,
+            reason: 'Should include top-level members from input.dart');
+        expect(inputDartSymbolNames[''], contains('makeSomeClosures'));
+        final closures = inputDartSymbolNames[''].where(
             (name) => name.startsWith('makeSomeClosures.<anonymous closure'));
-        expect(closures.length, 3);
-        expect(inputDartSymbolNames, contains('A.tornOff'));
-        expect(inputDartSymbolNames, contains('[tear-off] A.tornOff'));
-        expect(inputDartSymbolNames,
-            contains('[tear-off-extractor] A.get:tornOff'));
-        expect(inputDartSymbolNames, contains('B.tornOff'));
-        expect(inputDartSymbolNames, contains('[tear-off] B.tornOff'));
-        expect(inputDartSymbolNames,
-            contains('[tear-off-extractor] B.get:tornOff'));
+        expect(closures.length, 3,
+            reason: 'There are three closures inside makeSomeClosure');
+
+        expect(inputDartSymbolNames['A'], isNotNull,
+            reason: 'Should include class A members from input.dart');
+        expect(inputDartSymbolNames['A'], contains('tornOff'));
+        expect(inputDartSymbolNames['A'], contains('[tear-off] tornOff'));
+        expect(inputDartSymbolNames['A'],
+            contains('[tear-off-extractor] get:tornOff'));
+
+        expect(inputDartSymbolNames['B'], isNotNull,
+            reason: 'Should include class B members from input.dart');
+        expect(inputDartSymbolNames['B'], contains('tornOff'));
+        expect(inputDartSymbolNames['B'], contains('[tear-off] tornOff'));
+        expect(inputDartSymbolNames['B'],
+            contains('[tear-off-extractor] get:tornOff'));
 
         // Presence of async modifier should not cause tear-off name to end
         // with {body}.
-        expect(inputDartSymbolNames, contains('[tear-off] C.tornOff'));
+        expect(inputDartSymbolNames['C'], contains('[tear-off] tornOff'));
+
+        // Check that output does not contain '[unknown stub]'
+        expect(symbolRawNames[''][''], isNot(contains('[unknown stub]')),
+            reason: 'All stubs must be named');
+      });
+    });
+
+    test('program-info', () async {
+      await withSymbolSizes('program-info', testSource, (sizesJson) async {
+        final info = await instruction_sizes.loadProgramInfo(File(sizesJson));
+        expect(info.libraries, contains('dart:core'));
+        expect(info.libraries, contains('dart:typed_data'));
+        expect(info.libraries, contains('package:input/input.dart'));
+
+        final inputLib = info.libraries['package:input/input.dart'];
+        expect(inputLib.classes, contains('')); // Top-level class.
+        expect(inputLib.classes, contains('A'));
+        expect(inputLib.classes, contains('B'));
+        expect(inputLib.classes, contains('C'));
+
+        final topLevel = inputLib.classes[''];
+        expect(topLevel.functions, contains('makeSomeClosures'));
+        expect(
+            topLevel.functions['makeSomeClosures'].closures.length, equals(3));
+
+        for (var name in [
+          '[tear-off] tornOff',
+          'tornOff',
+          'Allocate A',
+          '[tear-off-extractor] get:tornOff'
+        ]) {
+          expect(inputLib.classes['A'].functions, contains(name));
+          expect(inputLib.classes['A'].functions[name].closures, isEmpty);
+        }
+
+        for (var name in [
+          '[tear-off] tornOff',
+          'tornOff',
+          'Allocate B',
+          '[tear-off-extractor] get:tornOff'
+        ]) {
+          expect(inputLib.classes['B'].functions, contains(name));
+          expect(inputLib.classes['B'].functions[name].closures, isEmpty);
+        }
+
+        for (var name in ['tornOff{body}', 'tornOff', '[tear-off] tornOff']) {
+          expect(inputLib.classes['C'].functions, contains(name));
+          expect(inputLib.classes['C'].functions[name].closures, isEmpty);
+        }
+      });
+    });
+
+    test('histograms', () async {
+      await withSymbolSizes('histograms', testSource, (sizesJson) async {
+        final info = await instruction_sizes.loadProgramInfo(File(sizesJson));
+        final bySymbol =
+            SizesHistogram.from(info, (size) => size, HistogramType.bySymbol);
+        expect(
+            bySymbol.buckets,
+            contains(bySymbol.bucketing
+                .bucketFor('package:input/input.dart', 'A', 'tornOff')));
+        expect(
+            bySymbol.buckets,
+            contains(bySymbol.bucketing
+                .bucketFor('package:input/input.dart', 'B', 'tornOff')));
+        expect(
+            bySymbol.buckets,
+            contains(bySymbol.bucketing
+                .bucketFor('package:input/input.dart', 'C', 'tornOff')));
+
+        final byClass =
+            SizesHistogram.from(info, (size) => size, HistogramType.byClass);
+        expect(
+            byClass.buckets,
+            contains(byClass.bucketing.bucketFor(
+                'package:input/input.dart', 'A', 'does-not-matter')));
+        expect(
+            byClass.buckets,
+            contains(byClass.bucketing.bucketFor(
+                'package:input/input.dart', 'B', 'does-not-matter')));
+        expect(
+            byClass.buckets,
+            contains(byClass.bucketing.bucketFor(
+                'package:input/input.dart', 'C', 'does-not-matter')));
+
+        final byLibrary =
+            SizesHistogram.from(info, (size) => size, HistogramType.byLibrary);
+        expect(
+            byLibrary.buckets,
+            contains(byLibrary.bucketing.bucketFor('package:input/input.dart',
+                'does-not-matter', 'does-not-matter')));
+
+        final byPackage =
+            SizesHistogram.from(info, (size) => size, HistogramType.byPackage);
+        expect(
+            byPackage.buckets,
+            contains(byPackage.bucketing.bucketFor(
+                'package:input/does-not-matter.dart',
+                'does-not-matter',
+                'does-not-matter')));
+      });
+    });
+
+    // On Windows there is some issue with interpreting entry point URI as a package URI
+    // it instead gets interpreted as a file URI - which breaks comparison. So we
+    // simply ignore entry point library (main.dart).
+    Map<String, dynamic> diffToJson(ProgramInfo<SymbolDiff> diff) {
+      final diffJson = diff.toJson((diff) => diff.inBytes);
+      final libraries = diffJson['libraries'] as Map<String, dynamic>;
+      libraries.removeWhere((key, _) => key.endsWith('main.dart'));
+      return diffJson;
+    }
+
+    test('diff', () async {
+      await withSymbolSizes('diff-1', testSource, (sizesJson) async {
+        await withSymbolSizes('diff-2', testSourceModified,
+            (modifiedSizesJson) async {
+          final info = await instruction_sizes.loadProgramInfo(File(sizesJson));
+          final modifiedInfo =
+              await instruction_sizes.loadProgramInfo(File(modifiedSizesJson));
+          final diff = computeDiff(info, modifiedInfo);
+
+          expect(
+              diffToJson(diff),
+              equals({
+                'stubs': {},
+                'libraries': {
+                  'package:input/input.dart': {
+                    '': {
+                      'makeSomeClosures': {
+                        'info': greaterThan(0), // We added code here.
+                        'closures': {
+                          '<anonymous closure @118>': {
+                            'info': greaterThan(0),
+                          },
+                        },
+                      },
+                      'main': {
+                        'info': lessThan(0), // We removed code from main.
+                      },
+                    },
+                    'A': {
+                      'tornOff': {
+                        'info': greaterThan(0),
+                      },
+                    }
+                  }
+                }
+              }));
+        });
+      });
+    });
+
+    test('diff-collapsed', () async {
+      await withSymbolSizes('diff-collapsed-1', testSource, (sizesJson) async {
+        await withSymbolSizes('diff-collapsed-2', testSourceModified2,
+            (modifiedSizesJson) async {
+          final info = await instruction_sizes.loadProgramInfo(File(sizesJson),
+              collapseAnonymousClosures: true);
+          final modifiedInfo = await instruction_sizes.loadProgramInfo(
+              File(modifiedSizesJson),
+              collapseAnonymousClosures: true);
+          final diff = computeDiff(info, modifiedInfo);
+
+          expect(
+              diffToJson(diff),
+              equals({
+                'stubs': {},
+                'libraries': {
+                  'package:input/input.dart': {
+                    '': {
+                      'makeSomeClosures': {
+                        'info': lessThan(0), // We removed code here.
+                        'closures': {
+                          '<anonymous closure>': {
+                            'info': lessThan(0),
+                          },
+                        },
+                      },
+                    },
+                  }
+                }
+              }));
+        });
       });
     });
   });
 }
 
-Future withTempDir(String prefix, Future fun(String dir)) async {
+Future withSymbolSizes(String prefix, Map<String, String> source,
+    Future Function(String sizesJson) f) {
+  return withTempDir(prefix, (dir) async {
+    final outputBinary = path.join(dir, 'output.exe');
+    final sizesJson = path.join(dir, 'sizes.json');
+    final packages = path.join(dir, '.packages');
+    final mainDart = path.join(dir, 'main.dart');
+
+    // Create test input.
+    for (var file in source.entries) {
+      await File(path.join(dir, file.key)).writeAsString(file.value);
+    }
+    await File(packages).writeAsString('''
+input:./
+''');
+    await File(mainDart).writeAsString('''
+import 'package:input/input.dart' as input;
+
+void main(List<String> args) => input.main(args);
+''');
+
+    // Compile input.dart to native and output instruction sizes.
+    final result = await Process.run(dart2native, [
+      '-o',
+      outputBinary,
+      '--packages=$packages',
+      '--extra-gen-snapshot-options=--print_instructions_sizes_to=$sizesJson',
+      mainDart,
+    ]);
+
+    expect(result.exitCode, equals(0), reason: '''
+Compilation completed successfully.
+
+stdout: ${result.stdout}
+stderr: ${result.stderr}
+''');
+    expect(File(outputBinary).existsSync(), isTrue,
+        reason: 'Output binary exists');
+    expect(File(sizesJson).existsSync(), isTrue,
+        reason: 'Instruction sizes output exists');
+
+    await f(sizesJson);
+  });
+}
+
+Future withTempDir(String prefix, Future Function(String dir) f) async {
   final tempDir =
       Directory.systemTemp.createTempSync('instruction-sizes-test-${prefix}');
   try {
-    await fun(tempDir.path);
+    await f(tempDir.path);
   } finally {
     tempDir.deleteSync(recursive: true);
   }
diff --git a/pkg/vm_service/CHANGELOG.md b/pkg/vm_service/CHANGELOG.md
index a64881c..e971a37 100644
--- a/pkg/vm_service/CHANGELOG.md
+++ b/pkg/vm_service/CHANGELOG.md
@@ -1,6 +1,7 @@
 # Changelog
 
 ## 4.1.0
+- Update to version `3.35.0` of the spec.
 - Expose more `@required` parameters on the named constructors of VM service objects.
 
 ## 4.0.4
diff --git a/pkg/vm_service/analysis_options.yaml b/pkg/vm_service/analysis_options.yaml
index b5e3320..413f412 100644
--- a/pkg/vm_service/analysis_options.yaml
+++ b/pkg/vm_service/analysis_options.yaml
@@ -1,4 +1,4 @@
-include: package:pedantic/analysis_options.1.7.0.yaml
+include: package:pedantic/analysis_options.1.8.0.yaml
 
 linter:
   rules:
diff --git a/pkg/vm_service/example/sample_isolates.dart b/pkg/vm_service/example/sample_isolates.dart
index 3089e13..3dd216b 100644
--- a/pkg/vm_service/example/sample_isolates.dart
+++ b/pkg/vm_service/example/sample_isolates.dart
@@ -22,7 +22,7 @@
   startIsolate(3);
   startIsolate(4);
 
-  await new Future.delayed(new Duration(seconds: 5));
+  await Future.delayed(Duration(seconds: 5));
 
   print('at end of main...');
 }
@@ -33,7 +33,7 @@
 
 isolateEntry(message) async {
   print('starting $message');
-  await new Future.delayed(new Duration(seconds: message));
+  await Future.delayed(Duration(seconds: message));
   print('ending $message');
 }
 
diff --git a/pkg/vm_service/example/sample_main.dart b/pkg/vm_service/example/sample_main.dart
index 0bce431..1fef21b 100644
--- a/pkg/vm_service/example/sample_main.dart
+++ b/pkg/vm_service/example/sample_main.dart
@@ -9,7 +9,7 @@
   int local2 = 2;
   var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
-    new Bar(),
+    Bar(),
     [
       [
         [
diff --git a/pkg/vm_service/example/vm_service_tester.dart b/pkg/vm_service/example/vm_service_tester.dart
index f02be8e..8038c98 100644
--- a/pkg/vm_service/example/vm_service_tester.dart
+++ b/pkg/vm_service/example/vm_service_tester.dart
@@ -49,10 +49,10 @@
     // ignore: strong_mode_down_cast_composite
     process.stderr.transform(utf8.decoder).listen(print);
 
-    await new Future.delayed(new Duration(milliseconds: 500));
+    await Future.delayed(Duration(milliseconds: 500));
 
     // ignore: deprecated_member_use_from_same_package
-    serviceClient = await vmServiceConnect(host, port, log: new StdoutLog());
+    serviceClient = await vmServiceConnect(host, port, log: StdoutLog());
 
     print('socket connected');
 
@@ -164,8 +164,8 @@
   await serviceClient.registerService(serviceName, serviceAlias);
   VmService otherClient =
       // ignore: deprecated_member_use_from_same_package
-      await vmServiceConnect(host, port, log: new StdoutLog());
-  Completer completer = new Completer();
+      await vmServiceConnect(host, port, log: StdoutLog());
+  Completer completer = Completer();
   otherClient.onEvent('Service').listen((e) async {
     if (e.service == serviceName && e.kind == EventKind.kServiceRegistered) {
       assert(e.alias == serviceAlias);
diff --git a/pkg/vm_service/java/example/sample_exception.dart b/pkg/vm_service/java/example/sample_exception.dart
index cfe1745..7afb095 100644
--- a/pkg/vm_service/java/example/sample_exception.dart
+++ b/pkg/vm_service/java/example/sample_exception.dart
@@ -10,7 +10,7 @@
   int local2 = 2;
   var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
-    new Bar(),
+    Bar(),
     [
       [
         [
diff --git a/pkg/vm_service/java/example/sample_main.dart b/pkg/vm_service/java/example/sample_main.dart
index da88291..6884434 100644
--- a/pkg/vm_service/java/example/sample_main.dart
+++ b/pkg/vm_service/java/example/sample_main.dart
@@ -7,7 +7,7 @@
   int local2 = 2;
   var longList = [1, "hello", 3, 5, 7, 11, 13, 14, 15, 16, 17, 18, 19, 20];
   var deepList = [
-    new Bar(),
+    Bar(),
     [
       [
         [
diff --git a/pkg/vm_service/lib/src/helpers.dart b/pkg/vm_service/lib/src/helpers.dart
index a7344f3..0d14c16 100644
--- a/pkg/vm_service/lib/src/helpers.dart
+++ b/pkg/vm_service/lib/src/helpers.dart
@@ -12,7 +12,7 @@
 
     List<TagCounter> result = [];
     for (int i = 0; i < counters.length; i++) {
-      result.add(new TagCounter(names[i], counters[i]));
+      result.add(TagCounter(names[i], counters[i]));
     }
     return result;
   }
diff --git a/pkg/vm_service/lib/vm_service_io.dart b/pkg/vm_service/lib/vm_service_io.dart
index c95d0ac..00597af 100644
--- a/pkg/vm_service/lib/vm_service_io.dart
+++ b/pkg/vm_service/lib/vm_service_io.dart
@@ -10,15 +10,15 @@
 @Deprecated('Prefer vmServiceConnectUri')
 Future<VmService> vmServiceConnect(String host, int port, {Log log}) async {
   final WebSocket socket = await WebSocket.connect('ws://$host:$port/ws');
-  final StreamController<dynamic> controller = new StreamController();
-  final Completer streamClosedCompleter = new Completer();
+  final StreamController<dynamic> controller = StreamController();
+  final Completer streamClosedCompleter = Completer();
 
   socket.listen(
     (data) => controller.add(data),
     onDone: () => streamClosedCompleter.complete(),
   );
 
-  return new VmService(
+  return VmService(
     controller.stream,
     (String message) => socket.add(message),
     log: log,
@@ -30,15 +30,15 @@
 /// Connect to the given uri and return a new [VmService] instance.
 Future<VmService> vmServiceConnectUri(String wsUri, {Log log}) async {
   final WebSocket socket = await WebSocket.connect(wsUri);
-  final StreamController<dynamic> controller = new StreamController();
-  final Completer streamClosedCompleter = new Completer();
+  final StreamController<dynamic> controller = StreamController();
+  final Completer streamClosedCompleter = Completer();
 
   socket.listen(
     (data) => controller.add(data),
     onDone: () => streamClosedCompleter.complete(),
   );
 
-  return new VmService(
+  return VmService(
     controller.stream,
     (String message) => socket.add(message),
     log: log,
diff --git a/pkg/vm_service/test/common/test_helper.dart b/pkg/vm_service/test/common/test_helper.dart
index dd1e71c..f226cc0 100644
--- a/pkg/vm_service/test/common/test_helper.dart
+++ b/pkg/vm_service/test/common/test_helper.dart
@@ -15,12 +15,12 @@
 
 /// Whether to use causal async stacks (if not we use lazy async stacks).
 const bool useCausalAsyncStacks =
-    const bool.fromEnvironment('dart.developer.causal_async_stacks');
+    bool.fromEnvironment('dart.developer.causal_async_stacks');
 
 /// The extra arguments to use
 const List<String> extraDebuggingArgs = useCausalAsyncStacks
-    ? const ['--causal-async-stacks', '--no-lazy-async-stacks']
-    : const ['--no-causal-async-stacks', '--lazy-async-stacks'];
+    ? ['--causal-async-stacks', '--no-lazy-async-stacks']
+    : ['--no-causal-async-stacks', '--lazy-async-stacks'];
 
 List<IsolateTest> ifLazyAsyncStacks(List<IsolateTest> lazyTests) {
   if (useCausalAsyncStacks) return const <IsolateTest>[];
diff --git a/pkg/vm_service/test/debugging_test.dart b/pkg/vm_service/test/debugging_test.dart
index df3a1ed..d5c1b9e 100644
--- a/pkg/vm_service/test/debugging_test.dart
+++ b/pkg/vm_service/test/debugging_test.dart
@@ -21,7 +21,7 @@
 }
 
 void startTimer() {
-  new Timer.periodic(const Duration(milliseconds: 10), periodicTask);
+  Timer.periodic(const Duration(milliseconds: 10), periodicTask);
 }
 
 int getLineNumberFromTokenPos(Script s, int token) =>
@@ -30,7 +30,7 @@
 var tests = <IsolateTest>[
 // Pause
   (VmService service, IsolateRef isolateRef) async {
-    Completer completer = new Completer();
+    Completer completer = Completer();
     var stream = service.onDebugEvent;
     var subscription;
     subscription = stream.listen((Event event) {
diff --git a/pkg/vm_service/test/eval_test.dart b/pkg/vm_service/test/eval_test.dart
index 4eb8bb5..ba30330 100644
--- a/pkg/vm_service/test/eval_test.dart
+++ b/pkg/vm_service/test/eval_test.dart
@@ -29,7 +29,7 @@
   while (true) {
     if (++i % 100000000 == 0) {
       MyClass.method(10000);
-      (new _MyClass()).foo();
+      (_MyClass()).foo();
     }
   }
 }
diff --git a/pkg/vm_service/tool/common/generate_common.dart b/pkg/vm_service/tool/common/generate_common.dart
index a54f785..f250c55 100644
--- a/pkg/vm_service/tool/common/generate_common.dart
+++ b/pkg/vm_service/tool/common/generate_common.dart
@@ -16,7 +16,7 @@
       parseVersionSemVer(nodes).toString();
 
   static Version parseVersionSemVer(List<Node> nodes) {
-    final RegExp regex = new RegExp(r'[\d.]+');
+    final RegExp regex = RegExp(r'[\d.]+');
 
     // Extract version from header: `# Dart VM Service Protocol 2.0`.
     Element node = nodes.firstWhere((n) => isH1(n));
@@ -25,6 +25,6 @@
     if (match == null) throw 'Unable to locate service protocol version';
 
     // Append a `.0`.
-    return new Version.parse('${match.group(0)}.0');
+    return Version.parse('${match.group(0)}.0');
   }
 }
diff --git a/pkg/vm_service/tool/common/parser.dart b/pkg/vm_service/tool/common/parser.dart
index 813b798..3a58340 100644
--- a/pkg/vm_service/tool/common/parser.dart
+++ b/pkg/vm_service/tool/common/parser.dart
@@ -5,7 +5,7 @@
 library parser;
 
 class Token {
-  static final RegExp _alpha = new RegExp(r'^[0-9a-zA-Z_\-@]+$');
+  static final RegExp _alpha = RegExp(r'^[0-9a-zA-Z_\-@]+$');
 
   final String text;
   Token next;
@@ -69,7 +69,7 @@
   }
 
   void _emit(String value) {
-    Token token = new Token(value);
+    Token token = Token(value);
     if (_head == null) _head = token;
     if (_last != null) _last.next = token;
     _last = token;
@@ -77,11 +77,11 @@
 
   String _peek(int i) {
     i += 1;
-    return i < text.length ? text[i] : new String.fromCharCodes([0]);
+    return i < text.length ? text[i] : String.fromCharCodes([0]);
   }
 
   String toString() {
-    StringBuffer buf = new StringBuffer();
+    StringBuffer buf = StringBuffer();
 
     Token t = _head;
 
@@ -138,7 +138,7 @@
   }
 
   String collectComments() {
-    StringBuffer buf = new StringBuffer();
+    StringBuffer buf = StringBuffer();
 
     while (peek().isComment) {
       Token t = advance();
diff --git a/pkg/vm_service/tool/common/src_gen_common.dart b/pkg/vm_service/tool/common/src_gen_common.dart
index ba7e585c..cb5a9fd 100644
--- a/pkg/vm_service/tool/common/src_gen_common.dart
+++ b/pkg/vm_service/tool/common/src_gen_common.dart
@@ -11,7 +11,7 @@
 const int RUNE_LEFT_CURLY = 123;
 const int RUNE_RIGHT_CURLY = 125;
 
-final RegExp _wsRegexp = new RegExp(r'\s+');
+final RegExp _wsRegexp = RegExp(r'\s+');
 
 String collapseWhitespace(String str) => str.replaceAll(_wsRegexp, ' ');
 
@@ -40,7 +40,7 @@
   if (strs.isEmpty) return '';
   List list = strs.toList();
   if (list.length == 1) return list.first;
-  StringBuffer buf = new StringBuffer();
+  StringBuffer buf = StringBuffer();
   for (int i = 0; i < list.length; i++) {
     if (i > 0) {
       if (i + 1 == list.length && last != null) {
diff --git a/pkg/vm_service/tool/dart/src_gen_dart.dart b/pkg/vm_service/tool/dart/src_gen_dart.dart
index 7028094..15cf723 100644
--- a/pkg/vm_service/tool/dart/src_gen_dart.dart
+++ b/pkg/vm_service/tool/dart/src_gen_dart.dart
@@ -16,7 +16,7 @@
   final int colBoundary;
 
   String _indent = "";
-  final StringBuffer _buf = new StringBuffer();
+  final StringBuffer _buf = StringBuffer();
 
   bool _previousWasEol = false;
 
@@ -86,7 +86,7 @@
         _buf.write(_indent);
       }
 
-      _buf.write(new String.fromCharCode(rune));
+      _buf.write(String.fromCharCode(rune));
 
       _previousWasEol = rune == RUNE_EOL;
     }
diff --git a/pkg/vm_service/tool/generate.dart b/pkg/vm_service/tool/generate.dart
index f8dc684..28dc548 100644
--- a/pkg/vm_service/tool/generate.dart
+++ b/pkg/vm_service/tool/generate.dart
@@ -20,10 +20,10 @@
   String appDirPath = dirname(Platform.script.toFilePath());
 
   // Parse service.md into a model.
-  var file = new File(
+  var file = File(
       normalize(join(appDirPath, '../../../runtime/vm/service/service.md')));
-  var document = new Document();
-  StringBuffer buf = new StringBuffer(file.readAsStringSync());
+  var document = Document();
+  StringBuffer buf = StringBuffer(file.readAsStringSync());
   var nodes = document.parseLines(buf.toString().split('\n'));
   print('Parsed ${file.path}.');
   print('Service protocol version ${ApiParseUtil.parseVersionString(nodes)}.');
@@ -38,11 +38,11 @@
 
 _generateDart(String appDirPath, List<Node> nodes) async {
   var outDirPath = normalize(join(appDirPath, '..', 'lib/src'));
-  var outDir = new Directory(outDirPath);
+  var outDir = Directory(outDirPath);
   if (!outDir.existsSync()) outDir.createSync(recursive: true);
-  var outputFile = new File(join(outDirPath, 'vm_service.dart'));
-  var generator = new dart.DartGenerator();
-  dart.api = new dart.Api();
+  var outputFile = File(join(outDirPath, 'vm_service.dart'));
+  var generator = dart.DartGenerator();
+  dart.api = dart.Api();
   dart.api.parse(nodes);
   dart.api.generate(generator);
   outputFile.writeAsStringSync(generator.toString());
@@ -66,8 +66,8 @@
 
 _generateJava(String appDirPath, List<Node> nodes) async {
   var srcDirPath = normalize(join(appDirPath, '..', 'java', 'src'));
-  var generator = new java.JavaGenerator(srcDirPath);
-  java.api = new java.Api();
+  var generator = java.JavaGenerator(srcDirPath);
+  java.api = java.Api();
   java.api.parse(nodes);
   java.api.generate(generator);
 
@@ -78,7 +78,7 @@
       .map((path) => relative(path, from: 'java'))
       .toList();
   generatedPaths.sort();
-  File gitignoreFile = new File(join(appDirPath, '..', 'java', '.gitignore'));
+  File gitignoreFile = File(join(appDirPath, '..', 'java', '.gitignore'));
   gitignoreFile.writeAsStringSync('''
 # This is a generated file.
 
@@ -87,7 +87,7 @@
 
   // Generate a version file.
   Version version = ApiParseUtil.parseVersionSemVer(nodes);
-  File file = new File(join('java', 'version.properties'));
+  File file = File(join('java', 'version.properties'));
   file.writeAsStringSync('version=${version.major}.${version.minor}\n');
 
   print('Wrote Java to $srcDirPath.');
@@ -95,11 +95,11 @@
 
 _generateAsserts(String appDirPath, List<Node> nodes) async {
   var outDirPath = normalize(join(appDirPath, '..', 'example'));
-  var outDir = new Directory(outDirPath);
+  var outDir = Directory(outDirPath);
   if (!outDir.existsSync()) outDir.createSync(recursive: true);
-  var outputFile = new File(join(outDirPath, 'vm_service_assert.dart'));
-  var generator = new dart.DartGenerator();
-  dart.api = new dart.Api();
+  var outputFile = File(join(outDirPath, 'vm_service_assert.dart'));
+  var generator = dart.DartGenerator();
+  dart.api = dart.Api();
   dart.api.parse(nodes);
   dart.api.generateAsserts(generator);
   outputFile.writeAsStringSync(generator.toString());
@@ -124,17 +124,17 @@
 // Push the major and minor versions into the pubspec.
 void _stampPubspec(Version version) {
   final String pattern = 'version: ';
-  File file = new File('pubspec.yaml');
+  File file = File('pubspec.yaml');
   String text = file.readAsStringSync();
   bool found = false;
 
   text = text.split('\n').map((line) {
     if (line.startsWith(pattern)) {
       found = true;
-      Version v = new Version.parse(line.substring(pattern.length));
+      Version v = Version.parse(line.substring(pattern.length));
       String pre = v.preRelease.isEmpty ? null : v.preRelease.join('-');
       String build = v.build.isEmpty ? null : v.build.join('+');
-      v = new Version(version.major, version.minor, v.patch,
+      v = Version(version.major, version.minor, v.patch,
           pre: pre, build: build);
       return '${pattern}${v.toString()}';
     } else {
@@ -151,7 +151,7 @@
   // Look for `## major.minor`.
   String check = '## ${version.major}.${version.minor}';
 
-  File file = new File('CHANGELOG.md');
+  File file = File('CHANGELOG.md');
   String text = file.readAsStringSync();
   bool containsReleaseNotes =
       text.split('\n').any((line) => line.startsWith(check));
diff --git a/pkg/vm_service/tool/java/generate_java.dart b/pkg/vm_service/tool/java/generate_java.dart
index 239abcf..6254446 100644
--- a/pkg/vm_service/tool/java/generate_java.dart
+++ b/pkg/vm_service/tool/java/generate_java.dart
@@ -16,7 +16,7 @@
 
 const String servicePackage = 'org.dartlang.vm.service';
 
-const List<String> simpleTypes = const [
+const List<String> simpleTypes = [
   'BigDecimal',
   'boolean',
   'int',
@@ -56,7 +56,7 @@
 /// from spec style of [className] to javadoc style {@link className}
 String convertDocLinks(String doc) {
   if (doc == null) return null;
-  var sb = new StringBuffer();
+  var sb = StringBuffer();
   int start = 0;
   int end = doc.indexOf('[');
   while (end != -1) {
@@ -114,10 +114,10 @@
         return;
       }
     }
-    var f = new TypeField(t, javadoc);
+    var f = TypeField(t, javadoc);
     f.name = propertyName;
-    f.type = new MemberType();
-    f.type.types = [new TypeRef('String')];
+    f.type = MemberType();
+    f.type.types = [TypeRef('String')];
     t.fields.add(f);
     print('added $propertyName field to $typeName');
   }
@@ -186,11 +186,11 @@
       }
 
       writer.addMethod('forwardResponse', [
-        new JavaMethodArg('consumer', 'Consumer'),
-        new JavaMethodArg('responseType', 'String'),
-        new JavaMethodArg('json', 'JsonObject')
+        JavaMethodArg('consumer', 'Consumer'),
+        JavaMethodArg('responseType', 'String'),
+        JavaMethodArg('json', 'JsonObject')
       ], (StatementWriter writer) {
-        var generatedForwards = new Set<String>();
+        var generatedForwards = Set<String>();
 
         var sorted = methods.toList()
           ..sort((m1, m2) {
@@ -210,7 +210,7 @@
       }, modifiers: null, isOverride: true);
 
       writer.addMethod("convertMapToJsonObject", [
-        new JavaMethodArg('map', 'Map<String, String>')
+        JavaMethodArg('map', 'Map<String, String>')
       ], (StatementWriter writer) {
         writer.addLine('JsonObject obj = new JsonObject();');
         writer.addLine('for (String key : map.keySet()) {');
@@ -220,7 +220,7 @@
       }, modifiers: "private", returnType: "JsonObject");
 
       writer.addMethod(
-          "convertIterableToJsonArray", [new JavaMethodArg('list', 'Iterable')],
+          "convertIterableToJsonArray", [JavaMethodArg('list', 'Iterable')],
           (StatementWriter writer) {
         writer.addLine('JsonArray arr = new JsonArray();');
         writer.addLine('for (Object element : list) {');
@@ -307,11 +307,11 @@
     if (docs != null) docs = docs.trim();
 
     if (definition.startsWith('class ')) {
-      types.add(new Type(this, name, definition, docs));
+      types.add(Type(this, name, definition, docs));
     } else if (name.substring(0, 1).toLowerCase() == name.substring(0, 1)) {
-      methods.add(new Method(name, definition, docs));
+      methods.add(Method(name, definition, docs));
     } else if (definition.startsWith('enum ')) {
-      enums.add(new Enum(name, definition, docs));
+      enums.add(Enum(name, definition, docs));
     } else {
       throw 'unexpected entity: ${name}, ${definition}';
     }
@@ -323,8 +323,8 @@
       if (line.startsWith('---')) continue;
       var index = line.indexOf('|');
       var streamId = line.substring(0, index).trim();
-      List<String> eventTypes = new List.from(
-          line.substring(index + 1).split(',').map((t) => t.trim()));
+      List<String> eventTypes =
+          List.from(line.substring(index + 1).split(',').map((t) => t.trim()));
       eventTypes.sort();
       streamIdMap[streamId] = eventTypes;
     }
@@ -366,7 +366,7 @@
   List<EnumValue> enums = [];
 
   Enum(this.name, String definition, [this.docs]) {
-    _parse(new Tokenizer(definition).tokenize());
+    _parse(Tokenizer(definition).tokenize());
   }
 
   String get elementTypeName => '$servicePackage.element.$name';
@@ -387,7 +387,7 @@
   }
 
   void _parse(Token token) {
-    new EnumParser(token).parseInto(this);
+    EnumParser(token).parseInto(this);
   }
 }
 
@@ -409,7 +409,7 @@
       t = expectName();
       consume(',');
 
-      e.enums.add(new EnumValue(e, t.text, docs));
+      e.enums.add(EnumValue(e, t.text, docs));
     }
   }
 }
@@ -473,7 +473,7 @@
       parser.consume('(');
       Token t = parser.expectName();
       if (parser.consume(')')) isMulti = true;
-      TypeRef ref = new TypeRef(_coerceRefType(t.text));
+      TypeRef ref = TypeRef(_coerceRefType(t.text));
       types.add(ref);
 
       while (parser.consume('[')) {
@@ -494,11 +494,11 @@
   final String name;
   final String docs;
 
-  MemberType returnType = new MemberType();
+  MemberType returnType = MemberType();
   List<MethodArg> args = [];
 
   Method(this.name, String definition, [this.docs]) {
-    _parse(new Tokenizer(definition).tokenize());
+    _parse(Tokenizer(definition).tokenize());
   }
 
   String get consumerTypeName {
@@ -522,8 +522,8 @@
       writer.isInterface = true;
       for (var t in returnType.types) {
         writer.addImport(t.elementTypeName);
-        writer.addMethod("received",
-            [new JavaMethodArg('response', t.elementTypeName)], null);
+        writer.addMethod(
+            "received", [JavaMethodArg('response', t.elementTypeName)], null);
       }
     });
   }
@@ -531,7 +531,7 @@
   void generateVmServiceForward(StatementWriter writer) {
     var consumerName = classNameFor(consumerTypeName);
     writer.addLine('if (consumer instanceof $consumerName) {');
-    List<Type> types = new List.from(returnType.types.map((ref) => ref.type));
+    List<Type> types = List.from(returnType.types.map((ref) => ref.type));
     for (int index = 0; index < types.length; ++index) {
       types.addAll(types[index].subtypes);
     }
@@ -557,11 +557,11 @@
 //    }
 
     // Update method docs
-    var javadoc = new StringBuffer(docs == null ? '' : docs);
+    var javadoc = StringBuffer(docs == null ? '' : docs);
     bool firstParamDoc = true;
     for (var a in args) {
       if (!includeOptional && a.optional) continue;
-      var paramDoc = new StringBuffer(a.docs ?? '');
+      var paramDoc = StringBuffer(a.docs ?? '');
       if (paramDoc.isEmpty) {}
       if (a.optional) {
         if (paramDoc.isNotEmpty) paramDoc.write(' ');
@@ -586,9 +586,9 @@
     }
 
     List<JavaMethodArg> javaMethodArgs =
-        new List.from(mthArgs.map((a) => a.asJavaMethodArg));
+        List.from(mthArgs.map((a) => a.asJavaMethodArg));
     javaMethodArgs
-        .add(new JavaMethodArg('consumer', classNameFor(consumerTypeName)));
+        .add(JavaMethodArg('consumer', classNameFor(consumerTypeName)));
     writer.addMethod(name, javaMethodArgs, (StatementWriter writer) {
       writer.addLine('final JsonObject params = new JsonObject();');
       for (MethodArg arg in args) {
@@ -612,7 +612,7 @@
   }
 
   void _parse(Token token) {
-    new MethodParser(token).parseInto(this);
+    MethodParser(token).parseInto(this);
   }
 }
 
@@ -627,15 +627,15 @@
 
   get asJavaMethodArg {
     if (optional && type.ref == 'int') {
-      return new JavaMethodArg(name, 'Integer');
+      return JavaMethodArg(name, 'Integer');
     }
     if (optional && type.ref == 'double') {
-      return new JavaMethodArg(name, 'Double');
+      return JavaMethodArg(name, 'Double');
     }
     if (optional && type.ref == 'boolean') {
-      return new JavaMethodArg(name, 'Boolean');
+      return JavaMethodArg(name, 'Boolean');
     }
-    return new JavaMethodArg(name, type.ref);
+    return JavaMethodArg(name, type.ref);
   }
 
   /// TODO: Hacked enum arg type determination
@@ -659,7 +659,7 @@
 
     while (peek().text != ')') {
       Token type = expectName();
-      TypeRef ref = new TypeRef(_coerceRefType(type.text));
+      TypeRef ref = TypeRef(_coerceRefType(type.text));
       if (peek().text == '[') {
         while (consume('[')) {
           expect(']');
@@ -671,14 +671,13 @@
         ref.genericTypes = [];
         while (peek().text != '>') {
           Token genericTypeName = expectName();
-          ref.genericTypes
-              .add(new TypeRef(_coerceRefType(genericTypeName.text)));
+          ref.genericTypes.add(TypeRef(_coerceRefType(genericTypeName.text)));
           consume(',');
         }
         expect('>');
       }
       Token name = expectName();
-      MethodArg arg = new MethodArg(method, ref, name.text);
+      MethodArg arg = MethodArg(method, ref, name.text);
       if (consume('[')) {
         expect('optional');
         expect(']');
@@ -693,7 +692,7 @@
 }
 
 class TextOutputVisitor implements NodeVisitor {
-  StringBuffer buf = new StringBuffer();
+  StringBuffer buf = StringBuffer();
 
   bool _inRef = false;
 
@@ -735,7 +734,7 @@
   }
 
   static String printText(Node node) {
-    TextOutputVisitor visitor = new TextOutputVisitor();
+    TextOutputVisitor visitor = TextOutputVisitor();
     node.accept(visitor);
     return visitor.toString();
   }
@@ -750,7 +749,7 @@
   List<TypeField> fields = [];
 
   Type(this.parent, String categoryName, String definition, [this.docs]) {
-    _parse(new Tokenizer(definition).tokenize());
+    _parse(Tokenizer(definition).tokenize());
   }
 
   String get elementTypeName {
@@ -785,9 +784,9 @@
       writer.addImport('com.google.gson.JsonObject');
       writer.javadoc = convertDocLinks(docs);
       writer.superclassName = superName ?? 'Element';
-      writer.addConstructor(<JavaMethodArg>[
-        new JavaMethodArg('json', 'com.google.gson.JsonObject')
-      ], (StatementWriter writer) {
+      writer.addConstructor(
+          <JavaMethodArg>[JavaMethodArg('json', 'com.google.gson.JsonObject')],
+          (StatementWriter writer) {
         writer.addLine('super(json);');
       });
 
@@ -832,7 +831,7 @@
   }
 
   void _parse(Token token) {
-    new TypeParser(token).parseInto(this);
+    TypeParser(token).parseInto(this);
   }
 
   void calculateFieldOverrides() {
@@ -862,7 +861,7 @@
 
   final Type parent;
   final String _docs;
-  MemberType type = new MemberType();
+  MemberType type = MemberType();
   String name;
   bool optional = false;
   String defaultValue;
@@ -961,7 +960,7 @@
     expect('{');
 
     while (peek().text != '}') {
-      TypeField field = new TypeField(type, collectComments());
+      TypeField field = TypeField(type, collectComments());
       field.type.parse(this);
       field.name = expectName().text;
       if (consume('[')) {
diff --git a/pkg/vm_service/tool/java/src_gen_java.dart b/pkg/vm_service/tool/java/src_gen_java.dart
index 2e298a6..91b71e2 100644
--- a/pkg/vm_service/tool/java/src_gen_java.dart
+++ b/pkg/vm_service/tool/java/src_gen_java.dart
@@ -50,7 +50,7 @@
   /// The java source directory into which files are generated.
   final String srcDirPath;
 
-  Set<String> _generatedPaths = new Set();
+  Set<String> _generatedPaths = Set();
 
   JavaGenerator(this.srcDirPath);
 
@@ -58,13 +58,13 @@
 
   /// Generate a Java class/interface in the given package
   void writeType(String typeName, WriteType write) {
-    var classWriter = new TypeWriter(typeName);
+    var classWriter = TypeWriter(typeName);
     write(classWriter);
     var pkgDirPath = join(srcDirPath, joinAll(pkgNameFor(typeName).split('.')));
-    var pkgDir = new Directory(pkgDirPath);
+    var pkgDir = Directory(pkgDirPath);
     if (!pkgDir.existsSync()) pkgDir.createSync(recursive: true);
     var classFilePath = join(pkgDirPath, '${classNameFor(typeName)}.java');
-    var classFile = new File(classFilePath);
+    var classFile = File(classFilePath);
     _generatedPaths.add(classFilePath);
     classFile.writeAsStringSync(classWriter.toSource());
   }
@@ -79,7 +79,7 @@
 
 class StatementWriter {
   final TypeWriter typeWriter;
-  final StringBuffer _content = new StringBuffer();
+  final StringBuffer _content = StringBuffer();
 
   StatementWriter(this.typeWriter);
 
@@ -117,12 +117,12 @@
   bool isEnum = false;
   String javadoc;
   String modifiers = 'public';
-  final Set<String> _imports = new Set<String>();
+  final Set<String> _imports = Set<String>();
   String superclassName;
   List<String> interfaceNames = <String>[];
-  final StringBuffer _content = new StringBuffer();
+  final StringBuffer _content = StringBuffer();
   final List<String> _fields = <String>[];
-  final Map<String, String> _methods = new Map<String, String>();
+  final Map<String, String> _methods = Map<String, String>();
 
   TypeWriter(String typeName)
       : this.pkgName = pkgNameFor(typeName),
@@ -150,7 +150,7 @@
     _content.write(')');
     if (write != null) {
       _content.writeln(' {');
-      StatementWriter writer = new StatementWriter(this);
+      StatementWriter writer = StatementWriter(this);
       write(writer);
       _content.write(writer.toSource());
       _content.writeln('  }');
@@ -182,7 +182,7 @@
 
   void addField(String name, String typeName,
       {String modifiers = 'public', String value, String javadoc}) {
-    var fieldDecl = new StringBuffer();
+    var fieldDecl = StringBuffer();
     if (javadoc != null && javadoc.isNotEmpty) {
       fieldDecl.writeln('  /**');
       wrap(javadoc.trim(), colBoundary - 6)
@@ -219,7 +219,7 @@
     String returnType = 'void',
     bool isOverride = false,
   }) {
-    var methodDecl = new StringBuffer();
+    var methodDecl = StringBuffer();
     if (javadoc != null && javadoc.isNotEmpty) {
       methodDecl.writeln('  /**');
       wrap(javadoc.trim(), colBoundary - 6)
@@ -243,7 +243,7 @@
     methodDecl.write(')');
     if (write != null) {
       methodDecl.writeln(' {');
-      StatementWriter writer = new StatementWriter(this);
+      StatementWriter writer = StatementWriter(this);
       write(writer);
       methodDecl.write(writer.toSource());
       methodDecl.writeln('  }');
@@ -258,7 +258,7 @@
   }
 
   String toSource() {
-    var buffer = new StringBuffer();
+    var buffer = StringBuffer();
     if (fileHeader != null) buffer.write(fileHeader);
     if (pkgName != null) {
       buffer.writeln('package $pkgName;');
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 39dec0c..45b625d 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -4,8 +4,6 @@
 
 #include "bin/dfe.h"
 
-#include <memory>
-
 #include "bin/abi_version.h"
 #include "bin/dartutils.h"
 #include "bin/directory.h"
@@ -191,53 +189,54 @@
          (KernelServiceDillAvailable() || (frontend_filename() != nullptr));
 }
 
-class WindowsPathSanitizer {
- public:
-  explicit WindowsPathSanitizer(const char* path) {
-    // For Windows we need to massage the paths a bit according to
-    // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
-    //
-    // Convert
-    // C:\one\two\three
-    // to
-    // /C:/one/two/three
-    //
-    // (see builtin.dart#_sanitizeWindowsPath)
-    intptr_t len = strlen(path);
-    sanitized_uri_ = reinterpret_cast<char*>(malloc(len + 1 + 1));
-    if (sanitized_uri_ == nullptr) {
-      OUT_OF_MEMORY();
-    }
-    char* s = sanitized_uri_;
-    if (len > 2 && path[1] == ':') {
-      *s++ = '/';
-    }
-    for (const char* p = path; *p != '\0'; ++p, ++s) {
-      *s = *p == '\\' ? '/' : *p;
-    }
-    *s = '\0';
+PathSanitizer::PathSanitizer(const char* path) {
+#if defined(HOST_OS_WINDOWS)
+  // For Windows we need to massage the paths a bit according to
+  // http://blogs.msdn.com/b/ie/archive/2006/12/06/file-uris-in-windows.aspx
+  //
+  // Convert
+  // C:\one\two\three
+  // to
+  // /C:/one/two/three
+  //
+  // (see builtin.dart#_sanitizeWindowsPath)
+  if (path == nullptr) {
+    return;
   }
-  ~WindowsPathSanitizer() { free(sanitized_uri_); }
+  intptr_t len = strlen(path);
+  char* uri = reinterpret_cast<char*>(new char[len + 1 + 1]);
+  if (uri == nullptr) {
+    OUT_OF_MEMORY();
+  }
+  char* s = uri;
+  if (len > 2 && path[1] == ':') {
+    *s++ = '/';
+  }
+  for (const char* p = path; *p != '\0'; ++p, ++s) {
+    *s = *p == '\\' ? '/' : *p;
+  }
+  *s = '\0';
+  sanitized_uri_ = std::unique_ptr<char[]>(uri);
+#else
+  sanitized_uri_ = path;
+#endif  // defined(HOST_OS_WINDOWS)
+}
 
-  const char* sanitized_uri() { return sanitized_uri_; }
-
- private:
-  char* sanitized_uri_;
-
-  DISALLOW_COPY_AND_ASSIGN(WindowsPathSanitizer);
-};
+const char* PathSanitizer::sanitized_uri() const {
+#if defined(HOST_OS_WINDOWS)
+  return sanitized_uri_.get();
+#else
+  return sanitized_uri_;
+#endif  // defined(HOST_OS_WINDOWS)
+}
 
 Dart_KernelCompilationResult DFE::CompileScript(const char* script_uri,
                                                 bool incremental,
                                                 const char* package_config) {
   // TODO(aam): When Frontend is ready, VM should be passing vm_outline.dill
   // instead of vm_platform.dill to Frontend for compilation.
-#if defined(HOST_OS_WINDOWS)
-  WindowsPathSanitizer path_sanitizer(script_uri);
+  PathSanitizer path_sanitizer(script_uri);
   const char* sanitized_uri = path_sanitizer.sanitized_uri();
-#else
-  const char* sanitized_uri = script_uri;
-#endif
 
   return Dart_CompileToKernel(
       sanitized_uri, platform_strong_dill_for_compilation_,
diff --git a/runtime/bin/dfe.h b/runtime/bin/dfe.h
index fc33e64..8bcaeaf 100644
--- a/runtime/bin/dfe.h
+++ b/runtime/bin/dfe.h
@@ -5,6 +5,8 @@
 #ifndef RUNTIME_BIN_DFE_H_
 #define RUNTIME_BIN_DFE_H_
 
+#include <memory>
+
 #include "include/dart_api.h"
 #include "include/dart_native_api.h"
 #include "platform/assert.h"
@@ -121,6 +123,21 @@
   DISALLOW_COPY_AND_ASSIGN(DFE);
 };
 
+class PathSanitizer {
+ public:
+  explicit PathSanitizer(const char* path);
+  const char* sanitized_uri() const;
+
+ private:
+#if defined(HOST_OS_WINDOWS)
+  std::unique_ptr<char[]> sanitized_uri_;
+#else
+  const char* sanitized_uri_;
+#endif  // defined(HOST_OS_WINDOWS)
+
+  DISALLOW_COPY_AND_ASSIGN(PathSanitizer);
+};
+
 #if !defined(DART_PRECOMPILED_RUNTIME)
 extern DFE dfe;
 #endif
diff --git a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
index 543f0fe..a80882b 100644
--- a/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
+++ b/runtime/bin/ffi_test/ffi_test_functions_vmspecific.cc
@@ -790,4 +790,126 @@
   dart_enter_isolate(isolate);
 }
 
+////////////////////////////////////////////////////////////////////////////////
+// Functions for handle tests.
+//
+// vmspecific_handle_test.dart
+
+static void RunFinalizer(void* isolate_callback_data,
+                         Dart_WeakPersistentHandle handle,
+                         void* peer) {
+  printf("Running finalizer for weak handle.\n");
+}
+
+// Tests that passing handles through FFI calls works, and that the FFI call
+// sets up the VM state etc. correctly so that the handle API calls work.
+DART_EXPORT Dart_Handle PassObjectToC(Dart_Handle h) {
+  // Can use "h" until this function returns.
+
+  // A persistent handle which outlives this call. Lifetime managed in C.
+  auto persistent_handle = Dart_NewPersistentHandle(h);
+
+  Dart_Handle handle_2 = Dart_HandleFromPersistent(persistent_handle);
+  Dart_DeletePersistentHandle(persistent_handle);
+  if (Dart_IsError(handle_2)) {
+    Dart_PropagateError(handle_2);
+  }
+
+  Dart_Handle return_value;
+  if (!Dart_IsNull(h)) {
+    // A weak handle which outlives this call. Lifetime managed in C.
+    auto weak_handle = Dart_NewWeakPersistentHandle(
+        h, reinterpret_cast<void*>(0x1234), 64, RunFinalizer);
+    return_value = Dart_HandleFromWeakPersistent(weak_handle);
+
+    // Deleting a weak handle is not required, it deletes itself on
+    // finalization.
+    // Deleting a weak handle cancels the finalizer.
+    Dart_DeleteWeakPersistentHandle(weak_handle);
+  } else {
+    return_value = h;
+  }
+
+  return return_value;
+}
+
+DART_EXPORT void ClosureCallbackThroughHandle(void (*callback)(Dart_Handle),
+                                              Dart_Handle closureHandle) {
+  printf("ClosureCallbackThroughHandle %p %p\n", callback, closureHandle);
+  callback(closureHandle);
+}
+
+DART_EXPORT Dart_Handle ReturnHandleInCallback(Dart_Handle (*callback)()) {
+  printf("ReturnHandleInCallback %p\n", callback);
+  Dart_Handle handle = callback();
+  if (Dart_IsError(handle)) {
+    printf("callback() returned an error, propagating error\n");
+    // Do C/C++ resource cleanup if needed, before propagating error.
+    Dart_PropagateError(handle);
+  }
+  return handle;
+}
+
+// Recurses til `i` reaches 0. Throws some Dart_Invoke in there as well.
+DART_EXPORT Dart_Handle HandleRecursion(Dart_Handle object,
+                                        Dart_Handle (*callback)(int64_t),
+                                        int64_t i) {
+  printf("HandleRecursion %" Pd64 "\n", i);
+  const bool do_invoke = i % 3 == 0;
+  const bool do_gc = i % 7 == 3;
+  if (do_gc) {
+    Dart_ExecuteInternalCommand("gc-now", nullptr);
+  }
+  Dart_Handle result;
+  if (do_invoke) {
+    Dart_Handle method_name = Dart_NewStringFromCString("a");
+    if (Dart_IsError(method_name)) {
+      Dart_PropagateError(method_name);
+    }
+    Dart_Handle arg = Dart_NewInteger(i - 1);
+    if (Dart_IsError(arg)) {
+      Dart_PropagateError(arg);
+    }
+    printf("Dart_Invoke\n");
+    result = Dart_Invoke(object, method_name, 1, &arg);
+  } else {
+    printf("callback\n");
+    result = callback(i - 1);
+  }
+  if (do_gc) {
+    Dart_ExecuteInternalCommand("gc-now", nullptr);
+  }
+  if (Dart_IsError(result)) {
+    // Do C/C++ resource cleanup if needed, before propagating error.
+    printf("Dart_PropagateError %" Pd64 "\n", i);
+    Dart_PropagateError(result);
+  }
+  printf("return %" Pd64 "\n", i);
+  return result;
+}
+
+DART_EXPORT int64_t HandleReadFieldValue(Dart_Handle handle) {
+  printf("HandleReadFieldValue\n");
+  Dart_Handle field_name = Dart_NewStringFromCString("a");
+  if (Dart_IsError(field_name)) {
+    printf("Dart_PropagateError(field_name)\n");
+    Dart_PropagateError(field_name);
+  }
+  Dart_Handle field_value = Dart_GetField(handle, field_name);
+  if (Dart_IsError(field_value)) {
+    printf("Dart_PropagateError(field_value)\n");
+    Dart_PropagateError(field_value);
+  }
+  int64_t value;
+  Dart_Handle err = Dart_IntegerToInt64(field_value, &value);
+  if (Dart_IsError(err)) {
+    Dart_PropagateError(err);
+  }
+  return value;
+}
+
+DART_EXPORT Dart_Handle TrueHandle() {
+  return Dart_True();
+}
+
 }  // namespace dart
diff --git a/runtime/bin/file_win.cc b/runtime/bin/file_win.cc
index d5d6529..ff32a17 100644
--- a/runtime/bin/file_win.cc
+++ b/runtime/bin/file_win.cc
@@ -17,7 +17,6 @@
 #include <sys/utime.h>  // NOLINT
 
 #include "bin/builtin.h"
-#include "bin/crypto.h"
 #include "bin/directory.h"
 #include "bin/namespace.h"
 #include "bin/utils.h"
@@ -504,85 +503,6 @@
   return (move_status != 0);
 }
 
-static wchar_t* CopyToDartScopeString(wchar_t* string) {
-  wchar_t* wide_path = reinterpret_cast<wchar_t*>(
-      Dart_ScopeAllocate(MAX_PATH * sizeof(wchar_t) + 1));
-  wcscpy(wide_path, string);
-  return wide_path;
-}
-
-static wchar_t* CopyIntoTempFile(const char* src, const char* dest) {
-  // This function will copy the file to a temp file in the destination
-  // directory and return the path of temp file.
-  // Creating temp file name has the same logic as Directory::CreateTemp(),
-  // which tries with the rng and falls back to a uuid if it failed.
-  const char* last_backslash = strrchr(dest, '\\');
-  if (last_backslash == NULL) {
-    return NULL;
-  }
-  int length_of_parent_dir = last_backslash - dest + 1;
-  if (length_of_parent_dir + 8 > MAX_PATH) {
-    return NULL;
-  }
-  uint32_t suffix_bytes = 0;
-  const int kSuffixSize = sizeof(suffix_bytes);
-  if (Crypto::GetRandomBytes(kSuffixSize,
-                             reinterpret_cast<uint8_t*>(&suffix_bytes))) {
-    PathBuffer buffer;
-    char* dir = reinterpret_cast<char*>(
-        Dart_ScopeAllocate(1 + sizeof(char) * length_of_parent_dir));
-    memmove(dir, dest, length_of_parent_dir);
-    dir[length_of_parent_dir] = '\0';
-    if (!buffer.Add(dir)) {
-      return NULL;
-    }
-
-    char suffix[8 + 1];
-    Utils::SNPrint(suffix, sizeof(suffix), "%x", suffix_bytes);
-    Utf8ToWideScope source_path(src);
-    if (!buffer.Add(suffix)) {
-      return NULL;
-    }
-    if (CopyFileExW(source_path.wide(), buffer.AsStringW(), NULL, NULL, NULL,
-                    0) != 0) {
-      return CopyToDartScopeString(buffer.AsStringW());
-    }
-  }
-  // UUID has a total of 36 characters in the form of
-  // xxxxxxxx-xxxx-Mxxx-Nxxx-xxxxxxxxxxxx.
-  if (length_of_parent_dir + 36 > MAX_PATH) {
-    return NULL;
-  }
-  UUID uuid;
-  RPC_STATUS status = UuidCreateSequential(&uuid);
-  if ((status != RPC_S_OK) && (status != RPC_S_UUID_LOCAL_ONLY)) {
-    return NULL;
-  }
-  RPC_WSTR uuid_string;
-  status = UuidToStringW(&uuid, &uuid_string);
-  if (status != RPC_S_OK) {
-    return NULL;
-  }
-  PathBuffer buffer;
-  char* dir = reinterpret_cast<char*>(
-      Dart_ScopeAllocate(1 + sizeof(char) * length_of_parent_dir));
-  memmove(dir, dest, length_of_parent_dir);
-  dir[length_of_parent_dir] = '\0';
-  Utf8ToWideScope dest_path(dir);
-  if (!buffer.AddW(dest_path.wide()) ||
-      !buffer.AddW(reinterpret_cast<wchar_t*>(uuid_string))) {
-    return NULL;
-  }
-
-  RpcStringFreeW(&uuid_string);
-  Utf8ToWideScope source_path(src);
-  if (CopyFileExW(source_path.wide(), buffer.AsStringW(), NULL, NULL, NULL,
-                  0) != 0) {
-    return CopyToDartScopeString(buffer.AsStringW());
-  }
-  return NULL;
-}
-
 bool File::Copy(Namespace* namespc,
                 const char* old_path,
                 const char* new_path) {
@@ -591,23 +511,11 @@
     SetLastError(ERROR_FILE_NOT_FOUND);
     return false;
   }
-
-  wchar_t* temp_file = CopyIntoTempFile(old_path, new_path);
-  if (temp_file == NULL) {
-    return false;
-  }
-  Utf8ToWideScope system_new_dest(new_path);
-
-  // Remove the existing file. Otherwise, renaming will fail.
-  if (Exists(namespc, new_path)) {
-    DeleteFileW(system_new_dest.wide());
-  }
-
-  if (!MoveFileW(temp_file, system_new_dest.wide())) {
-    DeleteFileW(temp_file);
-    return false;
-  }
-  return true;
+  Utf8ToWideScope system_old_path(old_path);
+  Utf8ToWideScope system_new_path(new_path);
+  bool success = CopyFileExW(system_old_path.wide(), system_new_path.wide(),
+                             NULL, NULL, NULL, 0) != 0;
+  return success;
 }
 
 int64_t File::LengthFromPath(Namespace* namespc, const char* name) {
diff --git a/runtime/bin/gen_snapshot.cc b/runtime/bin/gen_snapshot.cc
index 3598a3c..afbc896 100644
--- a/runtime/bin/gen_snapshot.cc
+++ b/runtime/bin/gen_snapshot.cc
@@ -664,6 +664,9 @@
 
   Dart_IsolateFlags isolate_flags;
   Dart_IsolateFlagsInitialize(&isolate_flags);
+  isolate_flags.null_safety =
+      Dart_DetectNullSafety(nullptr, nullptr, nullptr, nullptr, nullptr,
+                            kernel_buffer, kernel_buffer_size);
   if (IsSnapshottingForPrecompilation()) {
     isolate_flags.obfuscate = obfuscate;
     isolate_flags.entry_points = no_entry_points;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 3a49f5d..e99d675 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -599,6 +599,9 @@
   const uint8_t* isolate_snapshot_data = app_isolate_snapshot_data;
   const uint8_t* isolate_snapshot_instructions =
       app_isolate_snapshot_instructions;
+  flags->null_safety =
+      Dart_DetectNullSafety(nullptr, nullptr, nullptr, isolate_snapshot_data,
+                            isolate_snapshot_instructions, nullptr, -1);
 #else
   // JIT: Main isolate starts from the app snapshot, if any. Other isolates
   // use the core libraries snapshot.
@@ -635,6 +638,13 @@
   if (kernel_buffer == NULL && !isolate_run_app_snapshot) {
     dfe.ReadScript(script_uri, &kernel_buffer, &kernel_buffer_size);
   }
+  PathSanitizer script_uri_sanitizer(script_uri);
+  PathSanitizer packages_config_sanitizer(packages_config);
+  flags->null_safety = Dart_DetectNullSafety(
+      script_uri_sanitizer.sanitized_uri(),
+      packages_config_sanitizer.sanitized_uri(),
+      DartUtils::original_working_directory, isolate_snapshot_data,
+      isolate_snapshot_instructions, kernel_buffer, kernel_buffer_size);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
   auto isolate_group_data = new IsolateGroupData(
diff --git a/runtime/bin/stdio_android.cc b/runtime/bin/stdio_android.cc
index 2999118..f019f25 100644
--- a/runtime/bin/stdio_android.cc
+++ b/runtime/bin/stdio_android.cc
@@ -77,16 +77,18 @@
   return (status == 0);
 }
 
-static bool TermHasXTerm() {
+static bool TermIsKnownToSupportAnsi() {
   const char* term = getenv("TERM");
   if (term == NULL) {
     return false;
   }
-  return strstr(term, "xterm") != NULL;
+
+  return strstr(term, "xterm") != NULL || strstr(term, "screen") != NULL ||
+         strstr(term, "rxvt") != NULL;
 }
 
 bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = isatty(fd) && TermHasXTerm();
+  *supported = isatty(fd) && TermIsKnownToSupportAnsi();
   return true;
 }
 
@@ -102,7 +104,7 @@
 }
 
 bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = isatty(fd) && TermHasXTerm();
+  *supported = isatty(fd) && TermIsKnownToSupportAnsi();
   return true;
 }
 
diff --git a/runtime/bin/stdio_linux.cc b/runtime/bin/stdio_linux.cc
index 2ed9a90..50e25f3 100644
--- a/runtime/bin/stdio_linux.cc
+++ b/runtime/bin/stdio_linux.cc
@@ -77,16 +77,18 @@
   return (status == 0);
 }
 
-static bool TermHasXTerm() {
+static bool TermIsKnownToSupportAnsi() {
   const char* term = getenv("TERM");
   if (term == NULL) {
     return false;
   }
-  return strstr(term, "xterm") != NULL;
+
+  return strstr(term, "xterm") != NULL || strstr(term, "screen") != NULL ||
+         strstr(term, "rxvt") != NULL;
 }
 
 bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = (isatty(fd) != 0) && TermHasXTerm();
+  *supported = (isatty(fd) != 0) && TermIsKnownToSupportAnsi();
   return true;
 }
 
@@ -102,7 +104,7 @@
 }
 
 bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = (isatty(fd) != 0) && TermHasXTerm();
+  *supported = (isatty(fd) != 0) && TermIsKnownToSupportAnsi();
   return true;
 }
 
diff --git a/runtime/bin/stdio_macos.cc b/runtime/bin/stdio_macos.cc
index b81e352..3b1aa5e 100644
--- a/runtime/bin/stdio_macos.cc
+++ b/runtime/bin/stdio_macos.cc
@@ -77,16 +77,18 @@
   return (status == 0);
 }
 
-static bool TermHasXTerm() {
+static bool TermIsKnownToSupportAnsi() {
   const char* term = getenv("TERM");
   if (term == NULL) {
     return false;
   }
-  return strstr(term, "xterm") != NULL;
+
+  return strstr(term, "xterm") != NULL || strstr(term, "screen") != NULL ||
+         strstr(term, "rxvt") != NULL;
 }
 
 bool Stdin::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = isatty(fd) && TermHasXTerm();
+  *supported = isatty(fd) && TermIsKnownToSupportAnsi();
   return true;
 }
 
@@ -102,7 +104,7 @@
 }
 
 bool Stdout::AnsiSupported(intptr_t fd, bool* supported) {
-  *supported = isatty(fd) && TermHasXTerm();
+  *supported = isatty(fd) && TermIsKnownToSupportAnsi();
   return true;
 }
 
diff --git a/runtime/docs/gc.md b/runtime/docs/gc.md
index 8e6d463..ad3c964 100644
--- a/runtime/docs/gc.md
+++ b/runtime/docs/gc.md
@@ -67,7 +67,7 @@
 
 The barrier is equivalent to
 
-```
+```c++
 StorePoint(RawObject* source, RawObject** slot, RawObject* target) {
   *slot = target;
   if (target->IsSmi()) return;
@@ -84,7 +84,7 @@
 
 But we combine the generational and incremental checks with a shift-and-mask.
 
-```
+```c++
 enum HeaderBits {
   ...
   kOldAndNotMarkedBit,      // Incremental barrier target.
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 6a1a401..0e43ad9 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -532,6 +532,7 @@
   Dart_QualifiedFunctionName* entry_points;
   bool load_vmservice_library;
   bool copy_parent_code;
+  bool null_safety;
 } Dart_IsolateFlags;
 
 /**
@@ -3313,8 +3314,8 @@
 
 typedef struct {
   Dart_KernelCompilationStatus status;
+  bool null_safety;
   char* error;
-
   uint8_t* kernel;
   intptr_t kernel_size;
 } Dart_KernelCompilationResult;
@@ -3370,6 +3371,49 @@
     const uint8_t* platform_kernel,
     const intptr_t platform_kernel_size);
 
+/**
+ * Detect the null safety opt-in status.
+ *
+ * When running from source, it is based on the opt-in status of `script_uri`.
+ * When running from a kernel buffer, it is based on the mode used when
+ *   generating `kernel_buffer`.
+ * When running from an appJIT or AOT snapshot, it is based on the mode used
+ *   when generating `snapshot_data`.
+ *
+ * \param script_uri Uri of the script that contains the source code
+ *
+ * \param package_config Uri of the package configuration file (either in format
+ *   of .packages or .dart_tool/package_config.json) for the null safety
+ *   detection to resolve package imports against. If this parameter is not
+ *   passed the package resolution of the parent isolate should be used.
+ *
+ * \param original_working_directory current working directory when the VM
+ *   process was launched, this is used to correctly resolve the path specified
+ *   for package_config.
+ *
+ * \param snapshot_data
+ *
+ * \param snapshot_instructions Buffers containing a snapshot of the
+ *   isolate or NULL if no snapshot is provided. If provided, the buffers must
+ *   remain valid until the isolate shuts down.
+ *
+ * \param kernel_buffer
+ *
+ * \param kernel_buffer_size A buffer which contains a kernel/DIL program. Must
+ *   remain valid until isolate shutdown.
+ *
+ * \return Returns true if the null safety is opted in by the input being
+ *   run `script_uri`, `snapshot_data` or `kernel_buffer`.
+ *
+ */
+DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
+                                       const char* package_config,
+                                       const char* original_working_directory,
+                                       const uint8_t* snapshot_data,
+                                       const uint8_t* snapshot_instructions,
+                                       const uint8_t* kernel_buffer,
+                                       intptr_t kernel_buffer_size);
+
 #define DART_KERNEL_ISOLATE_NAME "kernel-service"
 
 /*
diff --git a/runtime/lib/object.cc b/runtime/lib/object.cc
index 6cb94cc..04afec9 100644
--- a/runtime/lib/object.cc
+++ b/runtime/lib/object.cc
@@ -196,6 +196,19 @@
   return Bool::Get(type.IsEquivalent(other, TypeEquality::kSyntactical)).raw();
 }
 
+DEFINE_NATIVE_ENTRY(LibraryPrefix_isLoaded, 0, 1) {
+  const LibraryPrefix& prefix =
+      LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
+  return Bool::Get(prefix.is_loaded()).raw();
+}
+
+DEFINE_NATIVE_ENTRY(LibraryPrefix_setLoaded, 0, 1) {
+  const LibraryPrefix& prefix =
+      LibraryPrefix::CheckedHandle(zone, arguments->NativeArgAt(0));
+  prefix.set_is_loaded(true);
+  return Instance::null();
+}
+
 DEFINE_NATIVE_ENTRY(Internal_inquireIs64Bit, 0, 0) {
 #if defined(ARCH_IS_64_BIT)
   return Bool::True().raw();
diff --git a/runtime/observatory/tests/service/string_escaping_test.dart b/runtime/observatory/tests/service/string_escaping_test.dart
index 8a11dfb..31729de 100644
--- a/runtime/observatory/tests/service/string_escaping_test.dart
+++ b/runtime/observatory/tests/service/string_escaping_test.dart
@@ -65,7 +65,6 @@
   expectTruncatedString(String varName, String varValueAsString) {
     Field field = lib.variables.singleWhere((v) => v.name == varName);
     Instance value = field.staticValue;
-    print(value.valueAsString);
     expect(varValueAsString, startsWith(value.valueAsString));
     expect(value.valueAsStringIsTruncated, isTrue);
   }
diff --git a/runtime/platform/globals.h b/runtime/platform/globals.h
index 091ad8fd..0ec560e 100644
--- a/runtime/platform/globals.h
+++ b/runtime/platform/globals.h
@@ -459,6 +459,8 @@
 const uint32_t kMaxUint32 = 0xFFFFFFFF;
 const int64_t kMinInt64 = DART_INT64_C(0x8000000000000000);
 const int64_t kMaxInt64 = DART_INT64_C(0x7FFFFFFFFFFFFFFF);
+const int kMinInt = INT_MIN;
+const int kMaxInt = INT_MAX;
 const int64_t kMinInt64RepresentableAsDouble = kMinInt64;
 const int64_t kMaxInt64RepresentableAsDouble = DART_INT64_C(0x7FFFFFFFFFFFFC00);
 const uint64_t kMaxUint64 = DART_2PART_UINT64_C(0xFFFFFFFF, FFFFFFFF);
diff --git a/runtime/tests/vm/dart/thread_priority_linux_test.dart b/runtime/tests/vm/dart/thread_priority_linux_test.dart
new file mode 100644
index 0000000..63a9168
--- /dev/null
+++ b/runtime/tests/vm/dart/thread_priority_linux_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// VMOptions=--worker-thread-priority=12
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+// Value of "PRIO_PROCESS".
+const int kPrioProcess = 0;
+const int kCurrentThreadId = 0;
+
+// int getpriority(int which, id_t who)
+typedef GetPriorityFT = int Function(int which, int who);
+typedef GetPriorityNFT = Int32 Function(Int32 which, Uint32 who);
+
+final getPriority = DynamicLibrary.process()
+    .lookupFunction<GetPriorityNFT, GetPriorityFT>('getpriority');
+
+main(args) {
+  if (Platform.isLinux || Platform.isAndroid) {
+    Expect.equals(12, getPriority(kPrioProcess, kCurrentThreadId));
+  }
+}
diff --git a/runtime/tests/vm/dart/thread_priority_macos_test.dart b/runtime/tests/vm/dart/thread_priority_macos_test.dart
new file mode 100644
index 0000000..b466eb0
--- /dev/null
+++ b/runtime/tests/vm/dart/thread_priority_macos_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.
+
+// VMOptions=--worker-thread-priority=15
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+// pthread_t pthread_self()
+typedef PthreadSelfFT = int Function();
+typedef PthreadSelfNFT = IntPtr Function();
+
+// int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
+typedef GetSchedParamFT = int Function(
+    int self, Pointer<Int32> policy, Pointer<SchedParam> param);
+typedef GetSchedParamNFT = IntPtr Function(
+    IntPtr self, Pointer<Int32> policy, Pointer<SchedParam> param);
+
+final pthreadSelf = DynamicLibrary.process()
+    .lookupFunction<PthreadSelfNFT, PthreadSelfFT>('pthread_self');
+
+final pthreadGetSchedParam = DynamicLibrary.process()
+    .lookupFunction<GetSchedParamNFT, GetSchedParamFT>('pthread_getschedparam');
+
+//  struct sched_param { int sched_priority; }
+class SchedParam extends Struct {
+  @Int32()
+  int schedPriority;
+}
+
+main(args) {
+  if (Platform.isMacOS) {
+    final policy = allocate<Int32>(count: 1);
+    final param = allocate<SchedParam>(count: 1);
+    Expect.equals(0, pthreadGetSchedParam(pthreadSelf(), policy, param));
+    Expect.equals(15, param.ref.schedPriority);
+    free(policy);
+    free(param);
+  }
+}
diff --git a/runtime/tests/vm/dart/thread_priority_windows_test.dart b/runtime/tests/vm/dart/thread_priority_windows_test.dart
new file mode 100644
index 0000000..a1c31f7
--- /dev/null
+++ b/runtime/tests/vm/dart/thread_priority_windows_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// VMOptions=--worker-thread-priority=-2
+// A priority of -2 means THREAD_PRIORITY_LOWEST on windows
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+final DynamicLibrary kernel32 = DynamicLibrary.open("kernel32.dll");
+
+// HANDLE GetCurrentThread();
+typedef GetCurrentThreadFT = int Function();
+typedef GetCurrentThreadNFT = IntPtr Function();
+
+// int GetThreadPriority(HANDLE hThread);
+typedef GetThreadPriorityFT = int Function(int handle);
+typedef GetThreadPriorityNFT = Int32 Function(IntPtr handle);
+
+final getCurrentThread =
+    kernel32.lookupFunction<GetCurrentThreadNFT, GetCurrentThreadFT>(
+        'GetCurrentThread');
+final getThreadPriority =
+    kernel32.lookupFunction<GetThreadPriorityNFT, GetThreadPriorityFT>(
+        'GetThreadPriority');
+
+main(args) {
+  if (Platform.isWindows) {
+    Expect.equals(-2, getThreadPriority(getCurrentThread()));
+  }
+}
diff --git a/runtime/tests/vm/dart_2/thread_priority_linux_test.dart b/runtime/tests/vm/dart_2/thread_priority_linux_test.dart
new file mode 100644
index 0000000..63a9168
--- /dev/null
+++ b/runtime/tests/vm/dart_2/thread_priority_linux_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// VMOptions=--worker-thread-priority=12
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+// Value of "PRIO_PROCESS".
+const int kPrioProcess = 0;
+const int kCurrentThreadId = 0;
+
+// int getpriority(int which, id_t who)
+typedef GetPriorityFT = int Function(int which, int who);
+typedef GetPriorityNFT = Int32 Function(Int32 which, Uint32 who);
+
+final getPriority = DynamicLibrary.process()
+    .lookupFunction<GetPriorityNFT, GetPriorityFT>('getpriority');
+
+main(args) {
+  if (Platform.isLinux || Platform.isAndroid) {
+    Expect.equals(12, getPriority(kPrioProcess, kCurrentThreadId));
+  }
+}
diff --git a/runtime/tests/vm/dart_2/thread_priority_macos_test.dart b/runtime/tests/vm/dart_2/thread_priority_macos_test.dart
new file mode 100644
index 0000000..b466eb0
--- /dev/null
+++ b/runtime/tests/vm/dart_2/thread_priority_macos_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.
+
+// VMOptions=--worker-thread-priority=15
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+import 'package:ffi/ffi.dart';
+
+// pthread_t pthread_self()
+typedef PthreadSelfFT = int Function();
+typedef PthreadSelfNFT = IntPtr Function();
+
+// int pthread_getschedparam(pthread_t thread, int *policy, struct sched_param *param);
+typedef GetSchedParamFT = int Function(
+    int self, Pointer<Int32> policy, Pointer<SchedParam> param);
+typedef GetSchedParamNFT = IntPtr Function(
+    IntPtr self, Pointer<Int32> policy, Pointer<SchedParam> param);
+
+final pthreadSelf = DynamicLibrary.process()
+    .lookupFunction<PthreadSelfNFT, PthreadSelfFT>('pthread_self');
+
+final pthreadGetSchedParam = DynamicLibrary.process()
+    .lookupFunction<GetSchedParamNFT, GetSchedParamFT>('pthread_getschedparam');
+
+//  struct sched_param { int sched_priority; }
+class SchedParam extends Struct {
+  @Int32()
+  int schedPriority;
+}
+
+main(args) {
+  if (Platform.isMacOS) {
+    final policy = allocate<Int32>(count: 1);
+    final param = allocate<SchedParam>(count: 1);
+    Expect.equals(0, pthreadGetSchedParam(pthreadSelf(), policy, param));
+    Expect.equals(15, param.ref.schedPriority);
+    free(policy);
+    free(param);
+  }
+}
diff --git a/runtime/tests/vm/dart_2/thread_priority_windows_test.dart b/runtime/tests/vm/dart_2/thread_priority_windows_test.dart
new file mode 100644
index 0000000..a1c31f7
--- /dev/null
+++ b/runtime/tests/vm/dart_2/thread_priority_windows_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// VMOptions=--worker-thread-priority=-2
+// A priority of -2 means THREAD_PRIORITY_LOWEST on windows
+
+import 'dart:ffi';
+import 'dart:io';
+
+import 'package:expect/expect.dart';
+
+final DynamicLibrary kernel32 = DynamicLibrary.open("kernel32.dll");
+
+// HANDLE GetCurrentThread();
+typedef GetCurrentThreadFT = int Function();
+typedef GetCurrentThreadNFT = IntPtr Function();
+
+// int GetThreadPriority(HANDLE hThread);
+typedef GetThreadPriorityFT = int Function(int handle);
+typedef GetThreadPriorityNFT = Int32 Function(IntPtr handle);
+
+final getCurrentThread =
+    kernel32.lookupFunction<GetCurrentThreadNFT, GetCurrentThreadFT>(
+        'GetCurrentThread');
+final getThreadPriority =
+    kernel32.lookupFunction<GetThreadPriorityNFT, GetThreadPriorityFT>(
+        'GetThreadPriority');
+
+main(args) {
+  if (Platform.isWindows) {
+    Expect.equals(-2, getThreadPriority(getCurrentThread()));
+  }
+}
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 0643940..0f68bb2 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -33,6 +33,18 @@
 dart_2/stack_overflow_shared_test: Pass, Slow # Uses --shared-slow-path-triggers-gc flag.
 dart_2/use_bare_instructions_flag_test: Pass, Slow # Spawns several subprocesses
 
+[ $system != macos || $arch == simarm || $arch == simarm64 ]
+dart/thread_priority_macos_test: SkipByDesign
+dart_2/thread_priority_macos_test: SkipByDesign
+
+[ ($system != linux && $system != android) || $arch == simarm || $arch == simarm64 ]
+dart/thread_priority_linux_test: SkipByDesign
+dart_2/thread_priority_linux_test: SkipByDesign
+
+[ $system != windows || $arch == simarm || $arch == simarm64 ]
+dart/thread_priority_windows_test: SkipByDesign
+dart_2/thread_priority_windows_test: SkipByDesign
+
 [ $runtime != dart_precompiled || $system == android ]
 dart/isolates/fibonacci_call_ig_test: Skip # Only AOT has lightweight enough isolates to run those tests, JIT work is pending.
 dart/isolates/fibonacci_call_test: Skip # Only AOT has lightweight enough isolates to run those tests.
diff --git a/runtime/vm/bootstrap.cc b/runtime/vm/bootstrap.cc
index 62be369..57445f7 100644
--- a/runtime/vm/bootstrap.cc
+++ b/runtime/vm/bootstrap.cc
@@ -109,7 +109,6 @@
 
   LongJumpScope jump;
   if (setjmp(*jump.Set()) == 0) {
-    program->AutoDetectNullSafety(thread->isolate());
     kernel::KernelLoader loader(program.get(), /*uri_to_source_table=*/nullptr);
 
     Isolate* isolate = thread->isolate();
diff --git a/runtime/vm/bootstrap_natives.h b/runtime/vm/bootstrap_natives.h
index 2460846..6ce5668 100644
--- a/runtime/vm/bootstrap_natives.h
+++ b/runtime/vm/bootstrap_natives.h
@@ -31,6 +31,8 @@
   V(AbstractType_toString, 1)                                                  \
   V(Type_getHashCode, 1)                                                       \
   V(Type_equality, 2)                                                          \
+  V(LibraryPrefix_isLoaded, 1)                                                 \
+  V(LibraryPrefix_setLoaded, 1)                                                \
   V(Identical_comparison, 2)                                                   \
   V(Integer_bitAndFromInteger, 2)                                              \
   V(Integer_bitOrFromInteger, 2)                                               \
diff --git a/runtime/vm/bss_relocs.cc b/runtime/vm/bss_relocs.cc
index 2ca72c5..80f50f5 100644
--- a/runtime/vm/bss_relocs.cc
+++ b/runtime/vm/bss_relocs.cc
@@ -15,6 +15,12 @@
   std::atomic<uword>* slot = reinterpret_cast<std::atomic<uword>*>(
       &bss_start[BSS::RelocationIndex(relocation)]);
   uword old_value = slot->load(std::memory_order_relaxed);
+  // FullSnapshotReader::ReadProgramSnapshot, and thus BSS::Initialize, can
+  // get called multiple times for the same isolate in different threads, though
+  // the initialized value will be consistent and thus change only once. Avoid
+  // calling compare_exchange_strong unless we actually need to change the
+  // value, to avoid spurious read/write races by TSAN.
+  if (old_value == new_value) return;
   if (!slot->compare_exchange_strong(old_value, new_value,
                                      std::memory_order_relaxed)) {
     RELEASE_ASSERT(old_value == new_value);
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index 324c51c..7531621 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -300,13 +300,13 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-void ClassFinalizer::FinalizeTypeParameters(const Class& cls,
-                                            PendingTypes* pending_types) {
+void ClassFinalizer::FinalizeTypeParameters(const Class& cls) {
   if (FLAG_trace_type_finalization) {
     THR_Print("Finalizing type parameters of '%s'\n",
               String::Handle(cls.Name()).ToCString());
   }
   // The type parameter bounds are not finalized here.
+  const intptr_t offset = cls.NumTypeArguments() - cls.NumTypeParameters();
   const TypeArguments& type_parameters =
       TypeArguments::Handle(cls.type_parameters());
   if (!type_parameters.IsNull()) {
@@ -314,9 +314,13 @@
     const intptr_t num_types = type_parameters.Length();
     for (intptr_t i = 0; i < num_types; i++) {
       type_parameter ^= type_parameters.TypeAt(i);
-      type_parameter ^=
-          FinalizeType(cls, type_parameter, kFinalize, pending_types);
-      type_parameters.SetTypeAt(i, type_parameter);
+      if (!type_parameter.IsFinalized()) {
+        type_parameter.set_index(type_parameter.index() + offset);
+        type_parameter.SetIsFinalized();
+      }
+      // The declaration of a type parameter is canonical.
+      ASSERT(type_parameter.IsDeclaration());
+      ASSERT(type_parameter.IsCanonical());
     }
   }
 }
@@ -425,7 +429,7 @@
   Class& type_class = Class::Handle(zone, type.type_class());
   type_class.EnsureDeclarationLoaded();
   if (!type_class.is_type_finalized()) {
-    FinalizeTypeParameters(type_class, pending_types);
+    FinalizeTypeParameters(type_class);
   }
 
   // The finalized type argument vector needs num_type_arguments types.
@@ -559,7 +563,7 @@
                                            TrailPtr trail) {
   ASSERT(arguments.Length() >= cls.NumTypeArguments());
   if (!cls.is_type_finalized()) {
-    FinalizeTypeParameters(cls, pending_types);
+    FinalizeTypeParameters(cls);
   }
   AbstractType& super_type = AbstractType::Handle(cls.super_type());
   if (!super_type.IsNull()) {
@@ -677,8 +681,7 @@
   ASSERT((pending_types == NULL) || (finalization < kCanonicalize));
   if (type.IsFinalized()) {
     // Ensure type is canonical if canonicalization is requested.
-    if ((finalization >= kCanonicalize) && !type.IsCanonical() &&
-        type.IsType()) {
+    if ((finalization >= kCanonicalize) && !type.IsCanonical()) {
       return type.Canonicalize();
     }
     return type.raw();
@@ -731,8 +734,12 @@
                 type_parameter.index());
     }
 
-    // We do not canonicalize type parameters.
-    return type_parameter.raw();
+    if (type_parameter.IsDeclaration()) {
+      // The declaration of a type parameter is canonical.
+      ASSERT(type_parameter.IsCanonical());
+      return type_parameter.raw();
+    }
+    return type_parameter.Canonicalize();
   }
 
   // At this point, we can only have a Type.
@@ -846,6 +853,12 @@
         type_param.set_index(num_parent_type_params + i);
         type_param.SetIsFinalized();
       }
+      // The declaration of a type parameter is canonical.
+      ASSERT(type_param.IsDeclaration());
+      ASSERT(type_param.IsCanonical());
+    }
+    for (intptr_t i = 0; i < num_type_params; i++) {
+      type_param ^= type_params.TypeAt(i);
       type = type_param.bound();
       finalized_type = FinalizeType(cls, type, finalization);
       if (finalized_type.raw() != type.raw()) {
@@ -1586,6 +1599,7 @@
 // Usages of canonical hash codes are:
 //
 //   * ObjectStore::canonical_types()
+//   * ObjectStore::canonical_type_parameters()
 //   * ObjectStore::canonical_type_arguments()
 //   * Class::constants()
 //
@@ -1629,23 +1643,17 @@
 
   // Rehash the canonical Types table.
   ObjectStore* object_store = I->object_store();
-  GrowableObjectArray& types =
-      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
-  Array& types_array = Array::Handle(Z);
+  Array& types = Array::Handle(Z);
   Type& type = Type::Handle(Z);
   {
     CanonicalTypeSet types_table(Z, object_store->canonical_types());
-    types_array = HashTables::ToArray(types_table, false);
-    for (intptr_t i = 0; i < types_array.Length(); i++) {
-      type ^= types_array.At(i);
-      types.Add(type);
-    }
+    types = HashTables::ToArray(types_table, false);
     types_table.Release();
   }
 
   intptr_t dict_size = Utils::RoundUpToPowerOfTwo(types.Length() * 4 / 3);
-  types_array = HashTables::New<CanonicalTypeSet>(dict_size, Heap::kOld);
-  CanonicalTypeSet types_table(Z, types_array.raw());
+  CanonicalTypeSet types_table(
+      Z, HashTables::New<CanonicalTypeSet>(dict_size, Heap::kOld));
   for (intptr_t i = 0; i < types.Length(); i++) {
     type ^= types.At(i);
     bool present = types_table.Insert(type);
@@ -1654,19 +1662,33 @@
   }
   object_store->set_canonical_types(types_table.Release());
 
+  // Rehash the canonical TypeParameters table.
+  Array& typeparams = Array::Handle(Z);
+  TypeParameter& typeparam = TypeParameter::Handle(Z);
+  {
+    CanonicalTypeParameterSet typeparams_table(
+        Z, object_store->canonical_type_parameters());
+    typeparams = HashTables::ToArray(typeparams_table, false);
+    typeparams_table.Release();
+  }
+
+  dict_size = Utils::RoundUpToPowerOfTwo(typeparams.Length() * 4 / 3);
+  CanonicalTypeParameterSet typeparams_table(
+      Z, HashTables::New<CanonicalTypeParameterSet>(dict_size, Heap::kOld));
+  for (intptr_t i = 0; i < typeparams.Length(); i++) {
+    typeparam ^= typeparams.At(i);
+    bool present = typeparams_table.Insert(typeparam);
+    ASSERT(!present);
+  }
+  object_store->set_canonical_type_parameters(typeparams_table.Release());
+
   // Rehash the canonical TypeArguments table.
-  Array& typeargs_array = Array::Handle(Z);
-  GrowableObjectArray& typeargs =
-      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  Array& typeargs = Array::Handle(Z);
   TypeArguments& typearg = TypeArguments::Handle(Z);
   {
     CanonicalTypeArgumentsSet typeargs_table(
         Z, object_store->canonical_type_arguments());
-    typeargs_array = HashTables::ToArray(typeargs_table, false);
-    for (intptr_t i = 0; i < typeargs_array.Length(); i++) {
-      typearg ^= typeargs_array.At(i);
-      typeargs.Add(typearg);
-    }
+    typeargs = HashTables::ToArray(typeargs_table, false);
     typeargs_table.Release();
   }
 
@@ -1675,9 +1697,8 @@
   I->RehashConstants();
 
   dict_size = Utils::RoundUpToPowerOfTwo(typeargs.Length() * 4 / 3);
-  typeargs_array =
-      HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld);
-  CanonicalTypeArgumentsSet typeargs_table(Z, typeargs_array.raw());
+  CanonicalTypeArgumentsSet typeargs_table(
+      Z, HashTables::New<CanonicalTypeArgumentsSet>(dict_size, Heap::kOld));
   for (intptr_t i = 0; i < typeargs.Length(); i++) {
     typearg ^= typeargs.At(i);
     bool present = typeargs_table.Insert(typearg);
diff --git a/runtime/vm/class_finalizer.h b/runtime/vm/class_finalizer.h
index b970fa1..a087ac5 100644
--- a/runtime/vm/class_finalizer.h
+++ b/runtime/vm/class_finalizer.h
@@ -79,8 +79,7 @@
 
  private:
   static void AllocateEnumValues(const Class& enum_cls);
-  static void FinalizeTypeParameters(const Class& cls,
-                                     PendingTypes* pending_types = NULL);
+  static void FinalizeTypeParameters(const Class& cls);
   static intptr_t ExpandAndFinalizeTypeArguments(const Class& cls,
                                                  const AbstractType& type,
                                                  PendingTypes* pending_types);
diff --git a/runtime/vm/class_id.h b/runtime/vm/class_id.h
index 40f6897..b71fa12 100644
--- a/runtime/vm/class_id.h
+++ b/runtime/vm/class_id.h
@@ -131,7 +131,8 @@
 
 #define CLASS_LIST_FFI_TYPE_MARKER(V)                                          \
   CLASS_LIST_FFI_NUMERIC(V)                                                    \
-  V(Void)
+  V(Void)                                                                      \
+  V(Handle)
 
 #define CLASS_LIST_FFI(V)                                                      \
   V(Pointer)                                                                   \
diff --git a/runtime/vm/clustered_snapshot.cc b/runtime/vm/clustered_snapshot.cc
index f213b2b..25a8d76 100644
--- a/runtime/vm/clustered_snapshot.cc
+++ b/runtime/vm/clustered_snapshot.cc
@@ -198,6 +198,7 @@
     }
   }
 
+ private:
   void WriteClass(Serializer* s, ClassPtr cls) {
     AutoTraceObjectName(cls, cls->ptr()->name_);
     WriteFromTo(cls);
@@ -228,7 +229,6 @@
     }
   }
 
- private:
   GrowableArray<ClassPtr> predefined_;
   GrowableArray<ClassPtr> objects_;
 
@@ -3248,6 +3248,7 @@
       ReadFromTo(prefix);
       prefix->ptr()->num_imports_ = d->Read<uint16_t>();
       prefix->ptr()->is_deferred_load_ = d->Read<bool>();
+      prefix->ptr()->is_loaded_ = !prefix->ptr()->is_deferred_load_;
     }
   }
 };
@@ -3498,19 +3499,28 @@
 class TypeParameterSerializationCluster : public SerializationCluster {
  public:
   TypeParameterSerializationCluster() : SerializationCluster("TypeParameter") {}
-
   ~TypeParameterSerializationCluster() {}
 
   void Trace(Serializer* s, ObjectPtr object) {
     TypeParameterPtr type = TypeParameter::RawCast(object);
-    objects_.Add(type);
-    ASSERT(!type->ptr()->IsCanonical());
+    if (type->ptr()->IsCanonical()) {
+      canonical_objects_.Add(type);
+    } else {
+      objects_.Add(type);
+    }
+
     PushFromTo(type);
   }
 
   void WriteAlloc(Serializer* s) {
     s->WriteCid(kTypeParameterCid);
-    const intptr_t count = objects_.length();
+    intptr_t count = canonical_objects_.length();
+    s->WriteUnsigned(count);
+    for (intptr_t i = 0; i < count; i++) {
+      TypeParameterPtr type = canonical_objects_[i];
+      s->AssignRef(type);
+    }
+    count = objects_.length();
     s->WriteUnsigned(count);
     for (intptr_t i = 0; i < count; i++) {
       TypeParameterPtr type = objects_[i];
@@ -3519,23 +3529,31 @@
   }
 
   void WriteFill(Serializer* s) {
-    const intptr_t count = objects_.length();
+    intptr_t count = canonical_objects_.length();
     for (intptr_t i = 0; i < count; i++) {
-      TypeParameterPtr type = objects_[i];
-      AutoTraceObject(type);
-      WriteFromTo(type);
-      s->Write<int32_t>(type->ptr()->parameterized_class_id_);
-      s->WriteTokenPosition(type->ptr()->token_pos_);
-      s->Write<int16_t>(type->ptr()->index_);
-      const uint8_t combined =
-          (type->ptr()->flags_ << 4) | type->ptr()->nullability_;
-      ASSERT(type->ptr()->flags_ == (combined >> 4));
-      ASSERT(type->ptr()->nullability_ == (combined & 0xf));
-      s->Write<uint8_t>(combined);
+      WriteTypeParameter(s, canonical_objects_[i]);
+    }
+    count = objects_.length();
+    for (intptr_t i = 0; i < count; i++) {
+      WriteTypeParameter(s, objects_[i]);
     }
   }
 
  private:
+  void WriteTypeParameter(Serializer* s, TypeParameterPtr type) {
+    AutoTraceObject(type);
+    WriteFromTo(type);
+    s->Write<int32_t>(type->ptr()->parameterized_class_id_);
+    s->WriteTokenPosition(type->ptr()->token_pos_);
+    s->Write<int16_t>(type->ptr()->index_);
+    const uint8_t combined =
+        (type->ptr()->flags_ << 4) | type->ptr()->nullability_;
+    ASSERT(type->ptr()->flags_ == (combined >> 4));
+    ASSERT(type->ptr()->nullability_ == (combined & 0xf));
+    s->Write<uint8_t>(combined);
+  }
+
+  GrowableArray<TypeParameterPtr> canonical_objects_;
   GrowableArray<TypeParameterPtr> objects_;
 };
 #endif  // !DART_PRECOMPILED_RUNTIME
@@ -3546,9 +3564,17 @@
   ~TypeParameterDeserializationCluster() {}
 
   void ReadAlloc(Deserializer* d) {
-    start_index_ = d->next_index();
+    canonical_start_index_ = d->next_index();
     PageSpace* old_space = d->heap()->old_space();
-    const intptr_t count = d->ReadUnsigned();
+    intptr_t count = d->ReadUnsigned();
+    for (intptr_t i = 0; i < count; i++) {
+      d->AssignRef(
+          AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
+    }
+    canonical_stop_index_ = d->next_index();
+
+    start_index_ = d->next_index();
+    count = d->ReadUnsigned();
     for (intptr_t i = 0; i < count; i++) {
       d->AssignRef(
           AllocateUninitialized(old_space, TypeParameter::InstanceSize()));
@@ -3557,17 +3583,15 @@
   }
 
   void ReadFill(Deserializer* d) {
+    for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+         id++) {
+      TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
+      ReadTypeParameter(d, type, /* is_canonical = */ true);
+    }
+
     for (intptr_t id = start_index_; id < stop_index_; id++) {
       TypeParameterPtr type = static_cast<TypeParameterPtr>(d->Ref(id));
-      Deserializer::InitializeHeader(type, kTypeParameterCid,
-                                     TypeParameter::InstanceSize());
-      ReadFromTo(type);
-      type->ptr()->parameterized_class_id_ = d->Read<int32_t>();
-      type->ptr()->token_pos_ = d->ReadTokenPosition();
-      type->ptr()->index_ = d->Read<int16_t>();
-      const uint8_t combined = d->Read<uint8_t>();
-      type->ptr()->flags_ = combined >> 4;
-      type->ptr()->nullability_ = combined & 0xf;
+      ReadTypeParameter(d, type, /* is_canonical = */ false);
     }
   }
 
@@ -3576,6 +3600,13 @@
     Code& stub = Code::Handle(zone);
 
     if (Snapshot::IncludesCode(kind)) {
+      for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+           id++) {
+        type_param ^= refs.At(id);
+        stub = type_param.type_test_stub();
+        type_param.SetTypeTestingStub(
+            stub);  // Update type_test_stub_entry_point_
+      }
       for (intptr_t id = start_index_; id < stop_index_; id++) {
         type_param ^= refs.At(id);
         stub = type_param.type_test_stub();
@@ -3583,6 +3614,12 @@
             stub);  // Update type_test_stub_entry_point_
       }
     } else {
+      for (intptr_t id = canonical_start_index_; id < canonical_stop_index_;
+           id++) {
+        type_param ^= refs.At(id);
+        stub = TypeTestingStubGenerator::DefaultCodeForType(type_param);
+        type_param.SetTypeTestingStub(stub);
+      }
       for (intptr_t id = start_index_; id < stop_index_; id++) {
         type_param ^= refs.At(id);
         stub = TypeTestingStubGenerator::DefaultCodeForType(type_param);
@@ -3590,6 +3627,24 @@
       }
     }
   }
+
+ private:
+  void ReadTypeParameter(Deserializer* d,
+                         TypeParameterPtr type,
+                         bool is_canonical) {
+    Deserializer::InitializeHeader(type, kTypeParameterCid,
+                                   TypeParameter::InstanceSize(), is_canonical);
+    ReadFromTo(type);
+    type->ptr()->parameterized_class_id_ = d->Read<int32_t>();
+    type->ptr()->token_pos_ = d->ReadTokenPosition();
+    type->ptr()->index_ = d->Read<int16_t>();
+    const uint8_t combined = d->Read<uint8_t>();
+    type->ptr()->flags_ = combined >> 4;
+    type->ptr()->nullability_ = combined & 0xf;
+  }
+
+  intptr_t canonical_start_index_;
+  intptr_t canonical_stop_index_;
 };
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -6608,23 +6663,50 @@
 #undef CHECK_FLAG
 #undef SET_FLAG
 
-    if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
-      if (strncmp(cursor, "null-safety", end - cursor) == 0) {
-        FLAG_null_safety = kNullSafetyOptionStrong;
-        cursor = end;
-        continue;
-      }
-      if (strncmp(cursor, "no-null-safety", end - cursor) == 0) {
-        FLAG_null_safety = kNullSafetyOptionWeak;
-        cursor = end;
-        continue;
-      }
+    cursor = end;
+  }
+
+  return nullptr;
+}
+
+bool SnapshotHeaderReader::NullSafetyFromSnapshot(const Snapshot* snapshot) {
+  bool null_safety = false;
+  SnapshotHeaderReader header_reader(snapshot);
+  const char* features = nullptr;
+  intptr_t features_length = 0;
+
+  char* error = header_reader.ReadFeatures(&features, &features_length);
+  if (error != nullptr) {
+    return false;
+  }
+
+  ASSERT(features[features_length] == '\0');
+  const char* cursor = features;
+  while (*cursor != '\0') {
+    while (*cursor == ' ') {
+      cursor++;
+    }
+
+    const char* end = strstr(cursor, " ");
+    if (end == nullptr) {
+      end = features + features_length;
+    }
+
+    if (strncmp(cursor, "null-safety", end - cursor) == 0) {
+      cursor = end;
+      null_safety = true;
+      continue;
+    }
+    if (strncmp(cursor, "no-null-safety", end - cursor) == 0) {
+      cursor = end;
+      null_safety = false;
+      continue;
     }
 
     cursor = end;
   }
 
-  return nullptr;
+  return null_safety;
 }
 
 ApiErrorPtr FullSnapshotReader::ReadVMSnapshot() {
diff --git a/runtime/vm/clustered_snapshot.h b/runtime/vm/clustered_snapshot.h
index bc86035..1827670 100644
--- a/runtime/vm/clustered_snapshot.h
+++ b/runtime/vm/clustered_snapshot.h
@@ -514,6 +514,7 @@
 class SnapshotHeaderReader {
  public:
   static char* InitializeGlobalVMFlagsFromSnapshot(const Snapshot* snapshot);
+  static bool NullSafetyFromSnapshot(const Snapshot* snapshot);
 
   explicit SnapshotHeaderReader(const Snapshot* snapshot)
       : SnapshotHeaderReader(snapshot->kind(),
diff --git a/runtime/vm/compiler/aot/precompiler.cc b/runtime/vm/compiler/aot/precompiler.cc
index a357237..52bf344 100644
--- a/runtime/vm/compiler/aot/precompiler.cc
+++ b/runtime/vm/compiler/aot/precompiler.cc
@@ -173,6 +173,7 @@
       classes_to_retain_(),
       typeargs_to_retain_(),
       types_to_retain_(),
+      typeparams_to_retain_(),
       consts_to_retain_(),
       seen_table_selectors_(),
       error_(Error::Handle()),
@@ -384,6 +385,7 @@
       DropFields();
       TraceTypesFromRetainedClasses();
       DropTypes();
+      DropTypeParameters();
       DropTypeArguments();
 
       // Clear these before dropping classes as they may hold onto otherwise
@@ -779,6 +781,8 @@
   ASSERT(!function.IsRedirectingFactory());
   functions_to_retain_.Insert(function);
 
+  AddTypeArguments(TypeArguments::Handle(Z, function.type_parameters()));
+
   AbstractType& type = AbstractType::Handle(Z);
   type = function.result_type();
   AddType(type);
@@ -823,6 +827,23 @@
 void Precompiler::AddType(const AbstractType& abstype) {
   if (abstype.IsNull()) return;
 
+  if (abstype.IsTypeParameter()) {
+    if (typeparams_to_retain_.HasKey(&TypeParameter::Cast(abstype))) return;
+    typeparams_to_retain_.Insert(
+        &TypeParameter::ZoneHandle(Z, TypeParameter::Cast(abstype).raw()));
+
+    const AbstractType& type =
+        AbstractType::Handle(Z, TypeParameter::Cast(abstype).bound());
+    AddType(type);
+    const auto& function = Function::Handle(
+        Z, TypeParameter::Cast(abstype).parameterized_function());
+    AddTypesOf(function);
+    const Class& cls =
+        Class::Handle(Z, TypeParameter::Cast(abstype).parameterized_class());
+    AddTypesOf(cls);
+    return;
+  }
+
   if (types_to_retain_.HasKey(&abstype)) return;
   types_to_retain_.Insert(&AbstractType::ZoneHandle(Z, abstype.raw()));
 
@@ -840,16 +861,6 @@
     AbstractType& type = AbstractType::Handle(Z);
     type = TypeRef::Cast(abstype).type();
     AddType(type);
-  } else if (abstype.IsTypeParameter()) {
-    const AbstractType& type =
-        AbstractType::Handle(Z, TypeParameter::Cast(abstype).bound());
-    AddType(type);
-    const auto& function = Function::Handle(
-        Z, TypeParameter::Cast(abstype).parameterized_function());
-    AddTypesOf(function);
-    const Class& cls =
-        Class::Handle(Z, TypeParameter::Cast(abstype).parameterized_class());
-    AddTypesOf(cls);
   }
 }
 
@@ -867,8 +878,8 @@
 }
 
 void Precompiler::AddConstObject(const class Instance& instance) {
-  // Types and type arguments require special handling.
-  if (instance.IsAbstractType()) {
+  // Types, type parameters, and type arguments require special handling.
+  if (instance.IsAbstractType()) {  // Includes type parameter.
     AddType(AbstractType::Cast(instance));
     return;
   } else if (instance.IsTypeArguments()) {
@@ -1783,6 +1794,48 @@
   object_store->set_canonical_types(types_table.Release());
 }
 
+void Precompiler::DropTypeParameters() {
+  ObjectStore* object_store = I->object_store();
+  GrowableObjectArray& retained_typeparams =
+      GrowableObjectArray::Handle(Z, GrowableObjectArray::New());
+  Array& typeparams_array = Array::Handle(Z);
+  TypeParameter& typeparam = TypeParameter::Handle(Z);
+  // First drop all the type parameters that are not referenced.
+  // Note that we only visit 'free-floating' type parameters and not
+  // declarations of type parameters contained in the 'type_parameters'
+  // array in generic classes and functions.
+  {
+    CanonicalTypeParameterSet typeparams_table(
+        Z, object_store->canonical_type_parameters());
+    typeparams_array = HashTables::ToArray(typeparams_table, false);
+    for (intptr_t i = 0; i < typeparams_array.Length(); i++) {
+      typeparam ^= typeparams_array.At(i);
+      bool retain = typeparams_to_retain_.HasKey(&typeparam);
+      if (retain) {
+        retained_typeparams.Add(typeparam);
+      } else {
+        typeparam.ClearCanonical();
+        dropped_typeparam_count_++;
+      }
+    }
+    typeparams_table.Release();
+  }
+
+  // Now construct a new type parameter table and save in the object store.
+  const intptr_t dict_size =
+      Utils::RoundUpToPowerOfTwo(retained_typeparams.Length() * 4 / 3);
+  typeparams_array =
+      HashTables::New<CanonicalTypeParameterSet>(dict_size, Heap::kOld);
+  CanonicalTypeParameterSet typeparams_table(Z, typeparams_array.raw());
+  bool present;
+  for (intptr_t i = 0; i < retained_typeparams.Length(); i++) {
+    typeparam ^= retained_typeparams.At(i);
+    present = typeparams_table.Insert(typeparam);
+    ASSERT(!present);
+  }
+  object_store->set_canonical_type_parameters(typeparams_table.Release());
+}
+
 void Precompiler::DropTypeArguments() {
   ObjectStore* object_store = I->object_store();
   Array& typeargs_array = Array::Handle(Z);
diff --git a/runtime/vm/compiler/aot/precompiler.h b/runtime/vm/compiler/aot/precompiler.h
index 4c1b140..d6cc219 100644
--- a/runtime/vm/compiler/aot/precompiler.h
+++ b/runtime/vm/compiler/aot/precompiler.h
@@ -149,6 +149,26 @@
 
 typedef DirectChainedHashMap<AbstractTypeKeyValueTrait> AbstractTypeSet;
 
+class TypeParameterKeyValueTrait {
+ public:
+  // Typedefs needed for the DirectChainedHashMap template.
+  typedef const TypeParameter* Key;
+  typedef const TypeParameter* Value;
+  typedef const TypeParameter* Pair;
+
+  static Key KeyOf(Pair kv) { return kv; }
+
+  static Value ValueOf(Pair kv) { return kv; }
+
+  static inline intptr_t Hashcode(Key key) { return key->Hash(); }
+
+  static inline bool IsKeyEqual(Pair pair, Key key) {
+    return pair->raw() == key->raw();
+  }
+};
+
+typedef DirectChainedHashMap<TypeParameterKeyValueTrait> TypeParameterSet;
+
 class TypeArgumentsKeyValueTrait {
  public:
   // Typedefs needed for the DirectChainedHashMap template.
@@ -270,6 +290,7 @@
   void DropFields();
   void TraceTypesFromRetainedClasses();
   void DropTypes();
+  void DropTypeParameters();
   void DropTypeArguments();
   void DropMetadata();
   void DropLibraryEntries();
@@ -309,6 +330,7 @@
   intptr_t dropped_class_count_;
   intptr_t dropped_typearg_count_;
   intptr_t dropped_type_count_;
+  intptr_t dropped_typeparam_count_;
   intptr_t dropped_library_count_;
 
   compiler::ObjectPoolBuilder global_object_pool_builder_;
@@ -322,6 +344,7 @@
   ClassSet classes_to_retain_;
   TypeArgumentsSet typeargs_to_retain_;
   AbstractTypeSet types_to_retain_;
+  TypeParameterSet typeparams_to_retain_;
   InstanceSet consts_to_retain_;
   TableSelectorSet seen_table_selectors_;
   Error& error_;
diff --git a/runtime/vm/compiler/assembler/assembler_arm.cc b/runtime/vm/compiler/assembler/assembler_arm.cc
index 5f12e5f..5c71f94 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm.cc
@@ -568,25 +568,32 @@
 
 void Assembler::TransitionGeneratedToNative(Register destination_address,
                                             Register exit_frame_fp,
-                                            Register addr,
-                                            Register state,
+                                            Register exit_through_ffi,
+                                            Register tmp1,
                                             bool enter_safepoint) {
   // Save exit frame information to enable stack walking.
   StoreToOffset(kWord, exit_frame_fp, THR,
                 target::Thread::top_exit_frame_info_offset());
 
+  StoreToOffset(kWord, exit_through_ffi, THR,
+                target::Thread::exit_through_ffi_offset());
+  Register tmp2 = exit_through_ffi;
+
   // Mark that the thread is executing native code.
   StoreToOffset(kWord, destination_address, THR,
                 target::Thread::vm_tag_offset());
-  LoadImmediate(state, target::Thread::native_execution_state());
-  StoreToOffset(kWord, state, THR, target::Thread::execution_state_offset());
+  LoadImmediate(tmp1, target::Thread::native_execution_state());
+  StoreToOffset(kWord, tmp1, THR, target::Thread::execution_state_offset());
 
   if (enter_safepoint) {
-    EnterSafepoint(addr, state);
+    EnterSafepoint(tmp1, tmp2);
   }
 }
 
-void Assembler::ExitSafepoint(Register addr, Register state) {
+void Assembler::ExitSafepoint(Register tmp1, Register tmp2) {
+  Register addr = tmp1;
+  Register state = tmp2;
+
   // We generate the same number of instructions whether or not the slow-path is
   // forced, for consistency with EnterSafepoint.
   Label slow_path, done, retry;
@@ -642,10 +649,11 @@
   LoadImmediate(state, target::Thread::generated_execution_state());
   StoreToOffset(kWord, state, THR, target::Thread::execution_state_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Reset exit frame information in Isolate's mutator thread structure.
   LoadImmediate(state, 0);
   StoreToOffset(kWord, state, THR,
                 target::Thread::top_exit_frame_info_offset());
+  StoreToOffset(kWord, state, THR, target::Thread::exit_through_ffi_offset());
 }
 
 void Assembler::clrex() {
@@ -3445,6 +3453,15 @@
   LeaveDartFrame();
 }
 
+void Assembler::EnterCFrame(intptr_t frame_space) {
+  EnterFrame(1 << FP, 0);
+  ReserveAlignedFrameSpace(frame_space);
+}
+
+void Assembler::LeaveCFrame() {
+  LeaveFrame(1 << FP);
+}
+
 // R0 receiver, R9 ICData entries array
 // Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
 void Assembler::MonomorphicCheckedEntryJIT() {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index d382569..5d36e51 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -404,6 +404,9 @@
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     LoadFromOffset(kWord, dst, base, offset, AL);
   }
+  void StoreMemoryValue(Register src, Register base, int32_t offset) {
+    StoreToOffset(kWord, src, base, offset, AL);
+  }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     ldr(dst, Address(address, offset));
     dmb();
@@ -581,8 +584,8 @@
   // registers (in addition to TMP).
   void TransitionGeneratedToNative(Register destination_address,
                                    Register exit_frame_fp,
+                                   Register exit_through_ffi,
                                    Register scratch0,
-                                   Register scratch1,
                                    bool enter_safepoint);
   void TransitionNativeToGenerated(Register scratch0,
                                    Register scratch1,
@@ -766,6 +769,8 @@
     blx(LR);
   }
 
+  void CallCFunction(Address target) { Call(target); }
+
   // Add signed immediate value to rd. May clobber IP.
   void AddImmediate(Register rd, int32_t value, Condition cond = AL) {
     AddImmediate(rd, rd, value, cond);
@@ -1137,6 +1142,13 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  // Set up a frame for calling a C function.
+  // Automatically save the pinned registers in Dart which are not callee-
+  // saved in the native calling convention.
+  // Use together with CallCFunction.
+  void EnterCFrame(intptr_t frame_space);
+  void LeaveCFrame();
+
   void MonomorphicCheckedEntryJIT();
   void MonomorphicCheckedEntryAOT();
   void BranchOnMonomorphicCheckedEntryJIT(Label* label);
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.cc b/runtime/vm/compiler/assembler/assembler_arm64.cc
index 388c37b..24d45a2 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.cc
+++ b/runtime/vm/compiler/assembler/assembler_arm64.cc
@@ -1405,19 +1405,23 @@
 
 void Assembler::TransitionGeneratedToNative(Register destination,
                                             Register new_exit_frame,
-                                            Register state,
+                                            Register new_exit_through_ffi,
                                             bool enter_safepoint) {
   // Save exit frame information to enable stack walking.
   StoreToOffset(new_exit_frame, THR,
                 target::Thread::top_exit_frame_info_offset());
 
+  StoreToOffset(new_exit_through_ffi, THR,
+                target::Thread::exit_through_ffi_offset());
+  Register tmp = new_exit_through_ffi;
+
   // Mark that the thread is executing native code.
   StoreToOffset(destination, THR, target::Thread::vm_tag_offset());
-  LoadImmediate(state, target::Thread::native_execution_state());
-  StoreToOffset(state, THR, target::Thread::execution_state_offset());
+  LoadImmediate(tmp, target::Thread::native_execution_state());
+  StoreToOffset(tmp, THR, target::Thread::execution_state_offset());
 
   if (enter_safepoint) {
-    EnterSafepoint(state);
+    EnterSafepoint(tmp);
   }
 }
 
@@ -1476,8 +1480,10 @@
   LoadImmediate(state, target::Thread::generated_execution_state());
   StoreToOffset(state, THR, target::Thread::execution_state_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Reset exit frame information in Isolate's mutator thread structure.
   StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
+  LoadImmediate(state, 0);
+  StoreToOffset(state, THR, target::Thread::exit_through_ffi_offset());
 }
 
 void Assembler::EnterCallRuntimeFrame(intptr_t frame_size) {
@@ -1550,6 +1556,15 @@
   LeaveDartFrame();
 }
 
+void Assembler::EnterCFrame(intptr_t frame_space) {
+  EnterFrame(0);
+  ReserveAlignedFrameSpace(frame_space);
+}
+
+void Assembler::LeaveCFrame() {
+  LeaveFrame();
+}
+
 // R0 receiver, R5 ICData entries array
 // Preserve R4 (ARGS_DESC_REG), not required today, but maybe later.
 void Assembler::MonomorphicCheckedEntryJIT() {
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index 743e95f..5c1fb60 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -487,6 +487,9 @@
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     LoadFromOffset(dst, base, offset, kDoubleWord);
   }
+  void StoreMemoryValue(Register src, Register base, int32_t offset) {
+    StoreToOffset(src, base, offset, kDoubleWord);
+  }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     if (offset != 0) {
       AddImmediate(TMP2, address, offset);
@@ -1445,6 +1448,8 @@
     blr(LR);
   }
 
+  void CallCFunction(Address target) { Call(target); }
+
   void AddImmediate(Register dest, int64_t imm) {
     AddImmediate(dest, dest, imm);
   }
@@ -1627,7 +1632,7 @@
 
   void TransitionGeneratedToNative(Register destination_address,
                                    Register new_exit_frame,
-                                   Register scratch,
+                                   Register new_exit_through_ffi,
                                    bool enter_safepoint);
   void TransitionNativeToGenerated(Register scratch, bool exit_safepoint);
   void EnterSafepoint(Register scratch);
@@ -1655,6 +1660,13 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  // Set up a frame for calling a C function.
+  // Automatically save the pinned registers in Dart which are not callee-
+  // saved in the native calling convention.
+  // Use together with CallCFunction.
+  void EnterCFrame(intptr_t frame_space);
+  void LeaveCFrame();
+
   void MonomorphicCheckedEntryJIT();
   void MonomorphicCheckedEntryAOT();
   void BranchOnMonomorphicCheckedEntryJIT(Label* label);
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.cc b/runtime/vm/compiler/assembler/assembler_ia32.cc
index 6043f7f..798c2ed 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32.cc
@@ -309,6 +309,19 @@
   EmitUint8(0xA4);
 }
 
+void Assembler::rep_movsw() {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0xF3);
+  EmitUint8(0x66);
+  EmitUint8(0xA5);
+}
+
+void Assembler::rep_movsl() {
+  AssemblerBuffer::EnsureCapacity ensured(&buffer_);
+  EmitUint8(0xF3);
+  EmitUint8(0xA5);
+}
+
 void Assembler::movss(XmmRegister dst, const Address& src) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(0xF3);
@@ -2205,12 +2218,17 @@
 
 void Assembler::TransitionGeneratedToNative(Register destination_address,
                                             Register new_exit_frame,
-                                            Register scratch,
+                                            Register new_exit_through_ffi,
                                             bool enter_safepoint) {
   // Save exit frame information to enable stack walking.
   movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
        new_exit_frame);
 
+  movl(compiler::Address(THR,
+                         compiler::target::Thread::exit_through_ffi_offset()),
+       new_exit_through_ffi);
+  Register scratch = new_exit_through_ffi;
+
   // Mark that the thread is executing native code.
   movl(VMTagAddress(), destination_address);
   movl(Address(THR, target::Thread::execution_state_offset()),
@@ -2222,6 +2240,7 @@
 }
 
 void Assembler::ExitSafepoint(Register scratch) {
+  ASSERT(scratch != EAX);
   // We generate the same number of instructions whether or not the slow-path is
   // forced, for consistency with EnterSafepoint.
 
@@ -2274,9 +2293,12 @@
   movl(Address(THR, target::Thread::execution_state_offset()),
        Immediate(target::Thread::generated_execution_state()));
 
-  // Reset exit frame information in Isolate structure.
+  // Reset exit frame information in Isolate's mutator thread structure.
   movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
        Immediate(0));
+  movl(compiler::Address(THR,
+                         compiler::target::Thread::exit_through_ffi_offset()),
+       compiler::Immediate(0));
 }
 
 static const intptr_t kNumberOfVolatileCpuRegisters = 3;
@@ -2546,6 +2568,15 @@
   LeaveFrame();
 }
 
+void Assembler::EnterCFrame(intptr_t frame_space) {
+  EnterFrame(0);
+  ReserveAlignedFrameSpace(frame_space);
+}
+
+void Assembler::LeaveCFrame() {
+  LeaveFrame();
+}
+
 void Assembler::EmitOperand(int rm, const Operand& operand) {
   ASSERT(rm >= 0 && rm < 8);
   const intptr_t length = operand.length_;
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index 01cc4eb..dd2fa97 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -156,7 +156,7 @@
   }
 
   Address(Register index, ScaleFactor scale, int32_t disp) {
-    ASSERT(index != ESP);  // Illegal addressing mode.
+    ASSERT(index != ESP);       // Illegal addressing mode.
     ASSERT(scale != TIMES_16);  // Unsupported scale factor.
     SetModRM(0, ESP);
     SetSIB(scale, index, EBP);
@@ -167,7 +167,7 @@
   Address(Register index, ScaleFactor scale, Register r);
 
   Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
-    ASSERT(index != ESP);  // Illegal addressing mode.
+    ASSERT(index != ESP);       // Illegal addressing mode.
     ASSERT(scale != TIMES_16);  // Unsupported scale factor.
     if (disp == 0 && base != EBP) {
       SetModRM(0, ESP);
@@ -298,6 +298,8 @@
   void cmovlessl(Register dst, Register src);
 
   void rep_movsb();
+  void rep_movsw();
+  void rep_movsl();
 
   void movss(XmmRegister dst, const Address& src);
   void movss(const Address& dst, XmmRegister src);
@@ -579,6 +581,9 @@
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     movl(dst, Address(base, offset));
   }
+  void StoreMemoryValue(Register src, Register base, int32_t offset) {
+    movl(Address(base, offset), src);
+  }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     // On intel loads have load-acquire behavior (i.e. loads are not re-ordered
     // with other loads).
@@ -711,7 +716,7 @@
   // However XMM0 is saved for convenience.
   void TransitionGeneratedToNative(Register destination_address,
                                    Register new_exit_frame,
-                                   Register scratch,
+                                   Register new_exit_through_ffi,
                                    bool enter_safepoint);
   void TransitionNativeToGenerated(Register scratch, bool exit_safepoint);
   void EnterSafepoint(Register scratch);
@@ -732,6 +737,8 @@
 
   void Call(Address target) { call(target); }
 
+  void CallCFunction(Address target) { Call(target); }
+
   void Jmp(const Code& code);
   void J(Condition condition, const Code& code);
 
@@ -843,6 +850,13 @@
   void LeaveStubFrame();
   static const intptr_t kEnterStubFramePushedWords = 2;
 
+  // Set up a frame for calling a C function.
+  // Automatically save the pinned registers in Dart which are not callee-
+  // saved in the native calling convention.
+  // Use together with CallCFunction.
+  void EnterCFrame(intptr_t frame_space);
+  void LeaveCFrame();
+
   // Instruction pattern from entrypoint is used in dart frame prologs
   // to set up the frame and save a PC which can be used to figure out the
   // RawInstruction object corresponding to the code running in the frame.
diff --git a/runtime/vm/compiler/assembler/assembler_ia32_test.cc b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
index 3bfccc0..6c13141 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_ia32_test.cc
@@ -4755,14 +4755,16 @@
 }
 
 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) {
-  const char* from = "0123456789";
-  const char* to = new char[10];
-  typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count);
+  const char* from = "0123456789x";
+  char* to = new char[11]{0};
+  to[10] = 'y';
+  typedef void (*TestRepMovsBytes)(const char* from, char* to, int count);
   reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10);
   EXPECT_EQ(to[0], '0');
   for (int i = 0; i < 10; i++) {
     EXPECT_EQ(from[i], to[i]);
   }
+  EXPECT_EQ(to[10], 'y');
   delete[] to;
   EXPECT_DISASSEMBLY(
       "push esi\n"
@@ -4778,6 +4780,93 @@
       "ret\n");
 }
 
+ASSEMBLER_TEST_GENERATE(TestRepMovsWords, assembler) {
+  // Preserve registers.
+  __ pushl(ESI);
+  __ pushl(EDI);
+  __ pushl(ECX);
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // from.
+  __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // to.
+  __ movl(ECX, Address(ESP, 6 * target::kWordSize));  // count.
+  __ rep_movsw();
+  __ popl(ECX);
+  __ popl(EDI);
+  __ popl(ESI);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TestRepMovsWords, test) {
+  const uint16_t from[11] = {0x0123, 0x1234, 0x2345, 0x3456, 0x4567, 0x5678,
+                             0x6789, 0x789A, 0x89AB, 0x9ABC, 0xABCD};
+  uint16_t* to = new uint16_t[11]{0};
+  to[10] = 0xFEFE;
+  typedef void (*TestRepMovsWords)(const uint16_t* from, uint16_t* to,
+                                   int count);
+  reinterpret_cast<TestRepMovsWords>(test->entry())(from, to, 10);
+  EXPECT_EQ(to[0], 0x0123u);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_EQ(from[i], to[i]);
+  }
+  EXPECT_EQ(to[10], 0xFEFEu);
+  delete[] to;
+  EXPECT_DISASSEMBLY(
+      "push esi\n"
+      "push edi\n"
+      "push ecx\n"
+      "mov esi,[esp+0x10]\n"
+      "mov edi,[esp+0x14]\n"
+      "mov ecx,[esp+0x18]\n"
+      "rep movsw\n"
+      "pop ecx\n"
+      "pop edi\n"
+      "pop esi\n"
+      "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(TestRepMovsDwords, assembler) {
+  // Preserve registers.
+  __ pushl(ESI);
+  __ pushl(EDI);
+  __ pushl(ECX);
+  __ movl(ESI, Address(ESP, 4 * target::kWordSize));  // from.
+  __ movl(EDI, Address(ESP, 5 * target::kWordSize));  // to.
+  __ movl(ECX, Address(ESP, 6 * target::kWordSize));  // count.
+  __ rep_movsl();
+  __ popl(ECX);
+  __ popl(EDI);
+  __ popl(ESI);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TestRepMovsDwords, test) {
+  const uint32_t from[11] = {0x01234567, 0x12345678, 0x23456789, 0x3456789A,
+                             0x456789AB, 0x56789ABC, 0x6789ABCD, 0x789ABCDE,
+                             0x89ABCDEF, 0x9ABCDEF0, 0xABCDEF01};
+  uint32_t* to = new uint32_t[11]{0};
+  to[10] = 0xFEFEFEFE;
+  typedef void (*TestRepMovsDwords)(const uint32_t* from, uint32_t* to,
+                                    int count);
+  reinterpret_cast<TestRepMovsDwords>(test->entry())(from, to, 10);
+  EXPECT_EQ(to[0], 0x01234567u);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_EQ(from[i], to[i]);
+  }
+  EXPECT_EQ(to[10], 0xFEFEFEFEu);
+  delete[] to;
+  EXPECT_DISASSEMBLY(
+      "push esi\n"
+      "push edi\n"
+      "push ecx\n"
+      "mov esi,[esp+0x10]\n"
+      "mov edi,[esp+0x14]\n"
+      "mov ecx,[esp+0x18]\n"
+      "rep movsl\n"
+      "pop ecx\n"
+      "pop edi\n"
+      "pop esi\n"
+      "ret\n");
+}
+
 // Called from assembler_test.cc.
 ASSEMBLER_TEST_GENERATE(StoreIntoObject, assembler) {
   __ pushl(THR);
diff --git a/runtime/vm/compiler/assembler/assembler_x64.cc b/runtime/vm/compiler/assembler/assembler_x64.cc
index ef5a397..99b4608 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64.cc
@@ -179,11 +179,16 @@
 
 void Assembler::TransitionGeneratedToNative(Register destination_address,
                                             Register new_exit_frame,
+                                            Register new_exit_through_ffi,
                                             bool enter_safepoint) {
   // Save exit frame information to enable stack walking.
   movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
        new_exit_frame);
 
+  movq(compiler::Address(THR,
+                         compiler::target::Thread::exit_through_ffi_offset()),
+       new_exit_through_ffi);
+
   movq(Assembler::VMTagAddress(), destination_address);
   movq(Address(THR, target::Thread::execution_state_offset()),
        Immediate(target::Thread::native_execution_state()));
@@ -248,9 +253,12 @@
   movq(Address(THR, target::Thread::execution_state_offset()),
        Immediate(target::Thread::generated_execution_state()));
 
-  // Reset exit frame information in Isolate structure.
+  // Reset exit frame information in Isolate's mutator thread structure.
   movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
        Immediate(0));
+  movq(compiler::Address(THR,
+                         compiler::target::Thread::exit_through_ffi_offset()),
+       compiler::Immediate(0));
 }
 
 void Assembler::EmitQ(int reg,
@@ -384,11 +392,14 @@
   }
 }
 
-void Assembler::EmitSimple(int opcode, int opcode2) {
+void Assembler::EmitSimple(int opcode, int opcode2, int opcode3) {
   AssemblerBuffer::EnsureCapacity ensured(&buffer_);
   EmitUint8(opcode);
   if (opcode2 != -1) {
     EmitUint8(opcode2);
+    if (opcode3 != -1) {
+      EmitUint8(opcode3);
+    }
   }
 }
 
@@ -1670,6 +1681,13 @@
   }
   call(reg);
 }
+void Assembler::CallCFunction(Address address) {
+  // Reserve shadow space for outgoing arguments.
+  if (CallingConventions::kShadowSpaceBytes != 0) {
+    subq(RSP, Immediate(CallingConventions::kShadowSpaceBytes));
+  }
+  call(address);
+}
 
 void Assembler::CallRuntime(const RuntimeEntry& entry,
                             intptr_t argument_count) {
@@ -1775,6 +1793,15 @@
   LeaveDartFrame();
 }
 
+void Assembler::EnterCFrame(intptr_t frame_space) {
+  EnterFrame(0);
+  ReserveAlignedFrameSpace(frame_space);
+}
+
+void Assembler::LeaveCFrame() {
+  LeaveFrame();
+}
+
 // RDX receiver, RBX ICData entries array
 // Preserve R10 (ARGS_DESC_REG), not required today, but maybe later.
 void Assembler::MonomorphicCheckedEntryJIT() {
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 386f9c0..de96771 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -195,7 +195,7 @@
   Address(Register base, Register r);
 
   Address(Register index, ScaleFactor scale, int32_t disp) {
-    ASSERT(index != RSP);  // Illegal addressing mode.
+    ASSERT(index != RSP);       // Illegal addressing mode.
     ASSERT(scale != TIMES_16);  // Unsupported scale factor.
     SetModRM(0, RSP);
     SetSIB(scale, index, RBP);
@@ -206,7 +206,7 @@
   Address(Register index, ScaleFactor scale, Register r);
 
   Address(Register base, Register index, ScaleFactor scale, int32_t disp) {
-    ASSERT(index != RSP);  // Illegal addressing mode.
+    ASSERT(index != RSP);       // Illegal addressing mode.
     ASSERT(scale != TIMES_16);  // Unsupported scale factor.
     if ((disp == 0) && ((base & 7) != RBP)) {
       SetModRM(0, RSP);
@@ -317,6 +317,7 @@
   void LeaveSafepoint();
   void TransitionGeneratedToNative(Register destination_address,
                                    Register new_exit_frame,
+                                   Register new_exit_through_ffi,
                                    bool enter_safepoint);
   void TransitionNativeToGenerated(bool leave_safepoint);
 
@@ -391,6 +392,9 @@
   SIMPLE(fsin, 0xD9, 0xFE)
   SIMPLE(lock, 0xF0)
   SIMPLE(rep_movsb, 0xF3, 0xA4)
+  SIMPLE(rep_movsw, 0xF3, 0x66, 0xA5)
+  SIMPLE(rep_movsl, 0xF3, 0xA5)
+  SIMPLE(rep_movsq, 0xF3, 0x48, 0xA5)
 #undef SIMPLE
 // XmmRegister operations with another register or an address.
 #define XX(width, name, ...)                                                   \
@@ -824,6 +828,7 @@
   // Call runtime function. Reserves shadow space on the stack before calling
   // if platform ABI requires that. Does not restore RSP after the call itself.
   void CallCFunction(Register reg);
+  void CallCFunction(Address address);
 
   void ExtractClassIdFromTags(Register result, Register tags);
   void ExtractInstanceSizeFromTags(Register result, Register tags);
@@ -866,6 +871,9 @@
   void LoadMemoryValue(Register dst, Register base, int32_t offset) {
     movq(dst, Address(base, offset));
   }
+  void StoreMemoryValue(Register src, Register base, int32_t offset) {
+    movq(Address(base, offset), src);
+  }
   void LoadAcquire(Register dst, Register address, int32_t offset = 0) {
     // On intel loads have load-acquire behavior (i.e. loads are not re-ordered
     // with other loads).
@@ -932,6 +940,13 @@
   void EnterStubFrame();
   void LeaveStubFrame();
 
+  // Set up a frame for calling a C function.
+  // Automatically save the pinned registers in Dart which are not callee-
+  // saved in the native calling convention.
+  // Use together with CallCFunction.
+  void EnterCFrame(intptr_t frame_space);
+  void LeaveCFrame();
+
   void MonomorphicCheckedEntryJIT();
   void MonomorphicCheckedEntryAOT();
   void BranchOnMonomorphicCheckedEntryJIT(Label* label);
@@ -1030,7 +1045,7 @@
             const Address& dst,
             const Immediate& imm);
 
-  void EmitSimple(int opcode, int opcode2 = -1);
+  void EmitSimple(int opcode, int opcode2 = -1, int opcode3 = -1);
   void EmitUnaryQ(Register reg, int opcode, int modrm_code);
   void EmitUnaryL(Register reg, int opcode, int modrm_code);
   void EmitUnaryQ(const Address& address, int opcode, int modrm_code);
diff --git a/runtime/vm/compiler/assembler/assembler_x64_test.cc b/runtime/vm/compiler/assembler/assembler_x64_test.cc
index ef0619a..8c416ab 100644
--- a/runtime/vm/compiler/assembler/assembler_x64_test.cc
+++ b/runtime/vm/compiler/assembler/assembler_x64_test.cc
@@ -5556,14 +5556,16 @@
 }
 
 ASSEMBLER_TEST_RUN(TestRepMovsBytes, test) {
-  const char* from = "0123456789";
-  const char* to = new char[10];
-  typedef void (*TestRepMovsBytes)(const char* from, const char* to, int count);
+  const char* from = "0123456789x";
+  char* to = new char[11]{0};
+  to[10] = 'y';
+  typedef void (*TestRepMovsBytes)(const char* from, char* to, int count);
   reinterpret_cast<TestRepMovsBytes>(test->entry())(from, to, 10);
   EXPECT_EQ(to[0], '0');
   for (int i = 0; i < 10; i++) {
     EXPECT_EQ(from[i], to[i]);
   }
+  EXPECT_EQ(to[10], 'y');
   delete[] to;
   EXPECT_DISASSEMBLY_NOT_WINDOWS(
       "push rsi\n"
@@ -5583,6 +5585,163 @@
       "ret\n");
 }
 
+ASSEMBLER_TEST_GENERATE(TestRepMovsWords, assembler) {
+  __ pushq(RSI);
+  __ pushq(RDI);
+  __ pushq(CallingConventions::kArg1Reg);             // from.
+  __ pushq(CallingConventions::kArg2Reg);             // to.
+  __ pushq(CallingConventions::kArg3Reg);             // count.
+  __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // from.
+  __ movq(RDI, Address(RSP, 1 * target::kWordSize));  // to.
+  __ movq(RCX, Address(RSP, 0 * target::kWordSize));  // count.
+  __ rep_movsw();
+  // Remove saved arguments.
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RDI);
+  __ popq(RSI);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TestRepMovsWords, test) {
+  const uint16_t from[11] = {0x0123, 0x1234, 0x2345, 0x3456, 0x4567, 0x5678,
+                             0x6789, 0x789A, 0x89AB, 0x9ABC, 0xABCD};
+  uint16_t* to = new uint16_t[11]{0};
+  to[10] = 0xFEFE;
+  typedef void (*TestRepMovsWords)(const uint16_t* from, uint16_t* to,
+                                   int count);
+  reinterpret_cast<TestRepMovsWords>(test->entry())(from, to, 10);
+  EXPECT_EQ(to[0], 0x0123u);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_EQ(from[i], to[i]);
+  }
+  EXPECT_EQ(to[10], 0xFEFEu);
+  delete[] to;
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "push rsi\n"
+      "push rdi\n"
+      "push rdi\n"
+      "push rsi\n"
+      "push rdx\n"
+      "movq rsi,[rsp+0x10]\n"
+      "movq rdi,[rsp+0x8]\n"
+      "movq rcx,[rsp]\n"
+      "rep movsw\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rdi\n"
+      "pop rsi\n"
+      "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(TestRepMovsDwords, assembler) {
+  __ pushq(RSI);
+  __ pushq(RDI);
+  __ pushq(CallingConventions::kArg1Reg);             // from.
+  __ pushq(CallingConventions::kArg2Reg);             // to.
+  __ pushq(CallingConventions::kArg3Reg);             // count.
+  __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // from.
+  __ movq(RDI, Address(RSP, 1 * target::kWordSize));  // to.
+  __ movq(RCX, Address(RSP, 0 * target::kWordSize));  // count.
+  __ rep_movsl();
+  // Remove saved arguments.
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RDI);
+  __ popq(RSI);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TestRepMovsDwords, test) {
+  const uint32_t from[11] = {0x01234567, 0x12345678, 0x23456789, 0x3456789A,
+                             0x456789AB, 0x56789ABC, 0x6789ABCD, 0x789ABCDE,
+                             0x89ABCDEF, 0x9ABCDEF0, 0xABCDEF01};
+  uint32_t* to = new uint32_t[11]{0};
+  to[10] = 0xFEFEFEFE;
+  typedef void (*TestRepMovsDwords)(const uint32_t* from, uint32_t* to,
+                                    int count);
+  reinterpret_cast<TestRepMovsDwords>(test->entry())(from, to, 10);
+  EXPECT_EQ(to[0], 0x01234567u);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_EQ(from[i], to[i]);
+  }
+  EXPECT_EQ(to[10], 0xFEFEFEFEu);
+  delete[] to;
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "push rsi\n"
+      "push rdi\n"
+      "push rdi\n"
+      "push rsi\n"
+      "push rdx\n"
+      "movq rsi,[rsp+0x10]\n"
+      "movq rdi,[rsp+0x8]\n"
+      "movq rcx,[rsp]\n"
+      "rep movsl\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rdi\n"
+      "pop rsi\n"
+      "ret\n");
+}
+
+ASSEMBLER_TEST_GENERATE(TestRepMovsQwords, assembler) {
+  __ pushq(RSI);
+  __ pushq(RDI);
+  __ pushq(CallingConventions::kArg1Reg);             // from.
+  __ pushq(CallingConventions::kArg2Reg);             // to.
+  __ pushq(CallingConventions::kArg3Reg);             // count.
+  __ movq(RSI, Address(RSP, 2 * target::kWordSize));  // from.
+  __ movq(RDI, Address(RSP, 1 * target::kWordSize));  // to.
+  __ movq(RCX, Address(RSP, 0 * target::kWordSize));  // count.
+  __ rep_movsq();
+  // Remove saved arguments.
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RAX);
+  __ popq(RDI);
+  __ popq(RSI);
+  __ ret();
+}
+
+ASSEMBLER_TEST_RUN(TestRepMovsQwords, test) {
+  const uint64_t from[11] = {
+      0x0123456789ABCDEF, 0x123456789ABCDEF0, 0x23456789ABCDEF01,
+      0x3456789ABCDEF012, 0x456789ABCDEF0123, 0x56789ABCDEF01234,
+      0x6789ABCDEF012345, 0x789ABCDEF0123456, 0x89ABCDEF01234567,
+      0x9ABCDEF012345678, 0xABCDEF0123456789};
+  uint64_t* to = new uint64_t[11]{0};
+  to[10] = 0xFEFEFEFEFEFEFEFE;
+  typedef void (*TestRepMovsQwords)(const uint64_t* from, uint64_t* to,
+                                    int count);
+  reinterpret_cast<TestRepMovsQwords>(test->entry())(from, to, 10);
+  EXPECT_EQ(to[0], 0x0123456789ABCDEFu);
+  for (int i = 0; i < 10; i++) {
+    EXPECT_EQ(from[i], to[i]);
+  }
+  EXPECT_EQ(to[10], 0xFEFEFEFEFEFEFEFEu);
+  delete[] to;
+  EXPECT_DISASSEMBLY_NOT_WINDOWS(
+      "push rsi\n"
+      "push rdi\n"
+      "push rdi\n"
+      "push rsi\n"
+      "push rdx\n"
+      "movq rsi,[rsp+0x10]\n"
+      "movq rdi,[rsp+0x8]\n"
+      "movq rcx,[rsp]\n"
+      "rep movsq\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rax\n"
+      "pop rdi\n"
+      "pop rsi\n"
+      "ret\n");
+}
+
 ASSEMBLER_TEST_GENERATE(ConditionalMovesCompare, assembler) {
   __ cmpq(CallingConventions::kArg1Reg, CallingConventions::kArg2Reg);
   __ movq(RDX, Immediate(1));   // Greater equal.
diff --git a/runtime/vm/compiler/assembler/disassembler.cc b/runtime/vm/compiler/assembler/disassembler.cc
index 8af6086..522e505 100644
--- a/runtime/vm/compiler/assembler/disassembler.cc
+++ b/runtime/vm/compiler/assembler/disassembler.cc
@@ -417,10 +417,11 @@
         } else if (function.IsNull()) {
           cls ^= code.owner();
           if (cls.IsNull()) {
-            THR_Print("  0x%" Px ": %s, (%s)%s\n", base + offset,
-                      code.QualifiedName(Object::kScrubbedName,
-                                         Object::NameDisambiguation::kYes),
-                      skind, s_entry_point);
+            THR_Print(
+                "  0x%" Px ": %s, (%s)%s\n", base + offset,
+                code.QualifiedName(NameFormattingParams(
+                    Object::kScrubbedName, Object::NameDisambiguation::kYes)),
+                skind, s_entry_point);
           } else {
             THR_Print("  0x%" Px ": allocation stub for %s, (%s)%s\n",
                       base + offset, cls.ToCString(), skind, s_entry_point);
diff --git a/runtime/vm/compiler/assembler/disassembler_x86.cc b/runtime/vm/compiler/assembler/disassembler_x86.cc
index 53fdd69..3cc6713 100644
--- a/runtime/vm/compiler/assembler/disassembler_x86.cc
+++ b/runtime/vm/compiler/assembler/disassembler_x86.cc
@@ -1150,7 +1150,25 @@
           // REP.
           Print("rep ");
         }
-        Print("%s", idesc.mnem);
+        if ((current & 0x01) == 0x01) {
+          // Operation size: word, dword or qword
+          switch (operand_size()) {
+            case WORD_SIZE:
+              Print("%sw", idesc.mnem);
+              break;
+            case DOUBLEWORD_SIZE:
+              Print("%sl", idesc.mnem);
+              break;
+            case QUADWORD_SIZE:
+              Print("%sq", idesc.mnem);
+              break;
+            default:
+              UNREACHABLE();
+          }
+        } else {
+          // Operation size: byte
+          Print("%s", idesc.mnem);
+        }
       } else if (current == 0x99 && rex_w()) {
         Print("cqo");  // Cdql is called cdq and cdqq is called cqo.
       } else {
diff --git a/runtime/vm/compiler/backend/constant_propagator.cc b/runtime/vm/compiler/backend/constant_propagator.cc
index 7d78825..d412104 100644
--- a/runtime/vm/compiler/backend/constant_propagator.cc
+++ b/runtime/vm/compiler/backend/constant_propagator.cc
@@ -298,6 +298,8 @@
 void ConstantPropagator::VisitStoreInstanceField(
     StoreInstanceFieldInstr* instr) {}
 
+void ConstantPropagator::VisitMemoryCopy(MemoryCopyInstr* instr) {}
+
 void ConstantPropagator::VisitDeoptimize(DeoptimizeInstr* instr) {
   // TODO(vegorov) remove all code after DeoptimizeInstr as dead.
 }
@@ -733,6 +735,22 @@
   SetValue(instr, non_constant_);
 }
 
+void ConstantPropagator::VisitEnterHandleScope(EnterHandleScopeInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+void ConstantPropagator::VisitExitHandleScope(ExitHandleScopeInstr* instr) {
+  // Nothing to do.
+}
+
+void ConstantPropagator::VisitAllocateHandle(AllocateHandleInstr* instr) {
+  SetValue(instr, non_constant_);
+}
+
+void ConstantPropagator::VisitRawStoreField(RawStoreFieldInstr* instr) {
+  // Nothing to do.
+}
+
 void ConstantPropagator::VisitDebugStepCheck(DebugStepCheckInstr* instr) {
   // Nothing to do.
 }
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 1112b9b..dc254d4 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -28,6 +28,7 @@
 #include "vm/os.h"
 #include "vm/regexp_assembler_ir.h"
 #include "vm/resolver.h"
+#include "vm/runtime_entry.h"
 #include "vm/scopes.h"
 #include "vm/stack_frame.h"
 #include "vm/stub_code.h"
@@ -1096,7 +1097,11 @@
     // tables used for certain character classes are represented as TypedData,
     // and so those values are also neither immutable (as there are no immutable
     // TypedData values) or canonical.
-    ASSERT(value.IsTypeParameter() || value.IsArray() || value.IsTypedData());
+    //
+    // LibraryPrefixes are also never canonicalized since their equality is
+    // their identity.
+    ASSERT(value.IsTypeParameter() || value.IsArray() || value.IsTypedData() ||
+           value.IsLibraryPrefix());
   }
 #endif
 }
@@ -2597,6 +2602,8 @@
     case Slot::Kind::kPointerBase_data_field:
     case Slot::Kind::kType_arguments:
     case Slot::Kind::kTypeArgumentsIndex:
+    case Slot::Kind::kUnhandledException_exception:
+    case Slot::Kind::kUnhandledException_stacktrace:
       return false;
   }
   UNREACHABLE();
@@ -4261,7 +4268,7 @@
 void NativeParameterInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
   // The native entry frame has size -kExitLinkSlotFromFp. In order to access
   // the top of stack from above the entry frame, we add a constant to account
-  // for the the two frame pointers and two return addresses of the entry frame.
+  // for the two frame pointers and two return addresses of the entry frame.
   constexpr intptr_t kEntryFramePadding = 4;
   compiler::ffi::FrameRebase rebase(
       /*old_base=*/SPREG, /*new_base=*/FPREG,
@@ -5959,6 +5966,133 @@
   compiler->EmitMoveFromNative(dst_loc, dst_type, src, &no_temp);
 }
 
+static Location FirstArgumentLocation() {
+#ifdef TARGET_ARCH_IA32
+  return Location::StackSlot(0, SPREG);
+#else
+  return Location::RegisterLocation(CallingConventions::ArgumentRegisters[0]);
+#endif
+}
+
+LocationSummary* EnterHandleScopeInstr::MakeLocationSummary(
+    Zone* zone,
+    bool is_optimizing) const {
+  LocationSummary* summary =
+      new (zone) LocationSummary(zone, /*num_inputs=*/0,
+                                 /*num_temps=*/0, LocationSummary::kCall);
+  summary->set_out(0,
+                   Location::RegisterLocation(CallingConventions::kReturnReg));
+  return summary;
+}
+
+void EnterHandleScopeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  if (kind_ == Kind::kGetTopHandleScope) {
+    __ LoadMemoryValue(CallingConventions::kReturnReg, THR,
+                       compiler::target::Thread::api_top_scope_offset());
+    return;
+  }
+
+  Location arg_loc = FirstArgumentLocation();
+  __ EnterCFrame(arg_loc.IsRegister() ? 0 : compiler::target::kWordSize);
+  NoTemporaryAllocator no_temp;
+  compiler->EmitMove(arg_loc, Location::RegisterLocation(THR), &no_temp);
+  __ CallCFunction(
+      compiler::Address(THR, compiler::target::Thread::OffsetFromThread(
+                                 &kEnterHandleScopeRuntimeEntry)));
+  __ LeaveCFrame();
+}
+
+LocationSummary* ExitHandleScopeInstr::MakeLocationSummary(
+    Zone* zone,
+    bool is_optimizing) const {
+  LocationSummary* summary =
+      new (zone) LocationSummary(zone, /*num_inputs=*/0,
+                                 /*num_temps=*/0, LocationSummary::kCall);
+  return summary;
+}
+
+void ExitHandleScopeInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Location arg_loc = FirstArgumentLocation();
+  __ EnterCFrame(arg_loc.IsRegister() ? 0 : compiler::target::kWordSize);
+  NoTemporaryAllocator no_temp;
+  compiler->EmitMove(arg_loc, Location::RegisterLocation(THR), &no_temp);
+  __ CallCFunction(
+      compiler::Address(THR, compiler::target::Thread::OffsetFromThread(
+                                 &kExitHandleScopeRuntimeEntry)));
+  __ LeaveCFrame();
+}
+
+LocationSummary* AllocateHandleInstr::MakeLocationSummary(
+    Zone* zone,
+    bool is_optimizing) const {
+  LocationSummary* summary =
+      new (zone) LocationSummary(zone, /*num_inputs=*/1,
+                                 /*num_temps=*/0, LocationSummary::kCall);
+
+  Location arg_loc = FirstArgumentLocation();
+  // Assign input to a register that does not conflict with anything if
+  // argument is passed on the stack.
+  const Register scope_reg =
+      arg_loc.IsStackSlot() ? CallingConventions::kSecondNonArgumentRegister
+                            : arg_loc.reg();
+
+  summary->set_in(kScope, Location::RegisterLocation(scope_reg));
+  summary->set_out(0,
+                   Location::RegisterLocation(CallingConventions::kReturnReg));
+  return summary;
+}
+
+Representation AllocateHandleInstr::RequiredInputRepresentation(
+    intptr_t idx) const {
+  ASSERT(idx == kScope);
+  return kUnboxedIntPtr;
+}
+
+void AllocateHandleInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  Location arg_loc = FirstArgumentLocation();
+  __ EnterCFrame(arg_loc.IsRegister() ? 0 : compiler::target::kWordSize);
+  if (arg_loc.IsStackSlot()) {
+    NoTemporaryAllocator no_temp;
+    compiler->EmitMove(arg_loc, locs()->in(kScope), &no_temp);
+  }
+  __ CallCFunction(
+      compiler::Address(THR, compiler::target::Thread::OffsetFromThread(
+                                 &kAllocateHandleRuntimeEntry)));
+  __ LeaveCFrame();
+}
+
+LocationSummary* RawStoreFieldInstr::MakeLocationSummary(
+    Zone* zone,
+    bool is_optimizing) const {
+  LocationSummary* summary =
+      new (zone) LocationSummary(zone, /*num_inputs=*/2,
+                                 /*num_temps=*/0, LocationSummary::kNoCall);
+
+  summary->set_in(kBase, Location::RequiresRegister());
+  summary->set_in(kValue, Location::RequiresRegister());
+
+  return summary;
+}
+
+Representation RawStoreFieldInstr::RequiredInputRepresentation(
+    intptr_t idx) const {
+  switch (idx) {
+    case kBase:
+      return kUntagged;
+    case kValue:
+      return kTagged;
+    default:
+      break;
+  }
+  UNREACHABLE();
+}
+
+void RawStoreFieldInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register base_reg = locs()->in(kBase).reg();
+  const Register value_reg = locs()->in(kValue).reg();
+  compiler->assembler()->StoreMemoryValue(value_reg, base_reg, offset_);
+}
+
 void NativeReturnInstr::EmitReturnMoves(FlowGraphCompiler* compiler) {
   const auto& dst = marshaller_.Location(compiler::ffi::kResultIndex);
   if (dst.payload_type().IsVoid()) {
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index 78d7b5f..05913ac 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -377,6 +377,7 @@
   M(NativeParameter, kNoGC)                                                    \
   M(LoadIndexedUnsafe, kNoGC)                                                  \
   M(StoreIndexedUnsafe, kNoGC)                                                 \
+  M(MemoryCopy, kNoGC)                                                         \
   M(TailCall, kNoGC)                                                           \
   M(ParallelMove, kNoGC)                                                       \
   M(PushArgument, kNoGC)                                                       \
@@ -394,6 +395,10 @@
   M(SpecialParameter, kNoGC)                                                   \
   M(ClosureCall, _)                                                            \
   M(FfiCall, _)                                                                \
+  M(EnterHandleScope, _)                                                       \
+  M(ExitHandleScope, _)                                                        \
+  M(AllocateHandle, _)                                                         \
+  M(RawStoreField, _)                                                          \
   M(InstanceCall, _)                                                           \
   M(PolymorphicInstanceCall, _)                                                \
   M(DispatchTableCall, _)                                                      \
@@ -2691,6 +2696,86 @@
   DISALLOW_COPY_AND_ASSIGN(LoadIndexedUnsafeInstr);
 };
 
+class MemoryCopyInstr : public TemplateInstruction<5, NoThrow> {
+ public:
+  MemoryCopyInstr(Value* src,
+                  Value* dest,
+                  Value* src_start,
+                  Value* dest_start,
+                  Value* length,
+                  classid_t src_cid,
+                  classid_t dest_cid)
+      : src_cid_(src_cid),
+        dest_cid_(dest_cid),
+        element_size_(Instance::ElementSizeFor(src_cid)) {
+    ASSERT(IsArrayTypeSupported(src_cid));
+    ASSERT(IsArrayTypeSupported(dest_cid));
+    ASSERT(Instance::ElementSizeFor(src_cid) ==
+           Instance::ElementSizeFor(dest_cid));
+    SetInputAt(kSrcPos, src);
+    SetInputAt(kDestPos, dest);
+    SetInputAt(kSrcStartPos, src_start);
+    SetInputAt(kDestStartPos, dest_start);
+    SetInputAt(kLengthPos, length);
+  }
+
+  enum {
+    kSrcPos = 0,
+    kDestPos = 1,
+    kSrcStartPos = 2,
+    kDestStartPos = 3,
+    kLengthPos = 4
+  };
+
+  DECLARE_INSTRUCTION(MemoryCopy)
+
+  virtual Representation RequiredInputRepresentation(intptr_t index) const {
+    // All inputs are tagged (for now).
+    return kTagged;
+  }
+
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool HasUnknownSideEffects() const { return true; }
+
+  virtual bool AttributesEqual(Instruction* other) const { return true; }
+
+  Value* src() const { return inputs_[kSrcPos]; }
+  Value* dest() const { return inputs_[kDestPos]; }
+  Value* src_start() const { return inputs_[kSrcStartPos]; }
+  Value* dest_start() const { return inputs_[kDestStartPos]; }
+  Value* length() const { return inputs_[kLengthPos]; }
+
+ private:
+  // Set array_reg to point to the index indicated by start (contained in
+  // start_reg) of the typed data or string in array (contained in array_reg).
+  void EmitComputeStartPointer(FlowGraphCompiler* compiler,
+                               classid_t array_cid,
+                               Value* start,
+                               Register array_reg,
+                               Register start_reg);
+
+  static bool IsArrayTypeSupported(classid_t array_cid) {
+    if (IsTypedDataBaseClassId(array_cid)) {
+      return true;
+    }
+    switch (array_cid) {
+      case kOneByteStringCid:
+      case kTwoByteStringCid:
+      case kExternalOneByteStringCid:
+      case kExternalTwoByteStringCid:
+        return true;
+      default:
+        return false;
+    }
+  }
+
+  classid_t src_cid_;
+  classid_t dest_cid_;
+  intptr_t element_size_;
+
+  DISALLOW_COPY_AND_ASSIGN(MemoryCopyInstr);
+};
+
 // Unwinds the current frame and tail calls a target.
 //
 // The return address saved by the original caller of this frame will be in it's
@@ -4956,7 +5041,10 @@
 
   virtual intptr_t InputCount() const { return inputs_.length(); }
   virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
-  virtual bool MayThrow() const { return false; }
+  virtual bool MayThrow() const {
+    // By Dart_PropagateError.
+    return true;
+  }
 
   // FfiCallInstr calls C code, which can call back into Dart.
   virtual bool ComputeCanDeoptimize() const {
@@ -4996,6 +5084,82 @@
   DISALLOW_COPY_AND_ASSIGN(FfiCallInstr);
 };
 
+class EnterHandleScopeInstr : public TemplateDefinition<0, NoThrow> {
+ public:
+  enum class Kind { kEnterHandleScope = 0, kGetTopHandleScope = 1 };
+
+  explicit EnterHandleScopeInstr(Kind kind) : kind_(kind) {}
+
+  DECLARE_INSTRUCTION(EnterHandleScope)
+
+  virtual Representation representation() const { return kUnboxedIntPtr; }
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool HasUnknownSideEffects() const { return false; }
+
+  PRINT_OPERANDS_TO_SUPPORT
+
+ private:
+  Kind kind_;
+
+  DISALLOW_COPY_AND_ASSIGN(EnterHandleScopeInstr);
+};
+
+class ExitHandleScopeInstr : public TemplateInstruction<0, NoThrow> {
+ public:
+  ExitHandleScopeInstr() {}
+
+  DECLARE_INSTRUCTION(ExitHandleScope)
+
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool HasUnknownSideEffects() const { return false; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(ExitHandleScopeInstr);
+};
+
+class AllocateHandleInstr : public TemplateDefinition<1, NoThrow> {
+ public:
+  explicit AllocateHandleInstr(Value* scope) { SetInputAt(kScope, scope); }
+
+  enum { kScope = 0 };
+
+  DECLARE_INSTRUCTION(AllocateHandle)
+
+  virtual intptr_t InputCount() const { return 1; }
+  virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const;
+  virtual Representation representation() const { return kUnboxedIntPtr; }
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool HasUnknownSideEffects() const { return false; }
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(AllocateHandleInstr);
+};
+
+class RawStoreFieldInstr : public TemplateInstruction<2, NoThrow> {
+ public:
+  RawStoreFieldInstr(Value* base, Value* value, int32_t offset)
+      : offset_(offset) {
+    SetInputAt(kBase, base);
+    SetInputAt(kValue, value);
+  }
+
+  enum { kBase = 0, kValue = 1 };
+
+  DECLARE_INSTRUCTION(RawStoreField)
+
+  virtual intptr_t InputCount() const { return 2; }
+  virtual Value* InputAt(intptr_t i) const { return inputs_[i]; }
+  virtual Representation RequiredInputRepresentation(intptr_t idx) const;
+  virtual bool ComputeCanDeoptimize() const { return false; }
+  virtual bool HasUnknownSideEffects() const { return false; }
+
+ private:
+  const int32_t offset_;
+
+  DISALLOW_COPY_AND_ASSIGN(RawStoreFieldInstr);
+};
+
 class DebugStepCheckInstr : public TemplateInstruction<0, NoThrow> {
  public:
   DebugStepCheckInstr(TokenPosition token_pos,
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 90414b2..21d3060 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -154,6 +154,127 @@
   __ set_constant_pool_allowed(true);
 }
 
+LocationSummary* MemoryCopyInstr::MakeLocationSummary(Zone* zone,
+                                                      bool opt) const {
+  const intptr_t kNumInputs = 5;
+  const intptr_t kNumTemps =
+      element_size_ == 16 ? 4 : element_size_ == 8 ? 2 : 1;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(kSrcPos, Location::WritableRegister());
+  locs->set_in(kDestPos, Location::WritableRegister());
+  locs->set_in(kSrcStartPos, Location::RequiresRegister());
+  locs->set_in(kDestStartPos, Location::RequiresRegister());
+  locs->set_in(kLengthPos, Location::WritableRegister());
+  for (intptr_t i = 0; i < kNumTemps; i++) {
+    locs->set_temp(i, Location::RequiresRegister());
+  }
+  return locs;
+}
+
+void MemoryCopyInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register src_reg = locs()->in(kSrcPos).reg();
+  const Register dest_reg = locs()->in(kDestPos).reg();
+  const Register src_start_reg = locs()->in(kSrcStartPos).reg();
+  const Register dest_start_reg = locs()->in(kDestStartPos).reg();
+  const Register length_reg = locs()->in(kLengthPos).reg();
+
+  const Register temp_reg = locs()->temp(0).reg();
+  RegList temp_regs = 0;
+  for (intptr_t i = 0; i < locs()->temp_count(); i++) {
+    temp_regs |= 1 << locs()->temp(i).reg();
+  }
+
+  EmitComputeStartPointer(compiler, src_cid_, src_start(), src_reg,
+                          src_start_reg);
+  EmitComputeStartPointer(compiler, dest_cid_, dest_start(), dest_reg,
+                          dest_start_reg);
+
+  compiler::Label loop, done;
+
+  compiler::Address src_address =
+      compiler::Address(src_reg, element_size_, compiler::Address::PostIndex);
+  compiler::Address dest_address =
+      compiler::Address(dest_reg, element_size_, compiler::Address::PostIndex);
+
+  // Untag length and skip copy if length is zero.
+  __ movs(length_reg, compiler::Operand(length_reg, ASR, 1));
+  __ b(&done, ZERO);
+
+  __ Bind(&loop);
+  switch (element_size_) {
+    case 1:
+      __ ldrb(temp_reg, src_address);
+      __ strb(temp_reg, dest_address);
+      break;
+    case 2:
+      __ ldrh(temp_reg, src_address);
+      __ strh(temp_reg, dest_address);
+      break;
+    case 4:
+      __ ldr(temp_reg, src_address);
+      __ str(temp_reg, dest_address);
+      break;
+    case 8:
+    case 16:
+      __ ldm(BlockAddressMode::IA_W, src_reg, temp_regs);
+      __ stm(BlockAddressMode::IA_W, dest_reg, temp_regs);
+      break;
+  }
+  __ subs(length_reg, length_reg, compiler::Operand(1));
+  __ b(&loop, NOT_ZERO);
+  __ Bind(&done);
+}
+
+void MemoryCopyInstr::EmitComputeStartPointer(FlowGraphCompiler* compiler,
+                                              classid_t array_cid,
+                                              Value* start,
+                                              Register array_reg,
+                                              Register start_reg) {
+  if (IsTypedDataBaseClassId(array_cid)) {
+    __ ldr(
+        array_reg,
+        compiler::FieldAddress(
+            array_reg, compiler::target::TypedDataBase::data_field_offset()));
+  } else {
+    switch (array_cid) {
+      case kOneByteStringCid:
+        __ add(
+            array_reg, array_reg,
+            compiler::Operand(compiler::target::OneByteString::data_offset() -
+                              kHeapObjectTag));
+        break;
+      case kTwoByteStringCid:
+        __ add(
+            array_reg, array_reg,
+            compiler::Operand(compiler::target::OneByteString::data_offset() -
+                              kHeapObjectTag));
+        break;
+      case kExternalOneByteStringCid:
+        __ ldr(array_reg,
+               compiler::FieldAddress(array_reg,
+                                      compiler::target::ExternalOneByteString::
+                                          external_data_offset()));
+        break;
+      case kExternalTwoByteStringCid:
+        __ ldr(array_reg,
+               compiler::FieldAddress(array_reg,
+                                      compiler::target::ExternalTwoByteString::
+                                          external_data_offset()));
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+  intptr_t shift = Utils::ShiftForPowerOfTwo(element_size_) - 1;
+  if (shift < 0) {
+    __ add(array_reg, array_reg, compiler::Operand(start_reg, ASR, -shift));
+  } else {
+    __ add(array_reg, array_reg, compiler::Operand(start_reg, LSL, shift));
+  }
+}
+
 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -1187,12 +1308,13 @@
   // For historical reasons, the PC on ARM points 8 bytes past the current
   // instruction. Therefore we emit the metadata here, 8 bytes (2 instructions)
   // after the original mov.
-  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
+  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, deopt_id(),
                                  PcDescriptorsLayout::Kind::kOther, locs());
 
   // Update information in the thread object and enter a safepoint.
   if (CanExecuteGeneratedCodeInSafepoint()) {
-    __ TransitionGeneratedToNative(branch, FPREG, saved_fp, temp,
+    __ LoadImmediate(temp, compiler::target::Thread::exit_through_ffi());
+    __ TransitionGeneratedToNative(branch, FPREG, temp, saved_fp,
                                    /*enter_safepoint=*/true);
 
     __ blx(branch);
@@ -1241,9 +1363,13 @@
 
   // These can be anything besides the return registers (R0 and R1) and THR
   // (R10).
-  const Register vm_tag_reg = R2, old_exit_frame_reg = R3, tmp = R4, tmp1 = R5;
+  const Register vm_tag_reg = R2;
+  const Register old_exit_frame_reg = R3;
+  const Register old_exit_through_ffi_reg = R4;
+  const Register tmp = R5;
 
   __ Pop(old_exit_frame_reg);
+  __ Pop(old_exit_through_ffi_reg);
 
   // Restore top_resource.
   __ Pop(tmp);
@@ -1255,7 +1381,7 @@
   // If we were called by a trampoline, it will enter the safepoint on our
   // behalf.
   __ TransitionGeneratedToNative(
-      vm_tag_reg, old_exit_frame_reg, tmp, tmp1,
+      vm_tag_reg, old_exit_frame_reg, old_exit_through_ffi_reg, tmp,
       /*enter_safepoint=*/!NativeCallbackTrampolines::Enabled());
 
   __ PopNativeCalleeSavedRegisters();
@@ -1376,6 +1502,10 @@
   __ LoadImmediate(R0, 0);
   __ StoreToOffset(kWord, R0, THR, top_resource_offset);
 
+  __ LoadFromOffset(kWord, R0, THR,
+                    compiler::target::Thread::exit_through_ffi_offset());
+  __ Push(R0);
+
   // Save top exit frame info. Don't set it to 0 yet,
   // TransitionNativeToGenerated will handle that.
   __ LoadFromOffset(kWord, R0, THR,
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index f39a4f6..52ec9a8 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -134,6 +134,134 @@
   __ set_constant_pool_allowed(true);
 }
 
+LocationSummary* MemoryCopyInstr::MakeLocationSummary(Zone* zone,
+                                                      bool opt) const {
+  const intptr_t kNumInputs = 5;
+  const intptr_t kNumTemps = 1;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(kSrcPos, Location::WritableRegister());
+  locs->set_in(kDestPos, Location::WritableRegister());
+  locs->set_in(kSrcStartPos, Location::RequiresRegister());
+  locs->set_in(kDestStartPos, Location::RequiresRegister());
+  locs->set_in(kLengthPos, Location::WritableRegister());
+  locs->set_temp(0, element_size_ == 16
+                        ? Location::Pair(Location::RequiresRegister(),
+                                         Location::RequiresRegister())
+                        : Location::RequiresRegister());
+  return locs;
+}
+
+void MemoryCopyInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register src_reg = locs()->in(kSrcPos).reg();
+  const Register dest_reg = locs()->in(kDestPos).reg();
+  const Register src_start_reg = locs()->in(kSrcStartPos).reg();
+  const Register dest_start_reg = locs()->in(kDestStartPos).reg();
+  const Register length_reg = locs()->in(kLengthPos).reg();
+
+  Register temp_reg, temp_reg2;
+  if (locs()->temp(0).IsPairLocation()) {
+    PairLocation* pair = locs()->temp(0).AsPairLocation();
+    temp_reg = pair->At(0).reg();
+    temp_reg2 = pair->At(1).reg();
+  } else {
+    temp_reg = locs()->temp(0).reg();
+    temp_reg2 = kNoRegister;
+  }
+
+  EmitComputeStartPointer(compiler, src_cid_, src_start(), src_reg,
+                          src_start_reg);
+  EmitComputeStartPointer(compiler, dest_cid_, dest_start(), dest_reg,
+                          dest_start_reg);
+
+  compiler::Label loop, done;
+
+  compiler::Address src_address =
+      compiler::Address(src_reg, element_size_, compiler::Address::PostIndex);
+  compiler::Address dest_address =
+      compiler::Address(dest_reg, element_size_, compiler::Address::PostIndex);
+
+  // Untag length and skip copy if length is zero.
+  __ adds(length_reg, ZR, compiler::Operand(length_reg, ASR, 1));
+  __ b(&done, ZERO);
+
+  __ Bind(&loop);
+  switch (element_size_) {
+    case 1:
+      __ ldr(temp_reg, src_address, kUnsignedByte);
+      __ str(temp_reg, dest_address, kUnsignedByte);
+      break;
+    case 2:
+      __ ldr(temp_reg, src_address, kUnsignedHalfword);
+      __ str(temp_reg, dest_address, kUnsignedHalfword);
+      break;
+    case 4:
+      __ ldr(temp_reg, src_address, kUnsignedWord);
+      __ str(temp_reg, dest_address, kUnsignedWord);
+      break;
+    case 8:
+      __ ldr(temp_reg, src_address, kDoubleWord);
+      __ str(temp_reg, dest_address, kDoubleWord);
+      break;
+    case 16:
+      __ ldp(temp_reg, temp_reg2, src_address, kDoubleWord);
+      __ stp(temp_reg, temp_reg2, dest_address, kDoubleWord);
+      break;
+  }
+  __ subs(length_reg, length_reg, compiler::Operand(1));
+  __ b(&loop, NOT_ZERO);
+  __ Bind(&done);
+}
+
+void MemoryCopyInstr::EmitComputeStartPointer(FlowGraphCompiler* compiler,
+                                              classid_t array_cid,
+                                              Value* start,
+                                              Register array_reg,
+                                              Register start_reg) {
+  if (IsTypedDataBaseClassId(array_cid)) {
+    __ ldr(
+        array_reg,
+        compiler::FieldAddress(
+            array_reg, compiler::target::TypedDataBase::data_field_offset()));
+  } else {
+    switch (array_cid) {
+      case kOneByteStringCid:
+        __ add(
+            array_reg, array_reg,
+            compiler::Operand(compiler::target::OneByteString::data_offset() -
+                              kHeapObjectTag));
+        break;
+      case kTwoByteStringCid:
+        __ add(
+            array_reg, array_reg,
+            compiler::Operand(compiler::target::OneByteString::data_offset() -
+                              kHeapObjectTag));
+        break;
+      case kExternalOneByteStringCid:
+        __ ldr(array_reg,
+               compiler::FieldAddress(array_reg,
+                                      compiler::target::ExternalOneByteString::
+                                          external_data_offset()));
+        break;
+      case kExternalTwoByteStringCid:
+        __ ldr(array_reg,
+               compiler::FieldAddress(array_reg,
+                                      compiler::target::ExternalTwoByteString::
+                                          external_data_offset()));
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+  intptr_t shift = Utils::ShiftForPowerOfTwo(element_size_) - 1;
+  if (shift < 0) {
+    __ add(array_reg, array_reg, compiler::Operand(start_reg, ASR, -shift));
+  } else {
+    __ add(array_reg, array_reg, compiler::Operand(start_reg, LSL, shift));
+  }
+}
+
 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -1008,13 +1136,14 @@
   // ADR loads relative to itself, so add kInstrSize to point to the next
   // instruction.
   __ adr(temp, compiler::Immediate(Instr::kInstrSize));
-  compiler->EmitCallsiteMetadata(token_pos(), DeoptId::kNone,
+  compiler->EmitCallsiteMetadata(token_pos(), deopt_id(),
                                  PcDescriptorsLayout::Kind::kOther, locs());
 
   __ StoreToOffset(temp, FPREG, kSavedCallerPcSlotFromFp * kWordSize);
 
   if (CanExecuteGeneratedCodeInSafepoint()) {
     // Update information in the thread object and enter a safepoint.
+    __ LoadImmediate(temp, compiler::target::Thread::exit_through_ffi());
     __ TransitionGeneratedToNative(branch, FPREG, temp,
                                    /*enter_safepoint=*/true);
 
@@ -1071,21 +1200,24 @@
   // The dummy return address is in LR, no need to pop it as on Intel.
 
   // These can be anything besides the return register (R0) and THR (R26).
-  const Register vm_tag_reg = R1, old_exit_frame_reg = R2, tmp = R3;
+  const Register vm_tag_reg = R1;
+  const Register old_exit_frame_reg = R2;
+  const Register old_exit_through_ffi_reg = R3;
+  const Register tmp = R4;
+
+  __ PopPair(old_exit_frame_reg, old_exit_through_ffi_reg);
 
   // Restore top_resource.
-  __ PopPair(old_exit_frame_reg, tmp);
+  __ PopPair(tmp, vm_tag_reg);
   __ StoreToOffset(tmp, THR, compiler::target::Thread::top_resource_offset());
 
-  __ Pop(vm_tag_reg);
-
   // Reset the exit frame info to old_exit_frame_reg *before* entering the
   // safepoint.
   //
   // If we were called by a trampoline, it will enter the safepoint on our
   // behalf.
   __ TransitionGeneratedToNative(
-      vm_tag_reg, old_exit_frame_reg, tmp,
+      vm_tag_reg, old_exit_frame_reg, old_exit_through_ffi_reg,
       /*enter_safepoint=*/!NativeCallbackTrampolines::Enabled());
 
   __ PopNativeCalleeSavedRegisters();
@@ -1202,6 +1334,10 @@
 
   __ StoreToOffset(ZR, THR, compiler::target::Thread::top_resource_offset());
 
+  __ LoadFromOffset(R0, THR,
+                    compiler::target::Thread::exit_through_ffi_offset());
+  __ Push(R0);
+
   // Save the top exit frame info. We don't set it to 0 yet:
   // TransitionNativeToGenerated will handle that.
   __ LoadFromOffset(R0, THR,
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 5141efc..956c45f 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -75,6 +75,121 @@
   __ jmp(temp);
 }
 
+LocationSummary* MemoryCopyInstr::MakeLocationSummary(Zone* zone,
+                                                      bool opt) const {
+  const intptr_t kNumInputs = 5;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(kSrcPos, Location::RequiresRegister());
+  locs->set_in(kDestPos, Location::RegisterLocation(EDI));
+  locs->set_in(kSrcStartPos, Location::WritableRegister());
+  locs->set_in(kDestStartPos, Location::WritableRegister());
+  locs->set_in(kLengthPos, Location::RegisterLocation(ECX));
+  return locs;
+}
+
+void MemoryCopyInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register src_reg = locs()->in(kSrcPos).reg();
+  const Register src_start_reg = locs()->in(kSrcStartPos).reg();
+  const Register dest_start_reg = locs()->in(kDestStartPos).reg();
+
+  // Save ESI which is THR.
+  __ pushl(ESI);
+  __ movl(ESI, src_reg);
+
+  EmitComputeStartPointer(compiler, src_cid_, src_start(), ESI, src_start_reg);
+  EmitComputeStartPointer(compiler, dest_cid_, dest_start(), EDI,
+                          dest_start_reg);
+  if (element_size_ <= 4) {
+    __ SmiUntag(ECX);
+  } else if (element_size_ == 16) {
+    __ shll(ECX, compiler::Immediate(1));
+  }
+  switch (element_size_) {
+    case 1:
+      __ rep_movsb();
+      break;
+    case 2:
+      __ rep_movsw();
+      break;
+    case 4:
+    case 8:
+    case 16:
+      __ rep_movsl();
+      break;
+  }
+
+  // Restore THR.
+  __ popl(ESI);
+}
+
+void MemoryCopyInstr::EmitComputeStartPointer(FlowGraphCompiler* compiler,
+                                              classid_t array_cid,
+                                              Value* start,
+                                              Register array_reg,
+                                              Register start_reg) {
+  intptr_t offset;
+  if (IsTypedDataBaseClassId(array_cid)) {
+    __ movl(
+        array_reg,
+        compiler::FieldAddress(
+            array_reg, compiler::target::TypedDataBase::data_field_offset()));
+    offset = 0;
+  } else {
+    switch (array_cid) {
+      case kOneByteStringCid:
+        offset =
+            compiler::target::OneByteString::data_offset() - kHeapObjectTag;
+        break;
+      case kTwoByteStringCid:
+        offset =
+            compiler::target::TwoByteString::data_offset() - kHeapObjectTag;
+        break;
+      case kExternalOneByteStringCid:
+        __ movl(array_reg,
+                compiler::FieldAddress(array_reg,
+                                       compiler::target::ExternalOneByteString::
+                                           external_data_offset()));
+        offset = 0;
+        break;
+      case kExternalTwoByteStringCid:
+        __ movl(array_reg,
+                compiler::FieldAddress(array_reg,
+                                       compiler::target::ExternalTwoByteString::
+                                           external_data_offset()));
+        offset = 0;
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+  ScaleFactor scale;
+  switch (element_size_) {
+    case 1:
+      __ SmiUntag(start_reg);
+      scale = TIMES_1;
+      break;
+    case 2:
+      scale = TIMES_1;
+      break;
+    case 4:
+      scale = TIMES_2;
+      break;
+    case 8:
+      scale = TIMES_4;
+      break;
+    case 16:
+      scale = TIMES_8;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  __ leal(array_reg, compiler::Address(array_reg, start_reg, scale, offset));
+}
+
 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -173,9 +288,12 @@
 
   // Anything besides the return register(s!). Callee-saved registers will be
   // restored later.
-  const Register vm_tag_reg = EBX, old_exit_frame_reg = ECX;
+  const Register vm_tag_reg = EBX;
+  const Register old_exit_frame_reg = ECX;
+  const Register old_exit_through_ffi_reg = tmp;
 
   __ popl(old_exit_frame_reg);
+  __ popl(vm_tag_reg); /* old_exit_through_ffi, we still need to use tmp. */
 
   // Restore top_resource.
   __ popl(tmp);
@@ -183,6 +301,7 @@
       compiler::Address(THR, compiler::target::Thread::top_resource_offset()),
       tmp);
 
+  __ movl(old_exit_through_ffi_reg, vm_tag_reg);
   __ popl(vm_tag_reg);
 
   // This will reset the exit frame info to old_exit_frame_reg *before* entering
@@ -191,7 +310,7 @@
   // If we were called by a trampoline, it will enter the safepoint on our
   // behalf.
   __ TransitionGeneratedToNative(
-      vm_tag_reg, old_exit_frame_reg, tmp,
+      vm_tag_reg, old_exit_frame_reg, old_exit_through_ffi_reg,
       /*enter_safepoint=*/!NativeCallbackTrampolines::Enabled());
 
   // Move XMM0 into ST0 if needed.
@@ -883,13 +1002,15 @@
   // PC-relative 'leaq' available, so we have do a trick with 'call'.
   compiler::Label get_pc;
   __ call(&get_pc);
-  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
+  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, deopt_id(),
                                  PcDescriptorsLayout::Kind::kOther, locs());
   __ Bind(&get_pc);
   __ popl(temp);
   __ movl(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), temp);
 
   if (CanExecuteGeneratedCodeInSafepoint()) {
+    __ movl(temp,
+            compiler::Immediate(compiler::target::Thread::exit_through_ffi()));
     __ TransitionGeneratedToNative(branch, FPREG, temp,
                                    /*enter_safepoint=*/true);
     __ call(branch);
@@ -987,6 +1108,9 @@
       compiler::Address(THR, compiler::target::Thread::top_resource_offset()),
       compiler::Immediate(0));
 
+  __ pushl(compiler::Address(
+      THR, compiler::target::Thread::exit_through_ffi_offset()));
+
   // Save top exit frame info. Stack walker expects it to be here.
   __ pushl(compiler::Address(
       THR, compiler::target::Thread::top_exit_frame_info_offset()));
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index 320538f..cb9d2c7 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -1054,6 +1054,14 @@
   }
 }
 
+void EnterHandleScopeInstr::PrintOperandsTo(BufferFormatter* f) const {
+  if (kind_ == Kind::kEnterHandleScope) {
+    f->Print("<enter handle scope>");
+  } else {
+    f->Print("<get top api scope>");
+  }
+}
+
 void NativeReturnInstr::PrintOperandsTo(BufferFormatter* f) const {
   value()->PrintTo(f);
   f->Print(" (@");
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 6093b65..770eec1 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -127,6 +127,113 @@
   __ set_constant_pool_allowed(true);
 }
 
+LocationSummary* MemoryCopyInstr::MakeLocationSummary(Zone* zone,
+                                                      bool opt) const {
+  const intptr_t kNumInputs = 5;
+  const intptr_t kNumTemps = 0;
+  LocationSummary* locs = new (zone)
+      LocationSummary(zone, kNumInputs, kNumTemps, LocationSummary::kNoCall);
+  locs->set_in(kSrcPos, Location::RegisterLocation(RSI));
+  locs->set_in(kDestPos, Location::RegisterLocation(RDI));
+  locs->set_in(kSrcStartPos, Location::WritableRegister());
+  locs->set_in(kDestStartPos, Location::WritableRegister());
+  locs->set_in(kLengthPos, Location::RegisterLocation(RCX));
+  return locs;
+}
+
+void MemoryCopyInstr::EmitNativeCode(FlowGraphCompiler* compiler) {
+  const Register src_start_reg = locs()->in(kSrcStartPos).reg();
+  const Register dest_start_reg = locs()->in(kDestStartPos).reg();
+
+  EmitComputeStartPointer(compiler, src_cid_, src_start(), RSI, src_start_reg);
+  EmitComputeStartPointer(compiler, dest_cid_, dest_start(), RDI,
+                          dest_start_reg);
+  if (element_size_ <= 8) {
+    __ SmiUntag(RCX);
+  }
+  switch (element_size_) {
+    case 1:
+      __ rep_movsb();
+      break;
+    case 2:
+      __ rep_movsw();
+      break;
+    case 4:
+      __ rep_movsl();
+      break;
+    case 8:
+    case 16:
+      __ rep_movsq();
+      break;
+  }
+}
+
+void MemoryCopyInstr::EmitComputeStartPointer(FlowGraphCompiler* compiler,
+                                              classid_t array_cid,
+                                              Value* start,
+                                              Register array_reg,
+                                              Register start_reg) {
+  intptr_t offset;
+  if (IsTypedDataBaseClassId(array_cid)) {
+    __ movq(
+        array_reg,
+        compiler::FieldAddress(
+            array_reg, compiler::target::TypedDataBase::data_field_offset()));
+    offset = 0;
+  } else {
+    switch (array_cid) {
+      case kOneByteStringCid:
+        offset =
+            compiler::target::OneByteString::data_offset() - kHeapObjectTag;
+        break;
+      case kTwoByteStringCid:
+        offset =
+            compiler::target::TwoByteString::data_offset() - kHeapObjectTag;
+        break;
+      case kExternalOneByteStringCid:
+        __ movq(array_reg,
+                compiler::FieldAddress(array_reg,
+                                       compiler::target::ExternalOneByteString::
+                                           external_data_offset()));
+        offset = 0;
+        break;
+      case kExternalTwoByteStringCid:
+        __ movq(array_reg,
+                compiler::FieldAddress(array_reg,
+                                       compiler::target::ExternalTwoByteString::
+                                           external_data_offset()));
+        offset = 0;
+        break;
+      default:
+        UNREACHABLE();
+        break;
+    }
+  }
+  ScaleFactor scale;
+  switch (element_size_) {
+    case 1:
+      __ SmiUntag(start_reg);
+      scale = TIMES_1;
+      break;
+    case 2:
+      scale = TIMES_1;
+      break;
+    case 4:
+      scale = TIMES_2;
+      break;
+    case 8:
+      scale = TIMES_4;
+      break;
+    case 16:
+      scale = TIMES_8;
+      break;
+    default:
+      UNREACHABLE();
+      break;
+  }
+  __ leaq(array_reg, compiler::Address(array_reg, start_reg, scale, offset));
+}
+
 LocationSummary* PushArgumentInstr::MakeLocationSummary(Zone* zone,
                                                         bool opt) const {
   const intptr_t kNumInputs = 1;
@@ -238,10 +345,14 @@
   __ popq(TMP);
 
   // Anything besides the return register.
-  const Register vm_tag_reg = RBX, old_exit_frame_reg = RCX;
+  const Register vm_tag_reg = RBX;
+  const Register old_exit_frame_reg = RCX;
+  const Register old_exit_through_ffi_reg = RDI;
 
   __ popq(old_exit_frame_reg);
 
+  __ popq(old_exit_through_ffi_reg);
+
   // Restore top_resource.
   __ popq(TMP);
   __ movq(
@@ -253,7 +364,7 @@
   // If we were called by a trampoline, it will enter the safepoint on our
   // behalf.
   __ TransitionGeneratedToNative(
-      vm_tag_reg, old_exit_frame_reg,
+      vm_tag_reg, old_exit_frame_reg, old_exit_through_ffi_reg,
       /*enter_safepoint=*/!NativeCallbackTrampolines::Enabled());
 
   // Restore C++ ABI callee-saved registers.
@@ -962,13 +1073,15 @@
   // instruction, so 'AddressRIPRelative' loads the address of the following
   // 'movq'.
   __ leaq(TMP, compiler::Address::AddressRIPRelative(0));
-  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, DeoptId::kNone,
+  compiler->EmitCallsiteMetadata(TokenPosition::kNoSource, deopt_id(),
                                  PcDescriptorsLayout::Kind::kOther, locs());
   __ movq(compiler::Address(FPREG, kSavedCallerPcSlotFromFp * kWordSize), TMP);
 
   if (CanExecuteGeneratedCodeInSafepoint()) {
     // Update information in the thread object and enter a safepoint.
-    __ TransitionGeneratedToNative(target_address, FPREG,
+    __ movq(TMP,
+            compiler::Immediate(compiler::target::Thread::exit_through_ffi()));
+    __ TransitionGeneratedToNative(target_address, FPREG, TMP,
                                    /*enter_safepoint=*/true);
 
     __ CallCFunction(target_address);
@@ -1097,6 +1210,9 @@
       compiler::Address(THR, compiler::target::Thread::top_resource_offset()),
       compiler::Immediate(0));
 
+  __ pushq(compiler::Address(
+      THR, compiler::target::Thread::exit_through_ffi_offset()));
+
   // Save top exit frame info. Stack walker expects it to be here.
   __ pushq(compiler::Address(
       THR, compiler::target::Thread::top_exit_frame_info_offset()));
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index ff24226..4983afd 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -2705,6 +2705,8 @@
     case Slot::Kind::kTypedDataView_data:
     case Slot::Kind::kType_arguments:
     case Slot::Kind::kTypeArgumentsIndex:
+    case Slot::Kind::kUnhandledException_exception:
+    case Slot::Kind::kUnhandledException_stacktrace:
       // Not an integer valued field.
       UNREACHABLE();
       break;
diff --git a/runtime/vm/compiler/backend/redundancy_elimination.cc b/runtime/vm/compiler/backend/redundancy_elimination.cc
index b86b8b6..a7a1610 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination.cc
@@ -3859,7 +3859,9 @@
   ASSERT(current->GetBlock() == block);
   if (MayHaveVisibleEffect(current) || current->CanDeoptimize() ||
       current == block->last_instruction() || current->IsMaterializeObject() ||
-      current->IsCheckStackOverflow() || current->IsReachabilityFence()) {
+      current->IsCheckStackOverflow() || current->IsReachabilityFence() ||
+      current->IsEnterHandleScope() || current->IsExitHandleScope() ||
+      current->IsRawStoreField()) {
     return false;
   }
   return true;
diff --git a/runtime/vm/compiler/backend/slot.h b/runtime/vm/compiler/backend/slot.h
index 2da369a..f314bd3 100644
--- a/runtime/vm/compiler/backend/slot.h
+++ b/runtime/vm/compiler/backend/slot.h
@@ -77,7 +77,9 @@
   V(ArgumentsDescriptor, ArrayLayout, count, Smi, FINAL)                       \
   V(ArgumentsDescriptor, ArrayLayout, size, Smi, FINAL)                        \
   V(PointerBase, PointerBaseLayout, data_field, Dynamic, FINAL)                \
-  V(Type, TypeLayout, arguments, TypeArguments, FINAL)
+  V(Type, TypeLayout, arguments, TypeArguments, FINAL)                         \
+  V(UnhandledException, UnhandledExceptionLayout, exception, Dynamic, FINAL)   \
+  V(UnhandledException, UnhandledExceptionLayout, stacktrace, Dynamic, FINAL)
 
 // Slot is an abstraction that describes an readable (and possibly writeable)
 // location within an object.
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index 8d9253f..8d2bb7a 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -1139,9 +1139,13 @@
     }
     // If parameter type was checked by caller, then use Dart type annotation,
     // plus non-nullability from inferred type if known.
-    if (param->was_type_checked_by_caller() ||
-        (is_unchecked_entry_param &&
-         !param->is_explicit_covariant_parameter())) {
+    // Do not trust static parameter type of 'operator ==' as it is a
+    // non-nullable Object but VM handles comparison with null in
+    // the callee, so 'operator ==' can take null as an argument.
+    if ((function.name() != Symbols::EqualOperator().raw()) &&
+        (param->was_type_checked_by_caller() ||
+         (is_unchecked_entry_param &&
+          !param->is_explicit_covariant_parameter()))) {
       const bool is_nullable =
           (inferred_type == NULL) || inferred_type->is_nullable();
       TraceStrongModeType(this, param->type());
diff --git a/runtime/vm/compiler/ffi/marshaller.cc b/runtime/vm/compiler/ffi/marshaller.cc
index 009e031..21eff2c 100644
--- a/runtime/vm/compiler/ffi/marshaller.cc
+++ b/runtime/vm/compiler/ffi/marshaller.cc
@@ -17,6 +17,18 @@
 
 namespace ffi {
 
+bool BaseMarshaller::ContainsHandles() const {
+  if (IsHandle(kResultIndex)) {
+    return true;
+  }
+  for (intptr_t i = 0; i < num_args(); i++) {
+    if (IsHandle(i)) {
+      return true;
+    }
+  }
+  return false;
+}
+
 Location CallMarshaller::LocInFfiCall(intptr_t arg_index) const {
   if (arg_index == kResultIndex) {
     return Location(arg_index).AsLocation();
diff --git a/runtime/vm/compiler/ffi/marshaller.h b/runtime/vm/compiler/ffi/marshaller.h
index d8d4647..d175ddc 100644
--- a/runtime/vm/compiler/ffi/marshaller.h
+++ b/runtime/vm/compiler/ffi/marshaller.h
@@ -67,6 +67,10 @@
     return AbstractType::Handle(zone_, CType(arg_index)).type_class_id() ==
            kFfiPointerCid;
   }
+  bool IsHandle(intptr_t arg_index) const {
+    return AbstractType::Handle(zone_, CType(arg_index)).type_class_id() ==
+           kFfiHandleCid;
+  }
 
   // Treated as a null constant in Dart.
   bool IsVoid(intptr_t arg_index) const {
@@ -74,6 +78,8 @@
            kFfiVoidCid;
   }
 
+  bool ContainsHandles() const;
+
   StringPtr function_name() const { return dart_signature_.name(); }
 
  protected:
diff --git a/runtime/vm/compiler/ffi/native_type.cc b/runtime/vm/compiler/ffi/native_type.cc
index d06d73f..57db124 100644
--- a/runtime/vm/compiler/ffi/native_type.cc
+++ b/runtime/vm/compiler/ffi/native_type.cc
@@ -233,6 +233,10 @@
       return compiler::target::kWordSize == 4 ? kUint32 : kInt64;
     case kFfiVoidCid:
       return kVoid;
+    case kFfiHandleCid:
+      // We never expose this pointer as a Dart int, so no need to make it
+      // unsigned on 32 bit architectures.
+      return compiler::target::kWordSize == 4 ? kInt32 : kInt64;
     default:
       UNREACHABLE();
   }
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index bf31d84..262d595 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -245,6 +245,18 @@
       Constant(Integer::ZoneHandle(Z, Integer::New(value, Heap::kOld))));
 }
 
+Fragment BaseFlowGraphBuilder::MemoryCopy(classid_t src_cid,
+                                          classid_t dest_cid) {
+  Value* length = Pop();
+  Value* dest_start = Pop();
+  Value* src_start = Pop();
+  Value* dest = Pop();
+  Value* src = Pop();
+  auto copy = new (Z) MemoryCopyInstr(src, dest, src_start, dest_start, length,
+                                      src_cid, dest_cid);
+  return Fragment(copy);
+}
+
 Fragment BaseFlowGraphBuilder::TailCall(const Code& code) {
   Value* arg_desc = Pop();
   return Fragment(new (Z) TailCallInstr(code, arg_desc));
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 1efa882..40b9d4f 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -285,6 +285,7 @@
                               intptr_t stack_depth,
                               intptr_t loop_depth);
   Fragment CheckStackOverflowInPrologue(TokenPosition position);
+  Fragment MemoryCopy(classid_t src_cid, classid_t dest_cid);
   Fragment TailCall(const Code& code);
   Fragment Utf8Scan();
 
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 9817021..5211208 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -671,6 +671,8 @@
                                    nullability, TokenPosition::kNoSource);
     parameter.set_index(offset + i);
     parameter.SetIsFinalized();
+    parameter.SetCanonical();
+    parameter.SetDeclaration(true);
     type_parameters.SetTypeAt(i, parameter);
   }
 
diff --git a/runtime/vm/compiler/frontend/constant_reader.cc b/runtime/vm/compiler/frontend/constant_reader.cc
index cb0c693..243478f 100644
--- a/runtime/vm/compiler/frontend/constant_reader.cc
+++ b/runtime/vm/compiler/frontend/constant_reader.cc
@@ -303,9 +303,8 @@
     }
     case kTypeLiteralConstant: {
       // Build type from the raw bytes (needs temporary translator).
-      TypeTranslator type_translator(
-          &reader, this, active_class_, true,
-          active_class_->RequireLegacyErasure(null_safety));
+      // Legacy erasure is not applied to type literals. See issue #42262.
+      TypeTranslator type_translator(&reader, this, active_class_, true);
       instance = type_translator.BuildType().raw();
       break;
     }
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index aba146c..589ed9e 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1363,9 +1363,9 @@
     case kInstantiation:
       return BuildPartialTearoffInstantiation(position);
     case kLoadLibrary:
+      return BuildLibraryPrefixAction(position, Symbols::LoadLibrary());
     case kCheckLibraryIsLoaded:
-      ReadUInt();  // skip library index
-      return BuildFutureNullValue(position);
+      return BuildLibraryPrefixAction(position, Symbols::CheckLoaded());
     case kConstStaticInvocation:
     case kConstConstructorInvocation:
     case kConstListLiteral:
@@ -4068,6 +4068,26 @@
   return instructions;
 }
 
+Fragment StreamingFlowGraphBuilder::BuildLibraryPrefixAction(
+    TokenPosition* position,
+    const String& selector) {
+  const intptr_t dependency_index = ReadUInt();
+  const Library& current_library = Library::Handle(
+      Z, Class::Handle(Z, parsed_function()->function().origin()).library());
+  const Array& dependencies = Array::Handle(Z, current_library.dependencies());
+  const LibraryPrefix& prefix =
+      LibraryPrefix::CheckedZoneHandle(Z, dependencies.At(dependency_index));
+  const Function& function =
+      Function::ZoneHandle(Z, Library::Handle(Z, Library::CoreLibrary())
+                                  .LookupFunctionAllowPrivate(selector));
+  ASSERT(!function.IsNull());
+  Fragment instructions;
+  instructions += Constant(prefix);
+  instructions +=
+      StaticCall(TokenPosition::kNoSource, function, 1, ICData::kStatic);
+  return instructions;
+}
+
 Fragment StreamingFlowGraphBuilder::BuildExpressionStatement() {
   Fragment instructions = BuildExpression();  // read expression.
   instructions += Drop();
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
index 2b1ba41..c36a7c8 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.h
@@ -335,6 +335,8 @@
   Fragment BuildFutureNullValue(TokenPosition* position);
   Fragment BuildConstantExpression(TokenPosition* position, Tag tag);
   Fragment BuildPartialTearoffInstantiation(TokenPosition* position);
+  Fragment BuildLibraryPrefixAction(TokenPosition* position,
+                                    const String& selector);
 
   Fragment BuildExpressionStatement();
   Fragment BuildBlock();
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 3ca275c..8ce6da1 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -22,6 +22,7 @@
 #include "vm/object_store.h"
 #include "vm/report.h"
 #include "vm/resolver.h"
+#include "vm/scopes.h"
 #include "vm/stack_frame.h"
 
 namespace dart {
@@ -831,6 +832,7 @@
     case MethodRecognizer::kGrowableArrayCapacity:
     case MethodRecognizer::kListFactory:
     case MethodRecognizer::kObjectArrayAllocate:
+    case MethodRecognizer::kCopyRangeFromUint8ListToOneByteString:
     case MethodRecognizer::kLinkedHashMap_getIndex:
     case MethodRecognizer::kLinkedHashMap_setIndex:
     case MethodRecognizer::kLinkedHashMap_getData:
@@ -1055,6 +1057,16 @@
       body += LoadLocal(parsed_function_->RawParameterVariable(1));
       body += CreateArray();
       break;
+    case MethodRecognizer::kCopyRangeFromUint8ListToOneByteString:
+      ASSERT(function.NumParameters() == 5);
+      body += LoadLocal(parsed_function_->RawParameterVariable(0));
+      body += LoadLocal(parsed_function_->RawParameterVariable(1));
+      body += LoadLocal(parsed_function_->RawParameterVariable(2));
+      body += LoadLocal(parsed_function_->RawParameterVariable(3));
+      body += LoadLocal(parsed_function_->RawParameterVariable(4));
+      body += MemoryCopy(kTypedDataUint8ArrayCid, kOneByteStringCid);
+      body += NullConstant();
+      break;
     case MethodRecognizer::kLinkedHashMap_getIndex:
       ASSERT(function.NumParameters() == 1);
       body += LoadLocal(parsed_function_->RawParameterVariable(0));
@@ -2716,6 +2728,99 @@
                            prologue_info);
 }
 
+Fragment FlowGraphBuilder::EnterHandleScope() {
+  auto* instr = new (Z)
+      EnterHandleScopeInstr(EnterHandleScopeInstr::Kind::kEnterHandleScope);
+  Push(instr);
+  return Fragment(instr);
+}
+
+Fragment FlowGraphBuilder::GetTopHandleScope() {
+  auto* instr = new (Z)
+      EnterHandleScopeInstr(EnterHandleScopeInstr::Kind::kGetTopHandleScope);
+  Push(instr);
+  return Fragment(instr);
+}
+
+Fragment FlowGraphBuilder::ExitHandleScope() {
+  auto* instr = new (Z) ExitHandleScopeInstr();
+  return Fragment(instr);
+}
+
+Fragment FlowGraphBuilder::AllocateHandle(LocalVariable* api_local_scope) {
+  Fragment code;
+  if (api_local_scope != nullptr) {
+    // Use the reference the scope we created in the trampoline.
+    code += LoadLocal(api_local_scope);
+  } else {
+    // Or get a reference to the top handle scope.
+    code += GetTopHandleScope();
+  }
+  Value* api_local_scope_value = Pop();
+  auto* instr = new (Z) AllocateHandleInstr(api_local_scope_value);
+  Push(instr);
+  code <<= instr;
+  return code;
+}
+
+Fragment FlowGraphBuilder::RawStoreField(int32_t offset) {
+  Fragment code;
+  Value* value = Pop();
+  Value* base = Pop();
+  auto* instr = new (Z) RawStoreFieldInstr(base, value, offset);
+  code <<= instr;
+  return code;
+}
+
+Fragment FlowGraphBuilder::WrapHandle(LocalVariable* api_local_scope) {
+  Fragment code;
+  LocalVariable* object = MakeTemporary();
+  code += AllocateHandle(api_local_scope);
+
+  code += LoadLocal(MakeTemporary());  // Duplicate handle pointer.
+  code += ConvertUnboxedToUntagged(kUnboxedIntPtr);
+  code += LoadLocal(object);
+  code += RawStoreField(compiler::target::LocalHandle::raw_offset());
+
+  code += DropTempsPreserveTop(1);  // Drop object below handle.
+  return code;
+}
+
+Fragment FlowGraphBuilder::UnwrapHandle() {
+  Fragment code;
+  code += ConvertUnboxedToUntagged(kUnboxedIntPtr);
+  code += IntConstant(compiler::target::LocalHandle::raw_offset());
+  code += UnboxTruncate(kUnboxedIntPtr);
+  code += LoadIndexedTypedData(kArrayCid, /*index_scale=*/1,
+                               /*index_unboxed=*/true);
+  return code;
+}
+
+Fragment FlowGraphBuilder::UnhandledException() {
+  const auto class_table = thread_->isolate()->class_table();
+  ASSERT(class_table->HasValidClassAt(kUnhandledExceptionCid));
+  const auto& klass =
+      Class::ZoneHandle(H.zone(), class_table->At(kUnhandledExceptionCid));
+  ASSERT(!klass.IsNull());
+  Fragment body;
+  body += AllocateObject(TokenPosition::kNoSource, klass, 0);
+  LocalVariable* error_instance = MakeTemporary();
+
+  body += LoadLocal(error_instance);
+  body += LoadLocal(CurrentException());
+  body += StoreInstanceField(
+      TokenPosition::kNoSource, Slot::UnhandledException_exception(),
+      StoreInstanceFieldInstr::Kind::kInitializing, kNoStoreBarrier);
+
+  body += LoadLocal(error_instance);
+  body += LoadLocal(CurrentStackTrace());
+  body += StoreInstanceField(
+      TokenPosition::kNoSource, Slot::UnhandledException_stacktrace(),
+      StoreInstanceFieldInstr::Kind::kInitializing, kNoStoreBarrier);
+
+  return body;
+}
+
 Fragment FlowGraphBuilder::UnboxTruncate(Representation to) {
   auto* unbox = UnboxInstr::Create(to, Pop(), DeoptId::kNone,
                                    Instruction::kNotSpeculative);
@@ -2777,6 +2882,8 @@
     body += Box(kUnboxedFfiIntPtr);
     body += FfiPointerFromAddress(
         Type::CheckedHandle(Z, marshaller.CType(arg_index)));
+  } else if (marshaller.IsHandle(arg_index)) {
+    body += UnwrapHandle();
   } else if (marshaller.IsVoid(arg_index)) {
     body += Drop();
     body += NullConstant();
@@ -2793,18 +2900,16 @@
 
 Fragment FlowGraphBuilder::FfiConvertArgumentToNative(
     const compiler::ffi::BaseMarshaller& marshaller,
-    intptr_t arg_index) {
+    intptr_t arg_index,
+    LocalVariable* api_local_scope) {
   Fragment body;
 
-  // Check for 'null'.
-  // TODO(36780): Mention the param name instead of function name and reciever.
-  body += CheckNullOptimized(TokenPosition::kNoSource,
-                             String::ZoneHandle(Z, marshaller.function_name()));
-
   if (marshaller.IsPointer(arg_index)) {
     // This can only be Pointer, so it is always safe to LoadUntagged.
     body += LoadUntagged(compiler::target::Pointer::data_field_offset());
     body += ConvertUntaggedToUnboxed(kUnboxedFfiIntPtr);
+  } else if (marshaller.IsHandle(arg_index)) {
+    body += WrapHandle(api_local_scope);
   } else {
     body += UnboxTruncate(marshaller.RepInDart(arg_index));
   }
@@ -2841,19 +2946,51 @@
   BlockEntryInstr* instruction_cursor =
       BuildPrologue(normal_entry, &prologue_info);
 
-  Fragment body(instruction_cursor);
-  body += CheckStackOverflowInPrologue(function.token_pos());
+  Fragment function_body(instruction_cursor);
+  function_body += CheckStackOverflowInPrologue(function.token_pos());
 
   const auto& marshaller = *new (Z) compiler::ffi::CallMarshaller(Z, function);
 
   BuildArgumentTypeChecks(TypeChecksToBuild::kCheckAllTypeParameterBounds,
-                          &body, &body, &body);
+                          &function_body, &function_body, &function_body);
+
+  // Null check arguments before we go into the try catch, so that we don't
+  // catch our own null errors.
+  const intptr_t num_args = marshaller.num_args();
+  for (intptr_t i = 0; i < num_args; i++) {
+    if (marshaller.IsHandle(i)) {
+      continue;
+    }
+    function_body += LoadLocal(
+        parsed_function_->ParameterVariable(kFirstArgumentParameterOffset + i));
+    // Check for 'null'.
+    // TODO(36780): Mention the param name instead of function reciever.
+    function_body +=
+        CheckNullOptimized(TokenPosition::kNoSource,
+                           String::ZoneHandle(Z, marshaller.function_name()));
+    function_body += StoreLocal(
+        TokenPosition::kNoSource,
+        parsed_function_->ParameterVariable(kFirstArgumentParameterOffset + i));
+    function_body += Drop();
+  }
+
+  // Wrap in Try catch to transition from Native to Generated on a throw from
+  // the dart_api.
+  const intptr_t try_handler_index = AllocateTryIndex();
+  Fragment body = TryCatch(try_handler_index);
+  ++try_depth_;
+
+  LocalVariable* api_local_scope = nullptr;
+  if (marshaller.ContainsHandles()) {
+    body += EnterHandleScope();
+    api_local_scope = MakeTemporary();
+  }
 
   // Unbox and push the arguments.
   for (intptr_t i = 0; i < marshaller.num_args(); i++) {
     body += LoadLocal(
         parsed_function_->ParameterVariable(kFirstArgumentParameterOffset + i));
-    body += FfiConvertArgumentToNative(marshaller, i);
+    body += FfiConvertArgumentToNative(marshaller, i, api_local_scope);
   }
 
   // Push the function pointer, which is stored (as Pointer object) in the
@@ -2881,8 +3018,30 @@
 
   body += FfiConvertArgumentToDart(marshaller, compiler::ffi::kResultIndex);
 
+  if (marshaller.ContainsHandles()) {
+    body += DropTempsPreserveTop(1);  // Drop api_local_scope.
+    body += ExitHandleScope();
+  }
+
   body += Return(TokenPosition::kNoSource);
 
+  --try_depth_;
+  function_body += body;
+
+  ++catch_depth_;
+  Fragment catch_body =
+      CatchBlockEntry(Array::empty_array(), try_handler_index,
+                      /*needs_stacktrace=*/true, /*is_synthesized=*/true);
+  if (marshaller.ContainsHandles()) {
+    // TODO(41984): If we want to pass in the handle scope, move it out
+    // of the try catch.
+    catch_body += ExitHandleScope();
+  }
+  catch_body += LoadLocal(CurrentException());
+  catch_body += LoadLocal(CurrentStackTrace());
+  catch_body += RethrowException(TokenPosition::kNoSource, try_handler_index);
+  --catch_depth_;
+
   return new (Z) FlowGraph(*parsed_function_, graph_entry_, last_used_block_id_,
                            prologue_info);
 }
@@ -2926,16 +3085,25 @@
                      marshaller.num_args(), Array::empty_array(),
                      ICData::kNoRebind);
 
-  body += FfiConvertArgumentToNative(marshaller, compiler::ffi::kResultIndex);
+  if (marshaller.IsVoid(compiler::ffi::kResultIndex)) {
+    body += Drop();
+    body += IntConstant(0);
+  } else if (!marshaller.IsHandle(compiler::ffi::kResultIndex)) {
+    body +=
+        CheckNullOptimized(TokenPosition::kNoSource,
+                           String::ZoneHandle(Z, marshaller.function_name()));
+  }
+  body += FfiConvertArgumentToNative(marshaller, compiler::ffi::kResultIndex,
+                                     /*api_local_scope=*/nullptr);
   body += NativeReturn(marshaller);
 
   --try_depth_;
   function_body += body;
 
   ++catch_depth_;
-  Fragment catch_body =
-      CatchBlockEntry(Array::empty_array(), try_handler_index,
-                      /*needs_stacktrace=*/false, /*is_synthesized=*/true);
+  Fragment catch_body = CatchBlockEntry(Array::empty_array(), try_handler_index,
+                                        /*needs_stacktrace=*/false,
+                                        /*is_synthesized=*/true);
 
   // Return the "exceptional return" value given in 'fromFunction'.
   //
@@ -2946,11 +3114,15 @@
     ASSERT(function.FfiCallbackExceptionalReturn() == Object::null());
     catch_body += IntConstant(0);
     catch_body += UnboxTruncate(kUnboxedFfiIntPtr);
+  } else if (marshaller.IsHandle(compiler::ffi::kResultIndex)) {
+    catch_body += UnhandledException();
+    catch_body += FfiConvertArgumentToNative(
+        marshaller, compiler::ffi::kResultIndex, /*api_local_scope=*/nullptr);
   } else {
     catch_body += Constant(
         Instance::ZoneHandle(Z, function.FfiCallbackExceptionalReturn()));
-    catch_body +=
-        FfiConvertArgumentToNative(marshaller, compiler::ffi::kResultIndex);
+    catch_body += FfiConvertArgumentToNative(
+        marshaller, compiler::ffi::kResultIndex, /*api_local_scope=*/nullptr);
   }
 
   catch_body += NativeReturn(marshaller);
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 3bf1230..c5ea5ee 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -205,13 +205,38 @@
   // semantics of FFI argument translation.
   Fragment FfiConvertArgumentToNative(
       const compiler::ffi::BaseMarshaller& marshaller,
-      intptr_t arg_index);
+      intptr_t arg_index,
+      LocalVariable* api_local_scope);
 
   // Reverse of 'FfiConvertArgumentToNative'.
   Fragment FfiConvertArgumentToDart(
       const compiler::ffi::BaseMarshaller& marshaller,
       intptr_t arg_index);
 
+  // Generates a call to `Thread::EnterApiScope`.
+  Fragment EnterHandleScope();
+
+  // Generates a call to `Thread::api_top_scope`.
+  Fragment GetTopHandleScope();
+
+  // Generates a call to `Thread::ExitApiScope`.
+  Fragment ExitHandleScope();
+
+  // Leaves a `LocalHandle` on the stack.
+  Fragment AllocateHandle(LocalVariable* api_local_scope);
+
+  // Populates the base + offset with a tagged value.
+  Fragment RawStoreField(int32_t offset);
+
+  // Wraps an `Object` from the stack and leaves a `LocalHandle` on the stack.
+  Fragment WrapHandle(LocalVariable* api_local_scope);
+
+  // Unwraps a `LocalHandle` from the stack and leaves the object on the stack.
+  Fragment UnwrapHandle();
+
+  // Wrap the current exception and stacktrace in an unhandled exception.
+  Fragment UnhandledException();
+
   // Return from a native -> Dart callback. Can only be used in conjunction with
   // NativeEntry and NativeParameter are used.
   Fragment NativeReturn(const compiler::ffi::CallbackMarshaller& marshaller);
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 2a694ee..5840768 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -3273,6 +3273,8 @@
           H.DartIdentifier(lib, helper.name_index_),  // read ith name index.
           null_bound, helper.IsGenericCovariantImpl(), nullability,
           TokenPosition::kNoSource);
+      parameter.SetCanonical();
+      parameter.SetDeclaration(true);
       type_parameters.SetTypeAt(i, parameter);
     }
   }
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index 3856434..35caee9 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -420,18 +420,14 @@
                                             : Object::dynamic_type().raw()));
         scope_->InsertParameterAt(i, variable);
       }
-      // Callbacks need try/catch variables.
-      if (function.IsFfiTrampoline() &&
-          function.FfiCallbackTarget() != Function::null()) {
-        current_function_async_marker_ = FunctionNodeHelper::kSync;
-        ++depth_.try_;
-        AddTryVariables();
-        --depth_.try_;
-        ++depth_.catch_;
-        AddCatchVariables();
-        FinalizeCatchVariables();
-        --depth_.catch_;
-      }
+      current_function_async_marker_ = FunctionNodeHelper::kSync;
+      ++depth_.try_;
+      AddTryVariables();
+      --depth_.try_;
+      ++depth_.catch_;
+      AddCatchVariables();
+      FinalizeCatchVariables();
+      --depth_.catch_;
       break;
     case FunctionLayout::kSignatureFunction:
     case FunctionLayout::kIrregexpFunction:
@@ -815,8 +811,8 @@
       if (translation_helper_.info().kernel_binary_version() >= 38) {
         helper_.ReadFlags();  // read flags.
       }
-      VisitExpression();       // read operand.
-      VisitDartType();         // read type.
+      VisitExpression();  // read operand.
+      VisitDartType();    // read type.
       return;
     case kAsExpression:
       helper_.ReadPosition();  // read position.
diff --git a/runtime/vm/compiler/offsets_extractor.cc b/runtime/vm/compiler/offsets_extractor.cc
index fc507f0..80a6870 100644
--- a/runtime/vm/compiler/offsets_extractor.cc
+++ b/runtime/vm/compiler/offsets_extractor.cc
@@ -6,6 +6,7 @@
 
 #include "vm/compiler/runtime_api.h"
 #include "vm/compiler/runtime_offsets_list.h"
+#include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/longjump.h"
 #include "vm/native_arguments.h"
diff --git a/runtime/vm/compiler/recognized_methods_list.h b/runtime/vm/compiler/recognized_methods_list.h
index 1c6ffb1..fc68832 100644
--- a/runtime/vm/compiler/recognized_methods_list.h
+++ b/runtime/vm/compiler/recognized_methods_list.h
@@ -65,6 +65,8 @@
   V(_Int32x4ArrayView, ._, TypedData_Int32x4ArrayView_factory, 0x9bfbd6d5)     \
   V(_Float64x2ArrayView, ._, TypedData_Float64x2ArrayView_factory, 0x1a383408) \
   V(::, _toClampedUint8, ConvertIntToClampedUint8, 0x59765a4a)                 \
+  V(::, copyRangeFromUint8ListToOneByteString,                                 \
+    CopyRangeFromUint8ListToOneByteString, 0x00000000)                         \
   V(_StringBase, _interpolate, StringBaseInterpolate, 0xc0a650e4)              \
   V(_IntegerImplementation, toDouble, IntegerToDouble, 0x22a26db3)             \
   V(_Double, _add, DoubleAdd, 0x2f5c036a)                                      \
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index bc48403..8948126 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -8,6 +8,7 @@
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 #include "vm/compiler/runtime_offsets_list.h"
+#include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/longjump.h"
 #include "vm/native_arguments.h"
@@ -373,6 +374,8 @@
       return TypedDataBase::InstanceSize();
     case kLinkedHashMapCid:
       return LinkedHashMap::InstanceSize();
+    case kUnhandledExceptionCid:
+      return UnhandledException::InstanceSize();
     case kByteBufferCid:
     case kByteDataViewCid:
     case kFfiPointerCid:
@@ -605,6 +608,14 @@
   return dart::VMTag::kDartCompiledTagId;
 }
 
+uword Thread::exit_through_runtime_call() {
+  return dart::Thread::kExitThroughRuntimeCall;
+}
+
+uword Thread::exit_through_ffi() {
+  return dart::Thread::kExitThroughFfi;
+}
+
 word Thread::OffsetFromThread(const dart::Object& object) {
   auto host_offset = dart::Thread::OffsetFromThread(object);
   return object_null_offset() +
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index d16b3cc..b5f1b74 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -603,6 +603,11 @@
   static word positional_count_offset();
 };
 
+class LocalHandle : public AllStatic {
+ public:
+  static word raw_offset();
+};
+
 class Pointer : public PointerBase {
  public:
   static word type_arguments_offset();
@@ -836,6 +841,8 @@
 
 class UnhandledException : public AllStatic {
  public:
+  static word exception_offset();
+  static word stacktrace_offset();
   static word InstanceSize();
   static word NextFieldOffset();
 };
@@ -945,6 +952,10 @@
 
 class Thread : public AllStatic {
  public:
+  static word api_top_scope_offset();
+  static word exit_through_ffi_offset();
+  static uword exit_through_runtime_call();
+  static uword exit_through_ffi();
   static word dart_stream_offset();
   static word async_stack_trace_offset();
   static word predefined_symbols_address_offset();
diff --git a/runtime/vm/compiler/runtime_offsets_extracted.h b/runtime/vm/compiler/runtime_offsets_extracted.h
index bc994c1..b7e6bda 100644
--- a/runtime/vm/compiler/runtime_offsets_extracted.h
+++ b/runtime/vm/compiler/runtime_offsets_extracted.h
@@ -159,6 +159,7 @@
     LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     20;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
@@ -197,9 +198,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    692;
+    704;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -224,6 +225,7 @@
     Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 740;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
@@ -236,7 +238,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 = 728;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 748;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -254,7 +256,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    712;
+    724;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -274,13 +276,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    700;
+    712;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    736;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
@@ -315,11 +319,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 = 704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 708;
+    Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    716;
+    728;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -352,7 +356,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 = 720;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 732;
 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;
@@ -371,6 +375,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -390,7 +398,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -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;
@@ -442,7 +450,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     64;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28;
-static constexpr dart::compiler::target::word Library_InstanceSize = 76;
+static constexpr dart::compiler::target::word Library_InstanceSize = 80;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -640,6 +648,7 @@
     LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     40;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
@@ -679,9 +688,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1392;
+    1416;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -706,6 +715,8 @@
     Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1488;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
@@ -718,7 +729,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 = 1464;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1504;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -736,7 +747,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1432;
+    1456;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -756,13 +767,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1480;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
@@ -797,11 +810,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 = 1416;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1440;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1424;
+    Thread_saved_shadow_call_stack_offset = 1448;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -835,7 +848,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -855,6 +868,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -874,8 +891,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
-        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
+        1328, 1336, 1344, 1352, -1,   -1,   1360, 1368,
+        1376, 1384, 1392, -1,   1400, 1408, -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;
@@ -927,7 +944,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     128;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 144;
+static constexpr dart::compiler::target::word Library_InstanceSize = 152;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -1124,6 +1141,7 @@
     LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     20;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
@@ -1162,9 +1180,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    660;
+    672;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    664;
+    676;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -1189,6 +1207,7 @@
     Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 708;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
@@ -1201,7 +1220,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 = 696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 716;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1219,7 +1238,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    680;
+    692;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -1239,13 +1258,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    668;
+    680;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    704;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
@@ -1280,11 +1301,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 = 672;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 684;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 676;
+    Thread_saved_shadow_call_stack_offset = 688;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    684;
+    696;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -1317,7 +1338,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 = 688;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 700;
 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;
@@ -1336,6 +1357,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -1404,7 +1429,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     64;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28;
-static constexpr dart::compiler::target::word Library_InstanceSize = 76;
+static constexpr dart::compiler::target::word Library_InstanceSize = 80;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -1602,6 +1627,7 @@
     LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     40;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
@@ -1641,9 +1667,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -1668,6 +1694,8 @@
     Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1560;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
@@ -1680,7 +1708,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 = 1536;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1576;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -1698,7 +1726,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -1718,13 +1746,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1552;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
@@ -1759,11 +1789,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 = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -1797,7 +1827,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -1817,6 +1847,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -1836,9 +1870,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        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};
+        1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408,
+        1416, 1424, 1432, 1440, -1,   -1,   -1,   -1,   1448, 1456, -1,
+        -1,   1464, 1472, 1480, -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;
@@ -1890,7 +1924,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     128;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 144;
+static constexpr dart::compiler::target::word Library_InstanceSize = 152;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -2086,6 +2120,7 @@
     LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     20;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
@@ -2124,9 +2159,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    692;
+    704;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    696;
+    708;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -2151,6 +2186,7 @@
     Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 740;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
@@ -2163,7 +2199,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 = 728;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 748;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2181,7 +2217,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    712;
+    724;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -2201,13 +2237,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    700;
+    712;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    736;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
@@ -2242,11 +2280,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 = 704;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 708;
+    Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    716;
+    728;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -2279,7 +2317,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 = 720;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 732;
 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;
@@ -2298,6 +2336,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -2314,7 +2356,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -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;
@@ -2366,7 +2408,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     64;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28;
-static constexpr dart::compiler::target::word Library_InstanceSize = 76;
+static constexpr dart::compiler::target::word Library_InstanceSize = 80;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -2561,6 +2603,7 @@
     LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     40;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
@@ -2600,9 +2643,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1392;
+    1416;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1400;
+    1424;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -2627,6 +2670,8 @@
     Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1488;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
@@ -2639,7 +2684,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 = 1464;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1504;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -2657,7 +2702,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1432;
+    1456;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -2677,13 +2722,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1408;
+    1432;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1480;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
@@ -2718,11 +2765,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 = 1416;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1440;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1424;
+    Thread_saved_shadow_call_stack_offset = 1448;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1440;
+    1464;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -2756,7 +2803,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -2776,6 +2823,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -2792,8 +2843,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
-        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
+        1328, 1336, 1344, 1352, -1,   -1,   1360, 1368,
+        1376, 1384, 1392, -1,   1400, 1408, -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;
@@ -2845,7 +2896,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     128;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 144;
+static constexpr dart::compiler::target::word Library_InstanceSize = 152;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -3039,6 +3090,7 @@
     LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     20;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 4;
@@ -3077,9 +3129,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 368;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    660;
+    672;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    664;
+    676;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -3104,6 +3156,7 @@
     Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset = 708;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     96;
 static constexpr dart::compiler::target::word
@@ -3116,7 +3169,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 = 696;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 716;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -3134,7 +3187,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 244;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    680;
+    692;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -3154,13 +3207,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 364;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    668;
+    680;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    704;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     68;
@@ -3195,11 +3250,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 = 672;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 684;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 676;
+    Thread_saved_shadow_call_stack_offset = 688;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    684;
+    696;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -3232,7 +3287,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 = 688;
+static constexpr dart::compiler::target::word Thread_callback_code_offset = 700;
 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;
@@ -3251,6 +3306,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -3316,7 +3375,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     64;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 28;
-static constexpr dart::compiler::target::word Library_InstanceSize = 76;
+static constexpr dart::compiler::target::word Library_InstanceSize = 80;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 20;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 28;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -3511,6 +3570,7 @@
     LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word LinkedHashMap_used_data_offset =
     40;
+static constexpr dart::compiler::target::word LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word MarkingStackBlock_top_offset = 8;
@@ -3550,9 +3610,9 @@
 static constexpr dart::compiler::target::word
     Thread_AllocateArray_entry_point_offset = 720;
 static constexpr dart::compiler::target::word Thread_active_exception_offset =
-    1464;
+    1488;
 static constexpr dart::compiler::target::word Thread_active_stacktrace_offset =
-    1472;
+    1496;
 static constexpr dart::compiler::target::word
     Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -3577,6 +3637,8 @@
     Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word Thread_api_top_scope_offset =
+    1560;
 static constexpr dart::compiler::target::word Thread_async_stack_trace_offset =
     192;
 static constexpr dart::compiler::target::word
@@ -3589,7 +3651,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 = 1536;
+static constexpr dart::compiler::target::word Thread_dart_stream_offset = 1576;
 static constexpr dart::compiler::target::word
     Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word Thread_optimize_entry_offset =
@@ -3607,7 +3669,7 @@
 static constexpr dart::compiler::target::word
     Thread_enter_safepoint_stub_offset = 472;
 static constexpr dart::compiler::target::word Thread_execution_state_offset =
-    1504;
+    1528;
 static constexpr dart::compiler::target::word
     Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -3627,13 +3689,15 @@
 static constexpr dart::compiler::target::word
     Thread_float_zerow_address_offset = 712;
 static constexpr dart::compiler::target::word Thread_global_object_pool_offset =
-    1480;
+    1504;
 static constexpr dart::compiler::target::word
     Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word Thread_exit_through_ffi_offset =
+    1552;
 static constexpr dart::compiler::target::word Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word Thread_field_table_values_offset =
     136;
@@ -3668,11 +3732,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 = 1488;
+static constexpr dart::compiler::target::word Thread_resume_pc_offset = 1512;
 static constexpr dart::compiler::target::word
-    Thread_saved_shadow_call_stack_offset = 1496;
+    Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word Thread_safepoint_state_offset =
-    1512;
+    1536;
 static constexpr dart::compiler::target::word
     Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -3706,7 +3770,7 @@
 static constexpr dart::compiler::target::word Thread_write_barrier_mask_offset =
     80;
 static constexpr dart::compiler::target::word Thread_callback_code_offset =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word TimelineStream_enabled_offset =
     16;
 static constexpr dart::compiler::target::word TwoByteString_data_offset = 16;
@@ -3726,6 +3790,10 @@
 static constexpr dart::compiler::target::word
     TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -3742,9 +3810,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     Thread_write_barrier_wrappers_thread_offset[] = {
-        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};
+        1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408,
+        1416, 1424, 1432, 1440, -1,   -1,   -1,   -1,   1448, 1456, -1,
+        -1,   1464, 1472, 1480, -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;
@@ -3796,7 +3864,7 @@
 static constexpr dart::compiler::target::word KernelProgramInfo_InstanceSize =
     128;
 static constexpr dart::compiler::target::word LanguageError_InstanceSize = 48;
-static constexpr dart::compiler::target::word Library_InstanceSize = 144;
+static constexpr dart::compiler::target::word Library_InstanceSize = 152;
 static constexpr dart::compiler::target::word LibraryPrefix_InstanceSize = 40;
 static constexpr dart::compiler::target::word LinkedHashMap_InstanceSize = 56;
 static constexpr dart::compiler::target::word LocalVarDescriptors_InstanceSize =
@@ -3996,6 +4064,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 20;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -4044,9 +4113,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 = 692;
+    AOT_Thread_active_exception_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 696;
+    AOT_Thread_active_stacktrace_offset = 708;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -4071,6 +4140,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    740;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 96;
 static constexpr dart::compiler::target::word
@@ -4085,7 +4156,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 =
-    728;
+    748;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -4104,7 +4175,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 = 712;
+    AOT_Thread_execution_state_offset = 724;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -4124,13 +4195,15 @@
 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 = 700;
+    AOT_Thread_global_object_pool_offset = 712;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 736;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
@@ -4166,11 +4239,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 = 704;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 708;
+    AOT_Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 716;
+    AOT_Thread_safepoint_state_offset = 728;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -4206,7 +4279,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 =
-    720;
+    732;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4230,6 +4303,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -4251,7 +4328,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -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;
@@ -4307,7 +4384,7 @@
     AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     28;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 72;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 76;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     20;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -4519,6 +4596,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -4567,9 +4645,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 = 1392;
+    AOT_Thread_active_exception_offset = 1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1400;
+    AOT_Thread_active_stacktrace_offset = 1424;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -4594,6 +4672,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    1488;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
@@ -4608,7 +4688,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 =
-    1464;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -4627,7 +4707,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 = 1432;
+    AOT_Thread_execution_state_offset = 1456;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -4647,13 +4727,15 @@
 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 = 1408;
+    AOT_Thread_global_object_pool_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 1480;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
@@ -4690,11 +4772,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 =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1424;
+    AOT_Thread_saved_shadow_call_stack_offset = 1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1440;
+    AOT_Thread_safepoint_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -4730,7 +4812,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 =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -4754,6 +4836,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -4775,8 +4861,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
-        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
+        1328, 1336, 1344, 1352, -1,   -1,   1360, 1368,
+        1376, 1384, 1392, -1,   1400, 1408, -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;
@@ -4833,7 +4919,7 @@
     AOT_KernelProgramInfo_InstanceSize = 128;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 136;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 144;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -5048,6 +5134,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -5096,9 +5183,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 = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -5123,6 +5210,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    1560;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
@@ -5137,7 +5226,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 =
-    1536;
+    1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -5156,7 +5245,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 = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -5176,13 +5265,15 @@
 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 = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 1552;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
@@ -5219,11 +5310,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 =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -5259,7 +5350,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 =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5283,6 +5374,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -5304,9 +5399,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        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};
+        1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408,
+        1416, 1424, 1432, 1440, -1,   -1,   -1,   -1,   1448, 1456, -1,
+        -1,   1464, 1472, 1480, -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;
@@ -5363,7 +5458,7 @@
     AOT_KernelProgramInfo_InstanceSize = 128;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 136;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 144;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -5572,6 +5667,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 4;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 20;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 8;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -5620,9 +5716,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 = 692;
+    AOT_Thread_active_exception_offset = 704;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 696;
+    AOT_Thread_active_stacktrace_offset = 708;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 128;
 static constexpr dart::compiler::target::word
@@ -5647,6 +5743,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 284;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 192;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    740;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 96;
 static constexpr dart::compiler::target::word
@@ -5661,7 +5759,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 =
-    728;
+    748;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 48;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -5680,7 +5778,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 = 712;
+    AOT_Thread_execution_state_offset = 724;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 248;
 static constexpr dart::compiler::target::word
@@ -5700,13 +5798,15 @@
 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 = 700;
+    AOT_Thread_global_object_pool_offset = 712;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 332;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 144;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 140;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 736;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 44;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 68;
@@ -5742,11 +5842,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 = 704;
+static constexpr dart::compiler::target::word AOT_Thread_resume_pc_offset = 716;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 708;
+    AOT_Thread_saved_shadow_call_stack_offset = 720;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 716;
+    AOT_Thread_safepoint_state_offset = 728;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 236;
 static constexpr dart::compiler::target::word
@@ -5782,7 +5882,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 =
-    720;
+    732;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 8;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -5806,6 +5906,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 16;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 12;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 4;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 8;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 8;
@@ -5824,7 +5928,7 @@
     4, 12, 8, 16};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        660, 664, 668, 672, 676, -1, 680, -1, 684, 688, -1, -1, -1, -1, -1, -1};
+        672, 676, 680, 684, 688, -1, 692, -1, 696, 700, -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;
@@ -5880,7 +5984,7 @@
     AOT_KernelProgramInfo_InstanceSize = 64;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     28;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 72;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 76;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     20;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -6088,6 +6192,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -6136,9 +6241,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 = 1392;
+    AOT_Thread_active_exception_offset = 1416;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1400;
+    AOT_Thread_active_stacktrace_offset = 1424;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -6163,6 +6268,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    1488;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
@@ -6177,7 +6284,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 =
-    1464;
+    1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -6196,7 +6303,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 = 1432;
+    AOT_Thread_execution_state_offset = 1456;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -6216,13 +6323,15 @@
 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 = 1408;
+    AOT_Thread_global_object_pool_offset = 1432;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 1480;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
@@ -6259,11 +6368,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 =
-    1416;
+    1440;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1424;
+    AOT_Thread_saved_shadow_call_stack_offset = 1448;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1440;
+    AOT_Thread_safepoint_state_offset = 1464;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -6299,7 +6408,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 =
-    1448;
+    1472;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6323,6 +6432,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -6341,8 +6454,8 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        1304, 1312, 1320, 1328, -1,   -1,   1336, 1344,
-        1352, 1360, 1368, -1,   1376, 1384, -1,   -1};
+        1328, 1336, 1344, 1352, -1,   -1,   1360, 1368,
+        1376, 1384, 1392, -1,   1400, 1408, -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;
@@ -6399,7 +6512,7 @@
     AOT_KernelProgramInfo_InstanceSize = 128;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 136;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 144;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
@@ -6610,6 +6723,7 @@
     AOT_LinkedHashMap_type_arguments_offset = 8;
 static constexpr dart::compiler::target::word
     AOT_LinkedHashMap_used_data_offset = 40;
+static constexpr dart::compiler::target::word AOT_LocalHandle_raw_offset = 0;
 static constexpr dart::compiler::target::word
     AOT_MarkingStackBlock_pointers_offset = 16;
 static constexpr dart::compiler::target::word AOT_MarkingStackBlock_top_offset =
@@ -6658,9 +6772,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 = 1464;
+    AOT_Thread_active_exception_offset = 1488;
 static constexpr dart::compiler::target::word
-    AOT_Thread_active_stacktrace_offset = 1472;
+    AOT_Thread_active_stacktrace_offset = 1496;
 static constexpr dart::compiler::target::word
     AOT_Thread_array_write_barrier_code_offset = 240;
 static constexpr dart::compiler::target::word
@@ -6685,6 +6799,8 @@
     AOT_Thread_allocate_object_slow_entry_point_offset = 552;
 static constexpr dart::compiler::target::word
     AOT_Thread_allocate_object_slow_stub_offset = 368;
+static constexpr dart::compiler::target::word AOT_Thread_api_top_scope_offset =
+    1560;
 static constexpr dart::compiler::target::word
     AOT_Thread_async_stack_trace_offset = 192;
 static constexpr dart::compiler::target::word
@@ -6699,7 +6815,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 =
-    1536;
+    1576;
 static constexpr dart::compiler::target::word
     AOT_Thread_dispatch_table_array_offset = 96;
 static constexpr dart::compiler::target::word AOT_Thread_optimize_entry_offset =
@@ -6718,7 +6834,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 = 1504;
+    AOT_Thread_execution_state_offset = 1528;
 static constexpr dart::compiler::target::word
     AOT_Thread_exit_safepoint_stub_offset = 480;
 static constexpr dart::compiler::target::word
@@ -6738,13 +6854,15 @@
 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 = 1480;
+    AOT_Thread_global_object_pool_offset = 1504;
 static constexpr dart::compiler::target::word
     AOT_Thread_interpret_call_entry_point_offset = 648;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_from_bytecode_stub_offset = 272;
 static constexpr dart::compiler::target::word
     AOT_Thread_invoke_dart_code_stub_offset = 264;
+static constexpr dart::compiler::target::word
+    AOT_Thread_exit_through_ffi_offset = 1552;
 static constexpr dart::compiler::target::word AOT_Thread_isolate_offset = 88;
 static constexpr dart::compiler::target::word
     AOT_Thread_field_table_values_offset = 136;
@@ -6781,11 +6899,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 =
-    1488;
+    1512;
 static constexpr dart::compiler::target::word
-    AOT_Thread_saved_shadow_call_stack_offset = 1496;
+    AOT_Thread_saved_shadow_call_stack_offset = 1520;
 static constexpr dart::compiler::target::word
-    AOT_Thread_safepoint_state_offset = 1512;
+    AOT_Thread_safepoint_state_offset = 1536;
 static constexpr dart::compiler::target::word
     AOT_Thread_slow_type_test_stub_offset = 456;
 static constexpr dart::compiler::target::word
@@ -6821,7 +6939,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 =
-    1520;
+    1544;
 static constexpr dart::compiler::target::word
     AOT_TimelineStream_enabled_offset = 16;
 static constexpr dart::compiler::target::word AOT_TwoByteString_data_offset =
@@ -6845,6 +6963,10 @@
 static constexpr dart::compiler::target::word
     AOT_TypedDataView_offset_in_bytes_offset = 32;
 static constexpr dart::compiler::target::word AOT_TypedData_data_offset = 24;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_exception_offset = 8;
+static constexpr dart::compiler::target::word
+    AOT_UnhandledException_stacktrace_offset = 16;
 static constexpr dart::compiler::target::word AOT_UserTag_tag_offset = 16;
 static constexpr dart::compiler::target::word
     AOT_MonomorphicSmiableCall_expected_cid_offset = 16;
@@ -6863,9 +6985,9 @@
     8, 24, 16, 32};
 static constexpr dart::compiler::target::word
     AOT_Thread_write_barrier_wrappers_thread_offset[] = {
-        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};
+        1328, 1336, 1344, 1352, 1360, 1368, 1376, 1384, 1392, 1400, 1408,
+        1416, 1424, 1432, 1440, -1,   -1,   -1,   -1,   1448, 1456, -1,
+        -1,   1464, 1472, 1480, -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;
@@ -6922,7 +7044,7 @@
     AOT_KernelProgramInfo_InstanceSize = 128;
 static constexpr dart::compiler::target::word AOT_LanguageError_InstanceSize =
     48;
-static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 136;
+static constexpr dart::compiler::target::word AOT_Library_InstanceSize = 144;
 static constexpr dart::compiler::target::word AOT_LibraryPrefix_InstanceSize =
     40;
 static constexpr dart::compiler::target::word AOT_LinkedHashMap_InstanceSize =
diff --git a/runtime/vm/compiler/runtime_offsets_list.h b/runtime/vm/compiler/runtime_offsets_list.h
index 36b717a..3cbb19d 100644
--- a/runtime/vm/compiler/runtime_offsets_list.h
+++ b/runtime/vm/compiler/runtime_offsets_list.h
@@ -120,6 +120,7 @@
   FIELD(LinkedHashMap, index_offset)                                           \
   FIELD(LinkedHashMap, type_arguments_offset)                                  \
   FIELD(LinkedHashMap, used_data_offset)                                       \
+  FIELD(LocalHandle, raw_offset)                                               \
   FIELD(MarkingStackBlock, pointers_offset)                                    \
   FIELD(MarkingStackBlock, top_offset)                                         \
   FIELD(MegamorphicCache, buckets_offset)                                      \
@@ -159,6 +160,7 @@
   FIELD(Thread, allocate_object_parameterized_stub_offset)                     \
   FIELD(Thread, allocate_object_slow_entry_point_offset)                       \
   FIELD(Thread, allocate_object_slow_stub_offset)                              \
+  FIELD(Thread, api_top_scope_offset)                                          \
   FIELD(Thread, async_stack_trace_offset)                                      \
   FIELD(Thread, auto_scope_native_wrapper_entry_point_offset)                  \
   FIELD(Thread, bool_false_offset)                                             \
@@ -190,6 +192,7 @@
   FIELD(Thread, interpret_call_entry_point_offset)                             \
   FIELD(Thread, invoke_dart_code_from_bytecode_stub_offset)                    \
   FIELD(Thread, invoke_dart_code_stub_offset)                                  \
+  FIELD(Thread, exit_through_ffi_offset)                                       \
   FIELD(Thread, isolate_offset)                                                \
   FIELD(Thread, field_table_values_offset)                                     \
   FIELD(Thread, lazy_deopt_from_return_stub_offset)                            \
@@ -247,6 +250,8 @@
   FIELD(TypedDataView, data_offset)                                            \
   FIELD(TypedDataView, offset_in_bytes_offset)                                 \
   FIELD(TypedData, data_offset)                                                \
+  FIELD(UnhandledException, exception_offset)                                  \
+  FIELD(UnhandledException, stacktrace_offset)                                 \
   FIELD(UserTag, tag_offset)                                                   \
   FIELD(MonomorphicSmiableCall, expected_cid_offset)                           \
   FIELD(MonomorphicSmiableCall, entrypoint_offset)                             \
diff --git a/runtime/vm/compiler/stub_code_compiler.cc b/runtime/vm/compiler/stub_code_compiler.cc
index 8f96b82..c02a246 100644
--- a/runtime/vm/compiler/stub_code_compiler.cc
+++ b/runtime/vm/compiler/stub_code_compiler.cc
@@ -5,6 +5,9 @@
 #include "vm/compiler/runtime_api.h"
 #include "vm/globals.h"
 
+// For `StubCodeCompiler::GenerateAllocateUnhandledExceptionStub`
+#include "vm/compiler/backend/il.h"
+
 #define SHOULD_NOT_INCLUDE_RUNTIME
 
 #include "vm/compiler/stub_code_compiler.h"
@@ -162,6 +165,22 @@
   __ Ret();
 }
 
+// The UnhandledException class lives in the VM isolate, so it cannot cache
+// an allocation stub for itself. Instead, we cache it in the stub code list.
+void StubCodeCompiler::GenerateAllocateUnhandledExceptionStub(
+    Assembler* assembler) {
+  Thread* thread = Thread::Current();
+  auto class_table = thread->isolate()->class_table();
+  ASSERT(class_table->HasValidClassAt(kUnhandledExceptionCid));
+  const auto& cls = Class::ZoneHandle(thread->zone(),
+                                      class_table->At(kUnhandledExceptionCid));
+  ASSERT(!cls.IsNull());
+
+  GenerateAllocationStubForClass(assembler, nullptr, cls,
+                                 Code::Handle(Code::null()),
+                                 Code::Handle(Code::null()));
+}
+
 }  // namespace compiler
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index 997d851..24a50e7 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -86,6 +86,10 @@
   __ StoreToOffset(kWord, FP, THR,
                    target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R8, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -135,8 +139,11 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
   __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(kWord, R2, THR,
                    target::Thread::top_exit_frame_info_offset());
 
@@ -349,6 +356,7 @@
   // TransitionGeneratedToNative might clobber LR if it takes the slow path.
   __ mov(R4, Operand(LR));
 
+  __ LoadImmediate(R9, target::Thread::exit_through_ffi());
   __ TransitionGeneratedToNative(R8, FPREG, R9 /*volatile*/, NOTFP,
                                  /*enter_safepoint=*/true);
 
@@ -583,6 +591,10 @@
   __ StoreToOffset(kWord, FP, THR,
                    target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R8, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -638,8 +650,11 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
   __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(kWord, R2, THR,
                    target::Thread::top_exit_frame_info_offset());
 
@@ -1243,21 +1258,27 @@
 
   // Save top resource and top exit frame info. Use R4-6 as temporary registers.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R9, THR,
-                    target::Thread::top_exit_frame_info_offset());
   __ LoadFromOffset(kWord, R4, THR, target::Thread::top_resource_offset());
+  __ Push(R4);
   __ LoadImmediate(R8, 0);
   __ StoreToOffset(kWord, R8, THR, target::Thread::top_resource_offset());
+
+  __ LoadFromOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ Push(R8);
+  __ LoadImmediate(R8, 0);
+  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+
+  __ LoadFromOffset(kWord, R9, THR,
+                    target::Thread::top_exit_frame_info_offset());
   __ StoreToOffset(kWord, R8, THR,
                    target::Thread::top_exit_frame_info_offset());
 
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
-  __ Push(R4);
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -26);
-#else
   ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -27);
+#else
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -28);
 #endif
   __ Push(R9);
 
@@ -1320,6 +1341,8 @@
   __ StoreToOffset(kWord, R9, THR,
                    target::Thread::top_exit_frame_info_offset());
   __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, target::Thread::exit_through_ffi_offset());
+  __ Pop(R9);
   __ StoreToOffset(kWord, R9, THR, target::Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
@@ -1390,21 +1413,27 @@
 
   // Save top resource and top exit frame info. Use R4-6 as temporary registers.
   // StackFrameIterator reads the top exit frame info saved in this frame.
-  __ LoadFromOffset(kWord, R9, THR,
-                    target::Thread::top_exit_frame_info_offset());
   __ LoadFromOffset(kWord, R4, THR, target::Thread::top_resource_offset());
+  __ Push(R4);
   __ LoadImmediate(R8, 0);
   __ StoreToOffset(kWord, R8, THR, target::Thread::top_resource_offset());
+
+  __ LoadFromOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+  __ Push(R8);
+  __ LoadImmediate(R8, 0);
+  __ StoreToOffset(kWord, R8, THR, target::Thread::exit_through_ffi_offset());
+
+  __ LoadFromOffset(kWord, R9, THR,
+                    target::Thread::top_exit_frame_info_offset());
   __ StoreToOffset(kWord, R8, THR,
                    target::Thread::top_exit_frame_info_offset());
 
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
-  __ Push(R4);
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -26);
-#else
   ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -27);
+#else
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -28);
 #endif
   __ Push(R9);
 
@@ -1458,6 +1487,8 @@
   __ StoreToOffset(kWord, R9, THR,
                    target::Thread::top_exit_frame_info_offset());
   __ Pop(R9);
+  __ StoreToOffset(kWord, R9, THR, target::Thread::exit_through_ffi_offset());
+  __ Pop(R9);
   __ StoreToOffset(kWord, R9, THR, target::Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
@@ -2764,6 +2795,10 @@
   __ StoreToOffset(kWord, FP, THR,
                    target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R5, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(kWord, R5, THR, target::Thread::exit_through_ffi_offset());
+
   // Mark that the thread is executing VM code.
   __ LoadFromOffset(kWord, R5, THR,
                     target::Thread::interpret_call_entry_point_offset());
@@ -2775,8 +2810,11 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
   __ LoadImmediate(R2, 0);
+  __ StoreToOffset(kWord, R2, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(kWord, R2, THR,
                    target::Thread::top_exit_frame_info_offset());
 
@@ -3251,6 +3289,18 @@
 #if defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
+  Label exit_through_non_ffi;
+  Register tmp1 = R0, tmp2 = R1;
+  // Check if we exited generated from FFI. If so do transition.
+  __ LoadFromOffset(kWord, tmp1, THR,
+                    compiler::target::Thread::exit_through_ffi_offset());
+  __ LoadImmediate(tmp2, target::Thread::exit_through_ffi());
+  __ cmp(tmp1, Operand(tmp2));
+  __ b(&exit_through_non_ffi, NE);
+  __ TransitionNativeToGenerated(tmp1, tmp2,
+                                 /*leave_safepoint=*/true);
+  __ Bind(&exit_through_non_ffi);
+
   // Set the tag.
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(kWord, R2, THR, target::Thread::vm_tag_offset());
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index b4051d2..f8c009c 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -85,6 +85,10 @@
   // to transition to Dart VM C++ code.
   __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R8, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(R8, THR, target::Thread::exit_through_ffi_offset());
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -156,7 +160,11 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(R2, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
 
   // Restore the global object pool after returning from runtime (old space is
@@ -294,6 +302,7 @@
   COMPILE_ASSERT((1 << R19) & kAbiPreservedCpuRegs);
 
   __ mov(R19, LR);
+  __ LoadImmediate(R9, target::Thread::exit_through_ffi());
   __ TransitionGeneratedToNative(R8, FPREG, R9 /*volatile*/,
                                  /*enter_safepoint=*/true);
   __ mov(R25, CSP);
@@ -626,6 +635,10 @@
   // to transition to native code.
   __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R6, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -697,7 +710,11 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ LoadImmediate(R2, 0);
+  __ StoreToOffset(R2, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
 
   // Restore the global object pool after returning from runtime (old space is
@@ -1340,14 +1357,20 @@
   __ LoadFromOffset(R6, THR, target::Thread::top_resource_offset());
   __ StoreToOffset(ZR, THR, target::Thread::top_resource_offset());
   __ Push(R6);
+
+  __ LoadFromOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+  __ Push(R6);
+  __ LoadImmediate(R6, 0);
+  __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+
   __ LoadFromOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
 #if defined(TARGET_OS_FUCHSIA)
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -24);
 #else
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
 #endif
   __ Push(R6);
 
@@ -1412,6 +1435,8 @@
   __ Pop(R6);
   __ StoreToOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
   __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+  __ Pop(R6);
   __ StoreToOffset(R6, THR, target::Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
@@ -1491,14 +1516,20 @@
   __ LoadFromOffset(R6, THR, target::Thread::top_resource_offset());
   __ StoreToOffset(ZR, THR, target::Thread::top_resource_offset());
   __ Push(R6);
+
+  __ LoadFromOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+  __ Push(R6);
+  __ LoadImmediate(R6, 0);
+  __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+
   __ LoadFromOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
   // target::frame_layout.exit_link_slot_from_entry_fp must be kept in sync
   // with the code below.
 #if defined(TARGET_OS_FUCHSIA)
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -24);
 #else
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -22);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -23);
 #endif
   __ Push(R6);
 
@@ -1555,6 +1586,8 @@
   __ Pop(R6);
   __ StoreToOffset(R6, THR, target::Thread::top_exit_frame_info_offset());
   __ Pop(R6);
+  __ StoreToOffset(R6, THR, target::Thread::exit_through_ffi_offset());
+  __ Pop(R6);
   __ StoreToOffset(R6, THR, target::Thread::top_resource_offset());
 
   // Restore the current VMTag from the stack.
@@ -1959,7 +1992,7 @@
 
     // Dirty the card.
     __ AndImmediate(TMP, R1, target::kOldPageMask);  // OldPage.
-    __ sub(R25, R25, Operand(TMP));               // Offset in page.
+    __ sub(R25, R25, Operand(TMP));                  // Offset in page.
     __ ldr(TMP,
            Address(TMP, target::OldPage::card_table_offset()));  // Card table.
     __ add(TMP, TMP,
@@ -2894,6 +2927,10 @@
   // to transition to Dart VM C++ code.
   __ StoreToOffset(FP, THR, target::Thread::top_exit_frame_info_offset());
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ LoadImmediate(R5, target::Thread::exit_through_runtime_call());
+  __ StoreToOffset(R5, THR, target::Thread::exit_through_ffi_offset());
+
   // Mark that the thread is executing VM code.
   __ LoadFromOffset(R5, THR,
                     target::Thread::interpret_call_entry_point_offset());
@@ -2918,7 +2955,10 @@
   __ LoadImmediate(R2, VMTag::kDartCompiledTagId);
   __ StoreToOffset(R2, THR, target::Thread::vm_tag_offset());
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ StoreToOffset(ZR, THR, target::Thread::exit_through_ffi_offset());
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ StoreToOffset(ZR, THR, target::Thread::top_exit_frame_info_offset());
 
   __ LeaveStubFrame();
@@ -3378,6 +3418,17 @@
 #elif defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
+  Label exit_through_non_ffi;
+  Register tmp1 = R0, tmp2 = R1;
+  // Check if we exited generated from FFI. If so do transition.
+  __ LoadFromOffset(tmp1, THR,
+                    compiler::target::Thread::exit_through_ffi_offset());
+  __ LoadImmediate(tmp2, target::Thread::exit_through_ffi());
+  __ cmp(tmp1, Operand(tmp2));
+  __ b(&exit_through_non_ffi, NE);
+  __ TransitionNativeToGenerated(tmp1, /*leave_safepoint=*/true);
+  __ Bind(&exit_through_non_ffi);
+
   // Refresh pinned registers values (inc. write barrier mask and null object).
   __ RestorePinnedRegisters();
   // Set the tag.
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index a4d8449..20e25d5 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -85,6 +85,10 @@
   // to transition to Dart VM C++ code.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -124,7 +128,11 @@
 
   __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -193,6 +201,7 @@
     Assembler* assembler) {
   __ popl(EBX);
 
+  __ movl(ECX, compiler::Immediate(target::Thread::exit_through_ffi()));
   __ TransitionGeneratedToNative(EAX, FPREG, ECX /*volatile*/,
                                  /*enter_safepoint=*/true);
   __ call(EAX);
@@ -373,6 +382,10 @@
   // to transition to dart VM code.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -415,7 +428,11 @@
 
   __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -946,9 +963,13 @@
   __ movl(EDX, Address(THR, target::Thread::top_resource_offset()));
   __ pushl(EDX);
   __ movl(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+  __ movl(EAX, Address(THR, target::Thread::exit_through_ffi_offset()));
+  __ pushl(EAX);
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
   // The constant target::frame_layout.exit_link_slot_from_entry_fp must be
   // kept in sync with the code below.
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -7);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -8);
   __ movl(EDX, Address(THR, target::Thread::top_exit_frame_info_offset()));
   __ pushl(EDX);
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
@@ -1012,6 +1033,7 @@
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure.
   __ popl(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popl(Address(THR, target::Thread::exit_through_ffi_offset()));
   __ popl(Address(THR, target::Thread::top_resource_offset()));
 
   // Restore the current VMTag from the stack.
@@ -1075,9 +1097,15 @@
   __ movl(EDX, Address(THR, target::Thread::top_resource_offset()));
   __ pushl(EDX);
   __ movl(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+
+  __ movl(EAX, Address(THR, target::Thread::exit_through_ffi_offset()));
+  __ pushl(EAX);
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
   // The constant target::frame_layout.exit_link_slot_from_entry_fp must be
   // kept in sync with the code below.
-  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -7);
+  ASSERT(target::frame_layout.exit_link_slot_from_entry_fp == -8);
   __ movl(EDX, Address(THR, target::Thread::top_exit_frame_info_offset()));
   __ pushl(EDX);
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
@@ -1133,6 +1161,7 @@
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure.
   __ popl(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popl(Address(THR, target::Thread::exit_through_ffi_offset()));
   __ popl(Address(THR, target::Thread::top_resource_offset()));
 
   // Restore the current VMTag from the stack.
@@ -1185,48 +1214,48 @@
   // EDX: number of context variables.
   __ cmpl(EBX, Address(THR, target::Thread::end_offset()));
 #if defined(DEBUG)
-    static const bool kJumpLength = Assembler::kFarJump;
+  static const bool kJumpLength = Assembler::kFarJump;
 #else
-    static const bool kJumpLength = Assembler::kNearJump;
+  static const bool kJumpLength = Assembler::kNearJump;
 #endif  // DEBUG
-    __ j(ABOVE_EQUAL, slow_case, kJumpLength);
+  __ j(ABOVE_EQUAL, slow_case, kJumpLength);
 
-    // Successfully allocated the object, now update top to point to
-    // next object start and initialize the object.
-    // EAX: new object.
-    // EBX: next object start.
-    // EDX: number of context variables.
-    __ movl(Address(THR, target::Thread::top_offset()), EBX);
-    // EBX: Size of allocation in bytes.
-    __ subl(EBX, EAX);
-    __ addl(EAX, Immediate(kHeapObjectTag));
-    // Generate isolate-independent code to allow sharing between isolates.
+  // Successfully allocated the object, now update top to point to
+  // next object start and initialize the object.
+  // EAX: new object.
+  // EBX: next object start.
+  // EDX: number of context variables.
+  __ movl(Address(THR, target::Thread::top_offset()), EBX);
+  // EBX: Size of allocation in bytes.
+  __ subl(EBX, EAX);
+  __ addl(EAX, Immediate(kHeapObjectTag));
+  // Generate isolate-independent code to allow sharing between isolates.
 
-    // Calculate the size tag.
+  // Calculate the size tag.
+  // EAX: new object.
+  // EDX: number of context variables.
+  {
+    Label size_tag_overflow, done;
+    __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
+    __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
+    __ cmpl(EBX, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
+    __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
+    __ shll(EBX, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
+                           target::ObjectAlignment::kObjectAlignmentLog2));
+    __ jmp(&done);
+
+    __ Bind(&size_tag_overflow);
+    // Set overflow size tag value.
+    __ movl(EBX, Immediate(0));
+
+    __ Bind(&done);
     // EAX: new object.
     // EDX: number of context variables.
-    {
-      Label size_tag_overflow, done;
-      __ leal(EBX, Address(EDX, TIMES_4, fixed_size_plus_alignment_padding));
-      __ andl(EBX, Immediate(-target::ObjectAlignment::kObjectAlignment));
-      __ cmpl(EBX, Immediate(target::ObjectLayout::kSizeTagMaxSizeTag));
-      __ j(ABOVE, &size_tag_overflow, Assembler::kNearJump);
-      __ shll(EBX, Immediate(target::ObjectLayout::kTagBitsSizeTagPos -
-                             target::ObjectAlignment::kObjectAlignmentLog2));
-      __ jmp(&done);
-
-      __ Bind(&size_tag_overflow);
-      // Set overflow size tag value.
-      __ movl(EBX, Immediate(0));
-
-      __ Bind(&done);
-      // EAX: new object.
-      // EDX: number of context variables.
-      // EBX: size and bit tags.
-      uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
-      __ orl(EBX, Immediate(tags));
-      __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX);  // Tags.
-    }
+    // EBX: size and bit tags.
+    uint32_t tags = target::MakeTagWordForNewSpaceObject(kContextCid, 0);
+    __ orl(EBX, Immediate(tags));
+    __ movl(FieldAddress(EAX, target::Object::tags_offset()), EBX);  // Tags.
+  }
 
   // Setup up number of context variables field.
   // EAX: new object.
@@ -2279,6 +2308,10 @@
   // to transition to Dart VM C++ code.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()), EBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
   // Mark that the thread is executing VM code.
   __ movl(EAX,
           Address(THR, target::Thread::interpret_call_entry_point_offset()));
@@ -2291,7 +2324,11 @@
   // Mark that the thread is executing Dart code.
   __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movl(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movl(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -2625,6 +2662,16 @@
 #if defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
+
+  Label exit_through_non_ffi;
+  // Check if we exited generated from FFI. If so do transition.
+  __ cmpl(compiler::Address(
+              THR, compiler::target::Thread::exit_through_ffi_offset()),
+          compiler::Immediate(target::Thread::exit_through_ffi()));
+  __ j(NOT_EQUAL, &exit_through_non_ffi, compiler::Assembler::kNearJump);
+  __ TransitionNativeToGenerated(ECX, /*leave_safepoint=*/true);
+  __ Bind(&exit_through_non_ffi);
+
   // Set tag.
   __ movl(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
   // Clear top exit frame.
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index a11128f..67261a1 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -87,6 +87,10 @@
   // to transition to Dart VM C++ code.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -134,7 +138,11 @@
   // Mark that the thread is executing Dart code.
   __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -255,7 +263,9 @@
 //   RBX, R12 clobbered
 void StubCodeCompiler::GenerateCallNativeThroughSafepointStub(
     Assembler* assembler) {
-  __ TransitionGeneratedToNative(RBX, FPREG, /*enter_safepoint=*/true);
+  __ movq(R12, compiler::Immediate(target::Thread::exit_through_ffi()));
+  __ TransitionGeneratedToNative(RBX, FPREG, R12,
+                                 /*enter_safepoint=*/true);
 
   __ popq(R12);
   __ CallCFunction(RBX);
@@ -574,6 +584,10 @@
   // to transition to native code.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
 #if defined(DEBUG)
   {
     Label ok;
@@ -619,7 +633,11 @@
   // Mark that the thread is executing Dart code.
   __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -1238,6 +1256,12 @@
   __ movq(RAX, Address(THR, target::Thread::top_resource_offset()));
   __ pushq(RAX);
   __ movq(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+
+  __ movq(RAX, Address(THR, target::Thread::exit_through_ffi_offset()));
+  __ pushq(RAX);
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
   __ movq(RAX, Address(THR, target::Thread::top_exit_frame_info_offset()));
   __ pushq(RAX);
 
@@ -1308,6 +1332,7 @@
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure.
   __ popq(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popq(Address(THR, target::Thread::exit_through_ffi_offset()));
   __ popq(Address(THR, target::Thread::top_resource_offset()));
 
   // Restore the current VMTag from the stack.
@@ -1391,6 +1416,12 @@
   __ movq(RAX, Address(THR, target::Thread::top_resource_offset()));
   __ pushq(RAX);
   __ movq(Address(THR, target::Thread::top_resource_offset()), Immediate(0));
+
+  __ movq(RAX, Address(THR, target::Thread::exit_through_ffi_offset()));
+  __ pushq(RAX);
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
   __ movq(RAX, Address(THR, target::Thread::top_exit_frame_info_offset()));
   __ pushq(RAX);
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
@@ -1467,6 +1498,7 @@
   // Restore the saved top exit frame info and top resource back into the
   // Isolate structure.
   __ popq(Address(THR, target::Thread::top_exit_frame_info_offset()));
+  __ popq(Address(THR, target::Thread::exit_through_ffi_offset()));
   __ popq(Address(THR, target::Thread::top_resource_offset()));
 
   // Restore the current VMTag from the stack.
@@ -2805,10 +2837,10 @@
     __ andq(RSP, Immediate(~(OS::ActivationFrameAlignment() - 1)));
   }
 
-  __ movq(CallingConventions::kArg1Reg, RAX);         // Function.
-  __ movq(CallingConventions::kArg2Reg, R10);         // Arguments descriptor.
-  __ movq(CallingConventions::kArg3Reg, R11);         // Negative argc.
-  __ movq(CallingConventions::kArg4Reg, R12);         // Argv.
+  __ movq(CallingConventions::kArg1Reg, RAX);  // Function.
+  __ movq(CallingConventions::kArg2Reg, R10);  // Arguments descriptor.
+  __ movq(CallingConventions::kArg3Reg, R11);  // Negative argc.
+  __ movq(CallingConventions::kArg4Reg, R12);  // Argv.
 
 #if defined(TARGET_OS_WINDOWS)
   __ movq(Address(RSP, 0 * target::kWordSize), THR);  // Thread.
@@ -2819,6 +2851,10 @@
   // to transition to Dart VM C++ code.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()), RBP);
 
+  // Mark that the thread exited generated code through a runtime call.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(target::Thread::exit_through_runtime_call()));
+
   // Mark that the thread is executing VM code.
   __ movq(RAX,
           Address(THR, target::Thread::interpret_call_entry_point_offset()));
@@ -2829,7 +2865,11 @@
   // Mark that the thread is executing Dart code.
   __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
 
-  // Reset exit frame information in Isolate structure.
+  // Mark that the thread has not exited generated Dart code.
+  __ movq(Address(THR, target::Thread::exit_through_ffi_offset()),
+          Immediate(0));
+
+  // Reset exit frame information in Isolate's mutator thread structure.
   __ movq(Address(THR, target::Thread::top_exit_frame_info_offset()),
           Immediate(0));
 
@@ -3292,6 +3332,15 @@
 #if defined(USING_SHADOW_CALL_STACK)
 #error Unimplemented
 #endif
+  Label exit_through_non_ffi;
+  // Check if we exited generated from FFI. If so do transition.
+  __ cmpq(compiler::Address(
+              THR, compiler::target::Thread::exit_through_ffi_offset()),
+          compiler::Immediate(target::Thread::exit_through_ffi()));
+  __ j(NOT_EQUAL, &exit_through_non_ffi, compiler::Assembler::kNearJump);
+  __ TransitionNativeToGenerated(/*leave_safepoint=*/true);
+  __ Bind(&exit_through_non_ffi);
+
   // Set the tag.
   __ movq(Assembler::VMTagAddress(), Immediate(VMTag::kDartCompiledTagId));
   // Clear top exit frame.
diff --git a/runtime/vm/compiler/write_barrier_elimination.cc b/runtime/vm/compiler/write_barrier_elimination.cc
index 8dc6b3c..9ffa022 100644
--- a/runtime/vm/compiler/write_barrier_elimination.cc
+++ b/runtime/vm/compiler/write_barrier_elimination.cc
@@ -319,8 +319,8 @@
 
 #if defined(DEBUG)
 bool WriteBarrierElimination::SlotEligibleForWBE(const Slot& slot) {
-  // We assume that Dart code only stores into Instances or Contexts.
-  // This assumption is used in
+  // We assume that Dart code only stores into Instances, Contexts, and
+  // UnhandledExceptions. This assumption is used in
   // RestoreWriteBarrierInvariantVisitor::VisitPointers.
 
   switch (slot.kind()) {
@@ -332,7 +332,8 @@
 #define FOR_EACH_NATIVE_SLOT(class, underlying_type, field, type, modifiers)   \
   case Slot::Kind::k##class##_##field:                                         \
     return std::is_base_of<InstanceLayout, underlying_type>::value ||          \
-           std::is_base_of<ContextLayout, underlying_type>::value;
+           std::is_base_of<ContextLayout, underlying_type>::value ||           \
+           std::is_base_of<UnhandledExceptionLayout, underlying_type>::value;
 
       NATIVE_SLOTS_LIST(FOR_EACH_NATIVE_SLOT)
 #undef FOR_EACH_NATIVE_SLOT
diff --git a/runtime/vm/constants_x86.h b/runtime/vm/constants_x86.h
index dd77690..36bc6a6 100644
--- a/runtime/vm/constants_x86.h
+++ b/runtime/vm/constants_x86.h
@@ -76,9 +76,9 @@
   F(cdq, 0x99)                                                                 \
   F(fwait, 0x9B)                                                               \
   F(movsb, 0xA4)                                                               \
-  F(movsl, 0xA5)                                                               \
+  F(movs, 0xA5) /* Size suffix added in code */                                \
   F(cmpsb, 0xA6)                                                               \
-  F(cmpsl, 0xA7)
+  F(cmps, 0xA7) /* Size suffix added in code */
 
 // clang-format off
 #define X86_ALU_CODES(F)                                                       \
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index 06afb21..3ec567d 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -746,6 +746,55 @@
   return Error::null();
 }
 
+bool Dart::DetectNullSafety(const char* script_uri,
+                            const uint8_t* snapshot_data,
+                            const uint8_t* snapshot_instructions,
+                            const uint8_t* kernel_buffer,
+                            intptr_t kernel_buffer_size,
+                            const char* package_config,
+                            const char* original_working_directory) {
+  // Before creating the isolate we first determine the null safety mode
+  // in which the isolate needs to run based on one of these factors :
+  // - if loading from source, based on opt-in status of the source
+  // - if loading from a kernel file, based on the mode used when
+  //   generating the kernel file
+  // - if loading from an appJIT or AOT snapshot, based on the mode used
+  //   when generating the snapshot.
+  ASSERT(FLAG_null_safety == kNullSafetyOptionUnspecified);
+
+  // If snapshot is an appJIT/AOT snapshot we will figure out the mode by
+  // sniffing the feature string in the snapshot.
+  if (snapshot_data != nullptr) {
+    // Read the snapshot and check for null safety option.
+    const Snapshot* snapshot = Snapshot::SetupFromBuffer(snapshot_data);
+    if (Snapshot::IncludesCode(snapshot->kind())) {
+      return SnapshotHeaderReader::NullSafetyFromSnapshot(snapshot);
+    }
+  }
+
+#if !defined(DART_PRECOMPILED_RUNTIME)
+  // If kernel_buffer is specified, it could be a self contained
+  // kernel file or the kernel file of the application,
+  // figure out the null safety mode by sniffing the kernel file.
+  if (kernel_buffer != nullptr) {
+    const char* error = nullptr;
+    std::unique_ptr<kernel::Program> program = kernel::Program::ReadFromBuffer(
+        kernel_buffer, kernel_buffer_size, &error);
+    if (program != nullptr) {
+      return program->compilation_mode() == NNBDCompiledMode::kStrong;
+    }
+    return false;
+  }
+
+  // If we are loading from source, figure out the mode from the source.
+  if (KernelIsolate::GetExperimentalFlag("non-nullable")) {
+    return KernelIsolate::DetectNullSafety(script_uri, package_config,
+                                           original_working_directory);
+  }
+#endif  // !defined(DART_PRECOMPILED_RUNTIME)
+  return false;
+}
+
 #if defined(DART_PRECOMPILED_RUNTIME)
 static void PrintLLVMConstantPool(Thread* T, Isolate* I) {
   StackZone printing_zone(T);
diff --git a/runtime/vm/dart.h b/runtime/vm/dart.h
index 6fa528d..78f7547 100644
--- a/runtime/vm/dart.h
+++ b/runtime/vm/dart.h
@@ -66,6 +66,15 @@
                                           const uint8_t* snapshot_instructions,
                                           const uint8_t* kernel_buffer,
                                           intptr_t kernel_buffer_size);
+
+  static bool DetectNullSafety(const char* script_uri,
+                               const uint8_t* snapshot_data,
+                               const uint8_t* snapshot_instructions,
+                               const uint8_t* kernel_buffer,
+                               intptr_t kernel_buffer_size,
+                               const char* package_config,
+                               const char* original_working_directory);
+
   static void RunShutdownCallback();
   static void ShutdownIsolate(Isolate* isolate);
   static void ShutdownIsolate();
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index eb13f6c..103df3f 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -1309,12 +1309,10 @@
   {
     TransitionNativeToVM native_to_vm(thread);
 
-    // Ensure new space is empty and there are no threads running.
+    // Ensure there are no helper threads running.
     BackgroundCompiler::Stop(isolate);
-    isolate->heap()->new_space()->Evacuate();
     isolate->heap()->WaitForMarkerTasks(thread);
     isolate->heap()->WaitForSweeperTasks(thread);
-    RELEASE_ASSERT(isolate->heap()->new_space()->UsedInWords() == 0);
     RELEASE_ASSERT(isolate->heap()->old_space()->tasks() == 0);
   }
 
@@ -1344,7 +1342,7 @@
         // Merge the heap from [spawning_group] to [group].
         {
           SafepointOperationScope safepoint_scope(thread);
-          group->heap()->MergeOtherHeap(isolate->group()->heap());
+          group->heap()->MergeFrom(isolate->group()->heap());
         }
 
         spawning_group->UnregisterIsolate(isolate);
@@ -5451,7 +5449,6 @@
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
-  program->AutoDetectNullSafety(I);
   const Object& tmp = kernel::KernelLoader::LoadEntireProgram(program.get());
   program.reset();
 
@@ -5757,7 +5754,6 @@
   DARTSCOPE(Thread::Current());
   API_TIMELINE_DURATION(T);
   StackZone zone(T);
-  Isolate* I = T->isolate();
 
   CHECK_CALLBACK_STATE(T);
 
@@ -5774,7 +5770,6 @@
   if (program == nullptr) {
     return Api::NewError("Can't load Kernel binary: %s.", error);
   }
-  program->AutoDetectNullSafety(I);
   const Object& result =
       kernel::KernelLoader::LoadEntireProgram(program.get(), false);
   program.reset();
@@ -6030,6 +6025,24 @@
 #endif
 }
 
+DART_EXPORT bool Dart_DetectNullSafety(const char* script_uri,
+                                       const char* package_config,
+                                       const char* original_working_directory,
+                                       const uint8_t* snapshot_data,
+                                       const uint8_t* snapshot_instructions,
+                                       const uint8_t* kernel_buffer,
+                                       intptr_t kernel_buffer_size) {
+  bool null_safety;
+  if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
+    null_safety = Dart::DetectNullSafety(
+        script_uri, snapshot_data, snapshot_instructions, kernel_buffer,
+        kernel_buffer_size, package_config, original_working_directory);
+  } else {
+    null_safety = (FLAG_null_safety == kNullSafetyOptionStrong);
+  }
+  return null_safety;
+}
+
 // --- Service support ---
 
 DART_EXPORT bool Dart_IsServiceIsolate(Dart_Isolate isolate) {
@@ -6430,7 +6443,9 @@
   StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
                                     callback, debug_callback_data);
 
-  Elf* elf = generate_debug ? new (Z) Elf(Z, &debug_stream) : nullptr;
+  auto const elf = generate_debug ? new (Z)
+                                        Elf(Z, &debug_stream, new (Z) Dwarf(Z))
+                                  : nullptr;
 
   AssemblyImageWriter image_writer(T, callback, callback_data, strip, elf);
   uint8_t* vm_snapshot_data_buffer = NULL;
@@ -6441,9 +6456,6 @@
 
   writer.WriteFullSnapshot();
   image_writer.Finalize();
-  if (elf != nullptr) {
-    elf->Finalize();
-  }
 
   return Api::Success();
 #endif
@@ -6504,11 +6516,13 @@
   StreamingWriteStream debug_stream(generate_debug ? kInitialDebugSize : 0,
                                     callback, debug_callback_data);
 
-  Elf* elf = new (Z) Elf(Z, &elf_stream, strip);
-  Dwarf* elf_dwarf = strip ? nullptr : new (Z) Dwarf(Z, nullptr, elf);
-  Elf* debug_elf = generate_debug ? new (Z) Elf(Z, &debug_stream) : nullptr;
-  Dwarf* debug_dwarf =
-      generate_debug ? new (Z) Dwarf(Z, nullptr, debug_elf) : nullptr;
+  auto const dwarf = strip ? nullptr : new (Z) Dwarf(Z);
+  auto const elf = new (Z) Elf(Z, &elf_stream, dwarf);
+  // Re-use the same DWARF object if unstripped.
+  auto const debug_elf =
+      generate_debug
+          ? new (Z) Elf(Z, &debug_stream, strip ? new (Z) Dwarf(Z) : dwarf)
+          : nullptr;
 
   // Here, both VM and isolate will be compiled into a single snapshot.
   // In assembly generation, each serialized text section gets a separate
@@ -6527,16 +6541,16 @@
   // Add the BSS section to the separately saved debugging information, even
   // though there will be no code in it to relocate, since it precedes the
   // .text sections and thus affects their virtual addresses.
-  if (debug_dwarf != nullptr) {
+  if (debug_elf != nullptr) {
     debug_elf->AddBSSData("_kDartBSSData", bss_size);
   }
 
   BlobImageWriter vm_image_writer(T, &vm_snapshot_instructions_buffer,
-                                  ApiReallocate, kInitialSize, debug_dwarf,
-                                  vm_bss_base, elf, elf_dwarf);
+                                  ApiReallocate, kInitialSize, debug_elf,
+                                  vm_bss_base, elf);
   BlobImageWriter isolate_image_writer(T, &isolate_snapshot_instructions_buffer,
-                                       ApiReallocate, kInitialSize, debug_dwarf,
-                                       isolate_bss_base, elf, elf_dwarf);
+                                       ApiReallocate, kInitialSize, debug_elf,
+                                       isolate_bss_base, elf);
   FullSnapshotWriter writer(Snapshot::kFullAOT, &vm_snapshot_data_buffer,
                             &isolate_snapshot_data_buffer, ApiReallocate,
                             &vm_image_writer, &isolate_image_writer);
@@ -6547,14 +6561,8 @@
   elf->AddROData(kIsolateSnapshotDataAsmSymbol, isolate_snapshot_data_buffer,
                  writer.IsolateSnapshotSize());
 
-  if (elf_dwarf != nullptr) {
-    // TODO(rmacnak): Generate .debug_frame / .eh_frame / .arm.exidx to
-    // provide unwinding information.
-    elf_dwarf->Write();
-  }
   elf->Finalize();
-  if (generate_debug) {
-    debug_dwarf->Write();
+  if (debug_elf != nullptr) {
     debug_elf->Finalize();
   }
 
@@ -6723,6 +6731,7 @@
   if (FLAG_dump_tables) {
     Symbols::DumpTable(I);
     DumpTypeTable(I);
+    DumpTypeParameterTable(I);
     DumpTypeArgumentsTable(I);
   }
 
diff --git a/runtime/vm/dwarf.cc b/runtime/vm/dwarf.cc
index 97880d8..cdee3d3 100644
--- a/runtime/vm/dwarf.cc
+++ b/runtime/vm/dwarf.cc
@@ -90,54 +90,68 @@
   return trie->value_;
 }
 
-Dwarf::Dwarf(Zone* zone, StreamingWriteStream* stream, Elf* elf)
+Dwarf::Dwarf(Zone* zone)
     : zone_(zone),
-      elf_(elf),
       reverse_obfuscation_trie_(CreateReverseObfuscationTrie(zone)),
-      asm_stream_(stream),
-      bin_stream_(nullptr),
       codes_(zone, 1024),
       code_to_address_(zone),
       functions_(zone, 1024),
       function_to_index_(zone),
       scripts_(zone, 1024),
       script_to_index_(zone),
-      abstract_origins_(nullptr),
-      temp_(0) {
-  // Must have at least one output, whether assembly or direct to ELF. Both
-  // may be set if we are not stripping assembly but also saving separate
-  // debug information.
-  RELEASE_ASSERT(stream != nullptr || elf != nullptr);
+      temp_(0) {}
+
+SegmentRelativeOffset Dwarf::CodeAddress(const Code& code) const {
+  const auto& pair = code_to_address_.LookupValue(&code);
+  // This is only used by Elf::Finalize(), and the image writers always give a
+  // text offset when calling AddCode() for an Elf object's Dwarf object. Thus,
+  // we should have known code offsets for each code object in the map.
+  ASSERT(pair.offset != SegmentRelativeOffset::kUnknownOffset);
+  return pair;
 }
 
-intptr_t Dwarf::AddCode(const Code& code) {
-  ASSERT(elf_ == nullptr);
-  ASSERT(!code.IsNull());
-  return AddCodeHelper(Code::ZoneHandle(zone_, code.raw()));
-}
+intptr_t Dwarf::AddCode(const Code& orig_code,
+                        const SegmentRelativeOffset& offset) {
+  ASSERT(!orig_code.IsNull());
+  // We should never get the no-argument constructed version here.
+  ASSERT(offset.offset != SegmentRelativeOffset::kInvalidOffset);
+  // Generate an appropriately zoned ZoneHandle for storing.
+  const auto& code = Code::ZoneHandle(zone_, orig_code.raw());
 
-void Dwarf::AddCode(const Code& code,
-                    const char* name,
-                    intptr_t payload_start) {
-  ASSERT(elf_ != nullptr);
+  // For now, we assume one of two flows for a given code object:
+  // ELF: Calls to AddCode(code, vm, offset), vm and offset are the same over
+  //      all calls.
+  // Assembly: An initial call to AddCode(code, vm) (assembly), possibly
+  //     followed by a later call to AddCode(code, vm, offset)
+  //     (separate debugging info ELF)
+  if (offset.offset == SegmentRelativeOffset::kUnknownOffset) {
+    // A call without an address should always come before any calls with
+    // addresses.
+    ASSERT(code_to_address_.Lookup(&code) == nullptr);
+    // Insert a marker so on later calls, we know we've already added to codes_.
+    code_to_address_.Insert(CodeAddressPair(&code, offset));
+  } else {
+    const auto& old_value = code_to_address_.LookupValue(&code);
+    // ELF does not need to know the index. If we've already added this Code
+    // object to codes_ in a previous call, don't bother scanning codes_ to find
+    // the corresponding index, just return -1 instead.
+    switch (old_value.offset) {
+      case SegmentRelativeOffset::kInvalidOffset:
+        code_to_address_.Insert(CodeAddressPair(&code, offset));
+        break;  // Still need to add to codes_.
+      case SegmentRelativeOffset::kUnknownOffset:
+        // Code objects should only be associated with either the VM or isolate.
+        ASSERT_EQUAL(old_value.vm, offset.vm);
+        code_to_address_.Update(CodeAddressPair(&code, offset));
+        return -1;
+      default:
+        // The information for the code object shouldn't have changed since the
+        // previous update.
+        ASSERT(old_value == offset);
+        return -1;
+    }
+  }
 
-  ASSERT(name != nullptr);
-  ASSERT(payload_start >= 0);
-  // Since we're in the middle of generating this section, pull the next section
-  // index and starting address for the next segment from the ELF object.
-  auto const section_index = elf_->NextSectionIndex();
-  auto const relocated_address = elf_->NextMemoryOffset() + payload_start;
-  elf_->AddCodeSymbol(name, section_index, relocated_address, code.Size());
-
-  ASSERT(!code.IsNull());
-  ASSERT(code_to_address_.Lookup(&code) == nullptr);
-  const auto& zone_code = Code::ZoneHandle(zone_, code.raw());
-  code_to_address_.Insert(CodeAddressPair(&zone_code, relocated_address));
-
-  AddCodeHelper(zone_code);
-}
-
-intptr_t Dwarf::AddCodeHelper(const Code& code) {
   const intptr_t index = codes_.length();
   codes_.Add(&code);
   if (code.IsFunctionCode()) {
@@ -213,219 +227,132 @@
   return pair->index_;
 }
 
-void Dwarf::Print(const char* format, ...) {
-  va_list args;
-  va_start(args, format);
-  asm_stream_->VPrint(format, args);
-  va_end(args);
-}
-
-static uint8_t* ZoneReallocate(uint8_t* ptr,
-                               intptr_t old_size,
-                               intptr_t new_size) {
-  return Thread::Current()->zone()->Realloc<uint8_t>(ptr, old_size, new_size);
-}
-
-void Dwarf::WriteAbbreviations() {
+void Dwarf::WriteAbbreviations(DwarfWriteStream* stream) {
   // Dwarf data mostly takes the form of a tree, whose nodes are called
   // DIEs. Each DIE begins with an abbreviation code, and the abbreviation
   // describes the attributes of that DIE and their representation.
 
-  uint8_t* buffer = nullptr;
-  WriteStream stream(&buffer, ZoneReallocate, 64 * KB);
+  stream->uleb128(kCompilationUnit);     // Abbrev code.
+  stream->uleb128(DW_TAG_compile_unit);  // Type.
+  stream->u1(DW_CHILDREN_yes);
+  stream->uleb128(DW_AT_name);  // Start of attributes.
+  stream->uleb128(DW_FORM_string);
+  stream->uleb128(DW_AT_producer);
+  stream->uleb128(DW_FORM_string);
+  stream->uleb128(DW_AT_comp_dir);
+  stream->uleb128(DW_FORM_string);
+  stream->uleb128(DW_AT_low_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(DW_AT_high_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(DW_AT_stmt_list);
+  stream->uleb128(DW_FORM_sec_offset);
+  stream->uleb128(0);
+  stream->uleb128(0);  // End of attributes.
 
-  if (asm_stream_ != nullptr) {
-#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_abbrev,regular,debug\n");
-#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
-    defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_abbrev,\"\"\n");
-#else
-    UNIMPLEMENTED();
-#endif
-  }
-  if (elf_ != nullptr) {
-    bin_stream_ = &stream;
-  }
+  stream->uleb128(kAbstractFunction);  // Abbrev code.
+  stream->uleb128(DW_TAG_subprogram);  // Type.
+  stream->u1(DW_CHILDREN_yes);
+  stream->uleb128(DW_AT_name);  // Start of attributes.
+  stream->uleb128(DW_FORM_string);
+  stream->uleb128(DW_AT_decl_file);
+  stream->uleb128(DW_FORM_udata);
+  stream->uleb128(DW_AT_decl_line);
+  stream->uleb128(DW_FORM_udata);
+  stream->uleb128(DW_AT_inline);
+  stream->uleb128(DW_FORM_udata);
+  stream->uleb128(0);
+  stream->uleb128(0);  // End of attributes.
 
-  uleb128(kCompilationUnit);     // Abbrev code.
-  uleb128(DW_TAG_compile_unit);  // Type.
-  u1(DW_CHILDREN_yes);
-  uleb128(DW_AT_name);  // Start of attributes.
-  uleb128(DW_FORM_string);
-  uleb128(DW_AT_producer);
-  uleb128(DW_FORM_string);
-  uleb128(DW_AT_comp_dir);
-  uleb128(DW_FORM_string);
-  uleb128(DW_AT_low_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(DW_AT_high_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(DW_AT_stmt_list);
-  uleb128(DW_FORM_sec_offset);
-  uleb128(0);
-  uleb128(0);  // End of attributes.
+  stream->uleb128(kConcreteFunction);  // Abbrev code.
+  stream->uleb128(DW_TAG_subprogram);  // Type.
+  stream->u1(DW_CHILDREN_yes);
+  stream->uleb128(DW_AT_abstract_origin);  // Start of attributes.
+  stream->uleb128(DW_FORM_ref4);
+  stream->uleb128(DW_AT_low_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(DW_AT_high_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(0);
+  stream->uleb128(0);  // End of attributes.
 
-  uleb128(kAbstractFunction);  // Abbrev code.
-  uleb128(DW_TAG_subprogram);  // Type.
-  u1(DW_CHILDREN_yes);
-  uleb128(DW_AT_name);  // Start of attributes.
-  uleb128(DW_FORM_string);
-  uleb128(DW_AT_decl_file);
-  uleb128(DW_FORM_udata);
-  uleb128(DW_AT_decl_line);
-  uleb128(DW_FORM_udata);
-  uleb128(DW_AT_inline);
-  uleb128(DW_FORM_udata);
-  uleb128(0);
-  uleb128(0);  // End of attributes.
+  stream->uleb128(kInlinedFunction);           // Abbrev code.
+  stream->uleb128(DW_TAG_inlined_subroutine);  // Type.
+  stream->u1(DW_CHILDREN_yes);
+  stream->uleb128(DW_AT_abstract_origin);  // Start of attributes.
+  stream->uleb128(DW_FORM_ref4);
+  stream->uleb128(DW_AT_low_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(DW_AT_high_pc);
+  stream->uleb128(DW_FORM_addr);
+  stream->uleb128(DW_AT_call_file);
+  stream->uleb128(DW_FORM_udata);
+  stream->uleb128(DW_AT_call_line);
+  stream->uleb128(DW_FORM_udata);
+  stream->uleb128(0);
+  stream->uleb128(0);  // End of attributes.
 
-  uleb128(kConcreteFunction);  // Abbrev code.
-  uleb128(DW_TAG_subprogram);  // Type.
-  u1(DW_CHILDREN_yes);
-  uleb128(DW_AT_abstract_origin);  // Start of attributes.
-  uleb128(DW_FORM_ref4);
-  uleb128(DW_AT_low_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(DW_AT_high_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(0);
-  uleb128(0);  // End of attributes.
-
-  uleb128(kInlinedFunction);           // Abbrev code.
-  uleb128(DW_TAG_inlined_subroutine);  // Type.
-  u1(DW_CHILDREN_yes);
-  uleb128(DW_AT_abstract_origin);  // Start of attributes.
-  uleb128(DW_FORM_ref4);
-  uleb128(DW_AT_low_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(DW_AT_high_pc);
-  uleb128(DW_FORM_addr);
-  uleb128(DW_AT_call_file);
-  uleb128(DW_FORM_udata);
-  uleb128(DW_AT_call_line);
-  uleb128(DW_FORM_udata);
-  uleb128(0);
-  uleb128(0);  // End of attributes.
-
-  uleb128(0);  // End of abbreviations.
-
-  if (elf_ != nullptr) {
-    elf_->AddDebug(".debug_abbrev", buffer, stream.bytes_written());
-    bin_stream_ = nullptr;
-  }
+  stream->uleb128(0);  // End of abbreviations.
 }
 
-void Dwarf::WriteCompilationUnit() {
-  uint8_t* buffer = nullptr;
-  WriteStream stream(&buffer, ZoneReallocate, 64 * KB);
-
+void Dwarf::WriteDebugInfo(DwarfWriteStream* stream) {
   SnapshotTextObjectNamer namer(zone_);
 
-  if (asm_stream_ != nullptr) {
-#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_info,regular,debug\n");
-#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
-    defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_info,\"\"\n");
-#else
-    UNIMPLEMENTED();
-#endif
-    Print(".Ldebug_info:\n");
-  }
-  if (elf_ != nullptr) {
-    bin_stream_ = &stream;
-  }
-
   // 7.5.1.1 Compilation Unit Header
 
-  // Unit length. Assignment to temp works around buggy Mac assembler.
-  intptr_t cu_size_fixup = 0;
-  intptr_t cu_start = 0;
-  if (asm_stream_ != nullptr) {
-    Print("Lcu_size = .Lcu_end - .Lcu_start\n");
-    Print(".4byte Lcu_size\n");
-    Print(".Lcu_start:\n");
-  }
-  if (elf_ != nullptr) {
-    cu_size_fixup = u4(0);
-    cu_start = position();
-  }
+  // Unit length.
+  auto const cu_prefix = "cu";
+  intptr_t cu_start;
+  intptr_t cu_size_fixup = stream->ReserveSize(cu_prefix, &cu_start);
 
-  u2(2);                            // DWARF version 2
-  u4(0);                            // debug_abbrev_offset
-  u1(compiler::target::kWordSize);  // address_size
+  stream->u2(2);                            // DWARF version 2
+  stream->u4(0);                            // debug_abbrev_offset
+  stream->u1(compiler::target::kWordSize);  // address_size
 
   // Compilation Unit DIE. We describe the entire Dart program as a single
   // compilation unit. Note we write attributes in the same order we declared
   // them in our abbreviation above in WriteAbbreviations.
-  uleb128(kCompilationUnit);
+  stream->uleb128(kCompilationUnit);
   const Library& root_library = Library::Handle(
       zone_, Isolate::Current()->object_store()->root_library());
   const String& root_uri = String::Handle(zone_, root_library.url());
-  string(root_uri.ToCString());  // DW_AT_name
-  string("Dart VM");             // DW_AT_producer
-  string("");                    // DW_AT_comp_dir
+  stream->string(root_uri.ToCString());  // DW_AT_name
+  stream->string("Dart VM");             // DW_AT_producer
+  stream->string("");                    // DW_AT_comp_dir
 
-  // DW_AT_low_pc and DW_AT_high_pc
-  // The lowest and highest instruction addresses in this object file that are
-  // part of our compilation unit. Dwarf consumers use this to quickly decide
-  // which compilation unit DIE to consult for a given pc.
-  //
-  // Currently, we only write DWARF information for Dart code and only the
-  // isolate contains instructions compiled from Dart code. If we ever add Dart
-  // code to the VM snapshot, this will need to be adjusted.
-  if (asm_stream_ != nullptr) {
-    // DW_AT_low_pc
-    PrintNamedAddress(kIsolateSnapshotInstructionsAsmSymbol);
-    // DW_AT_high_pc
-    intptr_t last_code_index = codes_.length() - 1;
-    const Code& last_code = *(codes_[last_code_index]);
-    PrintNamedAddressWithOffset(
-        namer.SnapshotNameFor(last_code_index, last_code), last_code.Size());
-  }
-  if (elf_ != nullptr) {
-    intptr_t offset;
-    intptr_t size;
-    if (!elf_->FindDynamicSymbol(kIsolateSnapshotInstructionsAsmSymbol, &offset,
-                                 &size)) {
-      UNREACHABLE();
-    }
-    // DW_AT_low_pc
-    addr(offset);
-    // DW_AT_high_pc
-    addr(offset + size);
-  }
+  // DW_AT_low_pc
+  // The lowest instruction address in this object file that is part of our
+  // compilation unit. Dwarf consumers use this to quickly decide which
+  // compilation unit DIE to consult for a given pc.
+  stream->OffsetFromSymbol(kIsolateSnapshotInstructionsAsmSymbol, 0);
+
+  // DW_AT_high_pc
+  // The highest instruction address in this object file that is part of our
+  // compilation unit. Dwarf consumers use this to quickly decide which
+  // compilation unit DIE to consult for a given pc.
+  intptr_t last_code_index = codes_.length() - 1;
+  const Code& last_code = *(codes_[last_code_index]);
+  auto const last_code_name = namer.SnapshotNameFor(last_code_index, last_code);
+  stream->OffsetFromSymbol(last_code_name, last_code.Size());
 
   // DW_AT_stmt_list (offset into .debug_line)
   // Indicates which line number program is associated with this compilation
   // unit. We only emit a single line number program.
-  u4(0);
+  stream->u4(0);
 
-  WriteAbstractFunctions();
-  WriteConcreteFunctions();
+  WriteAbstractFunctions(stream);
+  WriteConcreteFunctions(stream);
 
-  uleb128(0);  // End of children.
+  stream->uleb128(0);  // End of children.
 
-  uleb128(0);  // End of entries.
-
-  if (asm_stream_ != nullptr) {
-    Print(".Lcu_end:\n");
-  }
-  if (elf_ != nullptr) {
-    fixup_u4(cu_size_fixup, position() - cu_start);
-
-    elf_->AddDebug(".debug_info", buffer, stream.bytes_written());
-    bin_stream_ = nullptr;
-  }
+  stream->uleb128(0);  // End of entries.
+  stream->SetSize(cu_size_fixup, cu_prefix, cu_start);
 }
 
-void Dwarf::WriteAbstractFunctions() {
+void Dwarf::WriteAbstractFunctions(DwarfWriteStream* stream) {
   Script& script = Script::Handle(zone_);
   String& name = String::Handle(zone_);
-  if (elf_ != nullptr) {
-    abstract_origins_ = zone_->Alloc<uint32_t>(functions_.length());
-  }
+  stream->InitializeAbstractOrigins(functions_.length());
   // By the point we're creating DWARF information, scripts have already lost
   // their token stream, so we can't look up their line number information.
   auto const line = kNoLineInformation;
@@ -434,26 +361,19 @@
     name = function.QualifiedUserVisibleName();
     script = function.script();
     const intptr_t file = LookupScript(script);
-
-    if (asm_stream_ != nullptr) {
-      Print(".Lfunc%" Pd ":\n",
-            i);  // Label for DW_AT_abstract_origin references
-    }
-    if (elf_ != nullptr) {
-      abstract_origins_[i] = position();
-    }
     auto const name_cstr = Deobfuscate(name.ToCString());
 
-    uleb128(kAbstractFunction);
-    string(name_cstr);        // DW_AT_name
-    uleb128(file);            // DW_AT_decl_file
-    uleb128(line);            // DW_AT_decl_line
-    uleb128(DW_INL_inlined);  // DW_AT_inline
-    uleb128(0);               // End of children.
+    stream->RegisterAbstractOrigin(i);
+    stream->uleb128(kAbstractFunction);
+    stream->string(name_cstr);        // DW_AT_name
+    stream->uleb128(file);            // DW_AT_decl_file
+    stream->uleb128(line);            // DW_AT_decl_line
+    stream->uleb128(DW_INL_inlined);  // DW_AT_inline
+    stream->uleb128(0);               // End of children.
   }
 }
 
-void Dwarf::WriteConcreteFunctions() {
+void Dwarf::WriteConcreteFunctions(DwarfWriteStream* stream) {
   Function& function = Function::Handle(zone_);
   Script& script = Script::Handle(zone_);
   SnapshotTextObjectNamer namer(zone_);
@@ -464,53 +384,30 @@
       continue;
     }
 
-    intptr_t code_address = -1;
-    if (elf_ != nullptr) {
-      CodeAddressPair* pair = code_to_address_.Lookup(&code);
-      RELEASE_ASSERT(pair != NULL);
-      code_address = pair->address_;
-    }
-
     function = code.function();
     intptr_t function_index = LookupFunction(function);
     script = function.script();
+    const char* asm_name = namer.SnapshotNameFor(i, code);
 
-    uleb128(kConcreteFunction);
+    stream->uleb128(kConcreteFunction);
     // DW_AT_abstract_origin
     // References a node written above in WriteAbstractFunctions.
-    // Assignment to temp works around buggy Mac assembler.
-    if (asm_stream_ != nullptr) {
-      intptr_t temp = temp_++;
-      Print("Ltemp%" Pd " = .Lfunc%" Pd " - .Ldebug_info\n", temp,
-            function_index);
-      Print(".4byte Ltemp%" Pd "\n", temp);
-    }
-    if (elf_ != nullptr) {
-      u4(abstract_origins_[function_index]);
-    }
+    stream->AbstractOrigin(function_index);
 
     // DW_AT_low_pc
-    if (asm_stream_ != nullptr) {
-      const char* asm_name = namer.SnapshotNameFor(i, code);
-      // DW_AT_low_pc
-      PrintNamedAddress(asm_name);
-      // DW_AT_high_pc
-      PrintNamedAddressWithOffset(asm_name, code.Size());
-    }
-    if (elf_ != nullptr) {
-      addr(code_address);
-      addr(code_address + code.Size());
-    }
+    stream->OffsetFromSymbol(asm_name, 0);
+    // DW_AT_high_pc
+    stream->OffsetFromSymbol(asm_name, code.Size());
 
     InliningNode* node = ExpandInliningTree(code);
     if (node != NULL) {
       for (InliningNode* child = node->children_head; child != NULL;
            child = child->children_next) {
-        WriteInliningNode(child, i, code_address, script, &namer);
+        WriteInliningNode(stream, child, asm_name, script, &namer);
       }
     }
 
-    uleb128(0);  // End of children.
+    stream->uleb128(0);  // End of children.
   }
 }
 
@@ -595,131 +492,77 @@
   return root_node;
 }
 
-void Dwarf::WriteInliningNode(InliningNode* node,
-                              intptr_t root_code_index,
-                              intptr_t root_code_address,
+void Dwarf::WriteInliningNode(DwarfWriteStream* stream,
+                              InliningNode* node,
+                              const char* root_asm_name,
                               const Script& parent_script,
                               SnapshotTextObjectNamer* namer) {
-  RELEASE_ASSERT(elf_ == nullptr || root_code_address >= 0);
   intptr_t file = LookupScript(parent_script);
   const auto& token_pos = node->call_pos;
   intptr_t function_index = LookupFunction(node->function);
   const Script& script = Script::Handle(zone_, node->function.script());
 
-  uleb128(kInlinedFunction);
+  stream->uleb128(kInlinedFunction);
   // DW_AT_abstract_origin
   // References a node written above in WriteAbstractFunctions.
-  // Assignment to temp works around buggy Mac assembler.
-  if (asm_stream_ != nullptr) {
-    intptr_t temp = temp_++;
-    Print("Ltemp%" Pd " = .Lfunc%" Pd " - .Ldebug_info\n", temp,
-          function_index);
-    Print(".4byte Ltemp%" Pd "\n", temp);
-  }
-  if (elf_ != nullptr) {
-    u4(abstract_origins_[function_index]);
-  }
+  stream->AbstractOrigin(function_index);
 
-  if (asm_stream_ != nullptr) {
-    const char* asm_name =
-        namer->SnapshotNameFor(root_code_index, *codes_[root_code_index]);
-    // DW_AT_low_pc
-    PrintNamedAddressWithOffset(asm_name, node->start_pc_offset);
-    // DW_AT_high_pc
-    PrintNamedAddressWithOffset(asm_name, node->end_pc_offset);
-  }
-  if (elf_ != nullptr) {
-    // DW_AT_low_pc
-    addr(root_code_address + node->start_pc_offset);
-    // DW_AT_high_pc
-    addr(root_code_address + node->end_pc_offset);
-  }
-
+  // DW_AT_low_pc
+  stream->OffsetFromSymbol(root_asm_name, node->start_pc_offset);
+  // DW_AT_high_pc
+  stream->OffsetFromSymbol(root_asm_name, node->end_pc_offset);
   // DW_AT_call_file
-  uleb128(file);
+  stream->uleb128(file);
   // DW_AT_call_line
-  uleb128(TokenPositionToLine(token_pos));
+  stream->uleb128(TokenPositionToLine(token_pos));
 
   for (InliningNode* child = node->children_head; child != NULL;
        child = child->children_next) {
-    WriteInliningNode(child, root_code_index, root_code_address, script, namer);
+    WriteInliningNode(stream, child, root_asm_name, script, namer);
   }
 
-  uleb128(0);  // End of children.
+  stream->uleb128(0);  // End of children.
 }
 
-void Dwarf::WriteLines() {
-  uint8_t* buffer = nullptr;
-  WriteStream stream(&buffer, ZoneReallocate, 64 * KB);
-
-  if (asm_stream_ != nullptr) {
-#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-    Print(".section __DWARF,__debug_line,regular,debug\n");
-#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
-    defined(TARGET_OS_FUCHSIA)
-    Print(".section .debug_line,\"\"\n");
-#else
-    UNIMPLEMENTED();
-#endif
-  }
-  if (elf_ != nullptr) {
-    bin_stream_ = &stream;
-  }
-
+void Dwarf::WriteLineNumberProgram(DwarfWriteStream* stream) {
   // 6.2.4 The Line Number Program Header
 
   // 1. unit_length. This encoding implies 32-bit DWARF.
-  intptr_t line_size_fixup = 0;
-  intptr_t line_start = 0;
-  if (asm_stream_ != nullptr) {
-    Print("Lline_size = .Lline_end - .Lline_start\n");
-    Print(".4byte Lline_size\n");
-    Print(".Lline_start:\n");
-  }
-  if (elf_ != nullptr) {
-    line_size_fixup = u4(0);
-    line_start = position();
-  }
+  auto const line_prefix = "line";
+  intptr_t line_start;
+  intptr_t line_size_fixup = stream->ReserveSize(line_prefix, &line_start);
 
-  u2(2);  // 2. DWARF version 2
+  stream->u2(2);  // 2. DWARF version 2
 
   // 3. header_length
-  // Assignment to temp works around buggy Mac assembler.
-  intptr_t lineheader_size_fixup = 0;
-  intptr_t lineheader_start = 0;
-  if (asm_stream_ != nullptr) {
-    Print("Llineheader_size = .Llineheader_end - .Llineheader_start\n");
-    Print(".4byte Llineheader_size\n");
-    Print(".Llineheader_start:\n");
-  }
-  if (elf_ != nullptr) {
-    lineheader_size_fixup = u4(0);
-    lineheader_start = position();
-  }
+  auto const lineheader_prefix = "lineheader";
+  intptr_t lineheader_start;
+  intptr_t lineheader_size_fixup =
+      stream->ReserveSize(lineheader_prefix, &lineheader_start);
 
-  u1(1);   // 4. minimum_instruction_length
-  u1(1);   // 5. default_is_stmt (true for compatibility with dsymutil).
-  u1(0);   // 6. line_base
-  u1(1);   // 7. line_range
-  u1(13);  // 8. opcode_base (12 standard opcodes in Dwarf 2)
+  stream->u1(1);   // 4. minimum_instruction_length
+  stream->u1(1);   // 5. default_is_stmt (true for compatibility with dsymutil).
+  stream->u1(0);   // 6. line_base
+  stream->u1(1);   // 7. line_range
+  stream->u1(13);  // 8. opcode_base (12 standard opcodes in Dwarf 2)
 
   // 9. standard_opcode_lengths
-  u1(0);  // DW_LNS_copy, 0 operands
-  u1(1);  // DW_LNS_advance_pc, 1 operands
-  u1(1);  // DW_LNS_advance_list, 1 operands
-  u1(1);  // DW_LNS_set_file, 1 operands
-  u1(1);  // DW_LNS_set_column, 1 operands
-  u1(0);  // DW_LNS_negate_stmt, 0 operands
-  u1(0);  // DW_LNS_set_basic_block, 0 operands
-  u1(0);  // DW_LNS_const_add_pc, 0 operands
-  u1(1);  // DW_LNS_fixed_advance_pc, 1 operands
-  u1(0);  // DW_LNS_set_prolog_end, 0 operands
-  u1(0);  // DW_LNS_set_epligoue_begin, 0 operands
-  u1(1);  // DW_LNS_set_isa, 1 operands
+  stream->u1(0);  // DW_LNS_copy, 0 operands
+  stream->u1(1);  // DW_LNS_advance_pc, 1 operands
+  stream->u1(1);  // DW_LNS_advance_list, 1 operands
+  stream->u1(1);  // DW_LNS_set_file, 1 operands
+  stream->u1(1);  // DW_LNS_set_column, 1 operands
+  stream->u1(0);  // DW_LNS_negate_stmt, 0 operands
+  stream->u1(0);  // DW_LNS_set_basic_block, 0 operands
+  stream->u1(0);  // DW_LNS_const_add_pc, 0 operands
+  stream->u1(1);  // DW_LNS_fixed_advance_pc, 1 operands
+  stream->u1(0);  // DW_LNS_set_prolog_end, 0 operands
+  stream->u1(0);  // DW_LNS_set_epligoue_begin, 0 operands
+  stream->u1(1);  // DW_LNS_set_isa, 1 operands
 
   // 10. include_directories (sequence of path names)
   // We don't emit any because we use full paths below.
-  u1(0);
+  stream->u1(0);
 
   // 11. file_names (sequence of file entries)
   String& uri = String::Handle(zone_);
@@ -729,26 +572,19 @@
     auto const uri_cstr = Deobfuscate(uri.ToCString());
     RELEASE_ASSERT(strlen(uri_cstr) != 0);
 
-    string(uri_cstr);  // NOLINT
-    uleb128(0);  // Include directory index.
-    uleb128(0);  // File modification time.
-    uleb128(0);  // File length.
+    stream->string(uri_cstr);  // NOLINT
+    stream->uleb128(0);        // Include directory index.
+    stream->uleb128(0);        // File modification time.
+    stream->uleb128(0);        // File length.
   }
-  u1(0);  // End of file names.
-
-  if (asm_stream_ != nullptr) {
-    Print(".Llineheader_end:\n");
-  }
-  if (elf_ != nullptr) {
-    fixup_u4(lineheader_size_fixup, position() - lineheader_start);
-  }
+  stream->u1(0);  // End of file names.
+  stream->SetSize(lineheader_size_fixup, lineheader_prefix, lineheader_start);
 
   // 6.2.5 The Line Number Program
 
   intptr_t previous_file = 1;
   intptr_t previous_line = 1;
-  intptr_t previous_code_address = -1;
-  intptr_t previous_code_index = -1;
+  const char* previous_asm_name = nullptr;
   intptr_t previous_pc_offset = 0;
 
   Function& root_function = Function::Handle(zone_);
@@ -761,18 +597,7 @@
 
   for (intptr_t i = 0; i < codes_.length(); i++) {
     const Code& code = *(codes_[i]);
-
-    const char* asm_name = nullptr;
-    if (asm_stream_ != nullptr) {
-      asm_name = namer.SnapshotNameFor(i, code);
-    }
-
-    intptr_t current_code_address = -1;
-    if (elf_ != nullptr) {
-      CodeAddressPair* pair = code_to_address_.Lookup(&code);
-      RELEASE_ASSERT(pair != NULL);
-      current_code_address = pair->address_;
-    }
+    auto const asm_name = namer.SnapshotNameFor(i, code);
 
     map = code.code_source_map();
     if (map.IsNull()) {
@@ -782,7 +607,7 @@
     functions = code.inlined_id_to_function();
 
     NoSafepointScope no_safepoint;
-    ReadStream stream(map.Data(), map.Length());
+    ReadStream code_map_stream(map.Data(), map.Length());
 
     function_stack.Clear();
     token_positions.Clear();
@@ -791,17 +616,17 @@
     function_stack.Add(&root_function);
     token_positions.Add(CodeSourceMapBuilder::kInitialPosition);
 
-    while (stream.PendingBytes() > 0) {
-      uint8_t opcode = stream.Read<uint8_t>();
+    while (code_map_stream.PendingBytes() > 0) {
+      uint8_t opcode = code_map_stream.Read<uint8_t>();
       switch (opcode) {
         case CodeSourceMapBuilder::kChangePosition: {
-          int32_t position = stream.Read<int32_t>();
+          int32_t position = code_map_stream.Read<int32_t>();
           token_positions[token_positions.length() - 1] =
               TokenPosition(position);
           break;
         }
         case CodeSourceMapBuilder::kAdvancePC: {
-          int32_t delta = stream.Read<int32_t>();
+          int32_t delta = code_map_stream.Read<int32_t>();
           current_pc_offset += delta;
 
           const Function& function = *(function_stack.Last());
@@ -810,61 +635,44 @@
 
           // 1. Update LNP file.
           if (file != previous_file) {
-            u1(DW_LNS_set_file);
-            uleb128(file);
+            stream->u1(DW_LNS_set_file);
+            stream->uleb128(file);
             previous_file = file;
           }
 
           // 2. Update LNP line.
           const auto line = TokenPositionToLine(token_positions.Last());
           if (line != previous_line) {
-            u1(DW_LNS_advance_line);
-            sleb128(line - previous_line);
+            stream->u1(DW_LNS_advance_line);
+            stream->sleb128(line - previous_line);
             previous_line = line;
           }
 
           // 3. Emit LNP row if the address register has been updated to a
           // non-zero value (dartbug.com/41756).
-          if (previous_code_index >= 0) {
-            u1(DW_LNS_copy);
+          if (previous_asm_name != nullptr) {
+            stream->u1(DW_LNS_copy);
           }
 
           // 4. Update LNP pc.
-          if (previous_code_index < 0) {
-            // This variant is relocatable.
-            u1(0);                                // This is an extended opcode
-            u1(1 + compiler::target::kWordSize);  // that is 5 or 9 bytes long
-            u1(DW_LNE_set_address);
-            if (asm_stream_ != nullptr) {
-              PrintNamedAddressWithOffset(asm_name, current_pc_offset);
-            }
-            if (elf_ != nullptr) {
-              ASSERT(previous_code_address < 0);
-              addr(current_code_address + current_pc_offset);
-            }
+          if (previous_asm_name == nullptr) {
+            auto const instr_size = 1 + compiler::target::kWordSize;
+            stream->u1(0);           // This is an extended opcode
+            stream->u1(instr_size);  // that is 5 or 9 bytes long
+            stream->u1(DW_LNE_set_address);
+            stream->OffsetFromSymbol(asm_name, current_pc_offset);
           } else {
-            u1(DW_LNS_advance_pc);
-            if (asm_stream_ != nullptr) {
-              const char* previous_asm_name = namer.SnapshotNameFor(
-                  previous_code_index, *codes_[previous_code_index]);
-              Print(".uleb128 %s - %s + %" Pd "\n", asm_name, previous_asm_name,
-                    current_pc_offset - previous_pc_offset);
-            }
-            if (elf_ != nullptr) {
-              ASSERT(previous_code_address >= 0);
-              intptr_t delta = current_code_address - previous_code_address +
-                               current_pc_offset - previous_pc_offset;
-              RELEASE_ASSERT(delta > 0);
-              uleb128(delta);
-            }
+            stream->u1(DW_LNS_advance_pc);
+            stream->DistanceBetweenSymbolOffsets(asm_name, current_pc_offset,
+                                                 previous_asm_name,
+                                                 previous_pc_offset);
           }
-          previous_code_address = current_code_address;
-          previous_code_index = i;
+          previous_asm_name = asm_name;
           previous_pc_offset = current_pc_offset;
           break;
         }
         case CodeSourceMapBuilder::kPushFunction: {
-          int32_t func_index = stream.Read<int32_t>();
+          int32_t func_index = code_map_stream.Read<int32_t>();
           const Function& child_func = Function::Handle(
               zone_, Function::RawCast(functions.At(func_index)));
           function_stack.Add(&child_func);
@@ -880,7 +688,7 @@
           break;
         }
         case CodeSourceMapBuilder::kNullCheck: {
-          stream.Read<int32_t>();
+          code_map_stream.Read<int32_t>();
           break;
         }
         default:
@@ -889,45 +697,22 @@
     }
   }
 
-  // Advance pc to end of the compilation unit.
+  // Advance pc to end of the compilation unit if not already there.
   const intptr_t last_code_index = codes_.length() - 1;
   const Code& last_code = *(codes_[last_code_index]);
+  const intptr_t last_pc_offset = last_code.Size();
+  const char* last_asm_name = namer.SnapshotNameFor(last_code_index, last_code);
 
-  u1(DW_LNS_advance_pc);
-  if (asm_stream_ != nullptr) {
-    const char* last_asm_name =
-        namer.SnapshotNameFor(last_code_index, last_code);
-    ASSERT(previous_code_index >= 0);
-    const char* previous_asm_name = namer.SnapshotNameFor(
-        previous_code_index, *codes_[previous_code_index]);
-    Print(".uleb128 %s - %s + %" Pd "\n", last_asm_name, previous_asm_name,
-          last_code.Size() - previous_pc_offset);
-  }
-  if (elf_ != nullptr) {
-    auto const pair = code_to_address_.Lookup(&last_code);
-    RELEASE_ASSERT(pair != NULL);
-    const intptr_t last_code_address = pair->address_;
-
-    const intptr_t delta = last_code_address - previous_code_address +
-                           last_code.Size() - previous_pc_offset;
-    RELEASE_ASSERT(delta >= 0);
-    uleb128(delta);
-  }
+  stream->u1(DW_LNS_advance_pc);
+  ASSERT(previous_asm_name != nullptr);
+  stream->DistanceBetweenSymbolOffsets(last_asm_name, last_pc_offset,
+                                       previous_asm_name, previous_pc_offset);
 
   // End of contiguous machine code.
-  u1(0);  // This is an extended opcode
-  u1(1);  // that is 1 byte long
-  u1(DW_LNE_end_sequence);
-
-  if (asm_stream_ != nullptr) {
-    Print(".Lline_end:\n");
-  }
-  if (elf_ != nullptr) {
-    fixup_u4(line_size_fixup, position() - line_start);
-
-    elf_->AddDebug(".debug_line", buffer, stream.bytes_written());
-    bin_stream_ = nullptr;
-  }
+  stream->u1(0);  // This is an extended opcode
+  stream->u1(1);  // that is 1 byte long
+  stream->u1(DW_LNE_end_sequence);
+  stream->SetSize(line_size_fixup, line_prefix, line_start);
 }
 
 const char* Dwarf::Deobfuscate(const char* cstr) {
diff --git a/runtime/vm/dwarf.h b/runtime/vm/dwarf.h
index 385041b..dc1692c 100644
--- a/runtime/vm/dwarf.h
+++ b/runtime/vm/dwarf.h
@@ -14,7 +14,6 @@
 
 #ifdef DART_PRECOMPILER
 
-class Elf;
 class InliningNode;
 class SnapshotTextObjectNamer;
 
@@ -83,15 +82,41 @@
 
 typedef DirectChainedHashMap<FunctionIndexPair> FunctionIndexMap;
 
+struct SegmentRelativeOffset {
+  // Used for the empty constructor (for hash map usage).
+  static constexpr intptr_t kInvalidOffset = -2;
+  // Used for cases where we know which segment, but don't know the offset.
+  static constexpr intptr_t kUnknownOffset = -1;
+
+  SegmentRelativeOffset(bool vm, intptr_t offset) : vm(vm), offset(offset) {
+    ASSERT(offset >= 0);
+  }
+  explicit SegmentRelativeOffset(bool vm) : vm(vm), offset(kUnknownOffset) {}
+  SegmentRelativeOffset() : vm(false), offset(kInvalidOffset) {}
+
+  bool operator==(const SegmentRelativeOffset& b) const {
+    return vm == b.vm && offset == b.offset;
+  }
+  bool operator==(const SegmentRelativeOffset& b) {
+    return *const_cast<const SegmentRelativeOffset*>(this) == b;
+  }
+  bool operator!=(const SegmentRelativeOffset& b) { return !(*this == b); }
+
+  // Whether or not this is an offset into the VM text segment.
+  bool vm;
+  // The byte offset into the segment contents.
+  intptr_t offset;
+};
+
 struct CodeAddressPair {
   // Typedefs needed for the DirectChainedHashMap template.
   typedef const Code* Key;
-  typedef intptr_t Value;
+  typedef SegmentRelativeOffset Value;
   typedef CodeAddressPair Pair;
 
-  static Key KeyOf(Pair kv) { return kv.code_; }
+  static Key KeyOf(Pair kv) { return kv.code; }
 
-  static Value ValueOf(Pair kv) { return kv.address_; }
+  static Value ValueOf(Pair kv) { return kv.segment_offset; }
 
   static inline intptr_t Hashcode(Key key) {
     // Code objects are always allocated in old space, so they don't move.
@@ -99,22 +124,19 @@
   }
 
   static inline bool IsKeyEqual(Pair pair, Key key) {
-    return pair.code_->raw() == key->raw();
+    return pair.code->raw() == key->raw();
   }
 
-  CodeAddressPair(const Code* c, intptr_t address)
-      : code_(c), address_(address) {
+  CodeAddressPair(const Code* c, const SegmentRelativeOffset& o)
+      : code(c), segment_offset(o) {
     ASSERT(!c->IsNull());
     ASSERT(c->IsNotTemporaryScopedHandle());
-    ASSERT(address >= 0);
+    ASSERT(o.offset == SegmentRelativeOffset::kUnknownOffset || o.offset >= 0);
   }
+  CodeAddressPair() : code(nullptr), segment_offset() {}
 
-  CodeAddressPair() : code_(NULL), address_(-1) {}
-
-  void Print() const;
-
-  const Code* code_;
-  intptr_t address_;
+  const Code* code;
+  SegmentRelativeOffset segment_offset;
 };
 
 typedef DirectChainedHashMap<CodeAddressPair> CodeAddressMap;
@@ -193,43 +215,67 @@
   Trie<T>* children_[kNumValidChars];
 };
 
+class DwarfWriteStream : public ValueObject {
+ public:
+  DwarfWriteStream() {}
+  virtual ~DwarfWriteStream() {}
+
+  virtual void sleb128(intptr_t value) = 0;
+  virtual void uleb128(uintptr_t value) = 0;
+  virtual void u1(uint8_t value) = 0;
+  virtual void u2(uint16_t value) = 0;
+  virtual void u4(uint32_t value) = 0;
+  virtual void u8(uint64_t value) = 0;
+  virtual void string(const char* cstr) = 0;  // NOLINT
+
+  // Returns the position (if any) to fix up in SetSize().
+  virtual intptr_t ReserveSize(const char* prefix, intptr_t* start) = 0;
+  virtual void SetSize(intptr_t position,
+                       const char* prefix,
+                       intptr_t start) = 0;
+
+  virtual void OffsetFromSymbol(const char* symbol, intptr_t offset) = 0;
+  // Returns the difference between the relocated address at offset1 from
+  // symbol1 and the relocated address at offset2 from symbol2.
+  virtual void DistanceBetweenSymbolOffsets(const char* symbol1,
+                                            intptr_t offset1,
+                                            const char* symbol2,
+                                            intptr_t offset2) = 0;
+
+  virtual void InitializeAbstractOrigins(intptr_t size) = 0;
+  virtual void RegisterAbstractOrigin(intptr_t index) = 0;
+  virtual void AbstractOrigin(intptr_t index) = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(DwarfWriteStream);
+};
+
 class Dwarf : public ZoneAllocated {
  public:
-  Dwarf(Zone* zone, StreamingWriteStream* stream, Elf* elf);
+  explicit Dwarf(Zone* zone);
 
-  Elf* elf() const { return elf_; }
+  const ZoneGrowableArray<const Code*>& codes() const { return codes_; }
 
   // Stores the code object for later creating the line number program.
   //
-  // Should only be called when the output is not ELF.
-  //
-  // Returns the stored index of the code object.
-  intptr_t AddCode(const Code& code);
+  // Returns the stored index of the code object when the relocated address
+  // is not known at snapshot generation time (that is, when offset.offset is
+  // SegmentRelativeOffset::kUnknownOffset).
+  intptr_t AddCode(const Code& code, const SegmentRelativeOffset& offset);
 
-  // Stores the code object for later creating the line number program.
-  //
-  // [payload_offset] should be the offset of the payload within the text
-  // section. [name] is used to create an ELF static symbol for the payload.
-  //
-  // Should only be called when the output is ELF.
-  void AddCode(const Code& code, const char* name, intptr_t payload_offset);
+  // Returns the stored segment offset for the given Code object. If no
+  // address is stored, the second element will be kNoCodeAddressPairOffset.
+  SegmentRelativeOffset CodeAddress(const Code& code) const;
 
   intptr_t AddFunction(const Function& function);
   intptr_t AddScript(const Script& script);
   intptr_t LookupFunction(const Function& function);
   intptr_t LookupScript(const Script& script);
 
-  void Write() {
-    WriteAbbreviations();
-    WriteCompilationUnit();
-    WriteLines();
-  }
+  void WriteAbbreviations(DwarfWriteStream* stream);
+  void WriteDebugInfo(DwarfWriteStream* stream);
+  void WriteLineNumberProgram(DwarfWriteStream* stream);
 
  private:
-  // Implements shared functionality for the two AddCode calls. Assumes the
-  // Code handle is appropriately zoned.
-  intptr_t AddCodeHelper(const Code& code);
-
   static const intptr_t DW_TAG_compile_unit = 0x11;
   static const intptr_t DW_TAG_inlined_subroutine = 0x1d;
   static const intptr_t DW_TAG_subprogram = 0x2e;
@@ -278,158 +324,32 @@
     kInlinedFunction,
   };
 
-  void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3);
-
-#if defined(TARGET_ARCH_IS_32_BIT)
-#define FORM_ADDR ".4byte"
-#elif defined(TARGET_ARCH_IS_64_BIT)
-#define FORM_ADDR ".8byte"
-#endif
-
-  void PrintNamedAddress(const char* name) { Print(FORM_ADDR " %s\n", name); }
-  void PrintNamedAddressWithOffset(const char* name, intptr_t offset) {
-    Print(FORM_ADDR " %s + %" Pd "\n", name, offset);
-  }
-
-#undef FORM_ADDR
-
-  void sleb128(intptr_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".sleb128 %" Pd "\n", value);
-    }
-    if (elf_ != nullptr) {
-      bool is_last_part = false;
-      while (!is_last_part) {
-        uint8_t part = value & 0x7F;
-        value >>= 7;
-        if ((value == 0 && (part & 0x40) == 0) ||
-            (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
-          is_last_part = true;
-        } else {
-          part |= 0x80;
-        }
-        bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&part),
-                                sizeof(part));
-      }
-    }
-  }
-  void uleb128(uintptr_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".uleb128 %" Pd "\n", value);
-    }
-    if (elf_ != nullptr) {
-      bool is_last_part = false;
-      while (!is_last_part) {
-        uint8_t part = value & 0x7F;
-        value >>= 7;
-        if (value == 0) {
-          is_last_part = true;
-        } else {
-          part |= 0x80;
-        }
-        bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&part),
-                                sizeof(part));
-      }
-    }
-  }
-  void u1(uint8_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".byte %u\n", value);
-    }
-    if (elf_ != nullptr) {
-      bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&value),
-                              sizeof(value));
-    }
-  }
-  void u2(uint16_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".2byte %u\n", value);
-    }
-    if (elf_ != nullptr) {
-      bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&value),
-                              sizeof(value));
-    }
-  }
-  intptr_t u4(uint32_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".4byte %" Pu32 "\n", value);
-    }
-    if (elf_ != nullptr) {
-      intptr_t fixup = position();
-      bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&value),
-                              sizeof(value));
-      return fixup;
-    }
-    return -1;
-  }
-  void fixup_u4(intptr_t position, uint32_t value) {
-    RELEASE_ASSERT(elf_ != nullptr);
-    memmove(bin_stream_->buffer() + position, &value, sizeof(value));
-  }
-  void u8(uint64_t value) {
-    if (asm_stream_ != nullptr) {
-      Print(".8byte %" Pu64 "\n", value);
-    }
-    if (elf_ != nullptr) {
-      bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(&value),
-                              sizeof(value));
-    }
-  }
-  void addr(uword value) {
-    RELEASE_ASSERT(elf_ != nullptr);
-#if defined(TARGET_ARCH_IS_32_BIT)
-    u4(value);
-#else
-    u8(value);
-#endif
-  }
-  void string(const char* cstr) {  // NOLINT
-    if (asm_stream_ != nullptr) {
-      Print(".string \"%s\"\n", cstr);  // NOLINT
-    }
-    if (elf_ != nullptr) {
-      bin_stream_->WriteBytes(reinterpret_cast<const uint8_t*>(cstr),
-                              strlen(cstr) + 1);
-    }
-  }
-  intptr_t position() {
-    RELEASE_ASSERT(elf_ != nullptr);
-    return bin_stream_->Position();
-  }
-
   static constexpr intptr_t kNoLineInformation = 0;
 
   // Returns the line number or kNoLineInformation if there is no line
   // information available for the given token position.
   static intptr_t TokenPositionToLine(const TokenPosition& token_pos);
 
-  void WriteAbbreviations();
-  void WriteCompilationUnit();
-  void WriteAbstractFunctions();
-  void WriteConcreteFunctions();
+  void WriteAbstractFunctions(DwarfWriteStream* stream);
+  void WriteConcreteFunctions(DwarfWriteStream* stream);
   InliningNode* ExpandInliningTree(const Code& code);
-  void WriteInliningNode(InliningNode* node,
-                         intptr_t root_code_index,
-                         intptr_t root_code_offset,
+  void WriteInliningNode(DwarfWriteStream* stream,
+                         InliningNode* node,
+                         const char* root_code_name,
                          const Script& parent_script,
                          SnapshotTextObjectNamer* namer);
-  void WriteLines();
 
   const char* Deobfuscate(const char* cstr);
   static Trie<const char>* CreateReverseObfuscationTrie(Zone* zone);
 
   Zone* const zone_;
-  Elf* const elf_;
   Trie<const char>* const reverse_obfuscation_trie_;
-  StreamingWriteStream* asm_stream_;
-  WriteStream* bin_stream_;
   ZoneGrowableArray<const Code*> codes_;
   CodeAddressMap code_to_address_;
   ZoneGrowableArray<const Function*> functions_;
   FunctionIndexMap function_to_index_;
   ZoneGrowableArray<const Script*> scripts_;
   ScriptIndexMap script_to_index_;
-  uint32_t* abstract_origins_;
   intptr_t temp_;
 };
 
diff --git a/runtime/vm/elf.cc b/runtime/vm/elf.cc
index 6f8f5da..ee170f2 100644
--- a/runtime/vm/elf.cc
+++ b/runtime/vm/elf.cc
@@ -6,6 +6,7 @@
 
 #include "platform/elf.h"
 #include "vm/cpu.h"
+#include "vm/dwarf.h"
 #include "vm/hash_map.h"
 #include "vm/image_snapshot.h"
 #include "vm/thread.h"
@@ -156,10 +157,10 @@
   virtual intptr_t MemorySize() const = 0;
 
   // Other methods.
-  bool IsSegment() const { return segment_type != 0; }
+
   // Returns whether new content can be added to a section.
   bool HasBeenFinalized() const {
-    if (IsSegment()) {
+    if (segment_type != elf::PT_NULL) {
       // The contents of a segment must not change after the segment is added
       // (when its memory offset is calculated).
       return memory_offset_ != kInitValue;
@@ -430,6 +431,10 @@
     return offset;
   }
 
+  const char* At(intptr_t index) {
+    ASSERT(index < text_.length());
+    return text_.buffer() + index;
+  }
   intptr_t Lookup(const char* str) const {
     return text_indices_.LookupValue(str) - 1;
   }
@@ -673,10 +678,10 @@
 
 static const intptr_t kProgramTableSegmentSize = Elf::kPageSize;
 
-Elf::Elf(Zone* zone, StreamingWriteStream* stream, bool strip)
+Elf::Elf(Zone* zone, StreamingWriteStream* stream, Dwarf* dwarf)
     : zone_(zone),
       unwrapped_stream_(stream),
-      strip_(strip),
+      dwarf_(dwarf),
       shstrtab_(new (zone) StringTable(/*allocate=*/false)),
       dynstrtab_(new (zone) StringTable(/*allocate=*/true)),
       dynsym_(new (zone) SymbolTable(/*dynamic=*/true)),
@@ -689,6 +694,14 @@
   // Go ahead and add the section header string table, since it doesn't have
   // an in-memory segment and so can be added to until we compute file offsets.
   AddSection(shstrtab_, ".shstrtab");
+  if (dwarf_ != nullptr) {
+    // Not a stripped ELF file, so allocate static string and symbol tables.
+    strtab_ = new (zone_) StringTable(/* allocate= */ false);
+    AddSection(strtab_, ".strtab");
+    symtab_ = new (zone_) SymbolTable(/*dynamic=*/false);
+    AddSection(symtab_, ".symtab");
+    symtab_->section_link = strtab_->section_index();
+  }
 }
 
 void Elf::AddSection(Section* section, const char* name) {
@@ -708,6 +721,8 @@
 }
 
 intptr_t Elf::AddSegmentSymbol(const Section* section, const char* name) {
+  // While elf::STT_SECTION might seem more appropriate, those symbols are
+  // usually local and dlsym won't return them.
   auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
   auto const section_index = section->section_index();
   // For shared libraries, this is the offset from the DSO base. For static
@@ -730,21 +745,14 @@
   return AddSegmentSymbol(image, name);
 }
 
-void Elf::AddCodeSymbol(const char* name,
-                        intptr_t section_index,
-                        intptr_t address,
-                        intptr_t size) {
-  ASSERT(!strip_);
-  auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
-  AddStaticSymbol(name, info, section_index, address, size);
-}
-
-bool Elf::FindDynamicSymbol(const char* name,
-                            intptr_t* offset,
-                            intptr_t* size) const {
-  auto const name_index = dynstrtab_->Lookup(name);
+static bool FindSymbol(StringTable* strings,
+                       SymbolTable* symbols,
+                       const char* name,
+                       intptr_t* offset,
+                       intptr_t* size) {
+  auto const name_index = strings->Lookup(name);
   if (name_index < 0) return false;
-  auto const symbol = dynsym_->FindSymbolWithNameIndex(name_index);
+  auto const symbol = symbols->FindSymbolWithNameIndex(name_index);
   if (symbol == nullptr) return false;
   if (offset != nullptr) {
     *offset = symbol->offset;
@@ -755,6 +763,19 @@
   return true;
 }
 
+bool Elf::FindDynamicSymbol(const char* name,
+                            intptr_t* offset,
+                            intptr_t* size) const {
+  return FindSymbol(dynstrtab_, dynsym_, name, offset, size);
+}
+
+bool Elf::FindStaticSymbol(const char* name,
+                           intptr_t* offset,
+                           intptr_t* size) const {
+  if (strtab_ == nullptr || symtab_ == nullptr) return false;
+  return FindSymbol(strtab_, symtab_, name, offset, size);
+}
+
 intptr_t Elf::AddBSSData(const char* name, intptr_t size) {
   // Ideally the BSS segment would take no space in the object, but Android's
   // "strip" utility truncates the memory-size of our segments to their
@@ -783,7 +804,7 @@
 }
 
 void Elf::AddDebug(const char* name, const uint8_t* bytes, intptr_t size) {
-  ASSERT(!strip_);
+  ASSERT(dwarf_ != nullptr);
   ASSERT(bytes != nullptr);
   ProgramBits* image =
       new (zone_) ProgramBits(false, false, false, bytes, size);
@@ -803,9 +824,7 @@
 
   // Some tools assume the static symbol table is a superset of the dynamic
   // symbol table when it exists (see dartbug.com/41783).
-  if (!strip_) {
-    AddStaticSymbol(name, info, section_index, address, size);
-  }
+  AddStaticSymbol(name, info, section_index, address, size);
 }
 
 void Elf::AddStaticSymbol(const char* name,
@@ -813,19 +832,7 @@
                           intptr_t section_index,
                           intptr_t address,
                           intptr_t size) {
-  ASSERT(!strip_);
-
-  // Lazily allocate the static string and symbol tables, as we only add static
-  // symbols in unstripped ELF files.
-  if (strtab_ == nullptr) {
-    ASSERT(symtab_ == nullptr);
-    ASSERT(section_table_file_size_ < 0);
-    strtab_ = new (zone_) StringTable(/* allocate= */ false);
-    AddSection(strtab_, ".strtab");
-    symtab_ = new (zone_) SymbolTable(/*dynamic=*/false);
-    AddSection(symtab_, ".symtab");
-    symtab_->section_link = strtab_->section_index();
-  }
+  if (dwarf_ == nullptr) return;  // No static info kept in stripped ELF files.
 
   ASSERT(!symtab_->HasBeenFinalized() && !strtab_->HasBeenFinalized());
   auto const name_index = strtab_->AddString(name);
@@ -834,7 +841,211 @@
   symtab_->AddSymbol(symbol);
 }
 
+#if defined(DART_PRECOMPILER)
+class DwarfElfStream : public DwarfWriteStream {
+ public:
+  explicit DwarfElfStream(Zone* zone,
+                          WriteStream* stream,
+                          const CStringMap<intptr_t>& address_map)
+      : zone_(zone),
+        stream_(ASSERT_NOTNULL(stream)),
+        address_map_(address_map) {}
+
+  void sleb128(intptr_t value) {
+    bool is_last_part = false;
+    while (!is_last_part) {
+      uint8_t part = value & 0x7F;
+      value >>= 7;
+      if ((value == 0 && (part & 0x40) == 0) ||
+          (value == static_cast<intptr_t>(-1) && (part & 0x40) != 0)) {
+        is_last_part = true;
+      } else {
+        part |= 0x80;
+      }
+      stream_->WriteFixed(part);
+    }
+  }
+
+  void uleb128(uintptr_t value) {
+    bool is_last_part = false;
+    while (!is_last_part) {
+      uint8_t part = value & 0x7F;
+      value >>= 7;
+      if (value == 0) {
+        is_last_part = true;
+      } else {
+        part |= 0x80;
+      }
+      stream_->WriteFixed(part);
+    }
+  }
+
+  void u1(uint8_t value) { stream_->WriteFixed(value); }
+  // Can't use WriteFixed for these, as we may not be at aligned positions.
+  void u2(uint16_t value) { stream_->WriteBytes(&value, sizeof(value)); }
+  void u4(uint32_t value) { stream_->WriteBytes(&value, sizeof(value)); }
+  void u8(uint64_t value) { stream_->WriteBytes(&value, sizeof(value)); }
+  void string(const char* cstr) {  // NOLINT
+    stream_->WriteBytes(reinterpret_cast<const uint8_t*>(cstr),
+                        strlen(cstr) + 1);
+  }
+  intptr_t position() { return stream_->Position(); }
+  intptr_t ReserveSize(const char* prefix, intptr_t* start) {
+    ASSERT(start != nullptr);
+    intptr_t fixup = position();
+    // We assume DWARF v2, so all sizes are 32-bit.
+    u4(0);
+    // All sizes for DWARF sections measure the size of the section data _after_
+    // the size value.
+    *start = position();
+    return fixup;
+  }
+  void SetSize(intptr_t fixup, const char* prefix, intptr_t start) {
+    const uint32_t value = position() - start;
+    memmove(stream_->buffer() + fixup, &value, sizeof(value));
+  }
+  void OffsetFromSymbol(const char* symbol, intptr_t offset) {
+    auto const address = address_map_.LookupValue(symbol);
+    ASSERT(address != 0);
+    addr(address + offset);
+  }
+  void DistanceBetweenSymbolOffsets(const char* symbol1,
+                                    intptr_t offset1,
+                                    const char* symbol2,
+                                    intptr_t offset2) {
+    auto const address1 = address_map_.LookupValue(symbol1);
+    ASSERT(address1 != 0);
+    auto const address2 = address_map_.LookupValue(symbol2);
+    ASSERT(address2 != 0);
+    auto const delta = (address1 + offset1) - (address2 + offset2);
+    RELEASE_ASSERT(delta >= 0);
+    uleb128(delta);
+  }
+  void InitializeAbstractOrigins(intptr_t size) {
+    abstract_origins_size_ = size;
+    abstract_origins_ = zone_->Alloc<uint32_t>(abstract_origins_size_);
+  }
+  void RegisterAbstractOrigin(intptr_t index) {
+    ASSERT(abstract_origins_ != nullptr);
+    ASSERT(index < abstract_origins_size_);
+    abstract_origins_[index] = position();
+  }
+  void AbstractOrigin(intptr_t index) { u4(abstract_origins_[index]); }
+
+ private:
+  void addr(uword value) {
+#if defined(TARGET_ARCH_IS_32_BIT)
+    u4(value);
+#else
+    u8(value);
+#endif
+  }
+
+  Zone* const zone_;
+  WriteStream* const stream_;
+  const CStringMap<intptr_t>& address_map_;
+  uint32_t* abstract_origins_ = nullptr;
+  intptr_t abstract_origins_size_ = -1;
+
+  DISALLOW_COPY_AND_ASSIGN(DwarfElfStream);
+};
+
+static constexpr intptr_t kInitialDwarfBufferSize = 64 * KB;
+
+static uint8_t* ZoneReallocate(uint8_t* ptr, intptr_t len, intptr_t new_len) {
+  return Thread::Current()->zone()->Realloc<uint8_t>(ptr, len, new_len);
+}
+#endif
+
+const Section* Elf::FindSegmentForAddress(intptr_t address) const {
+  for (intptr_t i = 0; i < segments_.length(); i++) {
+    auto const segment = segments_[i];
+    auto const start = segment->memory_offset();
+    auto const end = start + segment->MemorySize();
+    if (address >= start && address < end) {
+      return segment;
+    }
+  }
+  return nullptr;
+}
+
+void Elf::FinalizeDwarfSections() {
+  if (dwarf_ == nullptr) return;
+#if defined(DART_PRECOMPILER)
+  // Add all the static symbols for Code objects. We'll keep a table of
+  // symbol names to relocated addresses for use in the DwarfElfStream.
+  // The default kNoValue of 0 is okay here, as no symbols are defined for
+  // relocated address 0.
+  CStringMap<intptr_t> symbol_to_address_map;
+  // Prime the map with any existing static symbols.
+  if (symtab_ != nullptr) {
+    ASSERT(strtab_ != nullptr);
+    // Skip the initial reserved entry in the symbol table.
+    for (intptr_t i = 1; i < symtab_->Length(); i++) {
+      auto const symbol = symtab_->At(i);
+      auto const name = strtab_->At(symbol->name_index);
+      symbol_to_address_map.Insert({name, symbol->offset});
+    }
+  }
+
+  // Need these to turn offsets into relocated addresses.
+  auto const vm_start =
+      symbol_to_address_map.LookupValue(kVmSnapshotInstructionsAsmSymbol);
+  ASSERT(vm_start > 0);
+  auto const isolate_start =
+      symbol_to_address_map.LookupValue(kIsolateSnapshotInstructionsAsmSymbol);
+  ASSERT(isolate_start > 0);
+  auto const vm_text = FindSegmentForAddress(vm_start);
+  ASSERT(vm_text != nullptr);
+  auto const isolate_text = FindSegmentForAddress(isolate_start);
+  ASSERT(isolate_text != nullptr);
+
+  SnapshotTextObjectNamer namer(zone_);
+  const auto& codes = dwarf_->codes();
+  for (intptr_t i = 0; i < codes.length(); i++) {
+    const auto& code = *codes[i];
+    auto const name = namer.SnapshotNameFor(i, code);
+    const auto& pair = dwarf_->CodeAddress(code);
+    ASSERT(pair.offset > 0);
+    auto const segment = pair.vm ? vm_text : isolate_text;
+    const intptr_t address = segment->memory_offset() + pair.offset;
+    auto const info = (elf::STB_GLOBAL << 4) | elf::STT_FUNC;
+    AddStaticSymbol(name, info, segment->section_index(), address, code.Size());
+    symbol_to_address_map.Insert({name, address});
+  }
+
+  // TODO(rmacnak): Generate .debug_frame / .eh_frame / .arm.exidx to
+  // provide unwinding information.
+
+  {
+    uint8_t* buffer = nullptr;
+    WriteStream stream(&buffer, ZoneReallocate, kInitialDwarfBufferSize);
+    DwarfElfStream dwarf_stream(zone_, &stream, symbol_to_address_map);
+    dwarf_->WriteAbbreviations(&dwarf_stream);
+    AddDebug(".debug_abbrev", buffer, stream.bytes_written());
+  }
+
+  {
+    uint8_t* buffer = nullptr;
+    WriteStream stream(&buffer, ZoneReallocate, kInitialDwarfBufferSize);
+    DwarfElfStream dwarf_stream(zone_, &stream, symbol_to_address_map);
+    dwarf_->WriteDebugInfo(&dwarf_stream);
+    AddDebug(".debug_info", buffer, stream.bytes_written());
+  }
+
+  {
+    uint8_t* buffer = nullptr;
+    WriteStream stream(&buffer, ZoneReallocate, kInitialDwarfBufferSize);
+    DwarfElfStream dwarf_stream(zone_, &stream, symbol_to_address_map);
+    dwarf_->WriteLineNumberProgram(&dwarf_stream);
+    AddDebug(".debug_line", buffer, stream.bytes_written());
+  }
+#endif
+}
+
 void Elf::Finalize() {
+  FinalizeDwarfSections();
+
   // Unlike the static tables, we must wait until finalization to add the
   // dynamic tables, as adding them marks them as finalized.
   AddSection(dynstrtab_, ".dynstr");
diff --git a/runtime/vm/elf.h b/runtime/vm/elf.h
index 9567ddf..a269192 100644
--- a/runtime/vm/elf.h
+++ b/runtime/vm/elf.h
@@ -13,6 +13,7 @@
 
 namespace dart {
 
+class Dwarf;
 class DynamicSegment;
 class DynamicTable;
 class ElfWriteStream;
@@ -23,26 +24,31 @@
 
 class Elf : public ZoneAllocated {
  public:
-  Elf(Zone* zone, StreamingWriteStream* stream, bool strip = false);
+  Elf(Zone* zone, StreamingWriteStream* stream, Dwarf* dwarf = nullptr);
 
   static const intptr_t kPageSize = 4096;
 
+  Zone* zone() { return zone_; }
+  const Dwarf* dwarf() const { return dwarf_; }
+  Dwarf* dwarf() { return dwarf_; }
+
   intptr_t NextMemoryOffset() const { return memory_offset_; }
   intptr_t NextSectionIndex() const { return sections_.length(); }
   intptr_t AddText(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddROData(const char* name, const uint8_t* bytes, intptr_t size);
   intptr_t AddBSSData(const char* name, intptr_t size);
   void AddDebug(const char* name, const uint8_t* bytes, intptr_t size);
-  void AddCodeSymbol(const char* name,
-                     intptr_t section,
-                     intptr_t address,
-                     intptr_t size);
 
   // Returns whether the symbol was found. If found, sets the contents of
   // offset and size appropriately if either or both are not nullptr.
   bool FindDynamicSymbol(const char* name,
                          intptr_t* offset,
                          intptr_t* size) const;
+  // Returns whether the symbol was found. If found, sets the contents of
+  // offset and size appropriately if either or both are not nullptr.
+  bool FindStaticSymbol(const char* name,
+                        intptr_t* offset,
+                        intptr_t* size) const;
 
   void Finalize();
 
@@ -60,6 +66,9 @@
                         intptr_t address,
                         intptr_t size);
 
+  const Section* FindSegmentForAddress(intptr_t address) const;
+
+  void FinalizeDwarfSections();
   void FinalizeProgramTable();
   void ComputeFileOffsets();
 
@@ -70,9 +79,9 @@
 
   Zone* const zone_;
   StreamingWriteStream* const unwrapped_stream_;
-  // Whether the ELF file should be stripped of static information like
+  // If nullptr, then the ELF file should be stripped of static information like
   // the static symbol table (and its corresponding string table).
-  const bool strip_;
+  Dwarf* const dwarf_;
 
   // All our strings would fit in a single page. However, we use separate
   // .shstrtab and .dynstr to work around a bug in Android's strip utility.
diff --git a/runtime/vm/heap/freelist.cc b/runtime/vm/heap/freelist.cc
index 3570378..a6ba604 100644
--- a/runtime/vm/heap/freelist.cc
+++ b/runtime/vm/heap/freelist.cc
@@ -377,13 +377,13 @@
   return NULL;
 }
 
-void FreeList::MergeOtherFreelist(FreeList* other, bool is_protected) {
+void FreeList::MergeFrom(FreeList* donor, bool is_protected) {
   // The [other] free list is from a dying isolate. There are no other threads
   // accessing it, so there is no need to lock here.
   MutexLocker ml(&mutex_);
   for (intptr_t i = 0; i < (kNumLists + 1); ++i) {
-    FreeListElement* other_head = other->free_lists_[i];
-    if (other_head != nullptr) {
+    FreeListElement* donor_head = donor->free_lists_[i];
+    if (donor_head != nullptr) {
       // If we didn't have a freelist element before we have to set the bit now,
       // since we will get 1+ elements from [other].
       FreeListElement* old_head = free_lists_[i];
@@ -392,7 +392,7 @@
       }
 
       // Chain other's list in.
-      FreeListElement* last = other_head;
+      FreeListElement* last = donor_head;
       while (last->next() != nullptr) {
         last = last->next();
       }
@@ -406,12 +406,12 @@
         VirtualMemory::Protect(reinterpret_cast<void*>(last), sizeof(*last),
                                VirtualMemory::kReadExecute);
       }
-      free_lists_[i] = other_head;
+      free_lists_[i] = donor_head;
     }
   }
 
   last_free_small_size_ =
-      Utils::Maximum(last_free_small_size_, other->last_free_small_size_);
+      Utils::Maximum(last_free_small_size_, donor->last_free_small_size_);
 }
 
 }  // namespace dart
diff --git a/runtime/vm/heap/freelist.h b/runtime/vm/heap/freelist.h
index 00414b8..e37ab52 100644
--- a/runtime/vm/heap/freelist.h
+++ b/runtime/vm/heap/freelist.h
@@ -157,7 +157,7 @@
   void set_end(uword value) { end_ = value; }
   void AddUnaccountedSize(intptr_t size) { unaccounted_size_ += size; }
 
-  void MergeOtherFreelist(FreeList* freelist, bool is_protected);
+  void MergeFrom(FreeList* donor, bool is_protected);
 
  private:
   static const int kNumLists = 128;
diff --git a/runtime/vm/heap/heap.cc b/runtime/vm/heap/heap.cc
index e677b0c..855ea7e 100644
--- a/runtime/vm/heap/heap.cc
+++ b/runtime/vm/heap/heap.cc
@@ -405,17 +405,42 @@
 
 void Heap::NotifyIdle(int64_t deadline) {
   Thread* thread = Thread::Current();
+  // Check if we want to collect new-space first, because if we want to collect
+  // both new-space and old-space, the new-space collection should run first
+  // to shrink the root set (make old-space GC faster) and avoid
+  // intergenerational garbage (make old-space GC free more memory).
   if (new_space_.ShouldPerformIdleScavenge(deadline)) {
     TIMELINE_FUNCTION_GC_DURATION(thread, "IdleGC");
     CollectNewSpaceGarbage(thread, kIdle);
   }
+
+  // Check if we want to collect old-space, in decreasing order of cost.
   // Because we use a deadline instead of a timeout, we automatically take any
   // time used up by a scavenge into account when deciding if we can complete
   // a mark-sweep on time.
   if (old_space_.ShouldPerformIdleMarkCompact(deadline)) {
+    // We prefer mark-compact over other old space GCs if we have enough time,
+    // since it removes old space fragmentation and frees up most memory.
+    // Blocks for O(heap), roughtly twice as costly as mark-sweep.
     TIMELINE_FUNCTION_GC_DURATION(thread, "IdleGC");
     CollectOldSpaceGarbage(thread, kMarkCompact, kIdle);
-  } else if (old_space_.ShouldStartIdleMarkSweep(deadline)) {
+  } else if (old_space_.ReachedHardThreshold()) {
+    // Even though the following GC may exceed our idle deadline, we need to
+    // ensure than that promotions during idle scavenges do not lead to
+    // unbounded growth of old space. If a program is allocating only in new
+    // space and all scavenges happen during idle time, then NotifyIdle will be
+    // the only place that checks the old space allocation limit.
+    // Compare the tail end of Heap::CollectNewSpaceGarbage.
+    // Blocks for O(heap).
+    TIMELINE_FUNCTION_GC_DURATION(thread, "IdleGC");
+    CollectOldSpaceGarbage(thread, kMarkSweep, kIdle);
+  } else if (old_space_.ShouldStartIdleMarkSweep(deadline) ||
+             old_space_.ReachedSoftThreshold()) {
+    // If we have both work to do and enough time, start or finish GC.
+    // If we have crossed the soft threshold, ignore time; the next old-space
+    // allocation will trigger this work anyway, so we try to pay at least some
+    // of that cost with idle time.
+    // Blocks for O(roots).
     PageSpace::Phase phase;
     {
       MonitorLocker ml(old_space_.tasks_lock());
@@ -428,16 +453,6 @@
       TIMELINE_FUNCTION_GC_DURATION(thread, "IdleGC");
       StartConcurrentMarking(thread);
     }
-  } else if (old_space_.ReachedHardThreshold()) {
-    // Even though the following GC may exceed our idle deadline, we need to
-    // ensure than that promotions during idle scavenges do not lead to
-    // unbounded growth of old space. If a program is allocating only in new
-    // space and all scavenges happen during idle time, then NotifyIdle will be
-    // the only place that checks the old space allocation limit.
-    // Compare the tail end of Heap::CollectNewSpaceGarbage.
-    CollectOldSpaceGarbage(thread, kMarkSweep, kIdle);  // Blocks for O(heap)
-  } else {
-    CheckStartConcurrentMarking(thread, kIdle);  // Blocks for up to O(roots)
   }
 }
 
@@ -724,19 +739,19 @@
   gc_on_nth_allocation_ = num_allocations;
 }
 
-void Heap::MergeOtherHeap(Heap* other) {
-  ASSERT(!other->gc_new_space_in_progress_);
-  ASSERT(!other->gc_old_space_in_progress_);
-  ASSERT(!other->read_only_);
-  ASSERT(other->new_space()->UsedInWords() == 0);
-  ASSERT(other->old_space()->tasks() == 0);
+void Heap::MergeFrom(Heap* donor) {
+  ASSERT(!donor->gc_new_space_in_progress_);
+  ASSERT(!donor->gc_old_space_in_progress_);
+  ASSERT(!donor->read_only_);
+  ASSERT(donor->old_space()->tasks() == 0);
 
-  old_space_.MergeOtherPageSpace(other->old_space());
+  new_space_.MergeFrom(donor->new_space());
+  old_space_.MergeFrom(donor->old_space());
 
   for (intptr_t i = 0; i < kNumWeakSelectors; ++i) {
     // The new space rehashing should not be necessary.
-    new_weak_tables_[i]->MergeOtherWeakTable(other->new_weak_tables_[i]);
-    old_weak_tables_[i]->MergeOtherWeakTable(other->old_weak_tables_[i]);
+    new_weak_tables_[i]->MergeFrom(donor->new_weak_tables_[i]);
+    old_weak_tables_[i]->MergeFrom(donor->old_weak_tables_[i]);
   }
 }
 
diff --git a/runtime/vm/heap/heap.h b/runtime/vm/heap/heap.h
index 92dda0a..fb57895 100644
--- a/runtime/vm/heap/heap.h
+++ b/runtime/vm/heap/heap.h
@@ -307,7 +307,7 @@
 
   void CollectOnNthAllocation(intptr_t num_allocations);
 
-  void MergeOtherHeap(Heap* other);
+  void MergeFrom(Heap* donor);
 
  private:
   class GCStats : public ValueObject {
diff --git a/runtime/vm/heap/pages.cc b/runtime/vm/heap/pages.cc
index 42d2bb1..a542ec4 100644
--- a/runtime/vm/heap/pages.cc
+++ b/runtime/vm/heap/pages.cc
@@ -1437,54 +1437,53 @@
 #endif
 }
 
-void PageSpace::MergeOtherPageSpace(PageSpace* other) {
-  other->AbandonBumpAllocation();
+void PageSpace::MergeFrom(PageSpace* donor) {
+  donor->AbandonBumpAllocation();
 
-  ASSERT(other->tasks_ == 0);
-  ASSERT(other->concurrent_marker_tasks_ == 0);
-  ASSERT(other->phase_ == kDone);
-  DEBUG_ASSERT(other->iterating_thread_ == nullptr);
-  ASSERT(other->marker_ == nullptr);
+  ASSERT(donor->tasks_ == 0);
+  ASSERT(donor->concurrent_marker_tasks_ == 0);
+  ASSERT(donor->phase_ == kDone);
+  DEBUG_ASSERT(donor->iterating_thread_ == nullptr);
+  ASSERT(donor->marker_ == nullptr);
 
   for (intptr_t i = 0; i < num_freelists_; ++i) {
-    ASSERT(other->freelists_[i].top() == 0);
-    ASSERT(other->freelists_[i].end() == 0);
+    ASSERT(donor->freelists_[i].top() == 0);
+    ASSERT(donor->freelists_[i].end() == 0);
     const bool is_protected =
         FLAG_write_protect_code && i == OldPage::kExecutable;
-    freelists_[i].MergeOtherFreelist(&other->freelists_[i], is_protected);
-    other->freelists_[i].Reset();
+    freelists_[i].MergeFrom(&donor->freelists_[i], is_protected);
+    donor->freelists_[i].Reset();
   }
 
   // The freelist locks will be taken in MergeOtherFreelist above, and the
   // locking order is the freelist locks are taken before the page list locks,
   // so don't take the pages lock until after MergeOtherFreelist.
   MutexLocker ml(&pages_lock_);
-  MutexLocker ml2(&other->pages_lock_);
+  MutexLocker ml2(&donor->pages_lock_);
 
-  AppendList(&pages_, &pages_tail_, &other->pages_, &other->pages_tail_);
-  AppendList(&exec_pages_, &exec_pages_tail_, &other->exec_pages_,
-             &other->exec_pages_tail_);
-  AppendList(&large_pages_, &large_pages_tail_, &other->large_pages_,
-             &other->large_pages_tail_);
+  AppendList(&pages_, &pages_tail_, &donor->pages_, &donor->pages_tail_);
+  AppendList(&exec_pages_, &exec_pages_tail_, &donor->exec_pages_,
+             &donor->exec_pages_tail_);
+  AppendList(&large_pages_, &large_pages_tail_, &donor->large_pages_,
+             &donor->large_pages_tail_);
   // We intentionall do not merge [image_pages_] beause [this] and [other] have
   // the same mmap()ed image page areas.
-  EnsureEqualImagePages(image_pages_, other->image_pages_);
+  EnsureEqualImagePages(image_pages_, donor->image_pages_);
 
   // We intentionaly do not increase [max_capacity_in_words_] because this can
   // lead [max_capacity_in_words_] to become larger and larger and eventually
   // wrap-around and become negative.
-  allocated_black_in_words_ += other->allocated_black_in_words_;
-  gc_time_micros_ += other->gc_time_micros_;
-  collections_ += other->collections_;
+  allocated_black_in_words_ += donor->allocated_black_in_words_;
+  gc_time_micros_ += donor->gc_time_micros_;
+  collections_ += donor->collections_;
 
-  usage_.capacity_in_words += other->usage_.capacity_in_words;
-  usage_.used_in_words += other->usage_.used_in_words;
-  usage_.external_in_words += other->usage_.external_in_words;
+  usage_.capacity_in_words += donor->usage_.capacity_in_words;
+  usage_.used_in_words += donor->usage_.used_in_words;
+  usage_.external_in_words += donor->usage_.external_in_words;
 
-  page_space_controller_.MergeOtherPageSpaceController(
-      &other->page_space_controller_);
+  page_space_controller_.MergeFrom(&donor->page_space_controller_);
 
-  ASSERT(FLAG_concurrent_mark || other->enable_concurrent_mark_ == false);
+  ASSERT(FLAG_concurrent_mark || donor->enable_concurrent_mark_ == false);
 }
 
 PageSpaceController::PageSpaceController(Heap* heap,
@@ -1697,11 +1696,10 @@
   }
 }
 
-void PageSpaceController::MergeOtherPageSpaceController(
-    PageSpaceController* other) {
-  last_usage_.capacity_in_words += other->last_usage_.capacity_in_words;
-  last_usage_.used_in_words += other->last_usage_.used_in_words;
-  last_usage_.external_in_words += other->last_usage_.external_in_words;
+void PageSpaceController::MergeFrom(PageSpaceController* donor) {
+  last_usage_.capacity_in_words += donor->last_usage_.capacity_in_words;
+  last_usage_.used_in_words += donor->last_usage_.used_in_words;
+  last_usage_.external_in_words += donor->last_usage_.external_in_words;
 }
 
 void PageSpaceGarbageCollectionHistory::AddGarbageCollectionTime(int64_t start,
diff --git a/runtime/vm/heap/pages.h b/runtime/vm/heap/pages.h
index 6235d1e..a493190 100644
--- a/runtime/vm/heap/pages.h
+++ b/runtime/vm/heap/pages.h
@@ -239,7 +239,7 @@
   friend class PageSpace;  // For MergeOtherPageSpaceController
 
   void RecordUpdate(SpaceUsage before, SpaceUsage after, const char* reason);
-  void MergeOtherPageSpaceController(PageSpaceController* other);
+  void MergeFrom(PageSpaceController* donor);
 
   void RecordUpdate(SpaceUsage before,
                     SpaceUsage after,
@@ -482,7 +482,7 @@
 
   bool IsObjectFromImagePages(ObjectPtr object);
 
-  void MergeOtherPageSpace(PageSpace* other);
+  void MergeFrom(PageSpace* donor);
 
  private:
   // Ids for time and data records in Heap::GCStats.
diff --git a/runtime/vm/heap/scavenger.cc b/runtime/vm/heap/scavenger.cc
index ee42db2..afea112 100644
--- a/runtime/vm/heap/scavenger.cc
+++ b/runtime/vm/heap/scavenger.cc
@@ -673,6 +673,19 @@
   tail_ = tail;
 }
 
+void SemiSpace::MergeFrom(SemiSpace* donor) {
+  for (NewPage* page = donor->head_; page != nullptr; page = page->next()) {
+    page->Release();
+  }
+
+  AddList(donor->head_, donor->tail_);
+  capacity_in_words_ += donor->capacity_in_words_;
+
+  donor->head_ = nullptr;
+  donor->tail_ = nullptr;
+  donor->capacity_in_words_ = 0;
+}
+
 // The initial estimate of how many words we can scavenge per microsecond (usage
 // before / scavenge time). This is a conservative value observed running
 // Flutter on a Nexus 4. After the first scavenge, we instead use a value based
@@ -1578,4 +1591,13 @@
   ASSERT((UsedInWords() == 0) || failed_to_promote_);
 }
 
+void Scavenger::MergeFrom(Scavenger* donor) {
+  MutexLocker ml(&space_lock_);
+  MutexLocker ml2(&donor->space_lock_);
+  to_->MergeFrom(donor->to_);
+
+  external_size_ += donor->external_size_;
+  donor->external_size_ = 0;
+}
+
 }  // namespace dart
diff --git a/runtime/vm/heap/scavenger.h b/runtime/vm/heap/scavenger.h
index 81db5fc..5cc105c 100644
--- a/runtime/vm/heap/scavenger.h
+++ b/runtime/vm/heap/scavenger.h
@@ -183,6 +183,7 @@
   NewPage* head() const { return head_; }
 
   void AddList(NewPage* head, NewPage* tail);
+  void MergeFrom(SemiSpace* donor);
 
  private:
   // Size of NewPages in this semi-space.
@@ -279,6 +280,8 @@
   // Promote all live objects.
   void Evacuate();
 
+  void MergeFrom(Scavenger* donor);
+
   int64_t UsedInWords() const {
     MutexLocker ml(&space_lock_);
     return to_->capacity_in_words();
diff --git a/runtime/vm/heap/weak_table.cc b/runtime/vm/heap/weak_table.cc
index 159ed5a..760e05d 100644
--- a/runtime/vm/heap/weak_table.cc
+++ b/runtime/vm/heap/weak_table.cc
@@ -132,10 +132,10 @@
   free(old_data);
 }
 
-void WeakTable::MergeOtherWeakTable(WeakTable* other) {
-  for (intptr_t i = 0; i < other->size(); i++) {
-    if (other->IsValidEntryAtExclusive(i)) {
-      SetValueExclusive(other->ObjectAtExclusive(i), ValueIndex(i));
+void WeakTable::MergeFrom(WeakTable* donor) {
+  for (intptr_t i = 0; i < donor->size(); i++) {
+    if (donor->IsValidEntryAtExclusive(i)) {
+      SetValueExclusive(donor->ObjectAtExclusive(i), ValueIndex(i));
     }
   }
 }
diff --git a/runtime/vm/heap/weak_table.h b/runtime/vm/heap/weak_table.h
index 6fc01f3..1a81be4 100644
--- a/runtime/vm/heap/weak_table.h
+++ b/runtime/vm/heap/weak_table.h
@@ -130,7 +130,7 @@
 
   void Reset();
 
-  void MergeOtherWeakTable(WeakTable* other);
+  void MergeFrom(WeakTable* donor);
 
  private:
   enum {
diff --git a/runtime/vm/image_snapshot.cc b/runtime/vm/image_snapshot.cc
index 63a49e6..fef47d6 100644
--- a/runtime/vm/image_snapshot.cc
+++ b/runtime/vm/image_snapshot.cc
@@ -337,9 +337,10 @@
       js.PrintPropertyStr("l", url);
       js.PrintPropertyStr("c", name);
     }
-    js.PrintProperty(
-        "n", data.code_->QualifiedName(Object::kInternalName,
-                                       Object::NameDisambiguation::kYes));
+    js.PrintProperty("n",
+                     data.code_->QualifiedName(
+                         NameFormattingParams::DisambiguatedWithoutClassName(
+                             Object::kInternalName)));
     js.PrintProperty("s", SizeInSnapshot(data.insns_->raw()));
     js.CloseObject();
   }
@@ -530,6 +531,139 @@
   }
 }
 
+#if defined(DART_PRECOMPILER)
+class DwarfAssemblyStream : public DwarfWriteStream {
+ public:
+  explicit DwarfAssemblyStream(StreamingWriteStream* stream)
+      : stream_(ASSERT_NOTNULL(stream)) {}
+
+  void sleb128(intptr_t value) { Print(".sleb128 %" Pd "\n", value); }
+  void uleb128(uintptr_t value) { Print(".uleb128 %" Pd "\n", value); }
+  void u1(uint8_t value) { Print(".byte %u\n", value); }
+  void u2(uint16_t value) { Print(".2byte %u\n", value); }
+  void u4(uint32_t value) { Print(".4byte %" Pu32 "\n", value); }
+  void u8(uint64_t value) { Print(".8byte %" Pu64 "\n", value); }
+  void string(const char* cstr) {     // NOLINT
+    Print(".string \"%s\"\n", cstr);  // NOLINT
+  }
+  // Uses labels, so doesn't output to start or return a useful fixup position.
+  intptr_t ReserveSize(const char* prefix, intptr_t* start) {
+    // Assignment to temp works around buggy Mac assembler.
+    Print("L%s_size = .L%s_end - .L%s_start\n", prefix, prefix, prefix);
+    Print(".4byte L%s_size\n", prefix);
+    Print(".L%s_start:\n", prefix);
+    return -1;
+  }
+  // Just need to label the end so the assembler can calculate the size, so
+  // start and the fixup position is unused.
+  void SetSize(intptr_t fixup, const char* prefix, intptr_t start) {
+    Print(".L%s_end:\n", prefix);
+  }
+  void OffsetFromSymbol(const char* symbol, intptr_t offset) {
+    if (offset == 0) {
+      PrintNamedAddress(symbol);
+    } else {
+      PrintNamedAddressWithOffset(symbol, offset);
+    }
+  }
+  void DistanceBetweenSymbolOffsets(const char* symbol1,
+                                    intptr_t offset1,
+                                    const char* symbol2,
+                                    intptr_t offset2) {
+    Print(".uleb128 %s - %s + %" Pd "\n", symbol1, symbol2, offset1 - offset2);
+  }
+
+  // No-op, we'll be using labels.
+  void InitializeAbstractOrigins(intptr_t size) {}
+  void RegisterAbstractOrigin(intptr_t index) {
+    // Label for DW_AT_abstract_origin references
+    Print(".Lfunc%" Pd ":\n", index);
+  }
+  void AbstractOrigin(intptr_t index) {
+    // Assignment to temp works around buggy Mac assembler.
+    Print("Ltemp%" Pd " = .Lfunc%" Pd " - %s\n", temp_, index, kDebugInfoLabel);
+    Print(".4byte Ltemp%" Pd "\n", temp_);
+    temp_++;
+  }
+
+  // Methods for writing the assembly prologues for various DWARF sections.
+  void AbbreviationsPrologue() {
+#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
+    Print(".section __DWARF,__debug_abbrev,regular,debug\n");
+#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
+    defined(TARGET_OS_FUCHSIA)
+    Print(".section .debug_abbrev,\"\"\n");
+#else
+    UNIMPLEMENTED();
+#endif
+  }
+  void DebugInfoPrologue() {
+#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
+    Print(".section __DWARF,__debug_info,regular,debug\n");
+#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
+    defined(TARGET_OS_FUCHSIA)
+    Print(".section .debug_info,\"\"\n");
+#else
+    UNIMPLEMENTED();
+#endif
+    // Used to calculate abstract origin values.
+    Print("%s:\n", kDebugInfoLabel);
+  }
+  void LineNumberProgramPrologue() {
+#if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
+    Print(".section __DWARF,__debug_line,regular,debug\n");
+#elif defined(TARGET_OS_LINUX) || defined(TARGET_OS_ANDROID) ||                \
+    defined(TARGET_OS_FUCHSIA)
+    Print(".section .debug_line,\"\"\n");
+#else
+    UNIMPLEMENTED();
+#endif
+  }
+
+ private:
+  static constexpr const char* kDebugInfoLabel = ".Ldebug_info";
+
+  void Print(const char* format, ...) PRINTF_ATTRIBUTE(2, 3) {
+    va_list args;
+    va_start(args, format);
+    stream_->VPrint(format, args);
+    va_end(args);
+  }
+
+#if defined(TARGET_ARCH_IS_32_BIT)
+#define FORM_ADDR ".4byte"
+#elif defined(TARGET_ARCH_IS_64_BIT)
+#define FORM_ADDR ".8byte"
+#endif
+
+  void PrintNamedAddress(const char* name) { Print(FORM_ADDR " %s\n", name); }
+  void PrintNamedAddressWithOffset(const char* name, intptr_t offset) {
+    Print(FORM_ADDR " %s + %" Pd "\n", name, offset);
+  }
+
+#undef FORM_ADDR
+
+  StreamingWriteStream* const stream_;
+  intptr_t temp_ = 0;
+
+  DISALLOW_COPY_AND_ASSIGN(DwarfAssemblyStream);
+};
+#endif
+
+static inline Dwarf* AddDwarfIfUnstripped(Zone* zone, bool strip, Elf* elf) {
+#if defined(DART_PRECOMPILER)
+  if (!strip) {
+    if (elf != nullptr) {
+      // Reuse the existing DWARF object.
+      ASSERT(elf->dwarf() != nullptr);
+      return elf->dwarf();
+    }
+    return new (zone) Dwarf(zone);
+  }
+#endif
+  return nullptr;
+}
+
 AssemblyImageWriter::AssemblyImageWriter(Thread* thread,
                                          Dart_StreamingWriteCallback callback,
                                          void* callback_data,
@@ -537,28 +671,22 @@
                                          Elf* debug_elf)
     : ImageWriter(thread),
       assembly_stream_(512 * KB, callback, callback_data),
-      assembly_dwarf_(nullptr),
-      debug_dwarf_(nullptr) {
-#if defined(DART_PRECOMPILER)
-  Zone* zone = Thread::Current()->zone();
-  if (!strip) {
-    assembly_dwarf_ =
-        new (zone) Dwarf(zone, &assembly_stream_, /*elf=*/nullptr);
-  }
-  if (debug_elf != nullptr) {
-    debug_dwarf_ =
-        new (zone) Dwarf(zone, /*assembly_stream=*/nullptr, debug_elf);
-  }
-#endif
-}
+      assembly_dwarf_(AddDwarfIfUnstripped(thread->zone(), strip, debug_elf)),
+      debug_elf_(debug_elf) {}
 
 void AssemblyImageWriter::Finalize() {
-#ifdef DART_PRECOMPILER
+#if defined(DART_PRECOMPILER)
   if (assembly_dwarf_ != nullptr) {
-    assembly_dwarf_->Write();
+    DwarfAssemblyStream dwarf_stream(&assembly_stream_);
+    dwarf_stream.AbbreviationsPrologue();
+    assembly_dwarf_->WriteAbbreviations(&dwarf_stream);
+    dwarf_stream.DebugInfoPrologue();
+    assembly_dwarf_->WriteDebugInfo(&dwarf_stream);
+    dwarf_stream.LineNumberProgramPrologue();
+    assembly_dwarf_->WriteLineNumberProgram(&dwarf_stream);
   }
-  if (debug_dwarf_ != nullptr) {
-    debug_dwarf_->Write();
+  if (debug_elf_ != nullptr) {
+    debug_elf_->Finalize();
   }
 #endif
 }
@@ -573,21 +701,6 @@
     *label = '_';
   }
 }
-
-static const char* NameOfStubIsolateSpecificStub(ObjectStore* object_store,
-                                                 const Code& code) {
-  if (code.raw() == object_store->build_method_extractor_code()) {
-    return "_iso_stub_BuildMethodExtractorStub";
-  }
-
-#define DO(member, name)                                                       \
-  if (code.raw() == object_store->member()) {                                  \
-    return "_iso_stub_" #name "Stub";                                          \
-  }
-  OBJECT_STORE_STUB_CODE_LIST(DO)
-#undef DO
-  return nullptr;
-}
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
 const char* SnapshotTextObjectNamer::SnapshotNameFor(intptr_t code_index,
@@ -598,12 +711,8 @@
   if (owner_.IsNull()) {
     insns_ = code.instructions();
     const char* name = StubCode::NameOfStub(insns_.EntryPoint());
-    if (name != nullptr) {
-      return OS::SCreate(zone_, "%sStub_%s", prefix, name);
-    }
-    name = NameOfStubIsolateSpecificStub(store_, code);
     ASSERT(name != nullptr);
-    return OS::SCreate(zone_, "%s_%s", prefix, name);
+    return OS::SCreate(zone_, "%sStub_%s", prefix, name);
   }
   // The weak reference to the Code's owner should never have been removed via
   // an intermediate serialization, since WSRs are only introduced during
@@ -650,8 +759,8 @@
   const char* bss_symbol =
       vm ? "_kDartVmSnapshotBss" : "_kDartIsolateSnapshotBss";
   intptr_t debug_segment_base = 0;
-  if (debug_dwarf_ != nullptr) {
-    debug_segment_base = debug_dwarf_->elf()->NextMemoryOffset();
+  if (debug_elf_ != nullptr) {
+    debug_segment_base = debug_elf_->NextMemoryOffset();
   }
 #endif
 
@@ -667,6 +776,12 @@
   assembly_stream_.Print("%s:\n", instructions_symbol);
 
   intptr_t text_offset = 0;
+#if defined(DART_PRECOMPILER)
+  // Parent used for later profile objects. Starts off as the Image. When
+  // writing bare instructions payloads, this is later updated with the
+  // InstructionsSection object which contains all the bare payloads.
+  V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
+#endif
 
   // This head also provides the gap to make the instructions snapshot
   // look like a OldPage.
@@ -686,18 +801,36 @@
   ASSERT_EQUAL(text_offset, Image::kHeaderSize);
 #if defined(DART_PRECOMPILER)
   if (profile_writer_ != nullptr) {
-    profile_writer_->AttributeBytesTo(
-        V8SnapshotProfileWriter::ArtificialRootId(),
-        (next_text_offset_ - image_size) + Image::kHeaderSize);
+    profile_writer_->SetObjectTypeAndName(parent_id, "Image",
+                                          instructions_symbol);
+    // Assign post-instruction padding to the Image, unless we're writing bare
+    // instruction payloads, in which case we'll assign it to the
+    // InstructionsSection object.
+    const intptr_t padding =
+        bare_instruction_payloads ? 0 : image_size - next_text_offset_;
+    profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
+    profile_writer_->AddRoot(parent_id);
   }
 #endif
 
-  // Only valid if bare_instruction_payloads is true.
-  V8SnapshotProfileWriter::ObjectId instructions_section_id(offset_space_, -1);
-
   if (bare_instruction_payloads) {
-    const intptr_t instructions_section_start = text_offset;
-    const intptr_t section_size = image_size - instructions_section_start;
+#if defined(DART_PRECOMPILER)
+    if (profile_writer_ != nullptr) {
+      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
+      profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
+                                            instructions_symbol);
+      const intptr_t padding = image_size - next_text_offset_;
+      profile_writer_->AttributeBytesTo(
+          id, compiler::target::InstructionsSection::HeaderSize() + padding);
+      const intptr_t element_offset = id.second - parent_id.second;
+      profile_writer_->AttributeReferenceTo(
+          parent_id,
+          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
+      // Later objects will have the InstructionsSection as a parent.
+      parent_id = id;
+    }
+#endif
+    const intptr_t section_size = image_size - text_offset;
     // Add the RawInstructionsSection header.
     const compiler::target::uword marked_tags =
         ObjectLayout::OldBit::encode(true) |
@@ -712,22 +845,8 @@
     const intptr_t instructions_length =
         next_text_offset_ - (text_offset + compiler::target::kWordSize);
     text_offset += WriteWordLiteralText(instructions_length);
-
-    if (profile_writer_ != nullptr) {
-      instructions_section_id = {offset_space_, instructions_section_start};
-      const intptr_t non_instruction_bytes =
-          compiler::target::InstructionsSection::HeaderSize();
-      profile_writer_->SetObjectTypeAndName(instructions_section_id,
-                                            instructions_section_type_,
-                                            instructions_symbol);
-      profile_writer_->AttributeBytesTo(instructions_section_id,
-                                        non_instruction_bytes);
-      profile_writer_->AddRoot(instructions_section_id);
-    }
   }
 
-  const intptr_t instructions_start = text_offset;
-
   FrameUnwindPrologue();
 
   PcDescriptors& descriptors = PcDescriptors::Handle(zone);
@@ -742,12 +861,14 @@
     intptr_t dwarf_index = i;
 #if defined(DART_PRECOMPILER)
     if (!is_trampoline && assembly_dwarf_ != nullptr) {
-      dwarf_index = assembly_dwarf_->AddCode(*data.code_);
+      dwarf_index =
+          assembly_dwarf_->AddCode(*data.code_, SegmentRelativeOffset(vm));
     }
 #endif
 
     const auto object_name = namer.SnapshotNameFor(dwarf_index, data);
 
+#if defined(DART_PRECOMPILER)
     if (profile_writer_ != nullptr) {
       const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
       auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
@@ -755,15 +876,12 @@
                                           : SizeInSnapshot(data.insns_->raw());
       profile_writer_->SetObjectTypeAndName(id, type, object_name);
       profile_writer_->AttributeBytesTo(id, size);
-      // If the object is wrapped in an InstructionSection, then add an
-      // element reference.
-      if (bare_instruction_payloads) {
-        const intptr_t element_offset = text_offset - instructions_start;
-        profile_writer_->AttributeReferenceTo(
-            instructions_section_id,
-            {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
-      }
+      const intptr_t element_offset = id.second - parent_id.second;
+      profile_writer_->AttributeReferenceTo(
+          parent_id,
+          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
     }
+#endif
 
     if (is_trampoline) {
       const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
@@ -822,8 +940,8 @@
     }
 
 #if defined(DART_PRECOMPILER)
-    if (debug_dwarf_ != nullptr) {
-      debug_dwarf_->AddCode(code, object_name, text_offset);
+    if (debug_elf_ != nullptr) {
+      debug_elf_->dwarf()->AddCode(code, {vm, text_offset});
     }
 #endif
     // 2. Write a label at the entry point.
@@ -908,7 +1026,7 @@
   FrameUnwindEpilogue();
 
 #if defined(DART_PRECOMPILER)
-  if (debug_dwarf_ != nullptr) {
+  if (debug_elf_ != nullptr) {
     // We need to generate a text segment of the appropriate size in the ELF
     // for two reasons:
     //
@@ -924,7 +1042,7 @@
     // Since we don't want to add the actual contents of the segment in the
     // separate debugging information, we pass nullptr for the bytes, which
     // creates an appropriate NOBITS section instead of PROGBITS.
-    auto const debug_segment_base2 = debug_dwarf_->elf()->AddText(
+    auto const debug_segment_base2 = debug_elf_->AddText(
         instructions_symbol, /*bytes=*/nullptr, text_offset);
     // Double-check that no other ELF sections were added in the middle of
     // writing the text section.
@@ -1071,22 +1189,18 @@
                                  uint8_t** instructions_blob_buffer,
                                  ReAlloc alloc,
                                  intptr_t initial_size,
-                                 Dwarf* debug_dwarf,
+                                 Elf* debug_elf,
                                  intptr_t bss_base,
-                                 Elf* elf,
-                                 Dwarf* elf_dwarf)
+                                 Elf* elf)
     : ImageWriter(thread),
       instructions_blob_stream_(instructions_blob_buffer, alloc, initial_size),
       elf_(elf),
-      elf_dwarf_(elf_dwarf),
       bss_base_(bss_base),
-      debug_dwarf_(debug_dwarf) {
+      debug_elf_(debug_elf) {
 #if defined(DART_PRECOMPILER)
-  RELEASE_ASSERT(elf_ == nullptr || elf_dwarf_ == nullptr ||
-                 elf_dwarf_->elf() == elf_);
+  ASSERT(debug_elf_ == nullptr || debug_elf_->dwarf() != nullptr);
 #else
   RELEASE_ASSERT(elf_ == nullptr);
-  RELEASE_ASSERT(elf_dwarf_ == nullptr);
 #endif
 }
 
@@ -1100,24 +1214,32 @@
 void BlobImageWriter::WriteText(WriteStream* clustered_stream, bool vm) {
   const bool bare_instruction_payloads =
       FLAG_precompiled_mode && FLAG_use_bare_instructions;
-  const char* instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
-                                       : kIsolateSnapshotInstructionsAsmSymbol;
   auto const zone = Thread::Current()->zone();
 
 #if defined(DART_PRECOMPILER)
+  auto const instructions_symbol = vm ? kVmSnapshotInstructionsAsmSymbol
+                                      : kIsolateSnapshotInstructionsAsmSymbol;
   intptr_t segment_base = 0;
   if (elf_ != nullptr) {
     segment_base = elf_->NextMemoryOffset();
   }
   intptr_t debug_segment_base = 0;
-  if (debug_dwarf_ != nullptr) {
-    debug_segment_base = debug_dwarf_->elf()->NextMemoryOffset();
+  if (debug_elf_ != nullptr) {
+    debug_segment_base = debug_elf_->NextMemoryOffset();
     // If we're also generating an ELF snapshot, we want the virtual addresses
     // in it and the separately saved DWARF information to match.
     ASSERT(elf_ == nullptr || segment_base == debug_segment_base);
   }
 #endif
 
+  intptr_t text_offset = 0;
+#if defined(DART_PRECOMPILER)
+  // Parent used for later profile objects. Starts off as the Image. When
+  // writing bare instructions payloads, this is later updated with the
+  // InstructionsSection object which contains all the bare payloads.
+  V8SnapshotProfileWriter::ObjectId parent_id(offset_space_, text_offset);
+#endif
+
   // This header provides the gap to make the instructions snapshot look like a
   // OldPage.
   const intptr_t image_size = Utils::RoundUp(
@@ -1136,19 +1258,38 @@
 #endif
   instructions_blob_stream_.Align(kMaxObjectAlignment);
   ASSERT_EQUAL(instructions_blob_stream_.Position(), Image::kHeaderSize);
+  text_offset += Image::kHeaderSize;
 #if defined(DART_PRECOMPILER)
   if (profile_writer_ != nullptr) {
-    profile_writer_->AttributeBytesTo(
-        V8SnapshotProfileWriter::ArtificialRootId(),
-        (image_size - next_text_offset_) + Image::kHeaderSize);
+    profile_writer_->SetObjectTypeAndName(parent_id, "Image",
+                                          instructions_symbol);
+    // Assign post-instruction padding to the Image, unless we're writing bare
+    // instruction payloads, in which case we'll assign it to the
+    // InstructionsSection object.
+    const intptr_t padding =
+        bare_instruction_payloads ? 0 : image_size - next_text_offset_;
+    profile_writer_->AttributeBytesTo(parent_id, Image::kHeaderSize + padding);
+    profile_writer_->AddRoot(parent_id);
   }
 #endif
 
-  // Only valid when bare_instructions_payloads is true.
-  const V8SnapshotProfileWriter::ObjectId instructions_section_id(
-      offset_space_, bare_instruction_payloads ? Image::kHeaderSize : -1);
-
   if (bare_instruction_payloads) {
+#if defined(DART_PRECOMPILER)
+    if (profile_writer_ != nullptr) {
+      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
+      profile_writer_->SetObjectTypeAndName(id, instructions_section_type_,
+                                            instructions_symbol);
+      const intptr_t padding = image_size - next_text_offset_;
+      profile_writer_->AttributeBytesTo(
+          id, compiler::target::InstructionsSection::HeaderSize() + padding);
+      const intptr_t element_offset = id.second - parent_id.second;
+      profile_writer_->AttributeReferenceTo(
+          parent_id,
+          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
+      // Later objects will have the InstructionsSection as a parent.
+      parent_id = id;
+    }
+#endif
     const intptr_t section_size = image_size - Image::kHeaderSize;
     // Add the RawInstructionsSection header.
     const compiler::target::uword marked_tags =
@@ -1164,20 +1305,12 @@
         next_text_offset_ - Image::kHeaderSize -
         compiler::target::InstructionsSection::HeaderSize();
     instructions_blob_stream_.WriteTargetWord(instructions_length);
-
-    if (profile_writer_ != nullptr) {
-      const intptr_t non_instruction_bytes =
-          compiler::target::InstructionsSection::HeaderSize();
-      profile_writer_->SetObjectTypeAndName(instructions_section_id,
-                                            instructions_section_type_,
-                                            instructions_symbol);
-      profile_writer_->AttributeBytesTo(instructions_section_id,
-                                        non_instruction_bytes);
-      profile_writer_->AddRoot(instructions_section_id);
-    }
+    ASSERT_EQUAL(instructions_blob_stream_.Position() - text_offset,
+                 compiler::target::InstructionsSection::HeaderSize());
+    text_offset += compiler::target::InstructionsSection::HeaderSize();
   }
 
-  intptr_t text_offset = 0;
+  ASSERT_EQUAL(text_offset, instructions_blob_stream_.Position());
 
 #if defined(DART_PRECOMPILER)
   auto& descriptors = PcDescriptors::Handle(zone);
@@ -1188,27 +1321,25 @@
   for (intptr_t i = 0; i < instructions_.length(); i++) {
     auto& data = instructions_[i];
     const bool is_trampoline = data.trampoline_bytes != nullptr;
-    ASSERT((data.text_offset_ - instructions_[0].text_offset_) == text_offset);
+    ASSERT(data.text_offset_ == text_offset);
 
+#if defined(DART_PRECOMPILER)
     const auto object_name = namer.SnapshotNameFor(i, data);
-
     if (profile_writer_ != nullptr) {
-      const V8SnapshotProfileWriter::ObjectId object_id(
-          offset_space_, instructions_blob_stream_.Position());
+      const V8SnapshotProfileWriter::ObjectId id(offset_space_, text_offset);
       auto const type = is_trampoline ? trampoline_type_ : instructions_type_;
       const intptr_t size = is_trampoline ? data.trampoline_length
                                           : SizeInSnapshot(data.insns_->raw());
-      profile_writer_->SetObjectTypeAndName(object_id, type, object_name);
-      profile_writer_->AttributeBytesTo(object_id, size);
+      profile_writer_->SetObjectTypeAndName(id, type, object_name);
+      profile_writer_->AttributeBytesTo(id, size);
       // If the object is wrapped in an InstructionSection, then add an
       // element reference.
-      if (bare_instruction_payloads) {
-        profile_writer_->AttributeReferenceTo(
-            instructions_section_id,
-            {object_id, V8SnapshotProfileWriter::Reference::kElement,
-             text_offset});
-      }
+      const intptr_t element_offset = id.second - parent_id.second;
+      profile_writer_->AttributeReferenceTo(
+          parent_id,
+          {id, V8SnapshotProfileWriter::Reference::kElement, element_offset});
     }
+#endif
 
     if (is_trampoline) {
       const auto start = reinterpret_cast<uword>(data.trampoline_bytes);
@@ -1286,11 +1417,11 @@
 
 #if defined(DART_PRECOMPILER)
     const auto& code = *data.code_;
-    if (elf_dwarf_ != nullptr) {
-      elf_dwarf_->AddCode(code, object_name, payload_offset);
+    if (elf_ != nullptr && elf_->dwarf() != nullptr) {
+      elf_->dwarf()->AddCode(code, {vm, payload_offset});
     }
-    if (debug_dwarf_ != nullptr) {
-      debug_dwarf_->AddCode(code, object_name, payload_offset);
+    if (debug_elf_ != nullptr) {
+      debug_elf_->dwarf()->AddCode(code, {vm, payload_offset});
     }
 
     // Don't patch the relocation if we're not generating ELF. The regular blobs
@@ -1318,10 +1449,10 @@
         // Overwrite the relocation position in the instruction stream with the
         // offset of the BSS segment from the relocation position plus the
         // addend in the relocation.
-        auto const text_offset = payload_offset + reloc_offset;
-        instructions_blob_stream_.SetPosition(text_offset);
+        auto const reloc_pos = payload_offset + reloc_offset;
+        instructions_blob_stream_.SetPosition(reloc_pos);
 
-        const compiler::target::word offset = bss_offset - text_offset + addend;
+        const compiler::target::word offset = bss_offset - reloc_pos + addend;
         instructions_blob_stream_.WriteTargetWord(offset);
       }
 
@@ -1341,8 +1472,11 @@
   // should match the alignment used in image_size above.
   instructions_blob_stream_.Align(
       compiler::target::ObjectAlignment::kObjectAlignment);
+  text_offset = Utils::RoundUp(
+      text_offset, compiler::target::ObjectAlignment::kObjectAlignment);
 
-  ASSERT_EQUAL(instructions_blob_stream_.bytes_written(), image_size);
+  ASSERT_EQUAL(text_offset, instructions_blob_stream_.bytes_written());
+  ASSERT_EQUAL(text_offset, image_size);
 
 #ifdef DART_PRECOMPILER
   if (elf_ != nullptr) {
@@ -1351,10 +1485,10 @@
                       instructions_blob_stream_.bytes_written());
     ASSERT(segment_base == segment_base2);
   }
-  if (debug_dwarf_ != nullptr) {
+  if (debug_elf_ != nullptr) {
     auto const debug_segment_base2 =
-        debug_dwarf_->elf()->AddText(instructions_symbol, nullptr,
-                                     instructions_blob_stream_.bytes_written());
+        debug_elf_->AddText(instructions_symbol, nullptr,
+                            instructions_blob_stream_.bytes_written());
     ASSERT(debug_segment_base == debug_segment_base2);
   }
 #endif
diff --git a/runtime/vm/image_snapshot.h b/runtime/vm/image_snapshot.h
index fcfd87a..7304ea7 100644
--- a/runtime/vm/image_snapshot.h
+++ b/runtime/vm/image_snapshot.h
@@ -417,7 +417,7 @@
 
   StreamingWriteStream assembly_stream_;
   Dwarf* assembly_dwarf_;
-  Dwarf* debug_dwarf_;
+  Elf* debug_elf_;
 
   DISALLOW_COPY_AND_ASSIGN(AssemblyImageWriter);
 };
@@ -428,10 +428,9 @@
                   uint8_t** instructions_blob_buffer,
                   ReAlloc alloc,
                   intptr_t initial_size,
-                  Dwarf* debug_dwarf = nullptr,
+                  Elf* debug_elf = nullptr,
                   intptr_t bss_base = 0,
-                  Elf* elf = nullptr,
-                  Dwarf* elf_dwarf = nullptr);
+                  Elf* elf = nullptr);
 
   virtual void WriteText(WriteStream* clustered_stream, bool vm);
 
@@ -444,9 +443,8 @@
 
   WriteStream instructions_blob_stream_;
   Elf* const elf_;
-  Dwarf* const elf_dwarf_;
   const intptr_t bss_base_;
-  Dwarf* const debug_dwarf_;
+  Elf* const debug_elf_;
 
   DISALLOW_COPY_AND_ASSIGN(BlobImageWriter);
 };
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index dfb80a5..31cfccb 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -1455,6 +1455,7 @@
   api_flags->entry_points = NULL;
   api_flags->load_vmservice_library = false;
   api_flags->copy_parent_code = false;
+  api_flags->null_safety = false;
 }
 
 void Isolate::FlagsCopyTo(Dart_IsolateFlags* api_flags) const {
@@ -1466,6 +1467,7 @@
   api_flags->entry_points = NULL;
   api_flags->load_vmservice_library = should_load_vmservice();
   api_flags->copy_parent_code = false;
+  api_flags->null_safety = null_safety();
 }
 
 void Isolate::FlagsCopyFrom(const Dart_IsolateFlags& api_flags) {
@@ -1495,6 +1497,7 @@
 #undef SET_FROM_FLAG
 
   set_should_load_vmservice(api_flags.load_vmservice_library);
+  set_null_safety(api_flags.null_safety);
 
   // Copy entry points list.
   ASSERT(embedder_entry_points_ == NULL);
@@ -1757,27 +1760,13 @@
   isolate_group->RegisterIsolate(result);
 
   if (ServiceIsolate::NameEquals(name_prefix)) {
-    // For now the service isolate always runs in weak mode.
-    result->set_null_safety(false);
     ASSERT(!ServiceIsolate::Exists());
     ServiceIsolate::SetServiceIsolate(result);
 #if !defined(DART_PRECOMPILED_RUNTIME)
   } else if (KernelIsolate::NameEquals(name_prefix)) {
-    // For now the kernel isolate always runs in weak mode.
-    result->set_null_safety(false);
     ASSERT(!KernelIsolate::Exists());
     KernelIsolate::SetKernelIsolate(result);
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
-  } else if (FLAG_null_safety != kNullSafetyOptionUnspecified) {
-    // If the null-safety option is specified on the command line then
-    // use the value specified on the command line, if the dill file being
-    // loaded is in a different mode than that specified on the command line
-    // we will get an error during kernel file loading.
-    result->set_null_safety(FLAG_null_safety == kNullSafetyOptionStrong);
-#if !defined(DART_PRECOMPILED_RUNTIME)
-  } else if (!KernelIsolate::GetExperimentalFlag("non-nullable")) {
-    result->set_null_safety(false);
-#endif  // !defined(DART_PRECOMPILED_RUNTIME)
   }
 
 #if !defined(PRODUCT)
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index dbf4a43..7aa57a0 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -1235,11 +1235,6 @@
   }
 
   bool null_safety() const {
-    // TODO(asiva) : We return false when the null safety mode is not yet set
-    // instead of just asserting as some code runs during bootstrapping that
-    // requires the mode to be set. Once all of that is resolved this could
-    // turn into just an assert.
-    if (null_safety_not_set()) return false;
     ASSERT(!null_safety_not_set());
     return NullSafetyBit::decode(isolate_flags_);
   }
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 7455635..6c83404 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -738,7 +738,7 @@
 
   // Ensure all functions on the stack have unoptimized code.
   // Deoptimize all code that had optimizing decisions that are dependent on
-  // assumptions from field guards or CHA.
+  // assumptions from field guards or CHA or deferred library prefixes.
   // TODO(johnmccutchan): Deoptimizing dependent code here (before the reload)
   // is paranoid. This likely can be moved to the commit phase.
   ForEachIsolate([&](Isolate* isolate) {
@@ -1312,6 +1312,8 @@
   }
 
   DeoptimizeTypeTestingStubs();
+
+  // TODO(rmacnak): Also call LibraryPrefix::InvalidateDependentCode.
 }
 
 void IsolateGroupReloadContext::CheckpointSharedClassTable() {
diff --git a/runtime/vm/json_stream.cc b/runtime/vm/json_stream.cc
index 0fd8b33..041f250 100644
--- a/runtime/vm/json_stream.cc
+++ b/runtime/vm/json_stream.cc
@@ -174,7 +174,6 @@
       va_start(args2, details_format);
       Utils::VSNPrint(buffer, (len + 1), details_format, args2);
       va_end(args2);
-
       data.AddProperty("details", buffer);
     }
   }
diff --git a/runtime/vm/json_stream.h b/runtime/vm/json_stream.h
index 89907d4d..b563f5f 100644
--- a/runtime/vm/json_stream.h
+++ b/runtime/vm/json_stream.h
@@ -38,6 +38,7 @@
 //
 //  - runtime/vm/service/vmservice.dart
 //  - runtime/observatory/lib/src/service/object.dart
+//  - pkg/dds/lib/src/rpc_error_codes.dart
 //
 enum JSONRpcErrorCode {
   kParseError = -32700,
diff --git a/runtime/vm/kernel.h b/runtime/vm/kernel.h
index f4df144..f612540 100644
--- a/runtime/vm/kernel.h
+++ b/runtime/vm/kernel.h
@@ -95,9 +95,6 @@
   intptr_t library_count() { return library_count_; }
   NNBDCompiledMode compilation_mode() const { return compilation_mode_; }
 
-  // Detect null-safety mode from this program if it was not set yet.
-  void AutoDetectNullSafety(Isolate* isolate);
-
  private:
   Program() : typed_data_(NULL), kernel_data_(NULL), kernel_data_size_(-1) {}
 
diff --git a/runtime/vm/kernel_binary.cc b/runtime/vm/kernel_binary.cc
index 3a77645..3720fe2 100644
--- a/runtime/vm/kernel_binary.cc
+++ b/runtime/vm/kernel_binary.cc
@@ -226,20 +226,6 @@
   return kernel::Program::ReadFrom(&reader, error);
 }
 
-void Program::AutoDetectNullSafety(Isolate* isolate) {
-  if (isolate->is_service_isolate() || isolate->is_kernel_isolate()) {
-    // For now the service isolate and kernel isolate will be running in
-    // weak mode and we assert for that here.
-    ASSERT(!isolate->null_safety());
-  } else {
-    // If null safety is not specified on the command line we use the value
-    // from the dill file that the CFE has computed based on how it was invoked.
-    if (FLAG_null_safety == kNullSafetyOptionUnspecified) {
-      isolate->set_null_safety(compilation_mode() == NNBDCompiledMode::kStrong);
-    }
-  }
-}
-
 }  // namespace kernel
 }  // namespace dart
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/vm/kernel_isolate.cc b/runtime/vm/kernel_isolate.cc
index 3803fbf..947d468 100644
--- a/runtime/vm/kernel_isolate.cc
+++ b/runtime/vm/kernel_isolate.cc
@@ -15,6 +15,7 @@
 #include "vm/message_handler.h"
 #include "vm/native_arguments.h"
 #include "vm/native_entry.h"
+#include "vm/native_message_handler.h"
 #include "vm/object.h"
 #include "vm/object_store.h"
 #include "vm/port.h"
@@ -52,6 +53,10 @@
 //   1 - Update in-memory file system with in-memory sources (used by tests).
 //   2 - Accept last compilation result.
 //   3 - APP JIT snapshot training run for kernel_service.
+//   4 - Compile expressions in context (used by expression evaluation).
+//   5 - Generate dependencies used to create a dependencies file.
+//   6 - Triggers shutdown of the kernel isolate.
+//   7 - Detects the nullability of a script based on it's opt-in status.
 const int KernelIsolate::kCompileTag = 0;
 const int KernelIsolate::kUpdateSourcesTag = 1;
 const int KernelIsolate::kAcceptTag = 2;
@@ -59,6 +64,7 @@
 const int KernelIsolate::kCompileExpressionTag = 4;
 const int KernelIsolate::kListDependenciesTag = 5;
 const int KernelIsolate::kNotifyIsolateShutdown = 6;
+const int KernelIsolate::kDetectNullabilityTag = 7;
 
 const char* KernelIsolate::kName = DART_KERNEL_ISOLATE_NAME;
 Dart_IsolateGroupCreateCallback KernelIsolate::create_group_callback_ = NULL;
@@ -695,7 +701,8 @@
       const char* package_config,
       const char* multiroot_filepaths,
       const char* multiroot_scheme,
-      const MallocGrowableArray<char*>* experimental_flags) {
+      const MallocGrowableArray<char*>* experimental_flags,
+      const char* original_working_directory) {
     // Build the message for the Kernel isolate.
     // tag is used to specify which operation the frontend should perform.
     Dart_CObject tag;
@@ -767,7 +774,10 @@
 
     Dart_CObject null_safety;
     null_safety.type = Dart_CObject_kInt32;
-    null_safety.value.as_int32 = FLAG_null_safety;
+    null_safety.value.as_int32 =
+        (isolate != NULL) ? (isolate->null_safety() ? kNullSafetyOptionStrong
+                                                    : kNullSafetyOptionWeak)
+                          : FLAG_null_safety;
 
     intptr_t num_experimental_flags = experimental_flags->length();
     Dart_CObject** experimental_flags_array =
@@ -822,6 +832,17 @@
       }
     }
 
+    Dart_CObject original_working_directory_object;
+    {
+      if (original_working_directory != NULL) {
+        original_working_directory_object.type = Dart_CObject_kString;
+        original_working_directory_object.value.as_string =
+            const_cast<char*>(original_working_directory);
+      } else {
+        original_working_directory_object.type = Dart_CObject_kNull;
+      }
+    }
+
     Dart_CObject* message_arr[] = {&tag,
                                    &send_port,
                                    &uri,
@@ -836,7 +857,8 @@
                                    &bytecode,
                                    &package_config_uri,
                                    &multiroot_filepaths_object,
-                                   &multiroot_scheme_object};
+                                   &multiroot_scheme_object,
+                                   &original_working_directory_object};
     message.value.as_array.values = message_arr;
     message.value.as_array.length = ARRAY_SIZE(message_arr);
     // Send the message.
@@ -862,11 +884,16 @@
  private:
   void LoadKernelFromResponse(Dart_CObject* response) {
     ASSERT((response->type == Dart_CObject_kTypedData) ||
+           (response->type == Dart_CObject_kBool) ||
            (response->type == Dart_CObject_kNull));
 
     if (response->type == Dart_CObject_kNull) {
       return;
     }
+    if (response->type == Dart_CObject_kBool) {
+      result_.null_safety = response->value.as_bool;
+      return;
+    }
 
     ASSERT(response->value.as_typed_data.type == Dart_TypedData_kUint8);
     result_.kernel_size = response->value.as_typed_data.length;
@@ -999,7 +1026,33 @@
       kCompileTag, kernel_port, script_uri, platform_kernel,
       platform_kernel_size, source_file_count, source_files,
       incremental_compile, package_config, multiroot_filepaths,
-      multiroot_scheme, experimental_flags_);
+      multiroot_scheme, experimental_flags_, NULL);
+}
+
+bool KernelIsolate::DetectNullSafety(const char* script_uri,
+                                     const char* package_config,
+                                     const char* original_working_directory) {
+  // Start the kernel Isolate if it is not already running.
+  if (!Start()) {
+    Dart_KernelCompilationResult result = {};
+    result.status = Dart_KernelCompilationStatus_Unknown;
+    result.error = strdup("Error while starting Kernel isolate task");
+    return false;
+  }
+  // Wait for Kernel isolate to finish initialization.
+  Dart_Port kernel_port = WaitForKernelPort();
+  if (kernel_port == ILLEGAL_PORT) {
+    Dart_KernelCompilationResult result = {};
+    result.status = Dart_KernelCompilationStatus_Unknown;
+    result.error = strdup("Error while initializing Kernel isolate");
+    return false;
+  }
+  KernelCompilationRequest request;
+  Dart_KernelCompilationResult result = request.SendAndWaitForResponse(
+      kDetectNullabilityTag, kernel_port, script_uri, nullptr, -1, 0, nullptr,
+      false, package_config, nullptr, nullptr, experimental_flags_,
+      original_working_directory);
+  return result.null_safety;
 }
 
 Dart_KernelCompilationResult KernelIsolate::ListDependencies() {
@@ -1014,7 +1067,7 @@
   KernelCompilationRequest request;
   return request.SendAndWaitForResponse(kListDependenciesTag, kernel_port, NULL,
                                         NULL, 0, 0, NULL, false, NULL, NULL,
-                                        NULL, experimental_flags_);
+                                        NULL, experimental_flags_, NULL);
 }
 
 Dart_KernelCompilationResult KernelIsolate::AcceptCompilation() {
@@ -1031,7 +1084,7 @@
   KernelCompilationRequest request;
   return request.SendAndWaitForResponse(kAcceptTag, kernel_port, NULL, NULL, 0,
                                         0, NULL, true, NULL, NULL, NULL,
-                                        experimental_flags_);
+                                        experimental_flags_, NULL);
 }
 
 Dart_KernelCompilationResult KernelIsolate::CompileExpressionToKernel(
@@ -1073,7 +1126,7 @@
   KernelCompilationRequest request;
   return request.SendAndWaitForResponse(
       kUpdateSourcesTag, kernel_port, NULL, NULL, 0, source_files_count,
-      source_files, true, NULL, NULL, NULL, experimental_flags_);
+      source_files, true, NULL, NULL, NULL, experimental_flags_, NULL);
 }
 
 void KernelIsolate::NotifyAboutIsolateShutdown(const Isolate* isolate) {
diff --git a/runtime/vm/kernel_isolate.h b/runtime/vm/kernel_isolate.h
index fc9f332..fbf31e2 100644
--- a/runtime/vm/kernel_isolate.h
+++ b/runtime/vm/kernel_isolate.h
@@ -30,6 +30,7 @@
   static const int kCompileExpressionTag;
   static const int kListDependenciesTag;
   static const int kNotifyIsolateShutdown;
+  static const int kDetectNullabilityTag;
 
   static void InitializeState();
   static bool Start();
@@ -53,6 +54,10 @@
       const char* multiroot_filepaths = NULL,
       const char* multiroot_scheme = NULL);
 
+  static bool DetectNullSafety(const char* script_uri,
+                               const char* package_config,
+                               const char* original_working_directory);
+
   static Dart_KernelCompilationResult AcceptCompilation();
   static Dart_KernelCompilationResult UpdateInMemorySources(
       int source_files_count,
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index 7bfd7d7..1d0d5437 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1305,6 +1305,7 @@
   LibraryPrefix& library_prefix = LibraryPrefix::Handle(Z);
 
   const intptr_t deps_count = helper_.ReadListLength();
+  const Array& deps = Array::Handle(Array::New(deps_count));
   for (intptr_t dep = 0; dep < deps_count; ++dep) {
     LibraryDependencyHelper dependency_helper(&helper_);
 
@@ -1388,12 +1389,21 @@
         }
       }
     }
+
     if (FLAG_enable_mirrors && dependency_helper.annotation_count_ > 0) {
       ASSERT(annotations_kernel_offset > 0);
       ns.AddMetadata(toplevel_class, TokenPosition::kNoSource,
                      annotations_kernel_offset);
     }
+
+    if (prefix.IsNull()) {
+      deps.SetAt(dep, ns);
+    } else {
+      deps.SetAt(dep, library_prefix);
+    }
   }
+
+  library->set_dependencies(deps);
 }
 
 void KernelLoader::LoadPreliminaryClass(ClassHelper* class_helper,
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index 5e8185c..04f500e 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -1661,6 +1661,12 @@
                                               Heap::kOld);
     object_store->set_canonical_types(array);
 
+    // Initialize hash set for canonical type parameters.
+    const intptr_t kInitialCanonicalTypeParameterSize = 4;
+    array = HashTables::New<CanonicalTypeParameterSet>(
+        kInitialCanonicalTypeParameterSize, Heap::kOld);
+    object_store->set_canonical_type_parameters(array);
+
     // Initialize hash set for canonical_type_arguments_.
     const intptr_t kInitialCanonicalTypeArgumentsSize = 4;
     array = HashTables::New<CanonicalTypeArgumentsSet>(
@@ -4892,9 +4898,8 @@
   }
   // For efficiency, the runtimeType intrinsic returns the type cached by
   // DeclarationType without checking its nullability. Therefore, we
-  // consistently cache the kLegacy version of a type, unless the non-nullable
-  // experiment is enabled, in which case we store the kNonNullable version.
-  // In either cases, the exception is type Null which is stored as kNullable.
+  // consistently cache the kNonNullable version of the type.
+  // The exception is type Null which is stored as kNullable.
   Type& type =
       Type::Handle(Type::New(*this, TypeArguments::Handle(type_parameters()),
                              token_pos(), Nullability::kNonNullable));
@@ -7496,6 +7501,12 @@
   // functions cannot deoptimize to unoptimized frames we prevent them from
   // being inlined (for now).
   if (ForceOptimize()) {
+    if (IsFfiTrampoline()) {
+      // The CallSiteInliner::InlineCall asserts in PrepareGraphs that
+      // GraphEntryInstr::SuccessorCount() == 1, but FFI trampoline has two
+      // entries (a normal and a catch entry).
+      return false;
+    }
     return CompilerState::Current().is_aot();
   }
 
@@ -7933,11 +7944,14 @@
           cls = type_param.parameterized_class();
           param_name = type_param.name();
           ASSERT(type_param.IsFinalized());
+          ASSERT(type_param.IsCanonical());
           type_param = TypeParameter::New(
               cls, sig, type_param.index(), param_name, type,
               type_param.IsGenericCovariantImpl(), type_param.nullability(),
               type_param.token_pos());
           type_param.SetIsFinalized();
+          type_param.SetCanonical();
+          type_param.SetDeclaration(true);
           if (instantiated_type_params.IsNull()) {
             instantiated_type_params = TypeArguments::New(type_params.Length());
             for (intptr_t j = 0; j < i; ++j) {
@@ -8839,27 +8853,24 @@
 StringPtr Function::QualifiedScrubbedName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
-  PrintQualifiedName(kScrubbedName, &printer);
+  PrintQualifiedName(NameFormattingParams(kScrubbedName), &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
 StringPtr Function::QualifiedUserVisibleName() const {
   Thread* thread = Thread::Current();
   ZoneTextBuffer printer(thread->zone());
-  PrintQualifiedName(kUserVisibleName, &printer);
+  PrintQualifiedName(NameFormattingParams(kUserVisibleName), &printer);
   return Symbols::New(thread, printer.buffer());
 }
 
-void Function::PrintQualifiedName(
-    NameVisibility name_visibility,
-    ZoneTextBuffer* printer,
-    NameDisambiguation name_disambiguation /* = NameDisambiguation::kNo */)
-    const {
+void Function::PrintQualifiedName(const NameFormattingParams& params,
+                                  ZoneTextBuffer* printer) const {
   // If |this| is the generated asynchronous body closure, use the
   // name of the parent function.
   Function& fun = Function::Handle(raw());
 
-  if (name_disambiguation == NameDisambiguation::kYes) {
+  if (params.disambiguate_names) {
     if (fun.IsInvokeFieldDispatcher()) {
       printer->AddString("[invoke-field] ");
     }
@@ -8891,50 +8902,49 @@
         // the parent.
         parent = parent.parent_function();
       }
-      parent.PrintQualifiedName(name_visibility, printer, name_disambiguation);
+      parent.PrintQualifiedName(params, printer);
       // A function's scrubbed name and its user visible name are identical.
       printer->AddString(".");
-      if (name_disambiguation == NameDisambiguation::kYes &&
+      if (params.disambiguate_names &&
           fun.name() == Symbols::AnonymousClosure().raw()) {
         printer->Printf("<anonymous closure @%" Pd ">", fun.token_pos().Pos());
       } else {
-        printer->AddString(fun.NameCString(name_visibility));
+        printer->AddString(fun.NameCString(params.name_visibility));
       }
       // If we skipped rewritten async/async*/sync* body then append a suffix
       // to the end of the name.
-      if (fun.raw() != raw() &&
-          name_disambiguation == NameDisambiguation::kYes) {
+      if (fun.raw() != raw() && params.disambiguate_names) {
         printer->AddString("{body}");
       }
       return;
     }
   }
-  const Class& cls = Class::Handle(Owner());
-  if (!cls.IsTopLevel()) {
-    if (fun.kind() == FunctionLayout::kConstructor) {
-      printer->AddString("new ");
-    } else {
+
+  if (fun.kind() == FunctionLayout::kConstructor) {
+    printer->AddString("new ");
+  } else if (params.include_class_name) {
+    const Class& cls = Class::Handle(Owner());
+    if (!cls.IsTopLevel()) {
       const Class& mixin = Class::Handle(cls.Mixin());
-      printer->AddString(name_visibility == kUserVisibleName
+      printer->AddString(params.name_visibility == kUserVisibleName
                              ? mixin.UserVisibleNameCString()
-                             : cls.NameCString(name_visibility));
+                             : cls.NameCString(params.name_visibility));
       printer->AddString(".");
     }
   }
 
-  printer->AddString(fun.NameCString(name_visibility));
+  printer->AddString(fun.NameCString(params.name_visibility));
 
   // If we skipped rewritten async/async*/sync* body then append a suffix
   // to the end of the name.
-  if (fun.raw() != raw() && name_disambiguation == NameDisambiguation::kYes) {
+  if (fun.raw() != raw() && params.disambiguate_names) {
     printer->AddString("{body}");
   }
 
   // Field dispatchers are specialized for an argument descriptor so there
   // might be multiples of them with the same name but different argument
   // descriptors. Add a suffix to disambiguate.
-  if (name_disambiguation == NameDisambiguation::kYes &&
-      fun.IsInvokeFieldDispatcher()) {
+  if (params.disambiguate_names && fun.IsInvokeFieldDispatcher()) {
     printer->AddString(" ");
     if (NumTypeParameters() != 0) {
       printer->Printf("<%" Pd ">", fun.NumTypeParameters());
@@ -11071,27 +11081,6 @@
   }
 }
 
-LibraryPrefixIterator::LibraryPrefixIterator(const Library& library)
-    : DictionaryIterator(library) {
-  Advance();
-}
-
-LibraryPrefixPtr LibraryPrefixIterator::GetNext() {
-  ASSERT(HasNext());
-  int ix = next_ix_++;
-  Object& obj = Object::Handle(array_.At(ix));
-  Advance();
-  return LibraryPrefix::Cast(obj).raw();
-}
-
-void LibraryPrefixIterator::Advance() {
-  Object& obj = Object::Handle(array_.At(next_ix_));
-  while (!obj.IsLibraryPrefix() && HasNext()) {
-    next_ix_++;
-    obj = array_.At(next_ix_);
-  }
-}
-
 static void ReportTooManyImports(const Library& lib) {
   const String& url = String::Handle(lib.url());
   Report::MessageF(Report::kError, Script::Handle(lib.LookupScript(url)),
@@ -12065,6 +12054,10 @@
   StorePointer(&raw_ptr()->toplevel_class_, value.raw());
 }
 
+void Library::set_dependencies(const Array& deps) const {
+  StorePointer(&raw_ptr()->dependencies_, deps.raw());
+}
+
 void Library::set_metadata(const GrowableObjectArray& value) const {
   StorePointer(&raw_ptr()->metadata_, value.raw());
 }
@@ -12933,6 +12926,7 @@
   result.set_num_imports(0);
   result.set_importer(importer);
   result.StoreNonPointer(&result.raw_ptr()->is_deferred_load_, deferred_load);
+  result.StoreNonPointer(&result.raw_ptr()->is_loaded_, !deferred_load);
   result.set_imports(Array::Handle(Array::New(kInitialSize)));
   result.AddImport(import);
   return result.raw();
@@ -12960,8 +12954,7 @@
 
 const char* LibraryPrefix::ToCString() const {
   const String& prefix = String::Handle(name());
-  return OS::SCreate(Thread::Current()->zone(), "LibraryPrefix:'%s'",
-                     prefix.ToCString());
+  return prefix.ToCString();
 }
 
 void Namespace::set_metadata_field(const Field& value) const {
@@ -16229,7 +16222,8 @@
 
 const char* Code::ToCString() const {
   return OS::SCreate(Thread::Current()->zone(), "Code(%s)",
-                     QualifiedName(kScrubbedName, NameDisambiguation::kYes));
+                     QualifiedName(NameFormattingParams(
+                         kScrubbedName, NameDisambiguation::kYes)));
 }
 
 const char* Code::Name() const {
@@ -16266,16 +16260,14 @@
   }
 }
 
-const char* Code::QualifiedName(NameVisibility name_visibility,
-                                NameDisambiguation name_disambiguation) const {
+const char* Code::QualifiedName(const NameFormattingParams& params) const {
   Zone* zone = Thread::Current()->zone();
   const Object& obj =
       Object::Handle(zone, WeakSerializationReference::UnwrapIfTarget(owner()));
   if (obj.IsFunction()) {
     ZoneTextBuffer printer(zone);
     printer.AddString(is_optimized() ? "[Optimized] " : "[Unoptimized] ");
-    Function::Cast(obj).PrintQualifiedName(name_visibility, &printer,
-                                           name_disambiguation);
+    Function::Cast(obj).PrintQualifiedName(params, &printer);
     return printer.buffer();
   }
   return Name();
@@ -18745,7 +18737,9 @@
       } else if (param.parameterized_function() != Function::null()) {
         const Function& func =
             Function::Handle(zone, param.parameterized_function());
-        func.PrintQualifiedName(name_visibility, printer, name_disambiguation);
+        func.PrintQualifiedName(
+            NameFormattingParams(name_visibility, name_disambiguation),
+            printer);
         printer->AddString("::");
       }
     }
@@ -19266,7 +19260,6 @@
     ASSERT(!type.IsCanonical());
     type ^= type.Canonicalize();
   }
-  // TODO(regis): Should we link canonical types of different nullability?
   return type.raw();
 }
 
@@ -20099,6 +20092,11 @@
       value, raw_ptr()->flags_));
 }
 
+void TypeParameter::SetDeclaration(bool value) const {
+  set_flags(
+      TypeParameterLayout::DeclarationBit::update(value, raw_ptr()->flags_));
+}
+
 void TypeParameter::set_nullability(Nullability value) const {
   StoreNonPointer(&raw_ptr()->nullability_, static_cast<int8_t>(value));
 }
@@ -20112,22 +20110,44 @@
   TypeParameter& type_parameter = TypeParameter::Handle();
   type_parameter ^= Object::Clone(*this, space);
   type_parameter.set_nullability(value);
+  type_parameter.SetDeclaration(false);
   type_parameter.SetHash(0);
   type_parameter.SetTypeTestingStub(Code::Handle(
       TypeTestingStubGenerator::DefaultCodeForType(type_parameter)));
-  // TODO(regis): Should we link type parameters of different nullability?
+  if (IsCanonical()) {
+    // Object::Clone does not clone canonical bit.
+    ASSERT(!type_parameter.IsCanonical());
+    if (IsFinalized()) {
+      type_parameter ^= type_parameter.Canonicalize();
+    }
+  }
   return type_parameter.raw();
 }
 
 bool TypeParameter::IsInstantiated(Genericity genericity,
                                    intptr_t num_free_fun_type_params,
                                    TrailPtr trail) const {
+  // Bounds of class type parameters are ignored in the VM.
   if (IsClassTypeParameter()) {
     return genericity == kFunctions;
   }
   ASSERT(IsFunctionTypeParameter());
   ASSERT(IsFinalized());
-  return (genericity == kCurrentClass) || (index() >= num_free_fun_type_params);
+  if ((genericity != kCurrentClass) && (index() < num_free_fun_type_params)) {
+    return false;
+  }
+  // Although the type parameter is instantiated, its bound may not be.
+  const AbstractType& upper_bound = AbstractType::Handle(bound());
+  if (upper_bound.IsTypeParameter() ||
+      upper_bound.arguments() != TypeArguments::null()) {
+    // Use trail to break cycles created by bound referring to type parameter.
+    if (!TestAndAddToTrail(&trail) &&
+        !upper_bound.IsInstantiated(genericity, num_free_fun_type_params,
+                                    trail)) {
+      return false;
+    }
+  }
+  return true;
 }
 
 bool TypeParameter::IsEquivalent(const Instance& other,
@@ -20265,42 +20285,144 @@
     Heap::Space space,
     TrailPtr trail) const {
   ASSERT(IsFinalized());
+  AbstractType& result = AbstractType::Handle();
   if (IsFunctionTypeParameter()) {
     if (index() >= num_free_fun_type_params) {
-      // Return uninstantiated type parameter unchanged.
-      return raw();
+      // Do not instantiate the function type parameter, but possibly its bound.
+      result = raw();
+      AbstractType& upper_bound = AbstractType::Handle(bound());
+      if (!upper_bound.IsInstantiated(kAny, num_free_fun_type_params,
+                                      nullptr)) {
+        // Use trail to break cycles created by bound referring to type param.
+        if (OnlyBuddyInTrail(trail) == Object::null()) {
+          AddOnlyBuddyToTrail(&trail, *this);
+          upper_bound = upper_bound.InstantiateFrom(
+              instantiator_type_arguments, function_type_arguments,
+              num_free_fun_type_params, space, trail);
+          if (upper_bound.raw() == Type::NeverType()) {
+            // Normalize 'X extends Never' to 'Never'.
+            result = Type::NeverType();
+          } else if (upper_bound.raw() != bound()) {
+            result ^= Object::Clone(result, space);
+            TypeParameter::Cast(result).set_bound(upper_bound);
+          }
+        }
+      }
+    } else if (function_type_arguments.IsNull()) {
+      return Type::DynamicType();
+    } else {
+      result = function_type_arguments.TypeAt(index());
+      ASSERT(!result.IsTypeParameter());
     }
-    if (function_type_arguments.IsNull()) {
+  } else {
+    ASSERT(IsClassTypeParameter());
+    if (instantiator_type_arguments.IsNull()) {
       return Type::DynamicType();
     }
-    AbstractType& result =
-        AbstractType::Handle(function_type_arguments.TypeAt(index()));
-    result = result.SetInstantiatedNullability(*this, space);
-    return result.NormalizeFutureOrType(space);
+    if (instantiator_type_arguments.Length() <= index()) {
+      // InstantiateFrom can be invoked from a compilation pipeline with
+      // mismatching type arguments vector. This can only happen for
+      // a dynamically unreachable code - which compiler can't remove
+      // statically for some reason.
+      // To prevent crashes we return AbstractType::null(), understood by caller
+      // (see AssertAssignableInstr::Canonicalize).
+      return AbstractType::null();
+    }
+    result = instantiator_type_arguments.TypeAt(index());
+    // Instantiating a class type parameter cannot result in a
+    // function type parameter.
+    // Bounds of class type parameters are ignored in the VM.
   }
-  ASSERT(IsClassTypeParameter());
-  if (instantiator_type_arguments.IsNull()) {
-    return Type::DynamicType();
-  }
-  if (instantiator_type_arguments.Length() <= index()) {
-    // InstantiateFrom can be invoked from a compilation pipeline with
-    // mismatching type arguments vector. This can only happen for
-    // a dynamically unreachable code - which compiler can't remove
-    // statically for some reason.
-    // To prevent crashes we return AbstractType::null(), understood by caller
-    // (see AssertAssignableInstr::Canonicalize).
-    return AbstractType::null();
-  }
-  AbstractType& result =
-      AbstractType::Handle(instantiator_type_arguments.TypeAt(index()));
   result = result.SetInstantiatedNullability(*this, space);
+  // Canonicalization is not part of instantiation.
   return result.NormalizeFutureOrType(space);
-  // There is no need to canonicalize the instantiated type parameter, since all
-  // type arguments are canonicalized at type finalization time. It would be too
-  // early to canonicalize the returned type argument here, since instantiation
-  // not only happens at run time, but also during type finalization.
 }
 
+AbstractTypePtr TypeParameter::Canonicalize(TrailPtr trail) const {
+  ASSERT(IsFinalized());
+  if (IsCanonical()) {
+    return this->raw();
+  }
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+
+  const Class& cls = Class::Handle(zone, parameterized_class());
+  const Function& function = Function::Handle(
+      zone, cls.IsNull() ? parameterized_function() : Function::null());
+  const TypeArguments& type_params = TypeArguments::Handle(
+      zone, cls.IsNull() ? function.type_parameters() : cls.type_parameters());
+  const intptr_t offset =
+      cls.IsNull() ? function.NumParentTypeParameters()
+                   : (cls.NumTypeArguments() - cls.NumTypeParameters());
+  TypeParameter& type_parameter = TypeParameter::Handle(zone);
+  type_parameter ^= type_params.TypeAt(index() - offset);
+  ASSERT(!type_parameter.IsNull());
+  if (type_parameter.nullability() == nullability()) {
+    ASSERT(this->Equals(type_parameter));
+    ASSERT(type_parameter.IsCanonical());
+    ASSERT(type_parameter.IsDeclaration());
+    ASSERT(type_parameter.IsOld());
+    return type_parameter.raw();
+  }
+
+  ObjectStore* object_store = isolate->object_store();
+  {
+    SafepointMutexLocker ml(isolate->group()->type_canonicalization_mutex());
+    CanonicalTypeParameterSet table(zone,
+                                    object_store->canonical_type_parameters());
+    type_parameter ^= table.GetOrNull(CanonicalTypeParameterKey(*this));
+    if (type_parameter.IsNull()) {
+      // The type parameter was not found in the table. It is not canonical yet.
+      // Add this type parameter into the canonical list of type parameters.
+      if (this->IsNew()) {
+        type_parameter ^= Object::Clone(*this, Heap::kOld);
+      } else {
+        type_parameter = this->raw();
+      }
+      ASSERT(type_parameter.IsOld());
+      type_parameter.SetCanonical();  // Mark object as being canonical.
+      bool present = table.Insert(type_parameter);
+      ASSERT(!present);
+    }
+    object_store->set_canonical_type_parameters(table.Release());
+  }
+  return type_parameter.raw();
+}
+
+#if defined(DEBUG)
+bool TypeParameter::CheckIsCanonical(Thread* thread) const {
+  Zone* zone = thread->zone();
+  Isolate* isolate = thread->isolate();
+
+  const Class& cls = Class::Handle(zone, parameterized_class());
+  const Function& function = Function::Handle(
+      zone, cls.IsNull() ? parameterized_function() : Function::null());
+  const TypeArguments& type_params = TypeArguments::Handle(
+      zone, cls.IsNull() ? function.type_parameters() : cls.type_parameters());
+  const intptr_t offset =
+      cls.IsNull() ? function.NumParentTypeParameters()
+                   : (cls.NumTypeArguments() - cls.NumTypeParameters());
+  TypeParameter& type_parameter = TypeParameter::Handle(zone);
+  type_parameter ^= type_params.TypeAt(index() - offset);
+  ASSERT(!type_parameter.IsNull());
+  if (type_parameter.nullability() == nullability()) {
+    ASSERT(type_parameter.IsCanonical());
+    return (raw() == type_parameter.raw());
+  }
+
+  ObjectStore* object_store = isolate->object_store();
+  {
+    SafepointMutexLocker ml(isolate->group()->type_canonicalization_mutex());
+    CanonicalTypeParameterSet table(zone,
+                                    object_store->canonical_type_parameters());
+    type_parameter ^= table.GetOrNull(CanonicalTypeParameterKey(*this));
+    object_store->set_canonical_type_parameters(table.Release());
+  }
+  return (raw() == type_parameter.raw());
+}
+#endif  // DEBUG
+
 void TypeParameter::EnumerateURIs(URIs* uris) const {
   Thread* thread = Thread::Current();
   Zone* zone = thread->zone();
@@ -20373,6 +20495,7 @@
   result.set_flags(0);
   result.set_nullability(nullability);
   result.SetGenericCovariantImpl(is_generic_covariant_impl);
+  result.SetDeclaration(false);
   result.SetHash(0);
   result.set_token_pos(token_pos);
 
@@ -24277,6 +24400,14 @@
   table.Release();
 }
 
+void DumpTypeParameterTable(Isolate* isolate) {
+  OS::PrintErr("canonical type parameters (cloned from declarations):\n");
+  CanonicalTypeParameterSet table(
+      isolate->object_store()->canonical_type_parameters());
+  table.Dump();
+  table.Release();
+}
+
 void DumpTypeArgumentsTable(Isolate* isolate) {
   OS::PrintErr("canonical type arguments:\n");
   CanonicalTypeArgumentsSet table(
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index d3eeb49..bd5baa1 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1097,9 +1097,6 @@
   intptr_t NumTypeParameters() const {
     return NumTypeParameters(Thread::Current());
   }
-  static intptr_t type_parameters_offset() {
-    return OFFSET_OF(ClassLayout, type_parameters_);
-  }
 
   // Return a TypeParameter if the type_name is a type parameter of this class.
   // Return null otherwise.
@@ -2427,6 +2424,32 @@
   kAllFree = kMaxInt32,
 };
 
+// Formatting configuration for Function::PrintQualifiedName.
+struct NameFormattingParams {
+  Object::NameVisibility name_visibility;
+  bool disambiguate_names;
+
+  // By default function name includes the name of the enclosing class if any.
+  // However in some context this information is redundant and class name
+  // is already known. In this case setting |include_class_name| to false
+  // allows you to exclude this information from the formatted name.
+  bool include_class_name = true;
+
+  NameFormattingParams(Object::NameVisibility visibility,
+                       Object::NameDisambiguation name_disambiguation =
+                           Object::NameDisambiguation::kNo)
+      : name_visibility(visibility),
+        disambiguate_names(name_disambiguation ==
+                           Object::NameDisambiguation::kYes) {}
+
+  static NameFormattingParams DisambiguatedWithoutClassName(
+      Object::NameVisibility visibility) {
+    NameFormattingParams params(visibility, Object::NameDisambiguation::kYes);
+    params.include_class_name = false;
+    return params;
+  }
+};
+
 class Function : public Object {
  public:
   StringPtr name() const { return raw_ptr()->name_; }
@@ -2435,10 +2458,8 @@
 
   const char* NameCString(NameVisibility name_visibility) const;
 
-  void PrintQualifiedName(
-      NameVisibility name_visibility,
-      ZoneTextBuffer* printer,
-      NameDisambiguation name_disambiguation = NameDisambiguation::kNo) const;
+  void PrintQualifiedName(const NameFormattingParams& params,
+                          ZoneTextBuffer* printer) const;
   StringPtr QualifiedScrubbedName() const;
   StringPtr QualifiedUserVisibleName() const;
 
@@ -4522,7 +4543,6 @@
   int next_ix_;     // Index of next element.
 
   friend class ClassDictionaryIterator;
-  friend class LibraryPrefixIterator;
   DISALLOW_COPY_AND_ASSIGN(DictionaryIterator);
 };
 
@@ -4553,16 +4573,6 @@
   DISALLOW_COPY_AND_ASSIGN(ClassDictionaryIterator);
 };
 
-class LibraryPrefixIterator : public DictionaryIterator {
- public:
-  explicit LibraryPrefixIterator(const Library& library);
-  LibraryPrefixPtr GetNext();
-
- private:
-  void Advance();
-  DISALLOW_COPY_AND_ASSIGN(LibraryPrefixIterator);
-};
-
 class Library : public Object {
  public:
   StringPtr name() const { return raw_ptr()->name_; }
@@ -4717,6 +4727,9 @@
   NamespacePtr ImportAt(intptr_t index) const;
   LibraryPtr ImportLibraryAt(intptr_t index) const;
 
+  ArrayPtr dependencies() const { return raw_ptr()->dependencies_; }
+  void set_dependencies(const Array& deps) const;
+
   void DropDependenciesAndCaches() const;
 
   // Resolving native methods for script loaded in the library.
@@ -6339,8 +6352,7 @@
   intptr_t GetDeoptIdForOsr(uword pc) const;
 
   const char* Name() const;
-  const char* QualifiedName(NameVisibility name_visibility,
-                            NameDisambiguation name_disambiguation) const;
+  const char* QualifiedName(const NameFormattingParams& params) const;
 
   int64_t compile_timestamp() const {
 #if defined(PRODUCT)
@@ -6503,7 +6515,7 @@
   friend class MegamorphicCacheTable;  // for set_object_pool
   friend class CodePatcher;            // for set_instructions
   friend class ProgramVisitor;         // for set_instructions
-  // So that the RawFunction pointer visitor can determine whether code the
+  // So that the FunctionLayout pointer visitor can determine whether code the
   // function points to is optimized.
   friend class FunctionLayout;
   friend class CallSiteResetter;
@@ -7322,6 +7334,10 @@
   void AddImport(const Namespace& import) const;
 
   bool is_deferred_load() const { return raw_ptr()->is_deferred_load_; }
+  bool is_loaded() const { return raw_ptr()->is_loaded_; }
+  void set_is_loaded(bool value) const {
+    return StoreNonPointer(&raw_ptr()->is_loaded_, value);
+  }
 
   static intptr_t InstanceSize() {
     return RoundedAllocationSize(sizeof(LibraryPrefixLayout));
@@ -8140,6 +8156,10 @@
         raw_ptr()->flags_);
   }
   void SetGenericCovariantImpl(bool value) const;
+  bool IsDeclaration() const {
+    return TypeParameterLayout::DeclarationBit::decode(raw_ptr()->flags_);
+  }
+  void SetDeclaration(bool value) const;
   virtual Nullability nullability() const {
     return static_cast<Nullability>(raw_ptr()->nullability_);
   }
@@ -8176,12 +8196,10 @@
       intptr_t num_free_fun_type_params,
       Heap::Space space,
       TrailPtr trail = nullptr) const;
-  virtual AbstractTypePtr Canonicalize(TrailPtr trail = nullptr) const {
-    return raw();
-  }
+  virtual AbstractTypePtr Canonicalize(TrailPtr trail = nullptr) const;
 #if defined(DEBUG)
   // Check if type parameter is canonical.
-  virtual bool CheckIsCanonical(Thread* thread) const { return true; }
+  virtual bool CheckIsCanonical(Thread* thread) const;
 #endif  // DEBUG
   virtual void EnumerateURIs(URIs* uris) const;
 
@@ -11277,6 +11295,7 @@
     ArrayOfTuplesView<MegamorphicCache::EntryType, std::tuple<Smi, Object>>;
 
 void DumpTypeTable(Isolate* isolate);
+void DumpTypeParameterTable(Isolate* isolate);
 void DumpTypeArgumentsTable(Isolate* isolate);
 
 EntryPointPragma FindEntryPointPragma(Isolate* I,
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index 6567789..cc6f720 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -692,6 +692,29 @@
   }
 };
 
+class UnimplementedDeferredLibrary : public ReasonForCancelling {
+ public:
+  UnimplementedDeferredLibrary(Zone* zone,
+                               const Library& from,
+                               const Library& to,
+                               const String& name)
+      : ReasonForCancelling(zone), from_(from), to_(to), name_(name) {}
+
+ private:
+  const Library& from_;
+  const Library& to_;
+  const String& name_;
+
+  StringPtr ToString() {
+    const String& lib_url = String::Handle(to_.url());
+    from_.ToCString();
+    return String::NewFormatted(
+        "Reloading support for deferred loading has not yet been implemented:"
+        " library '%s' has deferred import '%s'",
+        lib_url.ToCString(), name_.ToCString());
+  }
+};
+
 // This is executed before iterating over the instances.
 void Class::CheckReload(const Class& replacement,
                         IsolateReloadContext* context) const {
@@ -889,7 +912,23 @@
 
 void Library::CheckReload(const Library& replacement,
                           IsolateReloadContext* context) const {
-  // Currently no library properties will prevent a reload.
+  // TODO(26878): If the replacement library uses deferred loading,
+  // reject it.  We do not yet support reloading deferred libraries.
+  Object& object = Object::Handle();
+  LibraryPrefix& prefix = LibraryPrefix::Handle();
+  DictionaryIterator it(replacement);
+  while (it.HasNext()) {
+    object = it.GetNext();
+    if (!object.IsLibraryPrefix()) continue;
+    prefix ^= object.raw();
+    if (prefix.is_deferred_load()) {
+      const String& prefix_name = String::Handle(prefix.name());
+      context->group_reload_context()->AddReasonForCancelling(
+          new (context->zone()) UnimplementedDeferredLibrary(
+              context->zone(), *this, replacement, prefix_name));
+      return;
+    }
+  }
 }
 
 void CallSiteResetter::Reset(const ICData& ic) {
diff --git a/runtime/vm/object_service.cc b/runtime/vm/object_service.cc
index cf2d5c0..e9138c1 100644
--- a/runtime/vm/object_service.cc
+++ b/runtime/vm/object_service.cc
@@ -876,8 +876,8 @@
   AddCommonObjectProperties(&jsobj, "Code", ref);
   jsobj.AddFixedServiceId("code/%" Px64 "-%" Px "", compile_timestamp(),
                           PayloadStart());
-  const char* qualified_name =
-      QualifiedName(kUserVisibleName, NameDisambiguation::kNo);
+  const char* qualified_name = QualifiedName(
+      NameFormattingParams(kUserVisibleName, NameDisambiguation::kNo));
   const char* vm_name = Name();
   AddNameProperties(&jsobj, qualified_name, vm_name);
   const bool is_stub =
diff --git a/runtime/vm/object_store.h b/runtime/vm/object_store.h
index 20d4841..a42a8eb 100644
--- a/runtime/vm/object_store.h
+++ b/runtime/vm/object_store.h
@@ -130,6 +130,7 @@
   RW(Class, weak_property_class)                                               \
   RW(Array, symbol_table)                                                      \
   RW(Array, canonical_types)                                                   \
+  RW(Array, canonical_type_parameters)                                         \
   RW(Array, canonical_type_arguments)                                          \
   RW(Library, async_library)                                                   \
   RW(Library, builtin_library)                                                 \
@@ -189,6 +190,7 @@
   RW(Code, allocate_context_stub)                                              \
   RW(Code, allocate_object_stub)                                               \
   RW(Code, allocate_object_parametrized_stub)                                  \
+  RW(Code, allocate_unhandled_exception_stub)                                  \
   RW(Code, clone_context_stub)                                                 \
   RW(Code, write_barrier_wrappers_stub)                                        \
   RW(Code, array_write_barrier_stub)                                           \
@@ -233,6 +235,7 @@
   DO(allocate_context_stub, AllocateContext)                                   \
   DO(allocate_object_stub, AllocateObject)                                     \
   DO(allocate_object_parametrized_stub, AllocateObjectParameterized)           \
+  DO(allocate_unhandled_exception_stub, AllocateUnhandledException)            \
   DO(clone_context_stub, CloneContext)                                         \
   DO(call_closure_no_such_method_stub, CallClosureNoSuchMethod)                \
   DO(default_tts_stub, DefaultTypeTest)                                        \
diff --git a/runtime/vm/os_thread_android.cc b/runtime/vm/os_thread_android.cc
index 58e09d115..cff8378 100644
--- a/runtime/vm/os_thread_android.cc
+++ b/runtime/vm/os_thread_android.cc
@@ -10,7 +10,8 @@
 
 #include <errno.h>  // NOLINT
 #include <stdio.h>
-#include <sys/time.h>  // NOLINT
+#include <sys/resource.h>  // NOLINT
+#include <sys/time.h>      // NOLINT
 
 #include "platform/address_sanitizer.h"
 #include "platform/assert.h"
@@ -18,8 +19,15 @@
 #include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
+#include "vm/flags.h"
+
 namespace dart {
 
+DEFINE_FLAG(int,
+            worker_thread_priority,
+            kMinInt,
+            "The thread priority the VM should use for new worker threads.");
+
 #define VALIDATE_PTHREAD_RESULT(result)                                        \
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
@@ -114,6 +122,14 @@
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
 static void* ThreadStart(void* data_ptr) {
+  if (FLAG_worker_thread_priority != kMinInt) {
+    if (setpriority(PRIO_PROCESS, gettid(), FLAG_worker_thread_priority) ==
+        -1) {
+      FATAL2("Setting thread priority to %d failed: errno = %d\n",
+             FLAG_worker_thread_priority, errno);
+    }
+  }
+
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
   const char* name = data->name();
diff --git a/runtime/vm/os_thread_linux.cc b/runtime/vm/os_thread_linux.cc
index f2d2a4a..053736d 100644
--- a/runtime/vm/os_thread_linux.cc
+++ b/runtime/vm/os_thread_linux.cc
@@ -20,8 +20,15 @@
 #include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
+#include "vm/flags.h"
+
 namespace dart {
 
+DEFINE_FLAG(int,
+            worker_thread_priority,
+            kMinInt,
+            "The thread priority the VM should use for new worker threads.");
+
 #define VALIDATE_PTHREAD_RESULT(result)                                        \
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
@@ -116,6 +123,14 @@
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
 static void* ThreadStart(void* data_ptr) {
+  if (FLAG_worker_thread_priority != kMinInt) {
+    if (setpriority(PRIO_PROCESS, syscall(__NR_gettid),
+                    FLAG_worker_thread_priority) == -1) {
+      FATAL2("Setting thread priority to %d failed: errno = %d\n",
+             FLAG_worker_thread_priority, errno);
+    }
+  }
+
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
   const char* name = data->name();
diff --git a/runtime/vm/os_thread_macos.cc b/runtime/vm/os_thread_macos.cc
index a0d050e..e24ce12 100644
--- a/runtime/vm/os_thread_macos.cc
+++ b/runtime/vm/os_thread_macos.cc
@@ -25,8 +25,15 @@
 #include "platform/signal_blocker.h"
 #include "platform/utils.h"
 
+#include "vm/flags.h"
+
 namespace dart {
 
+DEFINE_FLAG(int,
+            worker_thread_priority,
+            kMinInt,
+            "The thread priority the VM should use for new worker threads.");
+
 #define VALIDATE_PTHREAD_RESULT(result)                                        \
   if (result != 0) {                                                           \
     const int kBufferSize = 1024;                                              \
@@ -92,6 +99,20 @@
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
 static void* ThreadStart(void* data_ptr) {
+  if (FLAG_worker_thread_priority != kMinInt) {
+    const pthread_t thread = pthread_self();
+    int policy = SCHED_FIFO;
+    struct sched_param schedule;
+    if (pthread_getschedparam(thread, &policy, &schedule) != 0) {
+      FATAL1("Obtainign sched param failed: errno = %d\n", errno);
+    }
+    schedule.sched_priority = FLAG_worker_thread_priority;
+    if (pthread_setschedparam(thread, policy, &schedule) != 0) {
+      FATAL2("Setting thread priority to %d failed: errno = %d\n",
+             FLAG_worker_thread_priority, errno);
+    }
+  }
+
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
   const char* name = data->name();
diff --git a/runtime/vm/os_thread_win.cc b/runtime/vm/os_thread_win.cc
index 1f86f3d..7c2f9b2 100644
--- a/runtime/vm/os_thread_win.cc
+++ b/runtime/vm/os_thread_win.cc
@@ -15,8 +15,15 @@
 #include "platform/assert.h"
 #include "platform/safe_stack.h"
 
+#include "vm/flags.h"
+
 namespace dart {
 
+DEFINE_FLAG(int,
+            worker_thread_priority,
+            kMinInt,
+            "The thread priority the VM should use for new worker threads.");
+
 // This flag is flipped by platform_win.cc when the process is exiting.
 // TODO(zra): Remove once VM shuts down cleanly.
 bool private_flag_windows_run_tls_destructors = true;
@@ -44,6 +51,14 @@
 // is used to ensure that the thread is properly destroyed if the thread just
 // exits.
 static unsigned int __stdcall ThreadEntry(void* data_ptr) {
+  if (FLAG_worker_thread_priority != kMinInt) {
+    if (SetThreadPriority(GetCurrentThread(), FLAG_worker_thread_priority) ==
+        0) {
+      FATAL2("Setting thread priority to %d failed: GetLastError() = %d\n",
+             FLAG_worker_thread_priority, GetLastError());
+    }
+  }
+
   ThreadStartData* data = reinterpret_cast<ThreadStartData*>(data_ptr);
 
   const char* name = data->name();
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 4031e34..a2ac18a 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -499,8 +499,8 @@
 
   const char* QualifiedName() const {
     if (code_.IsCode()) {
-      return Code::Cast(code_).QualifiedName(Object::kUserVisibleName,
-                                             Object::NameDisambiguation::kNo);
+      return Code::Cast(code_).QualifiedName(
+          NameFormattingParams(Object::kUserVisibleName));
     } else if (code_.IsBytecode()) {
       return Bytecode::Cast(code_).QualifiedName();
     } else {
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index ff37d6f..1870288 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1305,6 +1305,7 @@
   GrowableObjectArrayPtr used_scripts_;
   ArrayPtr imports_;  // List of Namespaces imported without prefix.
   ArrayPtr exports_;  // List of re-exported Namespaces.
+  ArrayPtr dependencies_;
   ExternalTypedDataPtr kernel_data_;
   ObjectPtr* to_snapshot(Snapshot::Kind kind) {
     switch (kind) {
@@ -2130,6 +2131,7 @@
   }
   uint16_t num_imports_;  // Number of library entries in libraries_.
   bool is_deferred_load_;
+  bool is_loaded_;
 };
 
 class TypeArgumentsLayout : public InstanceLayout {
@@ -2216,10 +2218,12 @@
   enum {
     kFinalizedBit = 0,
     kGenericCovariantImplBit,
+    kDeclarationBit,
   };
   class FinalizedBit : public BitField<uint8_t, bool, kFinalizedBit, 1> {};
   class GenericCovariantImplBit
       : public BitField<uint8_t, bool, kGenericCovariantImplBit, 1> {};
+  class DeclarationBit : public BitField<uint8_t, bool, kDeclarationBit, 1> {};
 
  private:
   RAW_HEAP_OBJECT_IMPLEMENTATION(TypeParameter);
diff --git a/runtime/vm/raw_object_snapshot.cc b/runtime/vm/raw_object_snapshot.cc
index 9eed51a..ebe73f8 100644
--- a/runtime/vm/raw_object_snapshot.cc
+++ b/runtime/vm/raw_object_snapshot.cc
@@ -229,6 +229,7 @@
   // Allocate type parameter object.
   TypeParameter& type_parameter =
       TypeParameter::ZoneHandle(reader->zone(), TypeParameter::New());
+  bool is_canonical = ObjectLayout::IsCanonical(tags);
   reader->AddBackRef(object_id, &type_parameter, kIsDeserialized);
 
   // Set all non object fields.
@@ -246,9 +247,13 @@
   READ_OBJECT_FIELDS(type_parameter, type_parameter.raw()->ptr()->from(),
                      type_parameter.raw()->ptr()->to(), kAsReference);
 
-  // Read in the parameterized class.
-  (*reader->ClassHandle()) =
-      Class::RawCast(reader->ReadObjectImpl(kAsReference));
+  if (type_parameter.parameterized_function() == Function::null()) {
+    // Read in the parameterized class.
+    (*reader->ClassHandle()) =
+        Class::RawCast(reader->ReadObjectImpl(kAsReference));
+  } else {
+    (*reader->ClassHandle()) = Class::null();
+  }
   type_parameter.set_parameterized_class(*reader->ClassHandle());
 
   // Fill in the type testing stub.
@@ -256,6 +261,10 @@
   code = TypeTestingStubGenerator::DefaultCodeForType(type_parameter);
   type_parameter.SetTypeTestingStub(code);
 
+  if (is_canonical) {
+    type_parameter ^= type_parameter.Canonicalize();
+  }
+
   return type_parameter.raw();
 }
 
@@ -287,10 +296,15 @@
   SnapshotWriterVisitor visitor(writer, kAsReference);
   visitor.VisitPointers(from(), to());
 
-  // Write out the parameterized class.
-  ClassPtr param_class =
-      writer->isolate()->class_table()->At(parameterized_class_id_);
-  writer->WriteObjectImpl(param_class, kAsReference);
+  if (parameterized_class_id_ != kFunctionCid) {
+    ASSERT(parameterized_function_ == Function::null());
+    // Write out the parameterized class.
+    ClassPtr param_class =
+        writer->isolate()->class_table()->At(parameterized_class_id_);
+    writer->WriteObjectImpl(param_class, kAsReference);
+  } else {
+    ASSERT(parameterized_function_ != Function::null());
+  }
 }
 
 TypeArgumentsPtr TypeArguments::ReadFrom(SnapshotReader* reader,
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index fd3f60f..98453f6 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -10,6 +10,7 @@
 #include "vm/compiler/api/type_check_mode.h"
 #include "vm/compiler/jit/compiler.h"
 #include "vm/dart_api_impl.h"
+#include "vm/dart_api_state.h"
 #include "vm/dart_entry.h"
 #include "vm/debugger.h"
 #include "vm/exceptions.h"
@@ -1254,48 +1255,20 @@
   return target.raw();
 }
 
-static FunctionPtr InlineCacheMissHandler(
+static FunctionPtr InlineCacheMissHandlerGivenTargetFunction(
     const GrowableArray<const Instance*>& args,  // Checked arguments only.
     const ICData& ic_data,
-    intptr_t count = 1) {
-  const Instance& receiver = *args[0];
-  ArgumentsDescriptor arguments_descriptor(
-      Array::Handle(ic_data.arguments_descriptor()));
-  String& function_name = String::Handle(ic_data.target_name());
-  ASSERT(function_name.IsSymbol());
-
-  Function& target_function = Function::Handle(
-      Resolver::ResolveDynamic(receiver, function_name, arguments_descriptor));
-
-  ObjectStore* store = Isolate::Current()->object_store();
-  if (target_function.raw() == store->simple_instance_of_function()) {
-    // Replace the target function with constant function.
-    ASSERT(args.length() == 2);
-    const AbstractType& type = AbstractType::Cast(*args[1]);
-    target_function =
-        ComputeTypeCheckTarget(receiver, type, arguments_descriptor);
-  }
+    intptr_t count,
+    const Function& target_function) {
   if (target_function.IsNull()) {
-    if (FLAG_trace_ic) {
-      OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n",
-                   String::Handle(ic_data.target_name()).ToCString(),
-                   receiver.ToCString());
-    }
-    const Array& args_descriptor =
-        Array::Handle(ic_data.arguments_descriptor());
-    const String& target_name = String::Handle(ic_data.target_name());
-    const Class& receiver_class = Class::Handle(receiver.clazz());
-    target_function =
-        InlineCacheMissHelper(receiver_class, args_descriptor, target_name);
-  }
-  if (target_function.IsNull()) {
-    ASSERT(!FLAG_lazy_dispatchers);
     return target_function.raw();
   }
+
+  const Instance& receiver = *args[0];
+
   if (args.length() == 1) {
     if (ic_data.is_tracking_exactness()) {
 #if !defined(DART_PRECOMPILED_RUNTIME)
-      const auto& receiver = *args[0];
       const auto state = receiver.IsNull()
                              ? StaticTypeExactnessState::NotExact()
                              : StaticTypeExactnessState::Compute(
@@ -1347,6 +1320,53 @@
   return target_function.raw();
 }
 
+static FunctionPtr InlineCacheMissHandler(
+    const GrowableArray<const Instance*>& args,  // Checked arguments only.
+    const ICData& ic_data,
+    intptr_t count = 1) {
+  Thread* thread = Thread::Current();
+  Zone* zone = thread->zone();
+
+  const Instance& receiver = *args[0];
+  ArgumentsDescriptor arguments_descriptor(
+      Array::Handle(zone, ic_data.arguments_descriptor()));
+  String& function_name = String::Handle(zone, ic_data.target_name());
+  ASSERT(function_name.IsSymbol());
+
+  const Class& receiver_class = Class::Handle(zone, receiver.clazz());
+  Function& target_function = Function::Handle(
+      zone, Resolver::ResolveDynamicForReceiverClass(
+                receiver_class, function_name, arguments_descriptor));
+
+  ObjectStore* store = thread->isolate()->object_store();
+  if (target_function.raw() == store->simple_instance_of_function()) {
+    // Replace the target function with constant function.
+    ASSERT(args.length() == 2);
+    const AbstractType& type = AbstractType::Cast(*args[1]);
+    target_function =
+        ComputeTypeCheckTarget(receiver, type, arguments_descriptor);
+  }
+  if (target_function.IsNull()) {
+    if (FLAG_trace_ic) {
+      OS::PrintErr("InlineCacheMissHandler NULL function for %s receiver: %s\n",
+                   String::Handle(zone, ic_data.target_name()).ToCString(),
+                   receiver.ToCString());
+    }
+    const Array& args_descriptor =
+        Array::Handle(zone, ic_data.arguments_descriptor());
+    const String& target_name = String::Handle(zone, ic_data.target_name());
+    target_function =
+        InlineCacheMissHelper(receiver_class, args_descriptor, target_name);
+  }
+  if (target_function.IsNull()) {
+    ASSERT(!FLAG_lazy_dispatchers);
+    return target_function.raw();
+  }
+
+  return InlineCacheMissHandlerGivenTargetFunction(args, ic_data, count,
+                                                   target_function);
+}
+
 // Handles inline cache misses by updating the IC data array of the call site.
 //   Arg0: Receiver object.
 //   Arg1: IC data object.
@@ -1359,7 +1379,7 @@
   GrowableArray<const Instance*> args(1);
   args.Add(&receiver);
   const Function& result =
-      Function::Handle(InlineCacheMissHandler(args, ic_data));
+      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
   arguments.SetReturn(result);
 }
 
@@ -1378,7 +1398,7 @@
   args.Add(&receiver);
   args.Add(&other);
   const Function& result =
-      Function::Handle(InlineCacheMissHandler(args, ic_data));
+      Function::Handle(zone, InlineCacheMissHandler(args, ic_data));
   arguments.SetReturn(result);
 }
 
@@ -1391,7 +1411,7 @@
   const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(1));
   // IC data for static call is prepopulated with the statically known target.
   ASSERT(ic_data.NumberOfChecksIs(1));
-  const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+  const Function& target = Function::Handle(zone, ic_data.GetTargetAt(0));
   target.EnsureHasCode();
   ASSERT(!target.IsNull() && target.HasCode());
   ic_data.AddReceiverCheck(arg.GetClassId(), target, 1);
@@ -1417,7 +1437,7 @@
   const ICData& ic_data = ICData::CheckedHandle(zone, arguments.ArgAt(2));
   // IC data for static call is prepopulated with the statically known target.
   ASSERT(!ic_data.NumberOfChecksIs(0));
-  const Function& target = Function::Handle(ic_data.GetTargetAt(0));
+  const Function& target = Function::Handle(zone, ic_data.GetTargetAt(0));
   target.EnsureHasCode();
   GrowableArray<intptr_t> cids(2);
   cids.Add(arg0.GetClassId());
@@ -1487,7 +1507,7 @@
 
   UnlinkedCallMap unlinked_call_map(zone,
                                     isolate_group->saved_unlinked_calls());
-  const auto& pc = Integer::Handle(Integer::NewFromUint64(frame_pc));
+  const auto& pc = Integer::Handle(zone, Integer::NewFromUint64(frame_pc));
   // Some other isolate might have updated unlinked_call_map[pc] too, but
   // their update should be identical to ours.
   UnlinkedCall& new_or_old_value = UnlinkedCall::Handle(
@@ -1508,7 +1528,7 @@
   UnlinkedCallMap unlinked_call_map(zone,
                                     isolate_group->saved_unlinked_calls());
 
-  const auto& pc_integer = Integer::Handle(Integer::NewFromUint64(pc));
+  const auto& pc_integer = Integer::Handle(zone, Integer::NewFromUint64(pc));
   const auto& unlinked_call = UnlinkedCall::Cast(
       Object::Handle(zone, unlinked_call_map.GetOrDie(pc_integer)));
   // Only remove entry from unlinked_call_map if we are actually transitioning
@@ -1539,22 +1559,32 @@
         caller_code_(caller_code),
         caller_function_(caller_function) {}
 
-  void HandleMiss(const Object& old_data, const Code& old_target);
+  FunctionPtr ResolveTargetFunction(const Object& data);
+  void HandleMiss(const Object& old_data,
+                  const Code& old_target,
+                  const Function& target_function);
 
  private:
-  FunctionPtr ResolveAndAddReceiverCheck(const String& name,
-                                         const Array& descriptor,
-                                         const ICData& ic_data);
-  void DoUnlinkedCall(const UnlinkedCall& unlinked);
+  void DoUnlinkedCall(const UnlinkedCall& unlinked,
+                      const Function& target_function);
   bool CanExtendSingleTargetRange(const String& name,
                                   const Function& old_target,
                                   const Function& target_function,
                                   intptr_t* lower,
                                   intptr_t* upper);
-  void DoMonomorphicMiss(const Object& data);
-  void DoSingleTargetMiss(const SingleTargetCache& data);
-  void DoICDataMiss(const ICData& data);
-  void DoMegamorphicMiss(const MegamorphicCache& data);
+  FunctionPtr LookupMonomorphicOldTargetNameDescriptorCid(
+      const Object& data,
+      String* out_name,
+      Array* out_descriptor,
+      classid_t* out_old_expected_cid,
+      bool keep_unlinked_call_map_entry_regardless,
+      bool* out_is_monomorphic_hit);
+  void DoMonomorphicMiss(const Object& data, const Function& target_function);
+  void DoSingleTargetMiss(const SingleTargetCache& data,
+                          const Function& target_function);
+  void DoICDataMiss(const ICData& data, const Function& target_function);
+  void DoMegamorphicMiss(const MegamorphicCache& data,
+                         const Function& target_function);
 
   Isolate* isolate_;
   Thread* thread_;
@@ -1566,35 +1596,17 @@
   const Function& caller_function_;
 };
 
-FunctionPtr SwitchableCallHandler::ResolveAndAddReceiverCheck(
-    const String& name,
-    const Array& descriptor,
-    const ICData& ic_data) {
-  ArgumentsDescriptor args_desc(descriptor);
-  const Class& cls = Class::Handle(zone_, receiver_.clazz());
-  Function& target_function = Function::Handle(
-      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
-  if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(cls, descriptor, name);
-  }
-  if (target_function.IsNull()) {
-    ASSERT(!FLAG_lazy_dispatchers);
-  } else {
-    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
-  }
-  return target_function.raw();
-}
-
-void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked) {
+void SwitchableCallHandler::DoUnlinkedCall(const UnlinkedCall& unlinked,
+                                           const Function& target_function) {
   const String& name = String::Handle(zone_, unlinked.target_name());
   const Array& descriptor = Array::Handle(zone_, unlinked.args_descriptor());
   const ICData& ic_data =
       ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
                                         DeoptId::kNone, 1, /* args_tested */
                                         ICData::kInstance));
-
-  const Function& target_function = Function::Handle(
-      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
+  if (!target_function.IsNull()) {
+    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
+  }
 
   // In AOT bare mode, the PC -> Code mapping is ambiguous, since multiple code
   // objects can have the same deduped instructions and bare frames are compact
@@ -1706,14 +1718,44 @@
 }
 #endif  // !defined(DART_PRECOMPILED_RUNTIME)
 
-void SwitchableCallHandler::DoMonomorphicMiss(const Object& data) {
+static FunctionPtr Resolve(Zone* zone,
+                           const Class& receiver_class,
+                           const String& name,
+                           const Array& descriptor) {
+  ASSERT(name.IsSymbol());
+
+  ArgumentsDescriptor args_desc(descriptor);
+  Function& target_function =
+      Function::Handle(zone, Resolver::ResolveDynamicForReceiverClass(
+                                 receiver_class, name, args_desc));
+
+  if (target_function.IsNull()) {
+    target_function = InlineCacheMissHelper(receiver_class, descriptor, name);
+    if (target_function.IsNull()) {
+      ASSERT(!FLAG_lazy_dispatchers);
+    }
+  }
+
+  return target_function.raw();
+}
+
+FunctionPtr SwitchableCallHandler::LookupMonomorphicOldTargetNameDescriptorCid(
+    const Object& data,
+    String* out_name,
+    Array* out_descriptor,
+    classid_t* out_old_expected_cid,
+    bool keep_unlinked_call_map_entry_regardless,
+    bool* out_is_monomorphic_hit) {
 #if defined(DART_PRECOMPILED_RUNTIME)
-  classid_t old_expected_cid;
+  ASSERT(out_name != nullptr);
+  ASSERT(out_descriptor != nullptr);
+  ASSERT(out_old_expected_cid != nullptr);
+  ASSERT(out_is_monomorphic_hit != nullptr);
   Function& old_target = Function::Handle(zone_);
   if (data.IsSmi()) {
-    old_expected_cid = Smi::Cast(data).Value();
+    *out_old_expected_cid = Smi::Cast(data).Value();
   } else if (data.IsMonomorphicSmiableCall()) {
-    old_expected_cid = MonomorphicSmiableCall::Cast(data).expected_cid();
+    *out_old_expected_cid = MonomorphicSmiableCall::Cast(data).expected_cid();
     old_target ^=
         Code::Handle(zone_, MonomorphicSmiableCall::Cast(data).target())
             .owner();
@@ -1723,53 +1765,64 @@
 
   // The site might have just been updated to monomorphic state with same
   // exact class id, in which case we are staying in monomorphic state.
-  bool is_monomorphic_hit = old_expected_cid == receiver_.GetClassId();
+  *out_is_monomorphic_hit = *out_old_expected_cid == receiver_.GetClassId();
 
-  String& name = String::Handle(zone_);
-  Array& descriptor = Array::Handle(zone_);
   if (FLAG_use_bare_instructions && FLAG_dedup_instructions) {
     const UnlinkedCall& unlinked_call = UnlinkedCall::Handle(
         zone_, LoadUnlinkedCall(zone_, isolate_, caller_frame_->pc(),
-                                is_monomorphic_hit));
-    name = unlinked_call.target_name();
-    descriptor = unlinked_call.args_descriptor();
+                                keep_unlinked_call_map_entry_regardless ||
+                                    *out_is_monomorphic_hit));
+    *out_name = unlinked_call.target_name();
+    *out_descriptor = unlinked_call.args_descriptor();
 
-    ArgumentsDescriptor args_desc(descriptor);
-    const Class& old_receiver_class =
-        Class::Handle(zone_, isolate_->class_table()->At(old_expected_cid));
-    old_target = Resolver::ResolveDynamicForReceiverClass(old_receiver_class,
-                                                          name, args_desc);
-    if (old_target.IsNull()) {
-      old_target = InlineCacheMissHelper(old_receiver_class, descriptor, name);
-    }
-  } else {
-    // We lost the original UnlinkedCall (and the name + arg descriptor inside
-    // it) when the call site transitioned from unlinked to monomorphic.
-    //
-    // Though we can deduce name + arg descriptor based on the first
-    // monomorphic callee (we are guaranteed it is not generic and does not have
-    // optional parameters, see DEFINE_RUNTIME_ENTRY(UnlinkedCall) above).
-    if (old_target.IsNull()) {
-      const Code& old_target_code =
-          Code::Handle(zone_, CodePatcher::GetSwitchableCallTargetAt(
-                                  caller_frame_->pc(), caller_code_));
-      old_target ^= old_target_code.owner();
-    }
-
-    const int kTypeArgsLen = 0;
-    name = old_target.name();
-    // TODO(dartbug.com/33549): Update this code to use the size of the
-    // parameters when supporting calls to non-static methods with
-    // unboxed parameters.
-    descriptor = ArgumentsDescriptor::NewBoxed(
-        kTypeArgsLen, old_target.num_fixed_parameters());
+    const Class& old_receiver_class = Class::Handle(
+        zone_, isolate_->class_table()->At(*out_old_expected_cid));
+    return Resolve(zone_, old_receiver_class, *out_name, *out_descriptor);
   }
 
+  // We lost the original UnlinkedCall (and the name + arg descriptor inside
+  // it) when the call site transitioned from unlinked to monomorphic.
+  //
+  // Though we can deduce name + arg descriptor based on the first
+  // monomorphic callee (we are guaranteed it is not generic and does not have
+  // optional parameters, see DEFINE_RUNTIME_ENTRY(UnlinkedCall) above).
+  if (old_target.IsNull()) {
+    const Code& old_target_code =
+        Code::Handle(zone_, CodePatcher::GetSwitchableCallTargetAt(
+                                caller_frame_->pc(), caller_code_));
+    old_target ^= old_target_code.owner();
+  }
+
+  const int kTypeArgsLen = 0;
+  *out_name = old_target.name();
+  // TODO(dartbug.com/33549): Update this code to use the size of the
+  // parameters when supporting calls to non-static methods with
+  // unboxed parameters.
+  *out_descriptor = ArgumentsDescriptor::NewBoxed(
+      kTypeArgsLen, old_target.num_fixed_parameters());
+  return old_target.raw();
+#else
+  UNREACHABLE();
+#endif
+}
+
+void SwitchableCallHandler::DoMonomorphicMiss(const Object& data,
+                                              const Function& target_function) {
+#if defined(DART_PRECOMPILED_RUNTIME)
+  String& name = String::Handle(zone_);
+  Array& descriptor = Array::Handle(zone_);
+  bool is_monomorphic_hit;
+  classid_t old_expected_cid;
+  const Function& old_target = Function::Handle(
+      zone_, LookupMonomorphicOldTargetNameDescriptorCid(
+                 data, &name, &descriptor, &old_expected_cid,
+                 /*keep_unlinked_call_map_entry_regardless=*/false,
+                 &is_monomorphic_hit));
+
   const ICData& ic_data =
       ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
                                         DeoptId::kNone, 1, /* args_tested */
                                         ICData::kInstance));
-
   // Add the first target.
   if (!old_target.IsNull()) {
     ic_data.AddReceiverCheck(old_expected_cid, old_target);
@@ -1783,16 +1836,13 @@
     return;
   }
 
-  const Function& target_function = Function::Handle(
-      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
-
   intptr_t lower = old_expected_cid;
   intptr_t upper = old_expected_cid;
   if (CanExtendSingleTargetRange(name, old_target, target_function, &lower,
                                  &upper)) {
     const SingleTargetCache& cache =
-        SingleTargetCache::Handle(SingleTargetCache::New());
-    const Code& code = Code::Handle(target_function.CurrentCode());
+        SingleTargetCache::Handle(zone_, SingleTargetCache::New());
+    const Code& code = Code::Handle(zone_, target_function.CurrentCode());
     cache.set_target(code);
     cache.set_entry_point(code.EntryPoint());
     cache.set_lower_limit(lower);
@@ -1842,15 +1892,17 @@
     args.Add(&receiver_);
     // Don't count during insertion because the IC stub we continue through will
     // do an increment.
-    intptr_t count = 0;
-    InlineCacheMissHandler(args, ic_data, count);
+    InlineCacheMissHandlerGivenTargetFunction(args, ic_data, /*count=*/0,
+                                              target_function);
   }
   arguments_.SetArgAt(0, stub);
   arguments_.SetReturn(ic_data);
 #endif  // defined(DART_PRECOMPILED_RUNTIME)
 }
 
-void SwitchableCallHandler::DoSingleTargetMiss(const SingleTargetCache& data) {
+void SwitchableCallHandler::DoSingleTargetMiss(
+    const SingleTargetCache& data,
+    const Function& target_function) {
   const Code& old_target_code = Code::Handle(zone_, data.target());
   const Function& old_target =
       Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
@@ -1867,9 +1919,9 @@
       ICData::Handle(zone_, ICData::New(caller_function_, name, descriptor,
                                         DeoptId::kNone, 1, /* args_tested */
                                         ICData::kInstance));
-
-  const Function& target_function = Function::Handle(
-      zone_, ResolveAndAddReceiverCheck(name, descriptor, ic_data));
+  if (!target_function.IsNull()) {
+    ic_data.AddReceiverCheck(receiver_.GetClassId(), target_function);
+  }
 
   intptr_t lower = data.lower_limit();
   intptr_t upper = data.upper_limit();
@@ -1895,7 +1947,8 @@
   arguments_.SetReturn(ic_data);
 }
 
-void SwitchableCallHandler::DoICDataMiss(const ICData& ic_data) {
+void SwitchableCallHandler::DoICDataMiss(const ICData& ic_data,
+                                         const Function& target_function) {
   const String& name = String::Handle(zone_, ic_data.target_name());
   const Class& cls = Class::Handle(zone_, receiver_.clazz());
   ASSERT(!cls.IsNull());
@@ -1906,16 +1959,11 @@
     OS::PrintErr("ICData miss, class=%s, function<%" Pd ">=%s\n",
                  cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
   }
-  Function& target_function = Function::Handle(
-      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
+
   if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(cls, descriptor, name);
-    if (target_function.IsNull()) {
-      ASSERT(!FLAG_lazy_dispatchers);
-      arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-      arguments_.SetReturn(ic_data);
-      return;
-    }
+    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
+    arguments_.SetReturn(ic_data);
+    return;
   }
 
   const intptr_t number_of_checks = ic_data.NumberOfChecks();
@@ -1962,7 +2010,8 @@
   }
 }
 
-void SwitchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data) {
+void SwitchableCallHandler::DoMegamorphicMiss(const MegamorphicCache& data,
+                                              const Function& target_function) {
   const String& name = String::Handle(zone_, data.target_name());
   const Class& cls = Class::Handle(zone_, receiver_.clazz());
   ASSERT(!cls.IsNull());
@@ -1973,16 +2022,10 @@
     OS::PrintErr("Megamorphic miss, class=%s, function<%" Pd ">=%s\n",
                  cls.ToCString(), args_desc.TypeArgsLen(), name.ToCString());
   }
-  Function& target_function = Function::Handle(
-      zone_, Resolver::ResolveDynamicForReceiverClass(cls, name, args_desc));
   if (target_function.IsNull()) {
-    target_function = InlineCacheMissHelper(cls, descriptor, name);
-    if (target_function.IsNull()) {
-      ASSERT(!FLAG_lazy_dispatchers);
-      arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
-      arguments_.SetReturn(data);
-      return;
-    }
+    arguments_.SetArgAt(0, StubCode::NoSuchMethodDispatcher());
+    arguments_.SetReturn(data);
+    return;
   }
 
   // Insert function found into cache.
@@ -1992,12 +2035,86 @@
   arguments_.SetReturn(data);
 }
 
+FunctionPtr SwitchableCallHandler::ResolveTargetFunction(const Object& data) {
+  const Class& cls = Class::Handle(zone_, receiver_.clazz());
+  switch (data.GetClassId()) {
+    case kUnlinkedCallCid: {
+      const UnlinkedCall& unlinked = UnlinkedCall::Cast(data);
+      const String& name = String::Handle(zone_, unlinked.target_name());
+      const Array& descriptor =
+          Array::Handle(zone_, unlinked.args_descriptor());
+      return Resolve(zone_, cls, name, descriptor);
+    }
+    case kMonomorphicSmiableCallCid:
+      FALL_THROUGH;
+#if defined(DART_PRECOMPILED_RUNTIME)
+    case kSmiCid: {
+      String& name = String::Handle(zone_);
+      Array& descriptor = Array::Handle(zone_);
+      classid_t old_expected_cid;
+      bool is_monomorphic_hit;
+      LookupMonomorphicOldTargetNameDescriptorCid(
+          data, &name, &descriptor, &old_expected_cid,
+          /*keep_unlinked_call_map_entry=*/true, &is_monomorphic_hit);
+      return Resolve(zone_, cls, name, descriptor);
+    }
+#else  // JIT
+    case kArrayCid:
+      // ICData three-element array: Smi(receiver CID), Smi(count),
+      // Function(target). It is the Array from ICData::entries_.
+      {
+        const ICData& ic_data = ICData::Handle(
+            zone_, FindICDataForInstanceCall(zone_, caller_code_,
+                                             caller_frame_->pc()));
+        RELEASE_ASSERT(!ic_data.IsNull());
+
+        const String& name = String::Handle(zone_, ic_data.target_name());
+        ASSERT(name.IsSymbol());
+
+        const Array& descriptor =
+            Array::CheckedHandle(zone_, ic_data.arguments_descriptor());
+        return Resolve(zone_, cls, name, descriptor);
+      }
+#endif
+    case kSingleTargetCacheCid: {
+      const SingleTargetCache& single_target_cache =
+          SingleTargetCache::Cast(data);
+      const Code& old_target_code =
+          Code::Handle(zone_, single_target_cache.target());
+      const Function& old_target =
+          Function::Handle(zone_, Function::RawCast(old_target_code.owner()));
+
+      // We lost the original ICData when we patched to the monomorphic case.
+      const String& name = String::Handle(zone_, old_target.name());
+      ASSERT(!old_target.HasOptionalParameters());
+      ASSERT(!old_target.IsGeneric());
+      const int kTypeArgsLen = 0;
+      const Array& descriptor = Array::Handle(
+          zone_, ArgumentsDescriptor::NewBoxed(
+                     kTypeArgsLen, old_target.num_fixed_parameters()));
+      return Resolve(zone_, cls, name, descriptor);
+    }
+    case kICDataCid:
+      FALL_THROUGH;
+    case kMegamorphicCacheCid: {
+      const CallSiteData& call_site_data = CallSiteData::Cast(data);
+      const String& name = String::Handle(zone_, call_site_data.target_name());
+      const Array& descriptor =
+          Array::CheckedHandle(zone_, call_site_data.arguments_descriptor());
+      return Resolve(zone_, cls, name, descriptor);
+    }
+    default:
+      UNREACHABLE();
+  }
+}
+
 void SwitchableCallHandler::HandleMiss(const Object& old_data,
-                                       const Code& old_code) {
+                                       const Code& old_code,
+                                       const Function& target_function) {
   switch (old_data.GetClassId()) {
     case kUnlinkedCallCid:
       ASSERT(old_code.raw() == StubCode::SwitchableCallMiss().raw());
-      DoUnlinkedCall(UnlinkedCall::Cast(old_data));
+      DoUnlinkedCall(UnlinkedCall::Cast(old_data), target_function);
       break;
     case kMonomorphicSmiableCallCid:
       ASSERT(old_code.raw() == StubCode::MonomorphicSmiableCheck().raw());
@@ -2009,19 +2126,19 @@
       // ICData three-element array: Smi(receiver CID), Smi(count),
       // Function(target). It is the Array from ICData::entries_.
 #endif
-      DoMonomorphicMiss(old_data);
+      DoMonomorphicMiss(old_data, target_function);
       break;
     case kSingleTargetCacheCid:
       ASSERT(old_code.raw() == StubCode::SingleTargetCall().raw());
-      DoSingleTargetMiss(SingleTargetCache::Cast(old_data));
+      DoSingleTargetMiss(SingleTargetCache::Cast(old_data), target_function);
       break;
     case kICDataCid:
       ASSERT(old_code.raw() == StubCode::ICCallThroughCode().raw());
-      DoICDataMiss(ICData::Cast(old_data));
+      DoICDataMiss(ICData::Cast(old_data), target_function);
       break;
     case kMegamorphicCacheCid:
       ASSERT(old_code.raw() == StubCode::MegamorphicCall().raw());
-      DoMegamorphicMiss(MegamorphicCache::Cast(old_data));
+      DoMegamorphicMiss(MegamorphicCache::Cast(old_data), target_function);
       break;
     default:
       UNREACHABLE();
@@ -2053,6 +2170,22 @@
 
   Object& old_data = Object::Handle(zone);
   Code& old_code = Code::Handle(zone);
+
+#if defined(DART_PRECOMPILED_RUNTIME)
+  // Grab old_data and do potentially long-running step of resolving the
+  // target function before we stop mutators.
+  // This will reduce amount of time spent with all mutators are stopped
+  // hopefully leaving only code patching to be done then.
+  old_data =
+      CodePatcher::GetSwitchableCallDataAt(caller_frame->pc(), caller_code);
+#else
+  old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(), caller_code,
+                                             &old_data);
+#endif
+  SwitchableCallHandler handler(thread, receiver, arguments, caller_frame,
+                                caller_code, caller_function);
+  const Function& target_function =
+      Function::Handle(zone, handler.ResolveTargetFunction(old_data));
   thread->isolate_group()->RunWithStoppedMutators(
       [&]() {
 #if defined(DART_PRECOMPILED_RUNTIME)
@@ -2066,9 +2199,7 @@
         old_code ^= CodePatcher::GetInstanceCallAt(caller_frame->pc(),
                                                    caller_code, &old_data);
 #endif
-        SwitchableCallHandler handler(thread, receiver, arguments, caller_frame,
-                                      caller_code, caller_function);
-        handler.HandleMiss(old_data, old_code);
+        handler.HandleMiss(old_data, old_code, target_function);
       },
       /*use_force_growth=*/true);
 }
@@ -3317,20 +3448,24 @@
 
 extern "C" void DFLRT_EnterSafepoint(NativeArguments __unusable_) {
   CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("%s", "EnterSafepoint");
   Thread* thread = Thread::Current();
   ASSERT(thread->top_exit_frame_info() != 0);
   ASSERT(thread->execution_state() == Thread::kThreadInNative);
   thread->EnterSafepoint();
+  TRACE_RUNTIME_CALL("%s", "EnterSafepoint done");
 }
 DEFINE_RAW_LEAF_RUNTIME_ENTRY(EnterSafepoint, 0, false, &DFLRT_EnterSafepoint);
 
 extern "C" void DFLRT_ExitSafepoint(NativeArguments __unusable_) {
   CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("%s", "ExitSafepoint");
   Thread* thread = Thread::Current();
   ASSERT(thread->top_exit_frame_info() != 0);
 
   ASSERT(thread->execution_state() == Thread::kThreadInVM);
   thread->ExitSafepoint();
+  TRACE_RUNTIME_CALL("%s", "ExitSafepoint done");
 }
 DEFINE_RAW_LEAF_RUNTIME_ENTRY(ExitSafepoint, 0, false, &DFLRT_ExitSafepoint);
 
@@ -3369,13 +3504,16 @@
 // code within this Isolate.
 extern "C" Thread* DLRT_GetThreadForNativeCallback(uword callback_id) {
   CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("GetThreadForNativeCallback %" Pd, callback_id);
 #if defined(HOST_OS_WINDOWS)
   void* return_address = _ReturnAddress();
 #else
   void* return_address = __builtin_return_address(0);
 #endif
-  return GetThreadForNativeCallback(callback_id,
-                                    reinterpret_cast<uword>(return_address));
+  Thread* return_value = GetThreadForNativeCallback(
+      callback_id, reinterpret_cast<uword>(return_address));
+  TRACE_RUNTIME_CALL("GetThreadForNativeCallback returning %p", return_value);
+  return return_value;
 }
 
 // This is called by a native callback trampoline
@@ -3389,4 +3527,46 @@
   return GetThreadForNativeCallback(callback_id, 0);
 }
 
+// This is called directly by EnterHandleScopeInstr.
+extern "C" ApiLocalScope* DLRT_EnterHandleScope(Thread* thread) {
+  CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("EnterHandleScope %p", thread);
+  thread->EnterApiScope();
+  ApiLocalScope* return_value = thread->api_top_scope();
+  TRACE_RUNTIME_CALL("EnterHandleScope returning %p", return_value);
+  return return_value;
+}
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(
+    EnterHandleScope,
+    1,
+    false /* is_float */,
+    reinterpret_cast<RuntimeFunction>(&DLRT_EnterHandleScope));
+
+// This is called directly by ExitHandleScopeInstr.
+extern "C" void DLRT_ExitHandleScope(Thread* thread) {
+  CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("ExitHandleScope %p", thread);
+  thread->ExitApiScope();
+  TRACE_RUNTIME_CALL("ExitHandleScope %s", "done");
+}
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(
+    ExitHandleScope,
+    1,
+    false /* is_float */,
+    reinterpret_cast<RuntimeFunction>(&DLRT_ExitHandleScope));
+
+// This is called directly by AllocateHandleInstr.
+extern "C" LocalHandle* DLRT_AllocateHandle(ApiLocalScope* scope) {
+  CHECK_STACK_ALIGNMENT;
+  TRACE_RUNTIME_CALL("AllocateHandle %p", scope);
+  LocalHandle* return_value = scope->local_handles()->AllocateHandle();
+  TRACE_RUNTIME_CALL("AllocateHandle returning %p", return_value);
+  return return_value;
+}
+DEFINE_RAW_LEAF_RUNTIME_ENTRY(
+    AllocateHandle,
+    1,
+    false /* is_float */,
+    reinterpret_cast<RuntimeFunction>(&DLRT_AllocateHandle));
+
 }  // namespace dart
diff --git a/runtime/vm/runtime_entry.h b/runtime/vm/runtime_entry.h
index 639cc8e..1b35e0e 100644
--- a/runtime/vm/runtime_entry.h
+++ b/runtime/vm/runtime_entry.h
@@ -145,6 +145,11 @@
 extern "C" Thread* DLRT_GetThreadForNativeCallback(uword callback_id);
 extern "C" Thread* DLRT_GetThreadForNativeCallbackTrampoline(uword callback_id);
 
+// For creating scoped handles in FFI trampolines.
+extern "C" ApiLocalScope* DLRT_EnterHandleScope(Thread* thread);
+extern "C" void DLRT_ExitHandleScope(Thread* thread);
+extern "C" LocalHandle* DLRT_AllocateHandle(ApiLocalScope* scope);
+
 const char* DeoptReasonToCString(ICData::DeoptReasonId deopt_reason);
 
 void DeoptimizeAt(const Code& optimized_code, StackFrame* frame);
diff --git a/runtime/vm/runtime_entry_list.h b/runtime/vm/runtime_entry_list.h
index b84e6c4..06bca1e 100644
--- a/runtime/vm/runtime_entry_list.h
+++ b/runtime/vm/runtime_entry_list.h
@@ -88,7 +88,10 @@
   V(uword /*BoolPtr*/, CaseInsensitiveCompareUTF16, uword /*StringPtr*/,       \
     uword /*SmiPtr*/, uword /*SmiPtr*/, uword /*SmiPtr*/)                      \
   V(void, EnterSafepoint)                                                      \
-  V(void, ExitSafepoint)
+  V(void, ExitSafepoint)                                                       \
+  V(ApiLocalScope*, EnterHandleScope, Thread*)                                 \
+  V(void, ExitHandleScope, Thread*)                                            \
+  V(LocalHandle*, AllocateHandle, ApiLocalScope*)
 
 }  // namespace dart
 
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
index c423a84..eb8e104c 100644
--- a/runtime/vm/stack_frame_arm.h
+++ b/runtime/vm/stack_frame_arm.h
@@ -50,11 +50,11 @@
 
 // Entry and exit frame layout.
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
-static const int kExitLinkSlotFromEntryFp = -26;
+static const int kExitLinkSlotFromEntryFp = -27;
 COMPILE_ASSERT(kAbiPreservedCpuRegCount == 6);
 COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
 #else
-static const int kExitLinkSlotFromEntryFp = -27;
+static const int kExitLinkSlotFromEntryFp = -28;
 COMPILE_ASSERT(kAbiPreservedCpuRegCount == 7);
 COMPILE_ASSERT(kAbiPreservedFpuRegCount == 4);
 #endif
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 7a5cfc5..3ede931 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -50,10 +50,10 @@
 
 // Entry and exit frame layout.
 #if defined(TARGET_OS_FUCHSIA)
-static const int kExitLinkSlotFromEntryFp = -23;
+static const int kExitLinkSlotFromEntryFp = -24;
 COMPILE_ASSERT(kAbiPreservedCpuRegCount == 11);
 #else
-static const int kExitLinkSlotFromEntryFp = -22;
+static const int kExitLinkSlotFromEntryFp = -23;
 COMPILE_ASSERT(kAbiPreservedCpuRegCount == 10);
 #endif
 COMPILE_ASSERT(kAbiPreservedFpuRegCount == 8);
diff --git a/runtime/vm/stack_frame_ia32.h b/runtime/vm/stack_frame_ia32.h
index c8221ee..2c8edad 100644
--- a/runtime/vm/stack_frame_ia32.h
+++ b/runtime/vm/stack_frame_ia32.h
@@ -48,7 +48,7 @@
 static const int kSavedCallerPpSlotFromFp = kSavedCallerFpSlotFromFp;
 
 // Entry and exit frame layout.
-static const int kExitLinkSlotFromEntryFp = -7;
+static const int kExitLinkSlotFromEntryFp = -8;
 
 // All arguments are passed on the stack, so none need to be saved. Therefore
 // there is no frame for holding the saved arguments.
diff --git a/runtime/vm/stack_frame_x64.h b/runtime/vm/stack_frame_x64.h
index b488d24..835a2f5 100644
--- a/runtime/vm/stack_frame_x64.h
+++ b/runtime/vm/stack_frame_x64.h
@@ -53,9 +53,9 @@
 
 // Entry and exit frame layout.
 #if defined(TARGET_OS_WINDOWS)
-static const int kExitLinkSlotFromEntryFp = -32;
+static const int kExitLinkSlotFromEntryFp = -33;
 #else
-static const int kExitLinkSlotFromEntryFp = -10;
+static const int kExitLinkSlotFromEntryFp = -11;
 #endif  // defined(TARGET_OS_WINDOWS)
 
 // For FFI native -> Dart callbacks, the number of stack slots between arguments
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 29906ec..58bba60 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -166,6 +166,8 @@
     return object_store->allocate_array_stub();
   } else if (cls.id() == kContextCid) {
     return object_store->allocate_context_stub();
+  } else if (cls.id() == kUnhandledExceptionCid) {
+    return object_store->allocate_unhandled_exception_stub();
   }
   Code& stub = Code::Handle(zone, cls.allocation_stub());
 #if !defined(DART_PRECOMPILED_RUNTIME)
@@ -321,13 +323,15 @@
   }
 
   auto object_store = Isolate::Current()->object_store();
-#define DO(member, name)                                                       \
+
+#define MATCH(member, name)                                                    \
   if (object_store->member() != Code::null() &&                                \
       entry_point == Code::EntryPointOf(object_store->member())) {             \
     return "_iso_stub_" #name "Stub";                                          \
   }
-  OBJECT_STORE_STUB_CODE_LIST(DO)
-#undef DO
+  OBJECT_STORE_STUB_CODE_LIST(MATCH)
+  MATCH(build_method_extractor_code, BuildMethodExtractor)
+#undef MATCH
   return nullptr;
 }
 
diff --git a/runtime/vm/stub_code_list.h b/runtime/vm/stub_code_list.h
index 0c188c9..a39a856 100644
--- a/runtime/vm/stub_code_list.h
+++ b/runtime/vm/stub_code_list.h
@@ -25,6 +25,7 @@
   V(AllocateObject)                                                            \
   V(AllocateObjectParameterized)                                               \
   V(AllocateObjectSlow)                                                        \
+  V(AllocateUnhandledException)                                                \
   V(CloneContext)                                                              \
   V(CallToRuntime)                                                             \
   V(LazyCompile)                                                               \
diff --git a/runtime/vm/symbols.cc b/runtime/vm/symbols.cc
index 200816c..10424d1 100644
--- a/runtime/vm/symbols.cc
+++ b/runtime/vm/symbols.cc
@@ -312,21 +312,25 @@
   // 1. Drop the tables and do a full garbage collection.
   object_store->set_symbol_table(Object::empty_array());
   object_store->set_canonical_types(Object::empty_array());
+  object_store->set_canonical_type_parameters(Object::empty_array());
   object_store->set_canonical_type_arguments(Object::empty_array());
   thread->heap()->CollectAllGarbage();
 
   // 2. Walk the heap to find surviving canonical objects.
   GrowableArray<String*> symbols;
   GrowableArray<class Type*> types;
+  GrowableArray<class TypeParameter*> type_params;
   GrowableArray<class TypeArguments*> type_args;
   class SymbolCollector : public ObjectVisitor {
    public:
     SymbolCollector(Thread* thread,
                     GrowableArray<String*>* symbols,
                     GrowableArray<class Type*>* types,
+                    GrowableArray<class TypeParameter*>* type_params,
                     GrowableArray<class TypeArguments*>* type_args)
         : symbols_(symbols),
           types_(types),
+          type_params_(type_params),
           type_args_(type_args),
           zone_(thread->zone()) {}
 
@@ -336,6 +340,9 @@
           symbols_->Add(&String::Handle(zone_, String::RawCast(obj)));
         } else if (obj->IsType()) {
           types_->Add(&Type::Handle(zone_, Type::RawCast(obj)));
+        } else if (obj->IsTypeParameter()) {
+          type_params_->Add(
+              &TypeParameter::Handle(zone_, TypeParameter::RawCast(obj)));
         } else if (obj->IsTypeArguments()) {
           type_args_->Add(
               &TypeArguments::Handle(zone_, TypeArguments::RawCast(obj)));
@@ -346,13 +353,14 @@
    private:
     GrowableArray<String*>* symbols_;
     GrowableArray<class Type*>* types_;
+    GrowableArray<class TypeParameter*>* type_params_;
     GrowableArray<class TypeArguments*>* type_args_;
     Zone* zone_;
   };
 
   {
     HeapIterationScope iteration(thread);
-    SymbolCollector visitor(thread, &symbols, &types, &type_args);
+    SymbolCollector visitor(thread, &symbols, &types, &type_params, &type_args);
     iteration.IterateObjects(&visitor);
   }
 
@@ -389,6 +397,22 @@
 
   {
     Array& array =
+        Array::Handle(zone, HashTables::New<CanonicalTypeParameterSet>(
+                                type_params.length() * 4 / 3, Heap::kOld));
+    CanonicalTypeParameterSet table(zone, array.raw());
+    for (intptr_t i = 0; i < type_params.length(); i++) {
+      class TypeParameter& type_param = *type_params[i];
+      ASSERT(type_param.IsTypeParameter());
+      ASSERT(type_param.IsCanonical());
+      if (type_param.IsDeclaration()) continue;
+      bool present = table.Insert(type_param);
+      ASSERT(!present);
+    }
+    object_store->set_canonical_type_parameters(table.Release());
+  }
+
+  {
+    Array& array =
         Array::Handle(zone, HashTables::New<CanonicalTypeArgumentsSet>(
                                 type_args.length() * 4 / 3, Heap::kOld));
     CanonicalTypeArgumentsSet table(zone, array.raw());
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index e5dc028..fb24834 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -44,6 +44,7 @@
   V(Call, "call")                                                              \
   V(Cancel, "cancel")                                                          \
   V(CastError, "_CastError")                                                   \
+  V(CheckLoaded, "_checkLoaded")                                               \
   V(Class, "Class")                                                            \
   V(ClassID, "ClassID")                                                        \
   V(ClearAsyncThreadStackTrace, "_clearAsyncThreadStackTrace")                 \
@@ -139,6 +140,7 @@
   V(FfiUint64, "Uint64")                                                       \
   V(FfiUint8, "Uint8")                                                         \
   V(FfiVoid, "Void")                                                           \
+  V(FfiHandle, "Handle")                                                       \
   V(Field, "Field")                                                            \
   V(FinallyRetVal, ":finally_ret_val")                                         \
   V(FirstArg, "x")                                                             \
@@ -205,6 +207,7 @@
   V(ListFactory, "List.")                                                      \
   V(ListFilledFactory, "List.filled")                                          \
   V(ListLiteralFactory, "List._fromLiteral")                                   \
+  V(LoadLibrary, "_loadLibrary")                                               \
   V(LocalVarDescriptors, "LocalVarDescriptors")                                \
   V(Map, "Map")                                                                \
   V(MapLiteralFactory, "Map._fromLiteral")                                     \
diff --git a/runtime/vm/tags.cc b/runtime/vm/tags.cc
index 8636df7..ecc7d18 100644
--- a/runtime/vm/tags.cc
+++ b/runtime/vm/tags.cc
@@ -78,16 +78,20 @@
 
 VMTagScope::VMTagScope(Thread* thread, uword tag, bool conditional_set)
     : ThreadStackResource(thread) {
-  ASSERT(isolate_group() != NULL);
-  previous_tag_ = thread->vm_tag();
-  if (conditional_set) {
-    thread->set_vm_tag(tag);
+  if (thread != NULL) {
+    ASSERT(isolate_group() != NULL);
+    previous_tag_ = thread->vm_tag();
+    if (conditional_set) {
+      thread->set_vm_tag(tag);
+    }
   }
 }
 
 VMTagScope::~VMTagScope() {
-  ASSERT(isolate_group() != NULL);
-  thread()->set_vm_tag(previous_tag_);
+  if (thread() != NULL) {
+    ASSERT(isolate_group() != NULL);
+    thread()->set_vm_tag(previous_tag_);
+  }
 }
 
 VMTagCounters::VMTagCounters() {
diff --git a/runtime/vm/thread.cc b/runtime/vm/thread.cc
index 42c751c..ecc51c5 100644
--- a/runtime/vm/thread.cc
+++ b/runtime/vm/thread.cc
@@ -84,11 +84,11 @@
       execution_state_(kThreadInNative),
       safepoint_state_(0),
       ffi_callback_code_(GrowableObjectArray::null()),
+      api_top_scope_(NULL),
       task_kind_(kUnknownTask),
       dart_stream_(NULL),
       thread_lock_(),
       api_reusable_scope_(NULL),
-      api_top_scope_(NULL),
       no_callback_scope_depth_(0),
 #if defined(DEBUG)
       no_safepoint_scope_depth_(0),
@@ -631,13 +631,6 @@
       isolate_group()->deferred_marking_stack()->PopEmptyBlock();
 }
 
-bool Thread::IsMutatorThread() const {
-  if (isolate_ != nullptr) {
-    ASSERT(is_mutator_thread_ == (isolate_->mutator_thread() == this));
-  }
-  return is_mutator_thread_;
-}
-
 bool Thread::CanCollectGarbage() const {
   // We grow the heap instead of triggering a garbage collection when a
   // thread is at a safepoint in the following situations :
@@ -751,10 +744,12 @@
       // if we can trigger GC between array allocation and store.
       if (obj->GetClassId() == kArrayCid) continue;
 
-      // Dart code won't store into VM-internal objects except Contexts.
-      // This assumption is checked by an assertion in
+      // Dart code won't store into VM-internal objects except Contexts and
+      // UnhandledExceptions. This assumption is checked by an assertion in
       // WriteBarrierElimination::UpdateVectorForBlock.
-      if (!obj->IsDartInstance() && !obj->IsContext()) continue;
+      if (!obj->IsDartInstance() && !obj->IsContext() &&
+          !obj->IsUnhandledException())
+        continue;
 
       // Dart code won't store into canonical instances.
       if (obj->ptr()->IsCanonical()) continue;
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index d7cde8f..48af59f 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -349,6 +349,22 @@
     return OFFSET_OF(Thread, ffi_callback_code_);
   }
 
+  // Tag state is maintained on transitions.
+  enum {
+    // Always true in generated state.
+    kDidNotExit = 0,
+    // The VM did exit the generated state through FFI.
+    // This can be true in both native and VM state.
+    kExitThroughFfi = 1,
+    // The VM exited the generated state through FFI.
+    // This can be true in both native and VM state.
+    kExitThroughRuntimeCall = 2,
+  };
+
+  static intptr_t exit_through_ffi_offset() {
+    return OFFSET_OF(Thread, exit_through_ffi_);
+  }
+
   TaskKind task_kind() const { return task_kind_; }
 
   // Retrieves and clears the stack overflow flags.  These are set by
@@ -386,6 +402,9 @@
   // are allocated.
   ApiLocalScope* api_top_scope() const { return api_top_scope_; }
   void set_api_top_scope(ApiLocalScope* value) { api_top_scope_ = value; }
+  static intptr_t api_top_scope_offset() {
+    return OFFSET_OF(Thread, api_top_scope_);
+  }
 
   void EnterApiScope();
   void ExitApiScope();
@@ -401,7 +420,8 @@
     return OFFSET_OF(Thread, field_table_values_);
   }
 
-  bool IsMutatorThread() const;
+  bool IsMutatorThread() const { return is_mutator_thread_; }
+
   bool CanCollectGarbage() const;
 
   // Offset of Dart TimelineStream object.
@@ -941,6 +961,8 @@
   uword execution_state_;
   std::atomic<uword> safepoint_state_;
   GrowableObjectArrayPtr ffi_callback_code_;
+  uword exit_through_ffi_ = 0;
+  ApiLocalScope* api_top_scope_;
 
   // ---- End accessed from generated code. ----
 
@@ -954,7 +976,6 @@
   IsolateGroup* isolate_group_ = nullptr;
   mutable Monitor thread_lock_;
   ApiLocalScope* api_reusable_scope_;
-  ApiLocalScope* api_top_scope_;
   int32_t no_callback_scope_depth_;
 #if defined(DEBUG)
   int32_t no_safepoint_scope_depth_;
diff --git a/runtime/vm/thread_interrupter.cc b/runtime/vm/thread_interrupter.cc
index 6f57f4fc..be990ab 100644
--- a/runtime/vm/thread_interrupter.cc
+++ b/runtime/vm/thread_interrupter.cc
@@ -146,6 +146,10 @@
   }
   {
     MonitorLocker ml(monitor_);
+    if (shutdown_) {
+      // Late call
+      return;
+    }
     if (!initialized_) {
       // Early call.
       return;
diff --git a/runtime/vm/type_table.h b/runtime/vm/type_table.h
index 003e8e8..99fad9f 100644
--- a/runtime/vm/type_table.h
+++ b/runtime/vm/type_table.h
@@ -50,6 +50,46 @@
 };
 typedef UnorderedHashSet<CanonicalTypeTraits> CanonicalTypeSet;
 
+class CanonicalTypeParameterKey {
+ public:
+  explicit CanonicalTypeParameterKey(const TypeParameter& key) : key_(key) {}
+  bool Matches(const TypeParameter& arg) const { return key_.Equals(arg); }
+  uword Hash() const { return key_.Hash(); }
+  const TypeParameter& key_;
+
+ private:
+  DISALLOW_ALLOCATION();
+};
+
+// Traits for looking up Canonical TypeParameter based on its hash.
+class CanonicalTypeParameterTraits {
+ public:
+  static const char* Name() { return "CanonicalTypeParameterTraits"; }
+  static bool ReportStats() { return false; }
+
+  // Called when growing the table.
+  static bool IsMatch(const Object& a, const Object& b) {
+    ASSERT(a.IsTypeParameter() && b.IsTypeParameter());
+    const TypeParameter& arg1 = TypeParameter::Cast(a);
+    const TypeParameter& arg2 = TypeParameter::Cast(b);
+    return arg1.Equals(arg2) && (arg1.Hash() == arg2.Hash());
+  }
+  static bool IsMatch(const CanonicalTypeParameterKey& a, const Object& b) {
+    ASSERT(b.IsTypeParameter());
+    return a.Matches(TypeParameter::Cast(b));
+  }
+  static uword Hash(const Object& key) {
+    ASSERT(key.IsTypeParameter());
+    return TypeParameter::Cast(key).Hash();
+  }
+  static uword Hash(const CanonicalTypeParameterKey& key) { return key.Hash(); }
+  static ObjectPtr NewKey(const CanonicalTypeParameterKey& obj) {
+    return obj.key_.raw();
+  }
+};
+typedef UnorderedHashSet<CanonicalTypeParameterTraits>
+    CanonicalTypeParameterSet;
+
 class CanonicalTypeArgumentsKey {
  public:
   explicit CanonicalTypeArgumentsKey(const TypeArguments& key) : key_(key) {}
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 1cd70d4..2f68527 100644
--- a/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
+++ b/sdk/lib/_internal/js_dev_runtime/patch/io_patch.dart
@@ -218,7 +218,7 @@
 
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
-  return buffer is Uint8List || buffer is Int8List;
+  throw UnsupportedError("_isDirectIOCapableTypedList");
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/io_patch.dart b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
index ad5c3ac..1333318 100644
--- a/sdk/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk/lib/_internal/js_runtime/lib/io_patch.dart
@@ -218,7 +218,7 @@
 
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
-  return buffer is Uint8List || buffer is Int8List;
+  throw UnsupportedError("_isDirectIOCapableTypedList");
 }
 
 @patch
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index cf0fcbb..7e06347 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2798,212 +2798,6 @@
   return value;
 }
 
-stringTypeCheck(value) {
-  if (value == null) return value;
-  if (value is String) return value;
-  throw new TypeErrorImplementation(value, 'String');
-}
-
-stringTypeCast(value) {
-  if (value is String || value == null) return value;
-  throw new CastErrorImplementation(value, 'String');
-}
-
-doubleTypeCheck(value) {
-  if (value == null) return value;
-  if (value is double) return value;
-  throw new TypeErrorImplementation(value, 'double');
-}
-
-doubleTypeCast(value) {
-  if (value is double || value == null) return value;
-  throw new CastErrorImplementation(value, 'double');
-}
-
-numTypeCheck(value) {
-  if (value == null) return value;
-  if (value is num) return value;
-  throw new TypeErrorImplementation(value, 'num');
-}
-
-numTypeCast(value) {
-  if (value is num || value == null) return value;
-  throw new CastErrorImplementation(value, 'num');
-}
-
-boolTypeCheck(value) {
-  if (value == null) return value;
-  if (value is bool) return value;
-  throw new TypeErrorImplementation(value, 'bool');
-}
-
-boolTypeCast(value) {
-  if (value is bool || value == null) return value;
-  throw new CastErrorImplementation(value, 'bool');
-}
-
-intTypeCheck(value) {
-  if (value == null) return value;
-  if (value is int) return value;
-  throw new TypeErrorImplementation(value, 'int');
-}
-
-intTypeCast(value) {
-  if (value is int || value == null) return value;
-  throw new CastErrorImplementation(value, 'int');
-}
-
-void propertyTypeError(value, property) {
-  String name = isCheckPropertyToJsConstructorName(property);
-  throw new TypeErrorImplementation(value, unminifyOrTag(name));
-}
-
-void propertyTypeCastError(value, property) {
-  // Cuts the property name to the class name.
-  String name = isCheckPropertyToJsConstructorName(property);
-  throw new CastErrorImplementation(value, unminifyOrTag(name));
-}
-
-/// For types that are not supertypes of native (eg DOM) types,
-/// we emit a simple property check to check that an object implements
-/// that type.
-propertyTypeCheck(value, property) {
-  if (value == null) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-/// For types that are not supertypes of native (eg DOM) types,
-/// we emit a simple property check to check that an object implements
-/// that type.
-propertyTypeCast(value, property) {
-  if (value == null || JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// For types that are supertypes of native (eg DOM) types, we use the
-/// interceptor for the class because we cannot add a JS property to the
-/// prototype at load time.
-interceptedTypeCheck(value, property) {
-  if (value == null) return value;
-  if ((JS('bool', 'typeof # === "object"', value) ||
-          JS('bool', 'typeof # === "function"', value)) &&
-      JS('bool', '#[#]', getInterceptor(value), property)) {
-    return value;
-  }
-  propertyTypeError(value, property);
-}
-
-/// For types that are supertypes of native (eg DOM) types, we use the
-/// interceptor for the class because we cannot add a JS property to the
-/// prototype at load time.
-interceptedTypeCast(value, property) {
-  if (value == null ||
-      ((JS('bool', 'typeof # === "object"', value) ||
-              JS('bool', 'typeof # === "function"', value)) &&
-          JS('bool', '#[#]', getInterceptor(value), property))) {
-    return value;
-  }
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for num and String and their
-/// supertype since [value] can be a JS primitive.
-numberOrStringSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-numberOrStringSuperTypeCast(value, property) {
-  if (value is String) return value;
-  if (value is num) return value;
-  return propertyTypeCast(value, property);
-}
-
-numberOrStringSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-numberOrStringSuperNativeTypeCast(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for String and its supertype
-/// since [value] can be a JS primitive.
-stringSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-stringSuperTypeCast(value, property) {
-  if (value is String) return value;
-  return propertyTypeCast(value, property);
-}
-
-stringSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-stringSuperNativeTypeCast(value, property) {
-  if (value is String || value == null) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for List and its supertypes,
-/// since [value] can be a JS array.
-listTypeCheck(value) {
-  if (value == null) return value;
-  if (value is List) return value;
-  throw new TypeErrorImplementation(value, 'List<dynamic>');
-}
-
-listTypeCast(value) {
-  if (value is List || value == null) return value;
-  throw new CastErrorImplementation(value, 'List<dynamic>');
-}
-
-listSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is List) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-listSuperTypeCast(value, property) {
-  if (value is List) return value;
-  return propertyTypeCast(value, property);
-}
-
-listSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is List) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-listSuperNativeTypeCast(value, property) {
-  if (value is List || value == null) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
 extractFunctionTypeObjectFrom(o) {
   var interceptor = getInterceptor(o);
   return extractFunctionTypeObjectFromInternal(interceptor);
@@ -3022,59 +2816,6 @@
   return null;
 }
 
-functionTypeTest(value, functionTypeRti) {
-  if (value == null) return false;
-  if (JS('bool', 'typeof # == "function"', value)) {
-    // JavaScript functions do not have an attached type, but for convenient
-    // JS-interop, we pretend they can be any function type.
-    // TODO(sra): Tighten this up to disallow matching function types with
-    // features inaccessible from JavaScript, i.e.  optional named parameters
-    // and type parameters functions.
-    // TODO(sra): If the JavaScript function was the output of `dart:js`'s
-    // `allowInterop` then we have access to the wrapped function.
-    return true;
-  }
-  var functionTypeObject = extractFunctionTypeObjectFrom(value);
-  if (functionTypeObject == null) return false;
-  return isFunctionSubtype(functionTypeObject, functionTypeRti);
-}
-
-// Declared as 'var' to avoid assignment checks.
-var _inTypeAssertion = false;
-
-functionTypeCheck(value, functionTypeRti) {
-  if (value == null) return value;
-
-  // The function type test code contains type assertions for function
-  // types. This leads to unbounded recursion, so disable the type checking of
-  // function types while checking function types.
-
-  if (true == _inTypeAssertion) return value;
-
-  _inTypeAssertion = true;
-  try {
-    if (functionTypeTest(value, functionTypeRti)) return value;
-    var self = runtimeTypeToString(functionTypeRti);
-    throw new TypeErrorImplementation(value, self);
-  } finally {
-    _inTypeAssertion = false;
-  }
-}
-
-functionTypeCast(value, functionTypeRti) {
-  if (value == null) return value;
-  if (functionTypeTest(value, functionTypeRti)) return value;
-
-  var self = runtimeTypeToString(functionTypeRti);
-  throw new CastErrorImplementation(value, self);
-}
-
-futureOrTest(o, futureOrRti) => checkSubtypeOfRuntimeType(o, futureOrRti);
-
-futureOrCheck(o, futureOrRti) => assertSubtypeOfRuntimeType(o, futureOrRti);
-
-futureOrCast(o, futureOrRti) => subtypeOfRuntimeTypeCast(o, futureOrRti);
-
 @pragma('dart2js:noInline')
 void checkDeferredIsLoaded(String loadId) {
   if (!_loadedLibraries.contains(loadId)) {
diff --git a/sdk/lib/_internal/js_runtime/lib/js_rti.dart b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
index 1ab9ce3..6ef5038 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_rti.dart
@@ -80,11 +80,6 @@
   const TypeVariable(this.owner, this.name, this.bound);
 }
 
-getMangledTypeName(Type t) {
-  TypeImpl type = t;
-  return type._typeName;
-}
-
 /// Sets the runtime type information on [target]. [rti] is a type
 /// representation of type 4 or 5, that is, either a JavaScript array or `null`.
 ///
@@ -356,52 +351,8 @@
   return '<$buffer>';
 }
 
-/// Returns a human-readable representation of the type of [object].
-///
-/// In minified mode does *not* use unminified identifiers (even when present).
-String getRuntimeTypeString(var object) {
-  if (object is Closure) {
-    // This excludes classes that implement Function via a `call` method, but
-    // includes classes generated to represent closures in closure conversion.
-    var functionRti = extractFunctionTypeObjectFrom(object);
-    if (functionRti != null) {
-      return runtimeTypeToString(functionRti);
-    }
-  }
-  String className = getClassName(object);
-  if (object == null) return className;
-  String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
-  var rti = JS('var', r'#[#]', object, rtiName);
-  return "$className${joinArguments(rti, 0)}";
-}
-
-/// Returns the full type of [o] in the runtime type representation.
-getRti(o) {
-  if (o is Closure) {
-    // This excludes classes that implement Function via a `call` method, but
-    // includes classes generated to represent closures in closure conversion.
-    var functionRti = extractFunctionTypeObjectFrom(o);
-    if (functionRti != null) return functionRti;
-  }
-  var interceptor = getInterceptor(o);
-  var type = getRawRuntimeType(interceptor);
-  if (o == null) return type;
-  if (JS('bool', 'typeof # != "object"', o)) return type;
-  var rti = getRuntimeTypeInfo(o);
-  if (rti != null) {
-    // If the type has type variables (that is, `rti != null`), make a copy of
-    // the type arguments and insert [o] in the first position to create a
-    // compound type representation.
-    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
-    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
-    type = rti;
-  }
-  return type;
-}
-
 Type getRuntimeType(var object) {
-  if (JS_GET_FLAG('USE_NEW_RTI')) return newRti.getRuntimeType(object);
-  return new TypeImpl(getRti(object));
+  return newRti.getRuntimeType(object);
 }
 
 /// Applies the [substitution] on the [arguments].
@@ -428,31 +379,6 @@
   return arguments;
 }
 
-/// Perform a type check with arguments on the Dart object [object].
-///
-/// Parameters:
-/// - [isField]: the name of the flag/function to check if the object
-///   is of the correct class.
-/// - [checks]: the (JavaScript) list of type representations for the
-///   arguments to check against.
-/// - [asField]: the name of the function that transforms the type
-///   arguments of [objects] to an instance of the class that we check
-///   against.
-bool checkSubtype(Object object, String isField, List checks, String asField) {
-  if (object == null) return false;
-  var arguments = getRuntimeTypeInfo(object);
-  // Interceptor is needed for JSArray and native classes.
-  // TODO(sra): It could be a more specialized interceptor since [object] is not
-  // `null` or a primitive.
-  var interceptor = getInterceptor(object);
-  var isSubclass = getField(interceptor, isField);
-  // When we read the field and it is not there, [isSubclass] will be `null`.
-  if (isSubclass == null) return false;
-  // Should the asField function be passed the receiver?
-  var substitution = getField(interceptor, asField);
-  return checkArguments(substitution, arguments, null, checks, null);
-}
-
 /// Returns the field's type name.
 ///
 /// In minified mode, uses the unminified names if available.
@@ -463,38 +389,6 @@
       unminifyOrTag(isCheckPropertyToJsConstructorName(isField)), arguments);
 }
 
-/// Called from generated code.
-Object subtypeCast(Object object, String isField, List checks, String asField) {
-  if (object == null) return object;
-  if (checkSubtype(object, isField, checks, asField)) return object;
-  String typeName = computeTypeName(isField, checks);
-  throw new CastErrorImplementation(object, typeName);
-}
-
-/// Called from generated code.
-Object assertSubtype(
-    Object object, String isField, List checks, String asField) {
-  if (object == null) return object;
-  if (checkSubtype(object, isField, checks, asField)) return object;
-  String typeName = computeTypeName(isField, checks);
-  throw new TypeErrorImplementation(object, typeName);
-}
-
-/// Checks that the type represented by [subtype] is a subtype of [supertype].
-/// If not a type error is thrown using [prefix], [infix], [suffix] and the
-/// runtime types [subtype] and [supertype] to generate the error message.
-///
-/// Called from generated code.
-assertIsSubtype(
-    var subtype, var supertype, String prefix, String infix, String suffix) {
-  if (!isSubtype(subtype, supertype)) {
-    String message = "TypeError: "
-        "$prefix${runtimeTypeToString(subtype)}$infix"
-        "${runtimeTypeToString(supertype)}$suffix";
-    throwTypeError(message);
-  }
-}
-
 throwTypeError(message) {
   throw new TypeErrorImplementation.fromMessage(message);
 }
@@ -559,46 +453,6 @@
       isDartJsInteropTypeArgumentRti(type);
 }
 
-/// Returns `true` if the runtime type representation [type] is a supertype of
-/// [Null].
-@pragma('dart2js:tryInline')
-bool isSupertypeOfNull(var type) {
-  return isSupertypeOfNullBase(type) || isSupertypeOfNullRecursive(type);
-}
-
-/// Returns `true` if the runtime type representation [type] is a simple
-/// supertype of [Null].
-///
-/// This method doesn't handle `FutureOr<Null>`. This is handle by
-/// [isSupertypeOfNullRecursive] because it requires a recursive check.
-@pragma('dart2js:tryInline')
-bool isSupertypeOfNullBase(var type) {
-  return isDartDynamicTypeRti(type) ||
-      isDartObjectTypeRti(type) ||
-      isNullTypeRti(type) ||
-      isDartVoidTypeRti(type) ||
-      isDartJsInteropTypeArgumentRti(type);
-}
-
-/// Returns `true` if the runtime type representation [type] is a `FutureOr`
-/// type that is a supertype of [Null].
-///
-/// This method is recursive to be able to handle both `FutureOr<Null>` and
-/// `FutureOr<FutureOr<Null>>` etc.
-bool isSupertypeOfNullRecursive(var type) {
-  if (isGenericFunctionTypeParameter(type)) {
-    // We need to check for function type variables because `isDartFutureOrType`
-    // doesn't work on numbers.
-    return false;
-  }
-  if (isDartFutureOrType(type)) {
-    var typeArgument = getFutureOrArgument(type);
-    return isSupertypeOfNullBase(type) ||
-        isSupertypeOfNullRecursive(typeArgument);
-  }
-  return false;
-}
-
 /// Returns the type argument of the `FutureOr` runtime type representation
 /// [type].
 ///
@@ -612,63 +466,6 @@
       : null;
 }
 
-/// Tests whether the Dart object [o] is a subtype of the runtime type
-/// representation [t].
-///
-/// See the comment in the beginning of this file for a description of type
-/// representations.
-bool checkSubtypeOfRuntimeType(o, t) {
-  if (o == null) return isSupertypeOfNull(t);
-  if (isTopType(t)) return true;
-  if (JS('bool', 'typeof # == "object"', t)) {
-    if (isDartFutureOrType(t)) {
-      // `o is FutureOr<T>` is equivalent to
-      //
-      //     o is T || o is Future<T>
-      //
-      // T might be a function type, requiring extracting the closure's
-      // signature, so do the `o is T` check here and let the `Future` interface
-      // type test fall through to the `isSubtype` check at the end of this
-      // function.
-      var tTypeArgument = getFutureOrArgument(t);
-      if (checkSubtypeOfRuntimeType(o, tTypeArgument)) return true;
-    }
-
-    if (isDartFunctionType(t)) {
-      return functionTypeTest(o, t);
-    }
-  }
-
-  var interceptor = getInterceptor(o);
-  var type = getRawRuntimeType(interceptor);
-  var rti = getRuntimeTypeInfo(o);
-  if (rti != null) {
-    // If the type has type variables (that is, `rti != null`), make a copy of
-    // the type arguments and insert [o] in the first position to create a
-    // compound type representation.
-    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
-    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
-    type = rti;
-  }
-  return isSubtype(type, t);
-}
-
-/// Called from generated code.
-Object subtypeOfRuntimeTypeCast(Object object, var type) {
-  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
-    throw new CastErrorImplementation(object, runtimeTypeToString(type));
-  }
-  return object;
-}
-
-/// Called from generated code.
-Object assertSubtypeOfRuntimeType(Object object, var type) {
-  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
-    throw new TypeErrorImplementation(object, runtimeTypeToString(type));
-  }
-  return object;
-}
-
 /// Extracts the type arguments from a type representation. The result is a
 /// JavaScript array or `null`.
 getArguments(var type) {
diff --git a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
index b605648..eacc877 100644
--- a/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -190,6 +190,8 @@
       platforms: DART2JS_PLATFORM),
   "_metadata": const LibraryInfo("html/html_common/metadata.dart",
       categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_js_annotations": const LibraryInfo("js/_js_annotations.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
 };
 
 /**
diff --git a/sdk/lib/_internal/vm/bin/common_patch.dart b/sdk/lib/_internal/vm/bin/common_patch.dart
index 1cd7847..ee3f1c9 100644
--- a/sdk/lib/_internal/vm/bin/common_patch.dart
+++ b/sdk/lib/_internal/vm/bin/common_patch.dart
@@ -54,7 +54,14 @@
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
   int classID = ClassID.getID(buffer);
-  return classID == ClassID.cidUint8Array || classID == ClassID.cidInt8Array;
+  return classID == ClassID.cidExternalInt8Array ||
+      classID == ClassID.cidExternalUint8Array ||
+      classID == ClassID.cidExternalUint8ClampedArray ||
+      classID == ClassID.cidInt8Array ||
+      classID == ClassID.cidInt8ArrayView ||
+      classID == ClassID.cidUint8Array ||
+      classID == ClassID.cidUint8ArrayView ||
+      classID == ClassID.cidUint8ClampedArray;
 }
 
 @patch
diff --git a/sdk/lib/_internal/vm/lib/convert_patch.dart b/sdk/lib/_internal/vm/lib/convert_patch.dart
index 14a2c17..da1da2c 100644
--- a/sdk/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk/lib/_internal/vm/lib/convert_patch.dart
@@ -14,6 +14,7 @@
         allocateOneByteString,
         allocateTwoByteString,
         ClassID,
+        copyRangeFromUint8ListToOneByteString,
         patch,
         POWERS_OF_TEN,
         unsafeCast,
@@ -1751,10 +1752,9 @@
     if (flags == 0) {
       // Pure ASCII.
       assert(size == end - start);
-      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
-      // checking types and ranges, which is redundant in this case. Find a
-      // more direct way to do the conversion.
-      return String.fromCharCodes(bytes, start, end);
+      String result = allocateOneByteString(size);
+      copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size);
+      return result;
     }
 
     String result;
@@ -1846,10 +1846,9 @@
       // Pure ASCII.
       assert(_state == accept);
       assert(size == end - start);
-      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
-      // checking types and ranges, which is redundant in this case. Find a
-      // more direct way to do the conversion.
-      return String.fromCharCodes(bytes, start, end);
+      String result = allocateOneByteString(size);
+      copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size);
+      return result;
     }
 
     // Do not include any final, incomplete character in size.
@@ -1932,8 +1931,6 @@
 
   String decode8(Uint8List bytes, int start, int end, int size) {
     assert(start < end);
-    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
-    // write characters to it using _setAt.
     final String result = allocateOneByteString(size);
     int i = start;
     int j = 0;
@@ -1986,8 +1983,6 @@
     assert(start < end);
     final String typeTable = _Utf8Decoder.typeTable;
     final String transitionTable = _Utf8Decoder.transitionTable;
-    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
-    // write characters to it using _setAt.
     final String result = allocateTwoByteString(size);
     int i = start;
     int j = 0;
diff --git a/sdk/lib/_internal/vm/lib/core_patch.dart b/sdk/lib/_internal/vm/lib/core_patch.dart
index d9e9e36..0994881 100644
--- a/sdk/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk/lib/_internal/vm/lib/core_patch.dart
@@ -17,6 +17,7 @@
         allocateTwoByteString,
         ClassID,
         CodeUnits,
+        copyRangeFromUint8ListToOneByteString,
         EfficientLengthIterable,
         FixedLengthListBase,
         IterableElementError,
diff --git a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
index 586e041..316dc7a 100644
--- a/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
+++ b/sdk/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -75,4 +75,8 @@
 
 @patch
 @pragma("vm:entry-point")
+abstract class Handle extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
 abstract class NativeFunction<T extends Function> extends NativeType {}
diff --git a/sdk/lib/_internal/vm/lib/internal_patch.dart b/sdk/lib/_internal/vm/lib/internal_patch.dart
index c895e04..2a05d99 100644
--- a/sdk/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk/lib/_internal/vm/lib/internal_patch.dart
@@ -12,7 +12,7 @@
 import "dart:core" hide Symbol;
 
 import "dart:isolate" show SendPort;
-import "dart:typed_data" show Int32List;
+import "dart:typed_data" show Int32List, Uint8List;
 
 /// These are the additional parts of this patch library:
 // part "class_id_fasta.dart";
@@ -41,6 +41,18 @@
 void writeIntoOneByteString(String string, int index, int codePoint)
     native "Internal_writeIntoOneByteString";
 
+/// This function is recognized by the VM and compiled into specialized code.
+/// It is assumed that [from] is a native [Uint8List] class and [to] is a
+/// [_OneByteString]. The [fromStart] and [toStart] indices together with the
+/// [length] must specify ranges within the bounds of the list / string.
+@pragma("vm:prefer-inline")
+void copyRangeFromUint8ListToOneByteString(
+    Uint8List from, String to, int fromStart, int toStart, int length) {
+  for (int i = 0; i < length; i++) {
+    writeIntoOneByteString(to, toStart + i, from[fromStart + i]);
+  }
+}
+
 /// The returned string is a [_TwoByteString] with uninitialized content.
 @pragma("vm:entry-point", "call")
 String allocateTwoByteString(int length)
diff --git a/sdk/lib/_internal/vm/lib/lib_prefix.dart b/sdk/lib/_internal/vm/lib/lib_prefix.dart
index 00b934c..5135a26 100644
--- a/sdk/lib/_internal/vm/lib/lib_prefix.dart
+++ b/sdk/lib/_internal/vm/lib/lib_prefix.dart
@@ -13,7 +13,32 @@
     throw "Unreachable";
   }
 
-  bool isLoaded() => true;
+  bool _isLoaded() native "LibraryPrefix_isLoaded";
+  void _setLoaded() native "LibraryPrefix_setLoaded";
+}
 
-  loadLibrary() => new Future.value(true);
+class _DeferredNotLoadedError extends Error implements NoSuchMethodError {
+  final _LibraryPrefix prefix;
+
+  _DeferredNotLoadedError(this.prefix);
+
+  String toString() {
+    return "Deferred library $prefix was not loaded.";
+  }
+}
+
+@pragma("vm:entry-point")
+@pragma("vm:never-inline") // Don't duplicate prefix checking code.
+Future<void> _loadLibrary(_LibraryPrefix prefix) {
+  return new Future<void>(() {
+    prefix._setLoaded();
+  });
+}
+
+@pragma("vm:entry-point")
+@pragma("vm:never-inline") // Don't duplicate prefix checking code.
+void _checkLoaded(_LibraryPrefix prefix) {
+  if (!prefix._isLoaded()) {
+    throw new _DeferredNotLoadedError(prefix);
+  }
 }
diff --git a/sdk/lib/_internal/vm/lib/string_patch.dart b/sdk/lib/_internal/vm/lib/string_patch.dart
index c5d4ff49..028bb6b 100644
--- a/sdk/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk/lib/_internal/vm/lib/string_patch.dart
@@ -224,14 +224,14 @@
     // It's always faster to do this in Dart than to call into the runtime.
     var s = _OneByteString._allocate(len);
 
-    // Special case for _Uint8ArrayView.
-    if (charCodes is Uint8List) {
-      if (start >= 0 && len >= 0) {
-        for (int i = 0; i < len; i++) {
-          s._setAt(i, charCodes[start + i]);
-        }
-        return s;
-      }
+    // Special case for native Uint8 typed arrays.
+    final int cid = ClassID.getID(charCodes);
+    if (cid == ClassID.cidUint8ArrayView ||
+        cid == ClassID.cidUint8Array ||
+        cid == ClassID.cidExternalUint8Array) {
+      Uint8List bytes = unsafeCast<Uint8List>(charCodes);
+      copyRangeFromUint8ListToOneByteString(bytes, s, start, 0, len);
+      return s;
     }
 
     // Fall through to normal case.
diff --git a/sdk/lib/async/stream_controller.dart b/sdk/lib/async/stream_controller.dart
index 3b5694f..396c53d 100644
--- a/sdk/lib/async/stream_controller.dart
+++ b/sdk/lib/async/stream_controller.dart
@@ -249,14 +249,41 @@
   /**
    * Closes the stream.
    *
-   * Listeners receive the done event at a later microtask. This behavior can be
-   * overridden by using `sync` controllers. Note, however, that sync
-   * controllers have to satisfy the preconditions mentioned in the
-   * documentation of the constructors.
+   * No further events can be added to a closed stream.
+   *
+   * The returned future is the same future provided by [done].
+   * It is completed when the stream listeners is done sending events,
+   * This happens either when the done event has been sent,
+   * or when the subscriber on a single-subscription stream is canceled.
+   *
+   * A broadcast stream controller will send the done event
+   * even if listeners are paused, so some broadcast events may not have been
+   * received yet when the returned future completes.
+   *
+   * If noone listens to a non-broadcast stream,
+   * or the listener pauses and never resumes,
+   * the done event will not be sent and this future will never complete.
    */
   Future close();
 
   /**
+   * A future which is completed when the stream controller is done
+   * sending events.
+   *
+   * This happens either when the done event has been sent, or if the
+   * subscriber on a single-subscription stream is canceled.
+   *
+   * A broadcast stream controller will send the done event
+   * even if listeners are paused, so some broadcast events may not have been
+   * received yet when the returned future completes.
+   *
+   * If there is no listener on a non-broadcast stream,
+   * or the listener pauses and never resumes,
+   * the done event will not be sent and this future will never complete.
+   */
+  Future get done;
+
+  /**
    * Receives events from [source] and puts them into this controller's stream.
    *
    * Returns a future which completes when the source stream is done.
@@ -575,13 +602,6 @@
     return addState.addStreamFuture;
   }
 
-  /**
-   * Returns a future that is completed when the stream is done
-   * processing events.
-   *
-   * This happens either when the done event has been sent, or if the
-   * subscriber of a single-subscription stream is cancelled.
-   */
   Future get done => _ensureDoneFuture();
 
   Future _ensureDoneFuture() {
diff --git a/sdk/lib/core/date_time.dart b/sdk/lib/core/date_time.dart
index ee8004b..b36aa3f 100644
--- a/sdk/lib/core/date_time.dart
+++ b/sdk/lib/core/date_time.dart
@@ -653,7 +653,10 @@
   external DateTime subtract(Duration duration);
 
   /**
-   * Returns a [Duration] with the difference between [this] and [other].
+   * Returns a [Duration] with the difference when subtracting [other] from
+   * [this].
+   *
+   * The returned [Duration] will be negative if [other] occurs after [this].
    *
    * ```
    * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9);
@@ -865,8 +868,8 @@
    * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
    * timezonemins_opt ::= <empty> | colon_opt digit{2}
    */
-  static final RegExp _parseFormat = RegExp(
-      r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
-      r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part.
-      r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
+  static final RegExp _parseFormat =
+      RegExp(r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
+          r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part.
+          r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
 }
diff --git a/sdk/lib/core/string.dart b/sdk/lib/core/string.dart
index b5b010a..fbbd7d0 100644
--- a/sdk/lib/core/string.dart
+++ b/sdk/lib/core/string.dart
@@ -295,16 +295,16 @@
   int indexOf(Pattern pattern, [int start]);
 
   /**
-   * Returns the position of the last match [pattern] in this string, searching
-   * backward starting at [start], inclusive:
+   * Returns the starting position of the last match [pattern] in this string,
+   * searching backward starting at [start], inclusive:
    *
    *     var string = 'Dartisans';
    *     string.lastIndexOf('a');                    // 6
-   *     string.lastIndexOf(new RegExp(r'a(r|n)'));  // 6
+   *     string.lastIndexOf(RegExp(r'a(r|n)'));      // 6
    *
    * Returns -1 if [pattern] could not be found in this string.
    *
-   *     string.lastIndexOf(new RegExp(r'DART'));    // -1
+   *     string.lastIndexOf(RegExp(r'DART'));        // -1
    *
    * The [start] must be non-negative and not greater than [length].
    */
diff --git a/sdk/lib/ffi/native_type.dart b/sdk/lib/ffi/native_type.dart
index c372b82..8496145 100644
--- a/sdk/lib/ffi/native_type.dart
+++ b/sdk/lib/ffi/native_type.dart
@@ -125,6 +125,12 @@
 @unsized
 abstract class Void extends NativeType {}
 
+/// Represents `Dart_Handle` in C.
+///
+/// [Handle] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+abstract class Handle extends NativeType {}
+
 /// Represents a function type in C.
 ///
 /// [NativeFunction] is not constructible in the Dart code and serves purely as
diff --git a/sdk/lib/html/dart2js/html_dart2js.dart b/sdk/lib/html/dart2js/html_dart2js.dart
index 10599a9..77a36ed 100644
--- a/sdk/lib/html/dart2js/html_dart2js.dart
+++ b/sdk/lib/html/dart2js/html_dart2js.dart
@@ -744,6 +744,7 @@
 
   // Shadowing definition.
 
+  @Returns('num|String|Null')
   Object get duration native;
 
   set duration(Object value) native;
@@ -26792,6 +26793,15 @@
   static const EventStreamProvider<Event> signalingStateChangeEvent =
       const EventStreamProvider<Event>('signalingstatechange');
 
+  /**
+   * Static factory designed to expose `track` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<RtcTrackEvent> trackEvent =
+      const EventStreamProvider<RtcTrackEvent>('track');
+
   String get iceConnectionState native;
 
   String get iceGatheringState native;
@@ -26923,6 +26933,9 @@
   /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
   Stream<Event> get onSignalingStateChange =>
       signalingStateChangeEvent.forTarget(this);
+
+  /// Stream of `track` events handled by this [RtcPeerConnection].
+  Stream<RtcTrackEvent> get onTrack => trackEvent.forTarget(this);
 }
 // 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
diff --git a/sdk/lib/io/common.dart b/sdk/lib/io/common.dart
index cccb927..58f5f70 100644
--- a/sdk/lib/io/common.dart
+++ b/sdk/lib/io/common.dart
@@ -108,7 +108,7 @@
   return new _BufferAndStart(newBuffer, 0);
 }
 
-// VM will use ClassID to check whether buffer is Uint8List or Int8List.
+// The VM will use ClassID to check whether buffer is Uint8List or Int8List.
 external bool _isDirectIOCapableTypedList(List<int> buffer);
 
 class _IOCrypto {
diff --git a/sdk/lib/io/process.dart b/sdk/lib/io/process.dart
index 93a6772..d9fad38 100644
--- a/sdk/lib/io/process.dart
+++ b/sdk/lib/io/process.dart
@@ -20,8 +20,8 @@
 /**
  * Exit the Dart VM process immediately with the given exit code.
  *
- * This does not wait for any asynchronous operations to terminate. Using
- * [exit] is therefore very likely to lose data.
+ * This does not wait for any asynchronous operations to terminate nor execute
+ * `finally` blocks. Using [exit] is therefore very likely to lose data.
  *
  * While debugging, the VM will not respect the `--pause-isolates-on-exit`
  * flag if [exit] is called as invoking this method causes the Dart VM
diff --git a/sdk/lib/js/_js_annotations.dart b/sdk/lib/js/_js_annotations.dart
new file mode 100644
index 0000000..8c8148d
--- /dev/null
+++ b/sdk/lib/js/_js_annotations.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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 implementation of the JS interop classes which are usable from the
+// Dart SDK. These types need to stay in-sync with
+// https://github.com/dart-lang/sdk/blob/master/pkg/js/lib/js.dart
+library _js_annotations;
+
+class JS {
+  final String name;
+  const JS([this.name]);
+}
+
+class _Anonymous {
+  const _Anonymous();
+}
+
+const _Anonymous anonymous = const _Anonymous();
diff --git a/sdk/lib/libraries.json b/sdk/lib/libraries.json
index 312ed14..0289238 100644
--- a/sdk/lib/libraries.json
+++ b/sdk/lib/libraries.json
@@ -211,6 +211,9 @@
         "uri": "js/_js.dart",
         "patches": "js/_js_client.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "js_util": {
         "uri": "js_util/js_util.dart"
       },
@@ -321,6 +324,9 @@
         "uri": "js/_js.dart",
         "patches": "js/_js_server.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "js_util": {
         "uri": "js_util/js_util.dart"
       },
@@ -397,6 +403,9 @@
       "_isolate_helper": {
         "uri": "_internal/js_dev_runtime/private/isolate_helper.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "_js_helper": {
         "uri": "_internal/js_dev_runtime/private/js_helper.dart"
       },
diff --git a/sdk/lib/libraries.yaml b/sdk/lib/libraries.yaml
index 81a5f51..a80284d 100644
--- a/sdk/lib/libraries.yaml
+++ b/sdk/lib/libraries.yaml
@@ -208,6 +208,9 @@
       uri: "js/_js.dart"
       patches: "js/_js_client.dart"
 
+    _js_annotations:
+      uri: "js/_js_annotations.dart"
+
     js_util:
       uri: "js_util/js_util.dart"
 
@@ -316,6 +319,9 @@
       uri: "js/_js.dart"
       patches: "js/_js_server.dart"
 
+    _js_annotations:
+      uri: "js/_js_annotations.dart"
+
     js_util:
       uri: "js_util/js_util.dart"
 
@@ -390,6 +396,9 @@
       _isolate_helper:
         uri: "_internal/js_dev_runtime/private/isolate_helper.dart"
 
+      _js_annotations:
+        uri: "js/_js_annotations.dart"
+
       _js_helper:
         uri: "_internal/js_dev_runtime/private/js_helper.dart"
 
diff --git a/sdk/lib/svg/dart2js/svg_dart2js.dart b/sdk/lib/svg/dart2js/svg_dart2js.dart
index 5704564..c54ac08 100644
--- a/sdk/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk/lib/svg/dart2js/svg_dart2js.dart
@@ -3244,7 +3244,7 @@
   SvgElement.created() : super.created();
 
   // Shadowing definition.
-
+  @JSName('className')
   AnimatedString get _svgClassName native;
 
   @JSName('ownerSVGElement')
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 df163f8..041dfd5 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
@@ -216,7 +216,7 @@
 
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
-  return buffer is Uint8List || buffer is Int8List;
+  throw UnsupportedError("_isDirectIOCapableTypedList");
 }
 
 @patch
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 2fa2e6f..77a2530 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/io_patch.dart
@@ -216,7 +216,7 @@
 
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
-  return buffer is Uint8List || buffer is Int8List;
+  throw UnsupportedError("_isDirectIOCapableTypedList");
 }
 
 @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 ff906ac..488f359 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2824,212 +2824,6 @@
   return value;
 }
 
-stringTypeCheck(value) {
-  if (value == null) return value;
-  if (value is String) return value;
-  throw new TypeErrorImplementation(value, 'String');
-}
-
-stringTypeCast(value) {
-  if (value is String || value == null) return value;
-  throw new CastErrorImplementation(value, 'String');
-}
-
-doubleTypeCheck(value) {
-  if (value == null) return value;
-  if (value is double) return value;
-  throw new TypeErrorImplementation(value, 'double');
-}
-
-doubleTypeCast(value) {
-  if (value is double || value == null) return value;
-  throw new CastErrorImplementation(value, 'double');
-}
-
-numTypeCheck(value) {
-  if (value == null) return value;
-  if (value is num) return value;
-  throw new TypeErrorImplementation(value, 'num');
-}
-
-numTypeCast(value) {
-  if (value is num || value == null) return value;
-  throw new CastErrorImplementation(value, 'num');
-}
-
-boolTypeCheck(value) {
-  if (value == null) return value;
-  if (value is bool) return value;
-  throw new TypeErrorImplementation(value, 'bool');
-}
-
-boolTypeCast(value) {
-  if (value is bool || value == null) return value;
-  throw new CastErrorImplementation(value, 'bool');
-}
-
-intTypeCheck(value) {
-  if (value == null) return value;
-  if (value is int) return value;
-  throw new TypeErrorImplementation(value, 'int');
-}
-
-intTypeCast(value) {
-  if (value is int || value == null) return value;
-  throw new CastErrorImplementation(value, 'int');
-}
-
-void propertyTypeError(value, property) {
-  String name = isCheckPropertyToJsConstructorName(property);
-  throw new TypeErrorImplementation(value, unminifyOrTag(name));
-}
-
-void propertyTypeCastError(value, property) {
-  // Cuts the property name to the class name.
-  String name = isCheckPropertyToJsConstructorName(property);
-  throw new CastErrorImplementation(value, unminifyOrTag(name));
-}
-
-/// For types that are not supertypes of native (eg DOM) types,
-/// we emit a simple property check to check that an object implements
-/// that type.
-propertyTypeCheck(value, property) {
-  if (value == null) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-/// For types that are not supertypes of native (eg DOM) types,
-/// we emit a simple property check to check that an object implements
-/// that type.
-propertyTypeCast(value, property) {
-  if (value == null || JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// For types that are supertypes of native (eg DOM) types, we use the
-/// interceptor for the class because we cannot add a JS property to the
-/// prototype at load time.
-interceptedTypeCheck(value, property) {
-  if (value == null) return value;
-  if ((JS('bool', 'typeof # === "object"', value) ||
-          JS('bool', 'typeof # === "function"', value)) &&
-      JS('bool', '#[#]', getInterceptor(value), property)) {
-    return value;
-  }
-  propertyTypeError(value, property);
-}
-
-/// For types that are supertypes of native (eg DOM) types, we use the
-/// interceptor for the class because we cannot add a JS property to the
-/// prototype at load time.
-interceptedTypeCast(value, property) {
-  if (value == null ||
-      ((JS('bool', 'typeof # === "object"', value) ||
-              JS('bool', 'typeof # === "function"', value)) &&
-          JS('bool', '#[#]', getInterceptor(value), property))) {
-    return value;
-  }
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for num and String and their
-/// supertype since [value] can be a JS primitive.
-numberOrStringSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-numberOrStringSuperTypeCast(value, property) {
-  if (value is String) return value;
-  if (value is num) return value;
-  return propertyTypeCast(value, property);
-}
-
-numberOrStringSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-numberOrStringSuperNativeTypeCast(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (value is num) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for String and its supertype
-/// since [value] can be a JS primitive.
-stringSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-stringSuperTypeCast(value, property) {
-  if (value is String) return value;
-  return propertyTypeCast(value, property);
-}
-
-stringSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is String) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-stringSuperNativeTypeCast(value, property) {
-  if (value is String || value == null) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
-/// Specialization of the type check for List and its supertypes,
-/// since [value] can be a JS array.
-listTypeCheck(value) {
-  if (value == null) return value;
-  if (value is List) return value;
-  throw new TypeErrorImplementation(value, 'List<dynamic>');
-}
-
-listTypeCast(value) {
-  if (value is List || value == null) return value;
-  throw new CastErrorImplementation(value, 'List<dynamic>');
-}
-
-listSuperTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is List) return value;
-  if (JS('bool', '!!#[#]', value, property)) return value;
-  propertyTypeError(value, property);
-}
-
-listSuperTypeCast(value, property) {
-  if (value is List) return value;
-  return propertyTypeCast(value, property);
-}
-
-listSuperNativeTypeCheck(value, property) {
-  if (value == null) return value;
-  if (value is List) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeError(value, property);
-}
-
-listSuperNativeTypeCast(value, property) {
-  if (value is List || value == null) return value;
-  if (JS('bool', '#[#]', getInterceptor(value), property)) return value;
-  propertyTypeCastError(value, property);
-}
-
 extractFunctionTypeObjectFrom(o) {
   var interceptor = getInterceptor(o);
   return extractFunctionTypeObjectFromInternal(interceptor);
@@ -3048,59 +2842,6 @@
   return null;
 }
 
-functionTypeTest(value, functionTypeRti) {
-  if (value == null) return false;
-  if (JS('bool', 'typeof # == "function"', value)) {
-    // JavaScript functions do not have an attached type, but for convenient
-    // JS-interop, we pretend they can be any function type.
-    // TODO(sra): Tighten this up to disallow matching function types with
-    // features inaccessible from JavaScript, i.e.  optional named parameters
-    // and type parameters functions.
-    // TODO(sra): If the JavaScript function was the output of `dart:js`'s
-    // `allowInterop` then we have access to the wrapped function.
-    return true;
-  }
-  var functionTypeObject = extractFunctionTypeObjectFrom(value);
-  if (functionTypeObject == null) return false;
-  return isFunctionSubtype(functionTypeObject, functionTypeRti);
-}
-
-// Declared as 'var' to avoid assignment checks.
-var _inTypeAssertion = false;
-
-functionTypeCheck(value, functionTypeRti) {
-  if (value == null) return value;
-
-  // The function type test code contains type assertions for function
-  // types. This leads to unbounded recursion, so disable the type checking of
-  // function types while checking function types.
-
-  if (true == _inTypeAssertion) return value;
-
-  _inTypeAssertion = true;
-  try {
-    if (functionTypeTest(value, functionTypeRti)) return value;
-    var self = runtimeTypeToString(functionTypeRti);
-    throw new TypeErrorImplementation(value, self);
-  } finally {
-    _inTypeAssertion = false;
-  }
-}
-
-functionTypeCast(value, functionTypeRti) {
-  if (value == null) return value;
-  if (functionTypeTest(value, functionTypeRti)) return value;
-
-  var self = runtimeTypeToString(functionTypeRti);
-  throw new CastErrorImplementation(value, self);
-}
-
-futureOrTest(o, futureOrRti) => checkSubtypeOfRuntimeType(o, futureOrRti);
-
-futureOrCheck(o, futureOrRti) => assertSubtypeOfRuntimeType(o, futureOrRti);
-
-futureOrCast(o, futureOrRti) => subtypeOfRuntimeTypeCast(o, futureOrRti);
-
 @pragma('dart2js:noInline')
 void checkDeferredIsLoaded(String loadId) {
   if (!_loadedLibraries.contains(loadId)) {
diff --git a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
index d484342..6bd9af5 100644
--- a/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
+++ b/sdk_nnbd/lib/_internal/js_runtime/lib/js_rti.dart
@@ -78,11 +78,6 @@
   const TypeVariable(this.owner, this.name, this.bound);
 }
 
-getMangledTypeName(Type t) {
-  TypeImpl type = t as TypeImpl;
-  return type._typeName;
-}
-
 /// Sets the runtime type information on [target]. [rti] is a type
 /// representation of type 4 or 5, that is, either a JavaScript array or `null`.
 ///
@@ -354,52 +349,8 @@
   return '<$buffer>';
 }
 
-/// Returns a human-readable representation of the type of [object].
-///
-/// In minified mode does *not* use unminified identifiers (even when present).
-String getRuntimeTypeString(var object) {
-  if (object is Closure) {
-    // This excludes classes that implement Function via a `call` method, but
-    // includes classes generated to represent closures in closure conversion.
-    var functionRti = extractFunctionTypeObjectFrom(object);
-    if (functionRti != null) {
-      return runtimeTypeToString(functionRti);
-    }
-  }
-  String className = getClassName(object);
-  if (object == null) return className;
-  String rtiName = JS_GET_NAME(JsGetName.RTI_NAME);
-  var rti = JS('var', r'#[#]', object, rtiName);
-  return "$className${joinArguments(rti, 0)}";
-}
-
-/// Returns the full type of [o] in the runtime type representation.
-getRti(o) {
-  if (o is Closure) {
-    // This excludes classes that implement Function via a `call` method, but
-    // includes classes generated to represent closures in closure conversion.
-    var functionRti = extractFunctionTypeObjectFrom(o);
-    if (functionRti != null) return functionRti;
-  }
-  var interceptor = getInterceptor(o);
-  var type = getRawRuntimeType(interceptor);
-  if (o == null) return type;
-  if (JS('bool', 'typeof # != "object"', o)) return type;
-  var rti = getRuntimeTypeInfo(o);
-  if (rti != null) {
-    // If the type has type variables (that is, `rti != null`), make a copy of
-    // the type arguments and insert [o] in the first position to create a
-    // compound type representation.
-    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
-    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
-    type = rti;
-  }
-  return type;
-}
-
 Type getRuntimeType(var object) {
-  if (JS_GET_FLAG('USE_NEW_RTI')) return newRti.getRuntimeType(object);
-  return new TypeImpl(getRti(object));
+  return newRti.getRuntimeType(object);
 }
 
 /// Applies the [substitution] on the [arguments].
@@ -426,31 +377,6 @@
   return arguments;
 }
 
-/// Perform a type check with arguments on the Dart object [object].
-///
-/// Parameters:
-/// - [isField]: the name of the flag/function to check if the object
-///   is of the correct class.
-/// - [checks]: the (JavaScript) list of type representations for the
-///   arguments to check against.
-/// - [asField]: the name of the function that transforms the type
-///   arguments of [objects] to an instance of the class that we check
-///   against.
-bool checkSubtype(Object object, String isField, List checks, String asField) {
-  if (object == null) return false;
-  var arguments = getRuntimeTypeInfo(object);
-  // Interceptor is needed for JSArray and native classes.
-  // TODO(sra): It could be a more specialized interceptor since [object] is not
-  // `null` or a primitive.
-  var interceptor = getInterceptor(object);
-  var isSubclass = getField(interceptor, isField);
-  // When we read the field and it is not there, [isSubclass] will be `null`.
-  if (isSubclass == null) return false;
-  // Should the asField function be passed the receiver?
-  var substitution = getField(interceptor, asField);
-  return checkArguments(substitution, arguments, null, checks, null);
-}
-
 /// Returns the field's type name.
 ///
 /// In minified mode, uses the unminified names if available.
@@ -461,38 +387,6 @@
       unminifyOrTag(isCheckPropertyToJsConstructorName(isField)), arguments);
 }
 
-/// Called from generated code.
-Object subtypeCast(Object object, String isField, List checks, String asField) {
-  if (object == null) return object;
-  if (checkSubtype(object, isField, checks, asField)) return object;
-  String typeName = computeTypeName(isField, checks);
-  throw new CastErrorImplementation(object, typeName);
-}
-
-/// Called from generated code.
-Object assertSubtype(
-    Object object, String isField, List checks, String asField) {
-  if (object == null) return object;
-  if (checkSubtype(object, isField, checks, asField)) return object;
-  String typeName = computeTypeName(isField, checks);
-  throw new TypeErrorImplementation(object, typeName);
-}
-
-/// Checks that the type represented by [subtype] is a subtype of [supertype].
-/// If not a type error is thrown using [prefix], [infix], [suffix] and the
-/// runtime types [subtype] and [supertype] to generate the error message.
-///
-/// Called from generated code.
-assertIsSubtype(
-    var subtype, var supertype, String prefix, String infix, String suffix) {
-  if (!isSubtype(subtype, supertype)) {
-    String message = "TypeError: "
-        "$prefix${runtimeTypeToString(subtype)}$infix"
-        "${runtimeTypeToString(supertype)}$suffix";
-    throwTypeError(message);
-  }
-}
-
 throwTypeError(message) {
   throw new TypeErrorImplementation.fromMessage(message);
 }
@@ -557,46 +451,6 @@
       isDartJsInteropTypeArgumentRti(type);
 }
 
-/// Returns `true` if the runtime type representation [type] is a supertype of
-/// [Null].
-@pragma('dart2js:tryInline')
-bool isSupertypeOfNull(var type) {
-  return isSupertypeOfNullBase(type) || isSupertypeOfNullRecursive(type);
-}
-
-/// Returns `true` if the runtime type representation [type] is a simple
-/// supertype of [Null].
-///
-/// This method doesn't handle `FutureOr<Null>`. This is handle by
-/// [isSupertypeOfNullRecursive] because it requires a recursive check.
-@pragma('dart2js:tryInline')
-bool isSupertypeOfNullBase(var type) {
-  return isDartDynamicTypeRti(type) ||
-      isDartObjectTypeRti(type) ||
-      isNullTypeRti(type) ||
-      isDartVoidTypeRti(type) ||
-      isDartJsInteropTypeArgumentRti(type);
-}
-
-/// Returns `true` if the runtime type representation [type] is a `FutureOr`
-/// type that is a supertype of [Null].
-///
-/// This method is recursive to be able to handle both `FutureOr<Null>` and
-/// `FutureOr<FutureOr<Null>>` etc.
-bool isSupertypeOfNullRecursive(var type) {
-  if (isGenericFunctionTypeParameter(type)) {
-    // We need to check for function type variables because `isDartFutureOrType`
-    // doesn't work on numbers.
-    return false;
-  }
-  if (isDartFutureOrType(type)) {
-    var typeArgument = getFutureOrArgument(type);
-    return isSupertypeOfNullBase(type) ||
-        isSupertypeOfNullRecursive(typeArgument);
-  }
-  return false;
-}
-
 /// Returns the type argument of the `FutureOr` runtime type representation
 /// [type].
 ///
@@ -610,63 +464,6 @@
       : null;
 }
 
-/// Tests whether the Dart object [o] is a subtype of the runtime type
-/// representation [t].
-///
-/// See the comment in the beginning of this file for a description of type
-/// representations.
-bool checkSubtypeOfRuntimeType(o, t) {
-  if (o == null) return isSupertypeOfNull(t);
-  if (isTopType(t)) return true;
-  if (JS('bool', 'typeof # == "object"', t)) {
-    if (isDartFutureOrType(t)) {
-      // `o is FutureOr<T>` is equivalent to
-      //
-      //     o is T || o is Future<T>
-      //
-      // T might be a function type, requiring extracting the closure's
-      // signature, so do the `o is T` check here and let the `Future` interface
-      // type test fall through to the `isSubtype` check at the end of this
-      // function.
-      var tTypeArgument = getFutureOrArgument(t);
-      if (checkSubtypeOfRuntimeType(o, tTypeArgument)) return true;
-    }
-
-    if (isDartFunctionType(t)) {
-      return functionTypeTest(o, t);
-    }
-  }
-
-  var interceptor = getInterceptor(o);
-  var type = getRawRuntimeType(interceptor);
-  var rti = getRuntimeTypeInfo(o);
-  if (rti != null) {
-    // If the type has type variables (that is, `rti != null`), make a copy of
-    // the type arguments and insert [o] in the first position to create a
-    // compound type representation.
-    rti = JS('JSExtendableArray', '#.slice()', rti); // Make a copy.
-    JS('', '#.splice(0, 0, #)', rti, type); // Insert type at position 0.
-    type = rti;
-  }
-  return isSubtype(type, t);
-}
-
-/// Called from generated code.
-Object subtypeOfRuntimeTypeCast(Object object, var type) {
-  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
-    throw new CastErrorImplementation(object, runtimeTypeToString(type));
-  }
-  return object;
-}
-
-/// Called from generated code.
-Object assertSubtypeOfRuntimeType(Object object, var type) {
-  if (object != null && !checkSubtypeOfRuntimeType(object, type)) {
-    throw new TypeErrorImplementation(object, runtimeTypeToString(type));
-  }
-  return object;
-}
-
 /// Extracts the type arguments from a type representation. The result is a
 /// JavaScript array or `null`.
 getArguments(var type) {
diff --git a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
index 9927bd4..ab7da7e 100644
--- a/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
+++ b/sdk_nnbd/lib/_internal/sdk_library_metadata/lib/libraries.dart
@@ -190,6 +190,8 @@
       platforms: DART2JS_PLATFORM),
   "_metadata": const LibraryInfo("html/html_common/metadata.dart",
       categories: "", documented: false, platforms: DART2JS_PLATFORM),
+  "_js_annotations": const LibraryInfo("js/_js_annotations.dart",
+      categories: "", documented: false, platforms: DART2JS_PLATFORM),
 };
 
 /**
diff --git a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
index 948350a..9899f2e 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/common_patch.dart
@@ -52,7 +52,14 @@
 @patch
 bool _isDirectIOCapableTypedList(List<int> buffer) {
   int classID = ClassID.getID(buffer);
-  return classID == ClassID.cidUint8Array || classID == ClassID.cidInt8Array;
+  return classID == ClassID.cidExternalInt8Array ||
+      classID == ClassID.cidExternalUint8Array ||
+      classID == ClassID.cidExternalUint8ClampedArray ||
+      classID == ClassID.cidInt8Array ||
+      classID == ClassID.cidInt8ArrayView ||
+      classID == ClassID.cidUint8Array ||
+      classID == ClassID.cidUint8ArrayView ||
+      classID == ClassID.cidUint8ClampedArray;
 }
 
 @patch
diff --git a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
index 4b30879..26f1bfa 100644
--- a/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
+++ b/sdk_nnbd/lib/_internal/vm/bin/vmservice_server.dart
@@ -362,7 +362,7 @@
         });
       } else {
         // Forward the websocket connection request to DDS.
-        request.response.redirect(_service.ddsUri);
+        request.response.redirect(_service.ddsUri!);
       }
       return;
     }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
index ff6009b..ef181be 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/array_patch.dart
@@ -69,6 +69,7 @@
   }
 
   @patch
+  @pragma("vm:prefer-inline")
   factory List.generate(int length, E generator(int index),
       {bool growable = true}) {
     final List<E> result =
diff --git a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
index 6375c2b..6f82337 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/convert_patch.dart
@@ -12,6 +12,7 @@
         allocateOneByteString,
         allocateTwoByteString,
         ClassID,
+        copyRangeFromUint8ListToOneByteString,
         patch,
         POWERS_OF_TEN,
         unsafeCast,
@@ -1755,10 +1756,9 @@
     if (flags == 0) {
       // Pure ASCII.
       assert(size == end - start);
-      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
-      // checking types and ranges, which is redundant in this case. Find a
-      // more direct way to do the conversion.
-      return String.fromCharCodes(bytes, start, end);
+      String result = allocateOneByteString(size);
+      copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size);
+      return result;
     }
 
     String result;
@@ -1850,10 +1850,9 @@
       // Pure ASCII.
       assert(_state == accept);
       assert(size == end - start);
-      // TODO(dartbug.com/41703): String.fromCharCodes has a lot of overhead
-      // checking types and ranges, which is redundant in this case. Find a
-      // more direct way to do the conversion.
-      return String.fromCharCodes(bytes, start, end);
+      String result = allocateOneByteString(size);
+      copyRangeFromUint8ListToOneByteString(bytes, result, start, 0, size);
+      return result;
     }
 
     // Do not include any final, incomplete character in size.
@@ -1936,8 +1935,6 @@
 
   String decode8(Uint8List bytes, int start, int end, int size) {
     assert(start < end);
-    // TODO(dartbug.com/41704): Allocate an uninitialized _OneByteString and
-    // write characters to it using _setAt.
     String result = allocateOneByteString(size);
     int i = start;
     int j = 0;
@@ -1990,8 +1987,6 @@
     assert(start < end);
     final String typeTable = _Utf8Decoder.typeTable;
     final String transitionTable = _Utf8Decoder.transitionTable;
-    // TODO(dartbug.com/41704): Allocate an uninitialized _TwoByteString and
-    // write characters to it using _setAt.
     String result = allocateTwoByteString(size);
     int i = start;
     int j = 0;
diff --git a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
index 396ad6b..2133763 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/core_patch.dart
@@ -15,6 +15,7 @@
         allocateTwoByteString,
         ClassID,
         CodeUnits,
+        copyRangeFromUint8ListToOneByteString,
         EfficientLengthIterable,
         FixedLengthListBase,
         IterableElementError,
diff --git a/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart
index 473ba7a..cc7831b 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/ffi_native_type_patch.dart
@@ -73,4 +73,8 @@
 
 @patch
 @pragma("vm:entry-point")
+abstract class Handle extends NativeType {}
+
+@patch
+@pragma("vm:entry-point")
 abstract class NativeFunction<T extends Function> extends NativeType {}
diff --git a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
index 8382618..b904f9e 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/internal_patch.dart
@@ -10,7 +10,7 @@
 import "dart:core" hide Symbol;
 
 import "dart:isolate" show SendPort;
-import "dart:typed_data" show Int32List;
+import "dart:typed_data" show Int32List, Uint8List;
 
 /// These are the additional parts of this patch library:
 // part "class_id_fasta.dart";
@@ -45,6 +45,18 @@
 void writeIntoOneByteString(String string, int index, int codePoint)
     native "Internal_writeIntoOneByteString";
 
+/// This function is recognized by the VM and compiled into specialized code.
+/// It is assumed that [from] is a native [Uint8List] class and [to] is a
+/// [_OneByteString]. The [fromStart] and [toStart] indices together with the
+/// [length] must specify ranges within the bounds of the list / string.
+@pragma("vm:prefer-inline")
+void copyRangeFromUint8ListToOneByteString(
+    Uint8List from, String to, int fromStart, int toStart, int length) {
+  for (int i = 0; i < length; i++) {
+    writeIntoOneByteString(to, toStart + i, from[fromStart + i]);
+  }
+}
+
 /// The returned string is a [_TwoByteString] with uninitialized content.
 @pragma("vm:entry-point", "call")
 String allocateTwoByteString(int length)
diff --git a/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart b/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart
index f588ee3..d8e52fd 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/lib_prefix.dart
@@ -11,7 +11,32 @@
     throw "Unreachable";
   }
 
-  bool isLoaded() => true;
+  bool _isLoaded() native "LibraryPrefix_isLoaded";
+  void _setLoaded() native "LibraryPrefix_setLoaded";
+}
 
-  loadLibrary() => new Future.value(true);
+class _DeferredNotLoadedError extends Error implements NoSuchMethodError {
+  final _LibraryPrefix prefix;
+
+  _DeferredNotLoadedError(this.prefix);
+
+  String toString() {
+    return "Deferred library $prefix was not loaded.";
+  }
+}
+
+@pragma("vm:entry-point")
+@pragma("vm:never-inline") // Don't duplicate prefix checking code.
+Future<void> _loadLibrary(_LibraryPrefix prefix) {
+  return new Future<void>(() {
+    prefix._setLoaded();
+  });
+}
+
+@pragma("vm:entry-point")
+@pragma("vm:never-inline") // Don't duplicate prefix checking code.
+void _checkLoaded(_LibraryPrefix prefix) {
+  if (!prefix._isLoaded()) {
+    throw new _DeferredNotLoadedError(prefix);
+  }
 }
diff --git a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
index f4c3a22..55fc053 100644
--- a/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
+++ b/sdk_nnbd/lib/_internal/vm/lib/string_patch.dart
@@ -229,14 +229,14 @@
     // It's always faster to do this in Dart than to call into the runtime.
     var s = _OneByteString._allocate(len);
 
-    // Special case for _Uint8ArrayView.
-    if (charCodes is Uint8List) {
-      if (start >= 0 && len >= 0) {
-        for (int i = 0; i < len; i++) {
-          s._setAt(i, charCodes[start + i]);
-        }
-        return s;
-      }
+    // Special case for native Uint8 typed arrays.
+    final int cid = ClassID.getID(charCodes);
+    if (cid == ClassID.cidUint8ArrayView ||
+        cid == ClassID.cidUint8Array ||
+        cid == ClassID.cidExternalUint8Array) {
+      Uint8List bytes = unsafeCast<Uint8List>(charCodes);
+      copyRangeFromUint8ListToOneByteString(bytes, s, start, 0, len);
+      return s;
     }
 
     // Fall through to normal case.
diff --git a/sdk_nnbd/lib/async/stream_controller.dart b/sdk_nnbd/lib/async/stream_controller.dart
index 0c0a93a..9688dd1 100644
--- a/sdk_nnbd/lib/async/stream_controller.dart
+++ b/sdk_nnbd/lib/async/stream_controller.dart
@@ -245,14 +245,41 @@
   /**
    * Closes the stream.
    *
-   * Listeners receive the done event at a later microtask. This behavior can be
-   * overridden by using `sync` controllers. Note, however, that sync
-   * controllers have to satisfy the preconditions mentioned in the
-   * documentation of the constructors.
+   * No further events can be added to a closed stream.
+   *
+   * The returned future is the same future provided by [done].
+   * It is completed when the stream listeners is done sending events,
+   * This happens either when the done event has been sent,
+   * or when the subscriber on a single-subscription stream is canceled.
+   *
+   * A broadcast stream controller will send the done event
+   * even if listeners are paused, so some broadcast events may not have been
+   * received yet when the returned future completes.
+   *
+   * If noone listens to a non-broadcast stream,
+   * or the listener pauses and never resumes,
+   * the done event will not be sent and this future will never complete.
    */
   Future close();
 
   /**
+   * A future which is completed when the stream controller is done
+   * sending events.
+   *
+   * This happens either when the done event has been sent, or if the
+   * subscriber on a single-subscription stream is canceled.
+   *
+   * A broadcast stream controller will send the done event
+   * even if listeners are paused, so some broadcast events may not have been
+   * received yet when the returned future completes.
+   *
+   * If there is no listener on a non-broadcast stream,
+   * or the listener pauses and never resumes,
+   * the done event will not be sent and this future will never complete.
+   */
+  Future get done;
+
+  /**
    * Receives events from [source] and puts them into this controller's stream.
    *
    * Returns a future which completes when the source stream is done.
diff --git a/sdk_nnbd/lib/core/date_time.dart b/sdk_nnbd/lib/core/date_time.dart
index 7ef2d84..ae13922 100644
--- a/sdk_nnbd/lib/core/date_time.dart
+++ b/sdk_nnbd/lib/core/date_time.dart
@@ -653,7 +653,10 @@
   external DateTime subtract(Duration duration);
 
   /**
-   * Returns a [Duration] with the difference between [this] and [other].
+   * Returns a [Duration] with the difference when subtracting [other] from
+   * [this].
+   *
+   * The returned [Duration] will be negative if [other] occurs after [this].
    *
    * ```
    * var berlinWallFell = new DateTime.utc(1989, DateTime.november, 9);
@@ -865,8 +868,8 @@
    * timezone ::= 'z' | 'Z' | sign digit{2} timezonemins_opt
    * timezonemins_opt ::= <empty> | colon_opt digit{2}
    */
-  static final RegExp _parseFormat = RegExp(
-      r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
-      r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part.
-      r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
+  static final RegExp _parseFormat =
+      RegExp(r'^([+-]?\d{4,6})-?(\d\d)-?(\d\d)' // Day part.
+          r'(?:[ T](\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d+))?)?)?' // Time part.
+          r'( ?[zZ]| ?([-+])(\d\d)(?::?(\d\d))?)?)?$'); // Timezone part.
 }
diff --git a/sdk_nnbd/lib/core/string.dart b/sdk_nnbd/lib/core/string.dart
index b7bba38..4a353b2 100644
--- a/sdk_nnbd/lib/core/string.dart
+++ b/sdk_nnbd/lib/core/string.dart
@@ -293,16 +293,16 @@
   int indexOf(Pattern pattern, [int start = 0]);
 
   /**
-   * Returns the position of the last match [pattern] in this string, searching
-   * backward starting at [start], inclusive:
+   * Returns the starting position of the last match [pattern] in this string,
+   * searching backward starting at [start], inclusive:
    *
    *     var string = 'Dartisans';
    *     string.lastIndexOf('a');                    // 6
-   *     string.lastIndexOf(new RegExp(r'a(r|n)'));  // 6
+   *     string.lastIndexOf(RegExp(r'a(r|n)'));      // 6
    *
    * Returns -1 if [pattern] could not be found in this string.
    *
-   *     string.lastIndexOf(new RegExp(r'DART'));    // -1
+   *     string.lastIndexOf(RegExp(r'DART'));        // -1
    *
    * If [start] is omitted, search starts from the end of the string.
    * If supplied, [start] must be non-negative and not greater than [length].
diff --git a/sdk_nnbd/lib/ffi/native_type.dart b/sdk_nnbd/lib/ffi/native_type.dart
index aa30e63..e319342 100644
--- a/sdk_nnbd/lib/ffi/native_type.dart
+++ b/sdk_nnbd/lib/ffi/native_type.dart
@@ -123,6 +123,12 @@
 @unsized
 abstract class Void extends NativeType {}
 
+/// Represents `Dart_Handle` in C.
+///
+/// [Handle] is not constructible in the Dart code and serves purely as marker in
+/// type signatures.
+abstract class Handle extends NativeType {}
+
 /// Represents a function type in C.
 ///
 /// [NativeFunction] is not constructible in the Dart code and serves purely as
diff --git a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
index d84d8f6..04dcc3d 100644
--- a/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
+++ b/sdk_nnbd/lib/html/dart2js/html_dart2js.dart
@@ -745,6 +745,7 @@
 
   // Shadowing definition.
 
+  @Returns('num|String|Null')
   Object? get duration native;
 
   set duration(Object? value) native;
@@ -26837,6 +26838,15 @@
   static const EventStreamProvider<Event> signalingStateChangeEvent =
       const EventStreamProvider<Event>('signalingstatechange');
 
+  /**
+   * Static factory designed to expose `track` events to event
+   * handlers that are not necessarily instances of [RtcPeerConnection].
+   *
+   * See [EventStreamProvider] for usage information.
+   */
+  static const EventStreamProvider<RtcTrackEvent> trackEvent =
+      const EventStreamProvider<RtcTrackEvent>('track');
+
   String get iceConnectionState native;
 
   String get iceGatheringState native;
@@ -26968,6 +26978,9 @@
   /// Stream of `signalingstatechange` events handled by this [RtcPeerConnection].
   Stream<Event> get onSignalingStateChange =>
       signalingStateChangeEvent.forTarget(this);
+
+  /// Stream of `track` events handled by this [RtcPeerConnection].
+  Stream<RtcTrackEvent> get onTrack => trackEvent.forTarget(this);
 }
 // 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
diff --git a/sdk_nnbd/lib/html/html_common/conversions.dart b/sdk_nnbd/lib/html/html_common/conversions.dart
index a7775ed..0b5459f 100644
--- a/sdk_nnbd/lib/html/html_common/conversions.dart
+++ b/sdk_nnbd/lib/html/html_common/conversions.dart
@@ -255,7 +255,7 @@
     if (isJavaScriptArray(e)) {
       var l = JS<List>('returns:List;creates:;', '#', e);
       var slot = findSlot(l);
-      var copy = JS<List>('returns:List|Null;creates:;', '#', readSlot(slot));
+      var copy = JS<List?>('returns:List|Null;creates:;', '#', readSlot(slot));
       if (copy != null) return copy;
 
       int length = l.length;
diff --git a/sdk_nnbd/lib/io/common.dart b/sdk_nnbd/lib/io/common.dart
index fe72acc..9688d8d 100644
--- a/sdk_nnbd/lib/io/common.dart
+++ b/sdk_nnbd/lib/io/common.dart
@@ -106,7 +106,7 @@
   return new _BufferAndStart(newBuffer, 0);
 }
 
-// VM will use ClassID to check whether buffer is Uint8List or Int8List.
+// The VM will use ClassID to check whether buffer is Uint8List or Int8List.
 external bool _isDirectIOCapableTypedList(List<int> buffer);
 
 class _IOCrypto {
diff --git a/sdk_nnbd/lib/io/process.dart b/sdk_nnbd/lib/io/process.dart
index e15ba58..e0d0b15 100644
--- a/sdk_nnbd/lib/io/process.dart
+++ b/sdk_nnbd/lib/io/process.dart
@@ -18,8 +18,8 @@
 /**
  * Exit the Dart VM process immediately with the given exit code.
  *
- * This does not wait for any asynchronous operations to terminate. Using
- * [exit] is therefore very likely to lose data.
+ * This does not wait for any asynchronous operations to terminate nor execute
+ * `finally` blocks. Using [exit] is therefore very likely to lose data.
  *
  * While debugging, the VM will not respect the `--pause-isolates-on-exit`
  * flag if [exit] is called as invoking this method causes the Dart VM
diff --git a/sdk_nnbd/lib/js/_js_annotations.dart b/sdk_nnbd/lib/js/_js_annotations.dart
new file mode 100644
index 0000000..8c8148d
--- /dev/null
+++ b/sdk_nnbd/lib/js/_js_annotations.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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 implementation of the JS interop classes which are usable from the
+// Dart SDK. These types need to stay in-sync with
+// https://github.com/dart-lang/sdk/blob/master/pkg/js/lib/js.dart
+library _js_annotations;
+
+class JS {
+  final String name;
+  const JS([this.name]);
+}
+
+class _Anonymous {
+  const _Anonymous();
+}
+
+const _Anonymous anonymous = const _Anonymous();
diff --git a/sdk_nnbd/lib/libraries.json b/sdk_nnbd/lib/libraries.json
index d94a4c6..5d8d5d3 100644
--- a/sdk_nnbd/lib/libraries.json
+++ b/sdk_nnbd/lib/libraries.json
@@ -211,6 +211,9 @@
         "uri": "js/_js.dart",
         "patches": "js/_js_client.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "js_util": {
         "uri": "js_util/js_util.dart"
       },
@@ -321,6 +324,9 @@
         "uri": "js/_js.dart",
         "patches": "js/_js_server.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "js_util": {
         "uri": "js_util/js_util.dart"
       },
@@ -397,6 +403,9 @@
       "_isolate_helper": {
         "uri": "_internal/js_dev_runtime/private/isolate_helper.dart"
       },
+      "_js_annotations": {
+        "uri": "js/_js_annotations.dart"
+      },
       "_js_helper": {
         "uri": "_internal/js_dev_runtime/private/js_helper.dart"
       },
diff --git a/sdk_nnbd/lib/libraries.yaml b/sdk_nnbd/lib/libraries.yaml
index bd36740..14ea40e 100644
--- a/sdk_nnbd/lib/libraries.yaml
+++ b/sdk_nnbd/lib/libraries.yaml
@@ -208,6 +208,9 @@
       uri: "js/_js.dart"
       patches: "js/_js_client.dart"
 
+    _js_annotations:
+      uri: "js/_js_annotations.dart"
+
     js_util:
       uri: "js_util/js_util.dart"
 
@@ -316,6 +319,9 @@
       uri: "js/_js.dart"
       patches: "js/_js_server.dart"
 
+    _js_annotations:
+      uri: "js/_js_annotations.dart"
+
     js_util:
       uri: "js_util/js_util.dart"
 
@@ -390,6 +396,9 @@
       _isolate_helper:
         uri: "_internal/js_dev_runtime/private/isolate_helper.dart"
 
+      _js_annotations:
+        uri: "js/_js_annotations.dart"
+
       _js_helper:
         uri: "_internal/js_dev_runtime/private/js_helper.dart"
 
diff --git a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
index eea4d49..ebb9015 100644
--- a/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
+++ b/sdk_nnbd/lib/svg/dart2js/svg_dart2js.dart
@@ -3282,7 +3282,7 @@
   SvgElement.created() : super.created();
 
   // Shadowing definition.
-
+  @JSName('className')
   AnimatedString get _svgClassName native;
 
   @JSName('ownerSVGElement')
diff --git a/sdk_nnbd/lib/vmservice/running_isolates.dart b/sdk_nnbd/lib/vmservice/running_isolates.dart
index a17b889..20ab8a2 100644
--- a/sdk_nnbd/lib/vmservice/running_isolates.dart
+++ b/sdk_nnbd/lib/vmservice/running_isolates.dart
@@ -75,6 +75,14 @@
   _Evaluator(this._message, this._isolate, this._service);
 
   Future<Response> run() async {
+    if (_service.ddsUri != null) {
+      return Response.from(encodeRpcError(
+        _message,
+        kInternalError,
+        details: 'Fell through to VM Service expression evaluation when a DDS '
+            'instance was connected. Please file an issue on GitHub.',
+      ));
+    }
     final buildScopeResponse = await _buildScope();
     final responseJson = buildScopeResponse.decodeJson();
 
diff --git a/sdk_nnbd/lib/vmservice/vmservice.dart b/sdk_nnbd/lib/vmservice/vmservice.dart
index bbfb61b..23f555b 100644
--- a/sdk_nnbd/lib/vmservice/vmservice.dart
+++ b/sdk_nnbd/lib/vmservice/vmservice.dart
@@ -47,7 +47,7 @@
 final isolateEmbedderData = <int, IsolateEmbedderData>{};
 
 // These must be kept in sync with the declarations in vm/json_stream.h and
-// pkg/dds/lib/src/stream_manager.dart.
+// pkg/dds/lib/src/rpc_error_codes.dart.
 const kParseError = -32700;
 const kInvalidRequest = -32600;
 const kMethodNotFound = -32601;
@@ -219,7 +219,7 @@
 
   final devfs = DevFS();
 
-  Uri get ddsUri => _ddsUri!;
+  Uri? get ddsUri => _ddsUri;
   Uri? _ddsUri;
 
   Future<String> _yieldControlToDDS(Message message) async {
diff --git a/tests/dart2js/10216a_test.dart b/tests/dart2js/10216a_test.dart
new file mode 100644
index 0000000..5032123
--- /dev/null
+++ b/tests/dart2js/10216a_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, 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";
+
+// Tests codegen of methods reached only via mixin.
+
+class A {
+  foo(x, [y]) => '$x;$y';
+}
+
+class B extends A with M1, M2, M3 {}
+
+class M1 {}
+
+class M2 {
+  // These methods are only defined in this non-first, non-last mixin.
+  plain(x) => 'P $x';
+  // Check arity stubs are also available.
+  bar(x, [y]) => '$y,$x';
+}
+
+class M3 {}
+
+makeB() {
+  return [new A(), new B()].last as B;
+}
+
+main() {
+  // makeB enters the compilation worklist after main, so the selectors are
+  // registered before the classes.
+  var b = makeB();
+  Expect.equals('1;2', b.foo(1, 2));
+  Expect.equals('2;null', b.foo(2));
+  Expect.equals('P 3', b.plain(3));
+  Expect.equals('100,4', b.bar(4, 100));
+  Expect.equals('null,5', b.bar(5));
+}
diff --git a/tests/dart2js/10216b_test.dart b/tests/dart2js/10216b_test.dart
new file mode 100644
index 0000000..a2ad8bb
--- /dev/null
+++ b/tests/dart2js/10216b_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, 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";
+
+// Tests codegen of methods reached only via mixin.
+
+class A {
+  foo(x, [y]) => '$x;$y';
+}
+
+class B extends A with M1, M2, M3 {}
+
+class M1 {}
+
+class M2 {
+  // These methods are only defined in this non-first, non-last mixin.
+  plain(x) => 'P $x';
+  // Check arity stubs are also available.
+  bar(x, [y]) => '$y,$x';
+}
+
+class M3 {}
+
+test() {
+  var b = [new A(), new B()].last as B;
+  Expect.equals('1;2', b.foo(1, 2));
+  Expect.equals('2;null', b.foo(2));
+  Expect.equals('P 3', b.plain(3));
+  Expect.equals('100,4', b.bar(4, 100));
+  Expect.equals('null,5', b.bar(5));
+}
+
+main() {
+  new A();
+  new B();
+  // 'test' enters the compilation worklist after main, so the classes are
+  // registered before the selectors.
+  test();
+}
diff --git a/tests/dart2js/11673_test.dart b/tests/dart2js/11673_test.dart
new file mode 100644
index 0000000..47aa416
--- /dev/null
+++ b/tests/dart2js/11673_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, 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";
+
+// Tests codegen of methods reached only via interface implemented by mixin
+// application.
+
+class JSIB {}
+
+class TD {}
+
+class M {
+  foo() => 123;
+}
+
+class I8 extends TD with M implements JSIB {}
+
+use(x) {
+  if (x is JSIB) {
+    // Should be able to find M.foo since I8 is a subtype of both JSIB and M.
+    Expect.equals(123, (x as dynamic).foo());
+  }
+}
+
+main() {
+  (use)(new I8());
+}
diff --git a/tests/dart2js/12320_test.dart b/tests/dart2js/12320_test.dart
new file mode 100644
index 0000000..d47c05a
--- /dev/null
+++ b/tests/dart2js/12320_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, 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";
+
+// Regression test for Issue 12320, Issue 12363.
+
+String log = '';
+int x;
+
+void main() {
+  (run)(run);
+  // The little dance with passing [run] as an argument to confuse the optimizer
+  // so that [run] is not inlined.  If [run] is inlined, the bug (Issue 12320)
+  // eliminates the following 'Expect', making the test appear to pass!
+  Expect.equals('[Foo][Foo 1][Bar][Foo][Foo 0]', log);
+}
+
+void run(f) {
+  if (f is! int) {
+    f(1);
+  } else {
+    x = f;
+    callFoo();
+    x = 2;
+    callBar();
+    callFoo();
+  }
+}
+
+void callFoo() {
+  log += '[Foo]';
+  switch (x) {
+    case 0:
+      log += '[Foo 0]';
+      break;
+    case 1:
+      log += '[Foo 1]';
+      break;
+    default:
+      throw 'invalid x';
+  }
+}
+
+void callBar() {
+  log += '[Bar]';
+  x = 0;
+}
diff --git a/tests/dart2js/12_test.dart b/tests/dart2js/12_test.dart
new file mode 100644
index 0000000..80a758a
--- /dev/null
+++ b/tests/dart2js/12_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+void main() {
+  print(3 + 4 + 5);
+}
diff --git a/tests/dart2js/16400_test.dart b/tests/dart2js/16400_test.dart
new file mode 100644
index 0000000..7902f07
--- /dev/null
+++ b/tests/dart2js/16400_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, 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.
+
+main() {
+  L:
+  {
+    var seeMe = 0;
+    if (seeMe == 0) {
+      ++seeMe;
+      break L;
+    }
+    var wontSeeMe = 2;
+    if (seeMe + wontSeeMe == 2) {
+      return true;
+    } else {
+      return false;
+    }
+  }
+}
diff --git a/tests/dart2js/16407_test.dart b/tests/dart2js/16407_test.dart
new file mode 100644
index 0000000..aff1ba3
--- /dev/null
+++ b/tests/dart2js/16407_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, 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";
+
+// Regression test for Issue 16407.
+
+void main() {
+  foo(null, true);
+  foo('x', false);
+}
+
+var foo = (x, result) {
+  Expect.equals(result, x is Null, '$x is Null');
+};
diff --git a/tests/dart2js/16967_test.dart b/tests/dart2js/16967_test.dart
new file mode 100644
index 0000000..26d9df7
--- /dev/null
+++ b/tests/dart2js/16967_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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';
+
+// Regression test for http://dartbug.com/16967
+// Tests type propagation of negation.
+
+void main() {
+  new Foo().test();
+}
+
+class Foo {
+  var scale = 1;
+
+  void test() {
+    var scaleX = scale;
+    var scaleY = scale;
+    var flipX = true;
+
+    if (flipX) {
+      scaleX = -scaleX;
+    }
+
+    Expect.equals('X: -1, Y: 1', 'X: $scaleX, Y: $scaleY');
+    Expect.equals('true', '${scaleX < 0}', '$scaleX < 0');
+    Expect.equals('false', '${scaleY < 0}', '$scaleY < 0');
+  }
+}
diff --git a/tests/dart2js/17094_test.dart b/tests/dart2js/17094_test.dart
new file mode 100644
index 0000000..41fba87
--- /dev/null
+++ b/tests/dart2js/17094_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, 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";
+
+//  Interpolation effect analysis test.
+
+get never => new DateTime.now().millisecondsSinceEpoch == 0;
+
+class A {
+  int a = 0;
+  toString() {
+    ++a;
+    return 'A';
+  }
+}
+
+// Many interpolations to make function too big to inline.
+// Summary for [fmt] must include effects from toString().
+fmt(x) => '$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x$x';
+
+test(a) {
+  if (a == null) return;
+  if (never) a.a += 1;
+  var b = a.a; // field load
+  var c = fmt(a); // field modified through implicit call to toString()
+  var d = a.a; // field re-load
+  Expect.equals('A 0 AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA 30', '$a $b $c $d');
+
+  // Extra use of [fmt] to prevent inlining on basis of single reference.
+  Expect.equals('', fmt(''));
+}
+
+main() {
+  test(null);
+  test(new A());
+}
diff --git a/tests/dart2js/17645_test.dart b/tests/dart2js/17645_test.dart
new file mode 100644
index 0000000..7469a6c
--- /dev/null
+++ b/tests/dart2js/17645_test.dart
@@ -0,0 +1,76 @@
+// Copyright (c) 2014, 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";
+
+//  Regression test for issue 17645.
+get never => new DateTime.now().millisecondsSinceEpoch == 0;
+
+class A {
+  var foo;
+  A(this.foo);
+}
+
+var log = [];
+
+test1(a, xs) {
+  // Called with a = [null|exact=A]
+  log.clear();
+  for (var x in xs) {
+    if (a != null) {
+      log.add('${a.foo}.$x'); // a.foo must not be hoisted
+    }
+  }
+  return '$log';
+}
+
+test2(a, xs) {
+  // Called with a = [exact=A]
+  log.clear();
+  for (var x in xs) {
+    if (a != null) {
+      log.add('${a.foo}.$x'); // a.foo may be hoisted
+    }
+  }
+  return '$log';
+}
+
+test3(a, xs) {
+  // Called with a = [null|exact=A]
+  log.clear();
+  for (var x in xs) {
+    if (a is A) {
+      log.add('${a.foo}.$x'); // a.foo must not be hoisted
+    }
+  }
+  return '$log';
+}
+
+test4(a, xs) {
+  // Called with a = [exact=A]
+  log.clear();
+  for (var x in xs) {
+    if (a is A) {
+      log.add('${a.foo}.$x'); // a.foo may be hoisted
+    }
+  }
+  return '$log';
+}
+
+main() {
+  var a1 = new A('a1');
+  var a2 = new A('a2');
+
+  Expect.equals('[a1.11]', test1(a1, [11]));
+  Expect.equals('[]', test1(null, [11]));
+
+  Expect.equals('[a1.22]', test2(a1, [22]));
+  Expect.equals('[a2.22]', test2(a2, [22]));
+
+  Expect.equals('[a1.33]', test3(a1, [33]));
+  Expect.equals('[]', test3(null, [2]));
+
+  Expect.equals('[a1.44]', test4(a1, [44]));
+  Expect.equals('[a2.44]', test4(a2, [44]));
+}
diff --git a/tests/dart2js/17856_test.dart b/tests/dart2js/17856_test.dart
new file mode 100644
index 0000000..aa5a243
--- /dev/null
+++ b/tests/dart2js/17856_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2014, 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";
+
+// Regression test for Issue 17856.
+
+void main() {
+  var all = {"a": new A(), "b": new B()};
+
+  A a = all["a"];
+  a.load();
+}
+
+class A {
+  Loader _loader = new Loader();
+
+  load() => _loader.loadAll({'a1': {}});
+}
+
+class B {
+  Loader _loader = new Loader();
+
+  load() => _loader.loadAll({
+        'a2': new DateTime.now(),
+      });
+}
+
+class Loader {
+  loadAll(Map assets) {
+    for (String key in assets.keys) {
+      Expect.isTrue(assets[key] is Map);
+    }
+  }
+}
diff --git a/tests/dart2js/18383_test.dart b/tests/dart2js/18383_test.dart
new file mode 100644
index 0000000..e15526b
--- /dev/null
+++ b/tests/dart2js/18383_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for http://dartbug.com/18383
+
+import "package:expect/expect.dart";
+
+class F {
+  call() => (x) => new G(x.toInt());
+}
+
+class G {
+  var z;
+  G(this.z);
+  foo() => '$this.foo';
+  toString() => 'G($z)';
+}
+
+main() {
+  var f = new F();
+  var m = f();
+  Expect.equals(m(66).foo(), "G(66).foo");
+}
diff --git a/tests/dart2js/19191_test.dart b/tests/dart2js/19191_test.dart
new file mode 100644
index 0000000..cf2bd24
--- /dev/null
+++ b/tests/dart2js/19191_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for http://dartbug.com/19191
+
+class A {
+  var method;
+
+  noSuchMethod(Invocation invocation) {
+    if (invocation.isGetter) {
+      return method;
+    } else if (invocation.isSetter) {
+      method = invocation.positionalArguments[0];
+      return null;
+    } else if (invocation.isMethod) {
+      return Function.apply(
+          method, invocation.positionalArguments, invocation.namedArguments);
+    } else {
+      throw new NoSuchMethodError(this, invocation.memberName,
+          invocation.positionalArguments, invocation.namedArguments);
+    }
+  }
+}
+
+void main() {
+  dynamic a = new A();
+  a.closure_fails = (String str) {
+    return str.toUpperCase();
+  };
+  print(a.closure_fails("Hello World"));
+}
diff --git a/tests/dart2js/21351_test.dart b/tests/dart2js/21351_test.dart
new file mode 100644
index 0000000..f3c0e53
--- /dev/null
+++ b/tests/dart2js/21351_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2014, 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 A {
+  bool _flag = false;
+  bool get flag => _flag;
+}
+
+main() {
+  var value1, value2;
+  var count = 0;
+
+  for (var x = 0; x < 10; x++) {
+    var otherThing = new A();
+    for (var dummy = 0; dummy < x; dummy++) {
+      otherThing._flag = !otherThing._flag;
+    }
+
+    value1 = value2;
+    value2 = otherThing;
+
+    if (value1 == null) continue;
+
+    if (value1.flag) count++;
+  }
+
+  if (count == 0) throw "FAIL";
+}
diff --git a/tests/dart2js/21579_test.dart b/tests/dart2js/21579_test.dart
new file mode 100644
index 0000000..a7b3079
--- /dev/null
+++ b/tests/dart2js/21579_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for http://dartbug.com/21579
+//
+// Fails for --trust-type-annotations:
+//
+// test.py -mrelease -cdart2js -rd8 --dart2js-options='--trust-type-annotations' dart2js_extra/21579_test
+
+import 'package:expect/expect.dart';
+
+main() {
+  var a = new List.generate(100, (i) => i);
+  a.sort((a, b) => 10000000000000 * a.compareTo(b));
+  Expect.equals(0, a.first);
+  Expect.equals(99, a.last);
+}
diff --git a/tests/dart2js/22487_test.dart b/tests/dart2js/22487_test.dart
new file mode 100644
index 0000000..4bf5426
--- /dev/null
+++ b/tests/dart2js/22487_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/22487
+
+import 'package:expect/expect.dart';
+
+divIsInt(a, b) => (a / b) is int;
+
+main() {
+  Expect.isFalse((divIsInt)(10, 3));
+}
diff --git a/tests/dart2js/22776_test.dart b/tests/dart2js/22776_test.dart
new file mode 100644
index 0000000..135f505
--- /dev/null
+++ b/tests/dart2js/22776_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/22776
+
+import "package:expect/expect.dart";
+
+class A {}
+
+main() {
+  try {
+    print(id(new Duration(milliseconds: 10)));
+    print(id(3) ~/ new A());
+  } catch (e) {
+    print("Error '$e' ${e.runtimeType}");
+  }
+}
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+id(x) => x;
diff --git a/tests/dart2js/22868_test.dart b/tests/dart2js/22868_test.dart
new file mode 100644
index 0000000..71907def
--- /dev/null
+++ b/tests/dart2js/22868_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/22868 and http://dartbug.com/22895
+// Ensure that the closure tracer properly handles await.
+
+main() async {
+  var closures = [(x, y) => x + y];
+  print(((await closures)[0])(4, 2));
+}
diff --git a/tests/dart2js/22917_test.dart b/tests/dart2js/22917_test.dart
new file mode 100644
index 0000000..35a629a
--- /dev/null
+++ b/tests/dart2js/22917_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/22917
+
+import 'package:expect/expect.dart';
+
+m(x) => print('x: $x');
+
+test() => Function.apply(m, []);
+
+main() {
+  Expect.throws(test);
+}
diff --git a/tests/dart2js/23404_test.dart b/tests/dart2js/23404_test.dart
new file mode 100644
index 0000000..699e63d
--- /dev/null
+++ b/tests/dart2js/23404_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23404
+//
+// Dart2js crashed when the global metadata had escaped characters. That
+// happens, for example, when tearing off a function that uses a default
+// argument containing escape characters.
+import 'package:expect/expect.dart';
+
+foo([a = '\u00a0']) => a;
+bar() => '';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  Expect.equals('\u00a0', confuse(foo)());
+  Expect.equals('', confuse(bar)());
+}
diff --git a/tests/dart2js/23432_test.dart b/tests/dart2js/23432_test.dart
new file mode 100644
index 0000000..bbb32ff
--- /dev/null
+++ b/tests/dart2js/23432_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23432.  Test that the receiver of a
+// NoSuchMethodError is correct on an intercepted method.  The bug (issue 23432)
+// is that the interceptor is captured instead of the receiver.
+
+import 'package:expect/expect.dart';
+
+class N {
+  noSuchMethod(i) {
+    print('x');
+    return 42;
+  }
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+get NEVER => false;
+
+main() {
+  dynamic c = 12345;
+  if (NEVER) c = new N();
+  var e;
+  try {
+    c
+      ..toString()
+      ..add(88);
+  } catch (ex) {
+    e = ex;
+  }
+  var s = e.toString();
+  Expect.isTrue(s.contains('$c'), 'Text "$s" should contain "$c"');
+}
diff --git a/tests/dart2js/23486_helper.dart b/tests/dart2js/23486_helper.dart
new file mode 100644
index 0000000..c15d826
--- /dev/null
+++ b/tests/dart2js/23486_helper.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2015, 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.
+
+int x = 1;
diff --git a/tests/dart2js/23486_test.dart b/tests/dart2js/23486_test.dart
new file mode 100644
index 0000000..1d41e26
--- /dev/null
+++ b/tests/dart2js/23486_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23486
+//
+// Dart2js used to crash when using `super` and prefixes inside parenthesized
+// expressions.
+import 'package:expect/expect.dart';
+
+import '23486_helper.dart' as p;
+
+class B {
+  var field = 1;
+}
+
+class A extends B {
+  m() {
+    (super).field = 1; //# 01: compile-time error
+  }
+}
+
+class C {
+  C();
+  C.name();
+}
+
+class D extends C {
+  D() : super();
+  D.name() : (super).name(); //# 02: compile-time error
+}
+
+main() {
+  Expect.throws(new A().m); //       //# 01: continued
+  Expect.throws(() => new D.name()); //# 02: continued
+  Expect.throws(() => (p).x); //     //# 03: compile-time error
+}
diff --git a/tests/dart2js/23804_test.dart b/tests/dart2js/23804_test.dart
new file mode 100644
index 0000000..32bb00b
--- /dev/null
+++ b/tests/dart2js/23804_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23804
+//
+// Inference incorrectly assumed that `any` and `every` didn't escape the values
+// in the collections.
+
+import 'package:expect/expect.dart';
+
+test(n) => n == 1;
+bool run(f(dynamic)) => f(1);
+main() {
+  Expect.equals([test].any(run), true);
+}
diff --git a/tests/dart2js/23828_test.dart b/tests/dart2js/23828_test.dart
new file mode 100644
index 0000000..e2fbf7d
--- /dev/null
+++ b/tests/dart2js/23828_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23828
+// Used to fail when methods contain a name starting with `get`
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class MA {
+  noSuchMethod(i) => Expect.equals(i.positionalArguments.length, 1);
+}
+
+main() {
+  confuse(new MA()).getFoo('a');
+}
diff --git a/tests/dart2js/26243_test.dart b/tests/dart2js/26243_test.dart
new file mode 100644
index 0000000..7f09cf3
--- /dev/null
+++ b/tests/dart2js/26243_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, 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';
+
+var trace = [];
+void write(String s, int a, int b) {
+  trace.add("$s $a $b");
+}
+
+void foo() {
+  var i = 0;
+  write("foo", i, i += 1);
+}
+
+void bar() {
+  var i = 0;
+  try {
+    write("bar", i, i += 1);
+  } catch (_) {}
+}
+
+void baz() {
+  var i = 0;
+  write("baz-notry", i, i += 1);
+
+  i = 0;
+  try {
+    write("baz-try", i, i += 1);
+  } catch (_) {}
+}
+
+void main() {
+  foo();
+  bar();
+  baz();
+  Expect.listEquals(
+      ['foo 0 1', 'bar 0 1', 'baz-notry 0 1', 'baz-try 0 1'], trace);
+}
diff --git a/tests/dart2js/27198_test.dart b/tests/dart2js/27198_test.dart
new file mode 100644
index 0000000..721476e
--- /dev/null
+++ b/tests/dart2js/27198_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, 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.
+
+// From co19/Language/Types/Parameterized_Types/Actual_Type_of_Declaration/actual_type_t05.dart
+import "package:expect/expect.dart";
+
+class C<T> {
+  List<T> f() => [];
+}
+
+main() {
+  C c = new C();
+  Expect.isTrue(c.f() is List<dynamic>);
+}
diff --git a/tests/dart2js/27199_test.dart b/tests/dart2js/27199_test.dart
new file mode 100644
index 0000000..b2d2fd5
--- /dev/null
+++ b/tests/dart2js/27199_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for http://dartbug.com/27199 in --checked mode.
+
+// Typedefs must be unaliased at some point before codegen to have the correct
+// number of references.  The unaliased type of ItemListFilter<T> has two
+// references to T: (Iterable<T>) -> Iterable<T>.
+
+import 'package:expect/expect.dart';
+
+typedef Iterable<T> ItemListFilter<T>(Iterable<T> items);
+
+class C<T> {
+  Map<String, ItemListFilter<T>> f = {};
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  dynamic c = new C();
+  dynamic a = 12;
+  if (confuse(true)) a = <String, ItemListFilter>{};
+  c.f = a;
+}
diff --git a/tests/dart2js/27323_test.dart b/tests/dart2js/27323_test.dart
new file mode 100644
index 0000000..c8439ec
--- /dev/null
+++ b/tests/dart2js/27323_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class C {
+  noSuchMethod(i) => i.typeArguments;
+}
+
+class D {
+  foo<U, V>() => [U, V];
+}
+
+@pragma('dart2js:noInline')
+test(dynamic x) {
+  dynamic typeArguments = x.foo<int, String>();
+  Expect.equals(int, typeArguments[0]);
+  Expect.equals(String, typeArguments[1]);
+}
+
+main() {
+  test(new C());
+  test(new D()); //# 01: ok
+}
diff --git a/tests/dart2js/27354_test.dart b/tests/dart2js/27354_test.dart
new file mode 100644
index 0000000..942dc49
--- /dev/null
+++ b/tests/dart2js/27354_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for Issue 27354.
+
+int total = 1;
+void inc() => total++ < 10 ? null : throw "do not loop forever!";
+
+void main() {
+  // Problem was moving the load of 'total' inside the loop.
+  int count = null ?? total;
+  for (int i = 0; i < count; i++) inc();
+}
diff --git a/tests/dart2js/28749_test.dart b/tests/dart2js/28749_test.dart
new file mode 100644
index 0000000..0735aa7
--- /dev/null
+++ b/tests/dart2js/28749_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2017, 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for http://dartbug.com/28749.
+//
+// This would crash at compile time because inner typedefs remain after calling
+// [type.unalias].  Expanding the typedef causes the inputs to be used multiple
+// types, breaking the invariant of HTypeInfoExpression that the type variable
+// occurrences correspond to inputs.
+
+import 'package:expect/expect.dart';
+
+typedef void F<T>(T value);
+typedef F<U> Converter<U>(F<U> function);
+typedef Converter<V> ConvertFactory<V>(int input);
+
+class B<W> {
+  final field = new Wrap<ConvertFactory<W>>();
+  @pragma('dart2js:noInline')
+  B();
+}
+
+class Wrap<X> {
+  @pragma('dart2js:noInline')
+  Wrap();
+}
+
+foo<Y>(int x) {
+  if (x == 0)
+    return new Wrap<ConvertFactory<Y>>().runtimeType;
+  else
+    return new B<Y>().field.runtimeType;
+}
+
+void main() {
+  var name = '${Wrap}';
+  if ('$Object' != 'Object') return; // minified
+
+  Expect.equals(
+    'Wrap<(int) => ((int) => void) => (int) => void>',
+    '${new B<int>().field.runtimeType}',
+  );
+  Expect.equals(
+    'Wrap<(int) => ((bool) => void) => (bool) => void>',
+    '${new B<bool>().field.runtimeType}',
+  );
+
+  Expect.equals(
+    'Wrap<(int) => ((int) => void) => (int) => void>',
+    '${foo<int>(0)}',
+  );
+  Expect.equals(
+    'Wrap<(int) => ((String) => void) => (String) => void>',
+    '${foo<String>(1)}',
+  );
+}
diff --git a/tests/dart2js/28919_test.dart b/tests/dart2js/28919_test.dart
new file mode 100644
index 0000000..e9b7106
--- /dev/null
+++ b/tests/dart2js/28919_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2017, 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.
+
+// Regression test for http://dartbug.com/28919.
+//
+// This would crash at runtime because the type of closure parameter 'x' was
+// empty, leading to bad codegen. The empty type was due to a tracing bug that
+// failed to escape the closure when stored into the list which was not traced
+// as a container.
+
+import 'package:expect/expect.dart';
+
+int foo([List _methods = const []]) {
+  final methods = new List.from(_methods);
+  for (int i = 0; i < 3; i++) {
+    methods.add((int x) => x + i);
+  }
+  return methods[0](499);
+}
+
+main() {
+  Expect.equals(499, foo());
+}
diff --git a/tests/dart2js/29130_test.dart b/tests/dart2js/29130_test.dart
new file mode 100644
index 0000000..e4daa34
--- /dev/null
+++ b/tests/dart2js/29130_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, 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.
+
+/// This is a regression test from issue #29310. The global type-inferrer does
+/// tracing of closures including allocated classes that implement a `call`
+/// method. We incorrectly considered also classes with invoked factory
+/// constructors, even if those were only abstract interfaces or mixins that
+/// weren't actually allocated explicitly.
+library regression_29130;
+
+main() {
+  new B();
+  new C();
+}
+
+class A {
+  call() {}
+}
+
+// interface scenario: we shouldn't trace B
+abstract class B implements A {
+  factory B() => null;
+}
+
+// mixin scenario: we should trace C, but we should trace _C
+abstract class C implements A {
+  factory C() => new D();
+}
+
+class D = A with C;
diff --git a/tests/dart2js/31803_test.dart b/tests/dart2js/31803_test.dart
new file mode 100644
index 0000000..03c1f7c
--- /dev/null
+++ b/tests/dart2js/31803_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+// Tests that the compiler doesn't crash on an annotation with fields
+
+class Annotation {
+  final Object obj;
+  const Annotation(this.obj);
+}
+
+class UnusedClass {
+  final Object x;
+
+  const factory UnusedClass(UnusedArgumentClass x) = UnusedClass._;
+
+  const UnusedClass._(this.x);
+}
+
+class UnusedArgumentClass {
+  const UnusedArgumentClass();
+}
+
+@Annotation(const UnusedClass(arg))
+class A {}
+
+const arg = const UnusedArgumentClass();
+
+main() {
+  var a = new A();
+  Expect.isTrue(a != null);
+}
diff --git a/tests/dart2js/32770a_test.dart b/tests/dart2js/32770a_test.dart
new file mode 100644
index 0000000..24aeb60
--- /dev/null
+++ b/tests/dart2js/32770a_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'package:expect/expect.dart';
+
+dynamic f;
+dynamic g;
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+class Class<T> {
+  void Function(E) method<E, F extends E>(void Function(F) callback) {
+    return (E event) {
+      g = () => callback(event as F);
+    };
+  }
+}
+
+main() {
+  f = new Class<String>().method<A, B>((o) => print(o));
+  f(new B());
+  g();
+  f(new C());
+  Expect.throws(() => g(), (_) => true);
+}
diff --git a/tests/dart2js/32770b_test.dart b/tests/dart2js/32770b_test.dart
new file mode 100644
index 0000000..f58bcf5
--- /dev/null
+++ b/tests/dart2js/32770b_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'package:expect/expect.dart';
+
+dynamic f;
+dynamic g;
+
+class A {}
+
+class B extends A {}
+
+class C extends A {}
+
+class Class<T> {
+  void Function(E) method<E, F extends E>(bool Function(bool) callback) {
+    return (E event) {
+      g = () => callback(event is F);
+    };
+  }
+}
+
+main() {
+  f = new Class<String>().method<A, B>((o) => o);
+  f(new B());
+  Expect.isTrue(g());
+  f(new C());
+  Expect.isFalse(g());
+}
diff --git a/tests/dart2js/32770c_test.dart b/tests/dart2js/32770c_test.dart
new file mode 100644
index 0000000..15ac166
--- /dev/null
+++ b/tests/dart2js/32770c_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32770.
+
+import 'dart:async' show Future;
+
+A<J> futureToA<T, J>(Future<T> future, [J wrapValue(T value)]) {
+  return new A<J>(
+    (void resolveFn(J value), void rejectFn(error)) {
+      future.then((value) {
+        dynamic wrapped;
+        if (wrapValue != null) {
+          wrapped = wrapValue(value);
+        } else if (value != null) {
+          wrapped = value;
+        }
+        resolveFn(wrapped);
+      }).catchError((error) {
+        rejectFn(error);
+      });
+    },
+  );
+}
+
+class A<X> {
+  var x;
+
+  A(this.x);
+}
+
+main() {
+  print(futureToA);
+}
diff --git a/tests/dart2js/32774_test.dart b/tests/dart2js/32774_test.dart
new file mode 100644
index 0000000..fbf3199
--- /dev/null
+++ b/tests/dart2js/32774_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+T id<T>(T t) => t;
+
+class C<T> {
+  final T t;
+  final T Function(T) f;
+
+  const C(this.t, this.f);
+}
+
+class D<T> {
+  final T t;
+  final T Function(T) f;
+
+  const D(this.t, this.f);
+}
+
+const C<int> c1a = const C<int>(0, id);
+const C<int> c1b = const C<int>(0, id);
+
+const C<double> c2a = const C<double>(0.5, id);
+const C<double> c2b = const C<double>(0.5, id);
+
+const D<int> d = const D<int>(0, id);
+
+main() {
+  Expect.equals(c1a, c1b);
+  Expect.isTrue(identical(c1a, c1b));
+  Expect.equals(c1a.f, c1b.f);
+
+  Expect.equals(c2a, c2b);
+  Expect.isTrue(identical(c2a, c2b));
+  Expect.equals(c2a.f, c2b.f);
+
+  Expect.notEquals(c1a, c2a);
+  Expect.notEquals(c1a.f, c2a.f);
+
+  Expect.notEquals(c1a, d);
+  Expect.isTrue(identical(c1a.f, d.f));
+}
diff --git a/tests/dart2js/32828_test.dart b/tests/dart2js/32828_test.dart
new file mode 100644
index 0000000..c56a904
--- /dev/null
+++ b/tests/dart2js/32828_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+class A {
+  void m2<T>(void Function(T) f, [a]) {}
+}
+
+main() => new A().m2<String>(null);
diff --git a/tests/dart2js/32853_test.dart b/tests/dart2js/32853_test.dart
new file mode 100644
index 0000000..ccf8dab
--- /dev/null
+++ b/tests/dart2js/32853_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+// Regression test for issue 32853.
+
+
+int foo<T extends Comparable<T>>(T a, T b) => a.compareTo(b);
+
+main() {
+  int Function<T extends Comparable<T>>(T, T) f = foo;
+  print(f<num>(1, 2));
+}
\ No newline at end of file
diff --git a/tests/dart2js/32928_test.dart b/tests/dart2js/32928_test.dart
new file mode 100644
index 0000000..549909b
--- /dev/null
+++ b/tests/dart2js/32928_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+/// Regression test for issue 32928.
+
+abstract class A<T> {
+  set f(T value) {
+    print(value);
+  }
+}
+
+abstract class B extends A {}
+
+class C extends B {
+  m(value) => super.f = value;
+}
+
+main() {
+  new C().m(null);
+}
diff --git a/tests/dart2js/32969_test.dart b/tests/dart2js/32969_test.dart
new file mode 100644
index 0000000..8599b3f
--- /dev/null
+++ b/tests/dart2js/32969_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+@JS()
+library foo;
+
+import 'package:expect/expect.dart';
+import 'package:js/js.dart';
+
+@JS()
+@anonymous
+class A<T> {
+  external factory A();
+}
+
+class B<T> {}
+
+@JS()
+@anonymous
+class C implements B<int> {
+  external factory C();
+}
+
+class D<T> {}
+
+@JS()
+@anonymous
+class E implements B<String> {
+  external factory E();
+}
+
+main() {
+  test(new A<int>());
+  test(new A<String>());
+  test(new C());
+  test(new E());
+}
+
+test(o) {
+  Expect.isTrue(o is A<int>, "Expected $o to be A<int>");
+  Expect.isTrue(o is A<String>, "Expected $o to be A<String>");
+
+  Expect.isTrue(o is B<int>, "Expected $o to be B<int>");
+  Expect.isTrue(o is B<String>, "Expected $o to be B<String>");
+
+  Expect.isFalse(o is D<int>, "Expected $o not to be D<int>");
+}
diff --git a/tests/dart2js/32997a_lib.dart b/tests/dart2js/32997a_lib.dart
new file mode 100644
index 0000000..54e4f54
--- /dev/null
+++ b/tests/dart2js/32997a_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+T getFoo<T>(T v) => v;
+
+typedef dynamic G<T>(T v);
+
+m(int x, {G<int> f: getFoo}) {
+  print(f(x));
+}
diff --git a/tests/dart2js/32997a_test.dart b/tests/dart2js/32997a_test.dart
new file mode 100644
index 0000000..4e2b00a
--- /dev/null
+++ b/tests/dart2js/32997a_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import '32997a_lib.dart' deferred as b;
+
+main() async {
+  await b.loadLibrary();
+  print(b.m(3));
+}
diff --git a/tests/dart2js/32997b_lib.dart b/tests/dart2js/32997b_lib.dart
new file mode 100644
index 0000000..62eee11
--- /dev/null
+++ b/tests/dart2js/32997b_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+T getFoo<T>(T v) => v;
+
+typedef dynamic G<T>(T v);
+
+m<T>(T x, {G<T> f: getFoo}) {
+  print(f);
+}
diff --git a/tests/dart2js/32997b_test.dart b/tests/dart2js/32997b_test.dart
new file mode 100644
index 0000000..7783285
--- /dev/null
+++ b/tests/dart2js/32997b_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import '32997b_lib.dart' deferred as b; //# 01: compile-time error
+
+main() async {
+  await b.loadLibrary(); //# 01: continued
+  print(b.m<int>(3)); //# 01: continued
+}
diff --git a/tests/dart2js/33296_test.dart b/tests/dart2js/33296_test.dart
new file mode 100644
index 0000000..7d06619
--- /dev/null
+++ b/tests/dart2js/33296_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+import 'dart:js';
+import 'dart:html'; // TODO(33316): Remove.
+import "package:expect/expect.dart";
+
+main() {
+  var f = () => [];
+  Expect.isTrue(f is List Function());
+  Expect.isFalse(f is int Function(int));
+
+  var g = allowInterop(f);
+  // g is inferred to have the same type as f.
+  Expect.isTrue(g is List Function());
+  // The JavaScriptFunction matches any function type.
+  Expect.isTrue(g is int Function(int));
+
+  if (false) new DivElement(); // TODO(33316): Remove.
+}
diff --git a/tests/dart2js/33572_test.dart b/tests/dart2js/33572_test.dart
new file mode 100644
index 0000000..2721bf7
--- /dev/null
+++ b/tests/dart2js/33572_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+// Regression test for issue 32853.
+
+import "package:expect/expect.dart";
+
+class A {
+  final x = null;
+  final y;
+  const A(this.y);
+}
+
+main() {
+  var a1 = new A(1);
+  var a2 = const A(2);
+  test(a1, null, 1);
+  test(a2, null, 2);
+}
+
+@pragma('dart2js:noInline')
+test(a, expectedX, expectedY) {
+  Expect.equals(expectedX, a.x);
+  Expect.equals(expectedY, a.y);
+}
diff --git a/tests/dart2js/33_test.dart b/tests/dart2js/33_test.dart
new file mode 100644
index 0000000..0d55209
--- /dev/null
+++ b/tests/dart2js/33_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+void main() {
+  print(3 + 4 * 10 - 8 / 2 - 19 ~/ 3);
+}
diff --git a/tests/dart2js/34156_test.dart b/tests/dart2js/34156_test.dart
new file mode 100644
index 0000000..f4dbb81
--- /dev/null
+++ b/tests/dart2js/34156_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:tryInline')
+// This function should not be inlined. Multiple returns and try-catch cannot
+// currently be inlined correctly.
+method() {
+  try {
+    thrower();
+    return 'x';
+  } catch (e) {
+    print(e);
+    return 'y';
+  }
+  return 'z';
+}
+
+thrower() {
+  if (g) throw 123;
+}
+
+var g;
+main() {
+  g = false;
+  var x1 = method();
+  Expect.equals('x', x1);
+
+  g = true;
+  var x2 = method();
+  Expect.equals('y', x2);
+}
diff --git a/tests/dart2js/34701_test.dart b/tests/dart2js/34701_test.dart
new file mode 100644
index 0000000..708024f
--- /dev/null
+++ b/tests/dart2js/34701_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2017, 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+/// Regression test for issue 34701.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+class A {
+  @pragma('dart2js:noInline') //# 01: ok
+  Future<T> _foo<T>(FutureOr<T> Function() f) async {
+    return await f();
+  }
+
+  @pragma('dart2js:noInline') //# 01: continued
+  Future<String> get m async => _foo(() => "a");
+}
+
+class M {}
+
+class B extends A with M {
+  @pragma('dart2js:noInline') //# 01: continued
+  Future<T> _foo<T>(FutureOr<T> Function() f) => super._foo(f);
+}
+
+main() async {
+  var b = new B();
+  print(b.m.runtimeType);
+  print((await b.m).runtimeType);
+  Expect.isTrue(b.m is Future<String>);
+  Expect.isTrue((await b.m) is String);
+}
diff --git a/tests/dart2js/35341_test.dart b/tests/dart2js/35341_test.dart
new file mode 100644
index 0000000..80310f0
--- /dev/null
+++ b/tests/dart2js/35341_test.dart
@@ -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.
+
+// Regression test for issue 35341.
+
+import "dart:async";
+
+@pragma('dart2js:disableFinal')
+void main() {
+  FutureOr<int> i = new Future<int>.value(0);
+  print(i.runtimeType);
+}
diff --git a/tests/dart2js/35356_test.dart b/tests/dart2js/35356_test.dart
new file mode 100644
index 0000000..13dc082
--- /dev/null
+++ b/tests/dart2js/35356_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+main() {
+  bool b = true & true;
+  b |= true;
+  b = b ^ b;
+  print(b);
+}
diff --git a/tests/dart2js/35853_test.dart b/tests/dart2js/35853_test.dart
new file mode 100644
index 0000000..3fe033ac
--- /dev/null
+++ b/tests/dart2js/35853_test.dart
@@ -0,0 +1,34 @@
+// 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';
+
+typedef F1 = int Function(int);
+typedef F2 = int Function(int);
+typedef F3 = int Function(double);
+
+@pragma('dart2js:noInline')
+id(x) => x;
+
+main() {
+  var f1 = F1;
+  var f2 = F2;
+  var f3 = F3;
+  Expect.isTrue(f1 == f2);
+  var result12 = identical(f1, f2);
+  Expect.isFalse(f1 == f3);
+  Expect.isFalse(identical(f1, f3));
+  Expect.isFalse(f2 == f3);
+  Expect.isFalse(identical(f2, f3));
+
+  var g1 = id(F1);
+  var g2 = id(F2);
+  var g3 = id(F3);
+  Expect.isTrue(g1 == g2);
+  Expect.equals(result12, identical(g1, g2));
+  Expect.isFalse(g1 == g3);
+  Expect.isFalse(identical(g1, g3));
+  Expect.isFalse(g2 == g3);
+  Expect.isFalse(identical(g2, g3));
+}
diff --git a/tests/dart2js/35965a_test.dart b/tests/dart2js/35965a_test.dart
new file mode 100644
index 0000000..56a3d7a
--- /dev/null
+++ b/tests/dart2js/35965a_test.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.
+
+// Regression test for issue 35965.
+//
+// The combination of generator bodies on mixin methods with super-calls caused
+// various kinds of broken generated JavaScript.
+//
+//  - The generator body name had unescaped '&' symbols from the Kernel
+//    synthesized super-mixin-application class.
+//  - The super-mixin-application class was missing the generator body because
+//    it did not expect injected members.
+
+import 'dart:async';
+
+abstract class II {
+  bar();
+}
+
+mixin M on II {
+  // The parameter type check causes the generator to have a body.
+  //
+  // The super call causes the body to be on the super mixin application.
+  //
+  // The super call causes the body to have a name depending on the super mixin
+  // application name.
+  Future<T> foo<T>(T a) async {
+    super.bar();
+    return a;
+  }
+
+  // The parameter type check causes the generator to have a body.
+  //
+  // The super call causes 'fred' to be on the super mixin application.
+  //
+  // The super call causes the closure's call method's generator to have a name
+  // depending on the super mixin application name.
+  fred<T>() => (T a) async {
+        super.bar();
+        return a;
+      };
+}
+
+class BB implements II {
+  bar() {
+    print('BB.bar');
+  }
+}
+
+class UU extends BB with M {}
+
+main() async {
+  print('hello');
+  var uu = UU();
+
+  print(await uu.foo<int>(1));
+  print(await uu.foo<String>("one"));
+
+  print(await uu.fred<int>()(1));
+  print(await uu.fred<String>()("uno"));
+}
diff --git a/tests/dart2js/37494_test.dart b/tests/dart2js/37494_test.dart
new file mode 100644
index 0000000..d2d8283
--- /dev/null
+++ b/tests/dart2js/37494_test.dart
@@ -0,0 +1,52 @@
+// 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.
+
+// Regression test for http://dartbug.com/37494
+
+import 'dart:collection';
+import 'dart:typed_data';
+
+void main() {
+  final u8 = Uint8List(10);
+  // Uint8List.{sort,join} are ListMixin.{sort,join} which takes and explicit
+  // receiver because Uint8List is an intercepted type.
+  u8.sort();
+  print(u8.join());
+
+  final list = Example();
+  list.addAll([1, 2, 3]);
+  list.sort();
+  print(list.join());
+}
+
+class Example<T> extends ListBase<T> {
+  final _list = <T>[];
+
+  @override
+  operator [](int index) => _list[index];
+
+  @override
+  operator []=(int index, T value) {
+    _list[index] = value;
+  }
+
+  @override
+  int get length => _list.length;
+
+  @override
+  set length(int value) {
+    _list.length = value;
+  }
+
+  @override
+  String join([String separator = ""]) {
+    return super.join(separator); // This super call had bad dummy interceptor.
+  }
+
+  @override
+  @pragma('dart2js:noInline')
+  void sort([int compare(T a, T b)]) {
+    super.sort(compare); // This super call had bad dummy interceptor.
+  }
+}
diff --git a/tests/dart2js/37576_test.dart b/tests/dart2js/37576_test.dart
new file mode 100644
index 0000000..b243963
--- /dev/null
+++ b/tests/dart2js/37576_test.dart
@@ -0,0 +1,14 @@
+// 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:js/js.dart';
+
+@JS('jsFun')
+external set jsFun(Function fun);
+
+void main() {
+  jsFun = allowInterop(dartFun);
+}
+
+void dartFun() {}
diff --git a/tests/dart2js/38005_test.dart b/tests/dart2js/38005_test.dart
new file mode 100644
index 0000000..2789b31
--- /dev/null
+++ b/tests/dart2js/38005_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.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+int foo<T>() {
+  switch (T) {
+    case A:
+      return 42;
+    default:
+      return -1;
+  }
+}
+
+void main() {
+  Expect.equals(42, foo<A>());
+  Expect.equals(-1, foo<int>());
+}
diff --git a/tests/dart2js/38949_test.dart b/tests/dart2js/38949_test.dart
new file mode 100644
index 0000000..4b0ceba
--- /dev/null
+++ b/tests/dart2js/38949_test.dart
@@ -0,0 +1,34 @@
+// 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';
+
+abstract class Foo<A, B> {
+  bool pip(o);
+}
+
+class Bar<X, Y> implements Foo<X, Y> {
+  bool pip(o) => o is Y;
+}
+
+class Baz<U, V> implements Foo<U, V> {
+  bool pip(o) => true;
+}
+
+void main() {
+  Expect.listEquals([], test(1));
+  Expect.listEquals([true, false], test(Bar<String, int>()));
+  Expect.listEquals([true, true], test(Baz<String, int>()));
+}
+
+@pragma('dart2js:noInline')
+List<bool> test(dynamic p) {
+  List<bool> result = [];
+  if (p is Foo) {
+    for (var o in [1, 'x']) {
+      result.add(p.pip(o));
+    }
+  }
+  return result;
+}
diff --git a/tests/dart2js/3_test.dart b/tests/dart2js/3_test.dart
new file mode 100644
index 0000000..520d8a8
--- /dev/null
+++ b/tests/dart2js/3_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+int main() {
+  return 3;
+}
diff --git a/tests/dart2js/40152a_test.dart b/tests/dart2js/40152a_test.dart
new file mode 100644
index 0000000..76e0698
--- /dev/null
+++ b/tests/dart2js/40152a_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Partial regression test for #40152.
+
+import 'package:js/js.dart';
+import 'package:expect/expect.dart';
+
+@JS()
+external dynamic eval(String s);
+
+main() {
+  // Regular JS-interop Array.
+  var a1 = eval('["hello","world"]');
+
+  // Array with $ti set to something.
+  // TODO(40175): Update this test if the access is changed.
+  var a2 = eval(r'(function(){var x =["hi","bye"]; x.$ti=[666]; return x})()');
+
+  var b1 = List.of(a1.cast<String>());
+  Expect.listEquals(['hello', 'world'], a1);
+  Expect.listEquals(['hello', 'world'], b1);
+
+  var b2 = List.of(a2.cast<String>());
+  Expect.listEquals(['hi', 'bye'], a2);
+  Expect.listEquals(['hi', 'bye'], b2);
+}
diff --git a/tests/dart2js/40902_test.dart b/tests/dart2js/40902_test.dart
new file mode 100644
index 0000000..d62c769
--- /dev/null
+++ b/tests/dart2js/40902_test.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.
+
+import "package:expect/expect.dart";
+
+class Foo {
+  int f() => 42;
+}
+
+class Bar extends Foo {
+  void test() {
+    Expect.isFalse(super.f is int);
+  }
+}
+
+void main() {
+  Bar().test();
+}
diff --git a/tests/dart2js/43_test.dart b/tests/dart2js/43_test.dart
new file mode 100644
index 0000000..2a85bb1
--- /dev/null
+++ b/tests/dart2js/43_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+void main() {
+  print(3 + 4 * 10);
+}
diff --git a/tests/dart2js/7_test.dart b/tests/dart2js/7_test.dart
new file mode 100644
index 0000000..742ca65
--- /dev/null
+++ b/tests/dart2js/7_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+void main() {
+  print(3 + 4);
+}
diff --git a/tests/dart2js/881_test.dart b/tests/dart2js/881_test.dart
new file mode 100644
index 0000000..5be849c
--- /dev/null
+++ b/tests/dart2js/881_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+// Regression test for DartPad issue 881.
+
+@pragma('dart2js:disableFinal')
+void main() {
+  String v = null;
+  print('${v.hashCode}');
+}
diff --git a/tests/dart2js/LayoutTests_fast_mediastream_getusermedia_t01_test.dart b/tests/dart2js/LayoutTests_fast_mediastream_getusermedia_t01_test.dart
new file mode 100644
index 0000000..3ca943b
--- /dev/null
+++ b/tests/dart2js/LayoutTests_fast_mediastream_getusermedia_t01_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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 derived from a broken co19 test
+/// (LayoutTests/fast/mediastream/getusermedia_t01.dart). Caused dart2js to
+/// crash.
+
+foo() {}
+
+gotStream1(stream) {
+  foo()
+      . //# 01: compile-time error
+      .then();
+}
+
+void main() {
+  print(gotStream1);
+}
diff --git a/tests/dart2js/assert_with_message_test.dart b/tests/dart2js/assert_with_message_test.dart
new file mode 100644
index 0000000..993ab11
--- /dev/null
+++ b/tests/dart2js/assert_with_message_test.dart
@@ -0,0 +1,107 @@
+// Copyright (c) 2015, 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";
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+confuse(x) => x;
+
+testFalse(name, fault) {
+  try {
+    fault();
+  } catch (e) {
+    Expect.isTrue(e is AssertionError, '$name: is AssertionError');
+    Expect.isTrue('$e'.contains('Mumble'), '$name: <<$e>> contains "Mumble"');
+    return;
+  }
+  Expect.fail('Expected assert to throw');
+}
+
+test1() {
+  testFalse('constant false', () {
+    assert(false, 'Mumble');
+  });
+}
+
+test2() {
+  testFalse('variable false', () {
+    assert(confuse(false), 'Mumble');
+  });
+}
+
+testTypeErrors() {
+  check(name, fault) {
+    try {
+      fault();
+    } catch (e) {
+      Expect.isTrue(
+          e is TypeError, 'name: <<$e>> (${e.runtimeType}) is TypeError');
+      return;
+    }
+    Expect.fail('Expected assert to throw');
+  }
+
+  check('constant type error', () {
+    assert(null, 'Mumble');
+  });
+  check('variable type error', () {
+    assert(confuse(null), 'Mumble');
+  });
+  check('function type error', () {
+    assert(confuse(() => null), 'Mumble');
+  });
+}
+
+testMessageEffect1() {
+  var v = 1;
+  // Message is not evaluated on succeeding assert.
+  assert(confuse(true), '${v = 123}');
+  Expect.equals(1, v);
+}
+
+testMessageEffect2() {
+  var v = 1;
+  try {
+    // Message is evaluated to produce AssertionError argument on failing
+    // assert.
+    assert(confuse(false), '${v = 123}');
+  } catch (e) {
+    Expect.equals(123, v);
+    Expect.isTrue('$e'.contains('123'), '<<$e>> contains "123"');
+    return;
+  }
+  Expect.fail('Expected assert to throw');
+}
+
+testMessageEffect3() {
+  var v = 1;
+  try {
+    // Message is evaluated to produce AssertionError argument on failing
+    // assert.
+    assert(confuse(() => ++v > 100), '${++v}');
+  } catch (e) {
+    Expect.equals(3, v);
+    Expect.isTrue('$e'.contains('3'), '<<$e>> contains "3"');
+    return;
+  }
+  Expect.fail('Expected assert to throw');
+}
+
+bool get assertionsEnabled {
+  bool b = false;
+  assert((b = true));
+  return b;
+}
+
+main() {
+  if (!assertionsEnabled) return;
+
+  test1();
+  test2();
+  testTypeErrors();
+  testMessageEffect1();
+  testMessageEffect2();
+  testMessageEffect3();
+}
diff --git a/tests/dart2js/async_helper.dart b/tests/dart2js/async_helper.dart
new file mode 100644
index 0000000..b7ee2fd
--- /dev/null
+++ b/tests/dart2js/async_helper.dart
@@ -0,0 +1,24 @@
+// 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.
+
+library async_helper;
+
+/**
+ * Asynchronous test runner.
+ *
+ * [test] is a one argument function which must accept a one argument
+ * function (onDone).  The test function may start asynchronous tasks,
+ * and must call onDone exactly once when all asynchronous tasks have
+ * completed.  The argument to onDone is a bool which indicates
+ * success of the complete test.
+ */
+void asyncTest(void test(void onDone(bool success))) {
+  onDone(bool success) {
+    if (!success) throw 'test failed';
+    print('unittest-suite-success');
+  }
+
+  test(onDone);
+  print('unittest-suite-wait-for-done');
+}
diff --git a/tests/dart2js/async_stacktrace_test.dart b/tests/dart2js/async_stacktrace_test.dart
new file mode 100644
index 0000000..708706b
--- /dev/null
+++ b/tests/dart2js/async_stacktrace_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+class Tracer {
+  final String expected;
+  final String name;
+  String _trace = "";
+
+  Tracer(this.expected, [this.name]);
+
+  void trace(msg) {
+    if (name != null) {
+      print("Tracing $name: $msg");
+    }
+    _trace += msg;
+  }
+
+  void done() {
+    Expect.equals(expected, _trace);
+  }
+}
+
+Future test1(Tracer tracer) {
+  foo() async
+      * //# asyncStar: ok
+  {
+    var savedStackTrace;
+    try {
+      try {
+        tracer.trace("a");
+        throw "Error";
+      } catch (e, st) {
+        tracer.trace("b");
+        savedStackTrace = st;
+      }
+      tracer.trace("c");
+      await new Future.error("Error 2", savedStackTrace);
+      tracer.trace("d");
+    } catch (e, st) {
+      tracer.trace("e");
+      Expect.equals(savedStackTrace.toString(), st.toString());
+    }
+    tracer.trace("f");
+  }
+
+  return foo()
+      .toList() //# asyncStar: continued
+      ;
+}
+
+Future test2(Tracer tracer) {
+  var savedStackTrace;
+  foo() async
+      * //# asyncStar: continued
+  {
+    try {
+      tracer.trace("a");
+      throw "Error";
+    } catch (e, st) {
+      tracer.trace("b");
+      savedStackTrace = st;
+    }
+    tracer.trace("c");
+    await new Future.error("Error 2", savedStackTrace);
+    tracer.trace("d");
+  }
+
+  return foo()
+      .toList() //# asyncStar: continued
+      .catchError((e, st) {
+    tracer.trace("e");
+    Expect.equals(savedStackTrace.toString(), st.toString());
+  });
+}
+
+Future test3(Tracer tracer) {
+  var savedStackTrace;
+  foo() async
+      * //# asyncStar: continued
+  {
+    try {
+      tracer.trace("a");
+      throw "Error";
+    } catch (e, st) {
+      tracer.trace("b");
+      savedStackTrace = st;
+      rethrow;
+    }
+  }
+
+  return foo()
+      .toList() //# asyncStar: continued
+      .catchError((e, st) {
+    tracer.trace("c");
+    Expect.equals(savedStackTrace.toString(), st.toString());
+  });
+}
+
+runTest(String expectedTrace, Future test(Tracer tracer)) async {
+  Tracer tracer = new Tracer(expectedTrace);
+  await test(tracer);
+  tracer.done();
+}
+
+runTests() async {
+  await runTest("abcef", test1);
+  await runTest("abce", test2);
+  await runTest("abc", test3);
+}
+
+main() {
+  asyncTest(runTests);
+}
diff --git a/tests/dart2js/big_allocation_expression_test.dart b/tests/dart2js/big_allocation_expression_test.dart
new file mode 100644
index 0000000..30653a3
--- /dev/null
+++ b/tests/dart2js/big_allocation_expression_test.dart
@@ -0,0 +1,1298 @@
+// Copyright (c) 2015, 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.
+
+// This program crashes the SSA backend. http://dartbug.com/24635.
+
+import "package:expect/expect.dart";
+
+class A {
+  var a;
+  var b;
+
+  factory A(a, x) = A.q;
+
+  // @pragma('dart2js:noInline')  // This annotation causes the test to compile on SSA backend.
+  A.q(this.a, x) : b = x == null ? null : new W(x);
+}
+
+class W {
+  var a;
+  W(this.a);
+}
+
+measure(x, m) {
+  if (x == null) {
+    m['null']++;
+  } else if (x is W) {
+    m['W']++;
+    measure(x.a, m);
+  } else if (x is A) {
+    m['A']++;
+    measure(x.a, m);
+    measure(x.b, m);
+  }
+  return m;
+}
+
+main() {
+  // 4095 'new A'(...)' expressions, 12 calls deep.
+  var e = new A(
+      new A(
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))))))),
+          new A(
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))))),
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))),
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))))))),
+              new A(
+                  new A(
+                      new A(
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))))),
+                          new A(
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))))),
+                              new A(
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null)))),
+                                  new A(
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(new A(null, null),
+                                              new A(null, null))),
+                                      new A(
+                                          new A(new A(null, null),
+                                              new A(null, null)),
+                                          new A(
+                                              new A(null, null), new A(null, null))))))),
+                      new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))),
+                  new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))))))),
+      new A(new A(new A(new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))), new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))))), new A(new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))), new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))))), new A(new A(new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))), new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))))), new A(new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))))), new A(new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))), new A(new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))))), new A(new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))), new A(new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null)))), new A(new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))), new A(new A(new A(null, null), new A(null, null)), new A(new A(null, null), new A(null, null))))))))))));
+
+  var m = measure(e, {'null': 0, 'A': 0, 'W': 0});
+  Expect.equals(4096, m['null']);
+  Expect.equals(4095, m['A']);
+  Expect.equals(2047, m['W']);
+}
diff --git a/tests/dart2js/block_expression_on_field_test.dart b/tests/dart2js/block_expression_on_field_test.dart
new file mode 100644
index 0000000..7b6449f
--- /dev/null
+++ b/tests/dart2js/block_expression_on_field_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+/// Regression test for #36864
+///
+/// Block expressions in top-level fields used to crash the compiler.
+import "package:expect/expect.dart";
+
+final _a = {
+  ...{1}
+};
+
+class B {
+  static Set _b = {
+    ...{2}
+  };
+  Set _c = {
+    ...{3}
+  };
+}
+
+main() {
+  Expect.setEquals({1}, _a);
+  Expect.setEquals({2}, B._b);
+  Expect.setEquals({3}, (new B()._c));
+}
diff --git a/tests/dart2js/boolean_conversion_test.dart b/tests/dart2js/boolean_conversion_test.dart
new file mode 100644
index 0000000..64cd441
--- /dev/null
+++ b/tests/dart2js/boolean_conversion_test.dart
@@ -0,0 +1,103 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+// Note: --omit-implicit-checks causes Expect.isNull to misbehave, so we use
+// Expect.equals(null, ...) instead.
+
+import 'package:expect/expect.dart';
+
+void main() {
+  conditionalTest();
+  orTest();
+  andTest();
+  ifTest();
+  forTest();
+  whileTest();
+  doTest();
+  notTest();
+  ifElementTest();
+  forElementTest();
+}
+
+void conditionalTest() {
+  bool x = null;
+  Expect.isFalse(x ? true : false);
+}
+
+void orTest() {
+  bool x = null;
+  Expect.equals(null, x || x);
+  Expect.isFalse(x || false);
+  Expect.isTrue(x || true);
+  Expect.equals(null, false || x);
+  Expect.isTrue(true || x);
+}
+
+void andTest() {
+  bool x = null;
+  Expect.isFalse(x && x);
+  Expect.isFalse(x && false);
+  Expect.isFalse(x && true);
+  Expect.isFalse(false && x);
+  Expect.equals(null, true && x);
+}
+
+void ifTest() {
+  bool x = null;
+  Expect.isFalse(() {
+    if (x) {
+      return true;
+    } else {
+      return false;
+    }
+  }());
+}
+
+void forTest() {
+  bool x = null;
+  Expect.isFalse(() {
+    for (; x;) {
+      return true;
+    }
+    return false;
+  }());
+}
+
+void whileTest() {
+  bool x = null;
+  Expect.isFalse(() {
+    while (x) {
+      return true;
+    }
+    return false;
+  }());
+}
+
+void doTest() {
+  bool x = null;
+  Expect.equals(1, () {
+    int n = 0;
+    do {
+      n++;
+    } while (x);
+    return n;
+  }());
+}
+
+void notTest() {
+  bool x = null;
+  Expect.isTrue(!x);
+}
+
+void ifElementTest() {
+  bool x = null;
+  Expect.listEquals([], [if (x) 1]);
+}
+
+void forElementTest() {
+  bool x = null;
+  Expect.listEquals([], [for (var i = 0; x; i++) i]);
+}
diff --git a/tests/dart2js/bound_closure_interceptor_methods_test.dart b/tests/dart2js/bound_closure_interceptor_methods_test.dart
new file mode 100644
index 0000000..f17b647
--- /dev/null
+++ b/tests/dart2js/bound_closure_interceptor_methods_test.dart
@@ -0,0 +1,80 @@
+// Copyright (c) 2014, 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";
+
+class A {
+  const A();
+  indexOf(item) => 42;
+
+  // This call get:indexOf has a known receiver type, so is is potentially
+  // eligible for a dummy receiver optimization.
+  getIndexOf() => this.indexOf;
+}
+
+var getIndexOfA = (a) => a.getIndexOf();
+
+var getter1 = (a) => a.indexOf;
+
+var getter2 = (a) {
+  // Known interceptor.
+  if (a is String) return a.indexOf;
+
+  // Call needs to be indirect to avoid inlining.
+  if (a is A) return getIndexOfA(a);
+
+  return a.indexOf;
+};
+
+var inscrutable;
+
+main() {
+  inscrutable = (x) => x;
+
+  var array = ['foo', 'bar', [], [], new A(), new A(), const [], const A()];
+
+  array = inscrutable(array);
+  getter1 = inscrutable(getter1);
+  getter2 = inscrutable(getter2);
+  getIndexOfA = inscrutable(getIndexOfA);
+
+  var set = new Set.from(array.map(getter1));
+
+  // Closures should be distinct since they are closures bound to distinct
+  // objects.
+  Expect.equals(array.length, set.length);
+
+  // And repeats should be equal to existing closures and add no new elements.
+  set.addAll(array.map(getter1));
+  Expect.equals(array.length, set.length);
+
+  // And closures created in different optimization contexts should be equal.
+  set.addAll(array.map(getter2));
+  Expect.equals(array.length, set.length);
+
+  for (int i = 0; i < array.length; i++) {
+    Expect.equals(array[i], array[i]);
+
+    Expect.isTrue(set.contains(getter1(array[i])));
+
+    Expect.equals(getter1(array[i]), getter1(array[i]));
+    Expect.equals(getter1(array[i]), getter2(array[i]));
+    Expect.equals(getter2(array[i]), getter1(array[i]));
+    Expect.equals(getter2(array[i]), getter2(array[i]));
+
+    Expect.equals(getter1(array[i]).hashCode, getter1(array[i]).hashCode);
+    Expect.equals(getter1(array[i]).hashCode, getter2(array[i]).hashCode);
+    Expect.equals(getter2(array[i]).hashCode, getter1(array[i]).hashCode);
+    Expect.equals(getter2(array[i]).hashCode, getter2(array[i]).hashCode);
+
+    for (int j = 0; j < array.length; j++) {
+      if (i == j) continue;
+
+      Expect.notEquals(getter1(array[i]), getter1(array[j]));
+      Expect.notEquals(getter1(array[i]), getter2(array[j]));
+      Expect.notEquals(getter2(array[i]), getter1(array[j]));
+      Expect.notEquals(getter2(array[i]), getter2(array[j]));
+    }
+  }
+}
diff --git a/tests/dart2js/bound_closure_interceptor_type_test.dart b/tests/dart2js/bound_closure_interceptor_type_test.dart
new file mode 100644
index 0000000..7d4ea10
--- /dev/null
+++ b/tests/dart2js/bound_closure_interceptor_type_test.dart
@@ -0,0 +1,125 @@
+// Copyright (c) 2014, 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";
+
+// Test for type checks against tear-off closures generated in different
+// optimization contexts.
+//
+// The type of a tear-off closure depends on the receiver when the method
+// signature uses a type parameter of the method's class.  This means that type
+// checking needs to reference the receiver correctly, either during closure
+// creation or during the type test.
+
+class A<T> {
+  const A();
+  void add(T x) {}
+  T elementAt(int index) => index == 0 ? 42 : 'string';
+
+  // This call get:elementAt has a known receiver type, so is is potentially
+  // eligible for a dummy receiver optimization.
+  getElementAt() => this.elementAt;
+  // Same for get:add.
+  getAdd() => this.add;
+
+  toString() => 'A<$T>';
+}
+
+var getAddOfA = (a) => a.getAdd();
+var getElementAtOfA = (a) => a.getElementAt();
+
+var getAdd1 = (a) => a.add; // receiver has unknown type here.
+
+var getAdd2 = (a) {
+  // Call needs to be indirect to avoid inlining.
+  if (a is A) return getAddOfA(a);
+  return a.add;
+};
+
+var getElementAt1 = (a) => a.elementAt; // receiver has unknown type here.
+
+var getElementAt2 = (a) {
+  // Call needs to be indirect to avoid inlining.
+  if (a is A) return getElementAtOfA(a);
+  return a.elementAt;
+};
+
+typedef void IntToVoid(int x);
+typedef void StringToVoid(String x);
+
+typedef int IntToInt(int x);
+typedef String IntToString(int x);
+typedef T IntToT<T>(int x);
+
+var inscrutable;
+
+var checkers = {
+  'IntToVoid': (x) => x is IntToVoid,
+  'StringToVoid': (x) => x is StringToVoid,
+  'IntToInt': (x) => x is IntToInt,
+  'IntToString': (x) => x is IntToString,
+  'IntToT<int>': (x) => x is IntToT<int>,
+  'IntToT<String>': (x) => x is IntToT<String>,
+};
+
+var methods = {
+  'getAdd1': (x) => getAdd1(x),
+  'getAdd2': (x) => getAdd2(x),
+  'getElementAt1': (x) => getElementAt1(x),
+  'getElementAt2': (x) => getElementAt2(x),
+};
+
+main() {
+  inscrutable = (x) => x;
+
+  getAdd1 = inscrutable(getAdd1);
+  getAdd2 = inscrutable(getAdd2);
+  getElementAt1 = inscrutable(getElementAt1);
+  getElementAt2 = inscrutable(getElementAt2);
+  getAddOfA = inscrutable(getAddOfA);
+  getElementAtOfA = inscrutable(getElementAtOfA);
+
+  check(methodNames, objects, trueCheckNames) {
+    for (var trueCheckName in trueCheckNames) {
+      if (!checkers.containsKey(trueCheckName)) {
+        Expect.fail("unknown check '$trueCheckName'");
+      }
+    }
+
+    for (var object in objects) {
+      for (var methodName in methodNames) {
+        var methodFn = methods[methodName];
+        var description = '$object';
+        checkers.forEach((checkName, checkFn) {
+          bool answer = trueCheckNames.contains(checkName);
+          Expect.equals(answer, checkFn(methodFn(object)),
+              '$methodName($description) is $checkName');
+        });
+      }
+    }
+  }
+
+  var objectsDyn = [[], new A(), new A<dynamic>()];
+  var objectsInt = [<int>[], new A<int>()];
+  var objectsStr = [<String>[], new A<String>()];
+  var objectsLst = [<List>[], new A<List>()];
+
+  var m = ['getAdd1', 'getAdd2'];
+  check(m, objectsDyn, ['IntToVoid', 'StringToVoid']);
+  check(m, objectsInt, ['IntToVoid']);
+  check(m, objectsStr, ['StringToVoid']);
+  check(m, objectsLst, []);
+
+  m = ['getElementAt1', 'getElementAt2'];
+  check(m, objectsDyn, [
+    'IntToInt',
+    'IntToString',
+    'IntToVoid',
+    'IntToT<int>',
+    'IntToT<String>'
+  ]);
+  check(m, objectsInt, ['IntToInt', 'IntToVoid', 'IntToT<int>']);
+  check(m, objectsStr, ['IntToString', 'IntToVoid', 'IntToT<String>']);
+  check(m, objectsLst, ['IntToVoid']);
+}
diff --git a/tests/dart2js/bounded_type_literal_test.dart b/tests/dart2js/bounded_type_literal_test.dart
new file mode 100644
index 0000000..ad0fbe8
--- /dev/null
+++ b/tests/dart2js/bounded_type_literal_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Foo<T extends num> {}
+
+main() {
+  var a = new Foo();
+  var b = Foo;
+  Expect.equals(a.runtimeType, b);
+
+  var runtimeTypeToString = "${a.runtimeType}";
+  var typeLiteralToString = "${b}";
+  Expect.equals(runtimeTypeToString, typeLiteralToString);
+
+  if ('$Object' == 'Object') {
+    // `true` if non-minified.
+    Expect.equals("Foo<num>", runtimeTypeToString);
+    Expect.equals("Foo<num>", typeLiteralToString);
+  }
+  print(runtimeTypeToString);
+  print(typeLiteralToString);
+}
diff --git a/tests/dart2js/bounds_check1a_test.dart b/tests/dart2js/bounds_check1a_test.dart
new file mode 100644
index 0000000..b42ca0d
--- /dev/null
+++ b/tests/dart2js/bounds_check1a_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  c.method();
+}
+
+class Class {
+  @pragma('dart2js:noInline')
+  method<T extends num>() => null;
+}
diff --git a/tests/dart2js/bounds_check1b_test.dart b/tests/dart2js/bounds_check1b_test.dart
new file mode 100644
index 0000000..8fad189
--- /dev/null
+++ b/tests/dart2js/bounds_check1b_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  c.method();
+}
+
+class Class {
+  method<T extends num>() => null;
+}
diff --git a/tests/dart2js/bounds_check2a_test.dart b/tests/dart2js/bounds_check2a_test.dart
new file mode 100644
index 0000000..654c71b
--- /dev/null
+++ b/tests/dart2js/bounds_check2a_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class<int>();
+  c.method();
+}
+
+class Class<T> {
+  @pragma('dart2js:noInline')
+  method<S extends T>() => null;
+}
diff --git a/tests/dart2js/bounds_check2b_test.dart b/tests/dart2js/bounds_check2b_test.dart
new file mode 100644
index 0000000..07cd595
--- /dev/null
+++ b/tests/dart2js/bounds_check2b_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class<int>();
+  c.method();
+}
+
+class Class<T> {
+  method<S extends T>() => null;
+}
diff --git a/tests/dart2js/bounds_check3a_test.dart b/tests/dart2js/bounds_check3a_test.dart
new file mode 100644
index 0000000..482b8ed
--- /dev/null
+++ b/tests/dart2js/bounds_check3a_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  Expect.equals(c.method(), num);
+}
+
+class Class {
+  @pragma('dart2js:noInline')
+  method<S extends num>() => S;
+}
diff --git a/tests/dart2js/bounds_check3b_test.dart b/tests/dart2js/bounds_check3b_test.dart
new file mode 100644
index 0000000..af34397
--- /dev/null
+++ b/tests/dart2js/bounds_check3b_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  Expect.equals(c.method(), num);
+}
+
+class Class {
+  method<S extends num>() => S;
+}
diff --git a/tests/dart2js/bounds_check3c_test.dart b/tests/dart2js/bounds_check3c_test.dart
new file mode 100644
index 0000000..696afdd
--- /dev/null
+++ b/tests/dart2js/bounds_check3c_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class();
+  Expect.equals(c.method(), num);
+}
+
+class Class {
+  @pragma('dart2js:noInline')
+  method<S extends num>() => S;
+}
diff --git a/tests/dart2js/bounds_check4a_test.dart b/tests/dart2js/bounds_check4a_test.dart
new file mode 100644
index 0000000..49e8d42
--- /dev/null
+++ b/tests/dart2js/bounds_check4a_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class<int>();
+  Expect.equals(c.method(), int);
+}
+
+class Class<T> {
+  @pragma('dart2js:noInline')
+  method<S extends T>() => S;
+}
diff --git a/tests/dart2js/bounds_check4b_test.dart b/tests/dart2js/bounds_check4b_test.dart
new file mode 100644
index 0000000..fdb7863
--- /dev/null
+++ b/tests/dart2js/bounds_check4b_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+main() {
+  dynamic c = new Class<int>();
+  Expect.equals(c.method(), int);
+}
+
+class Class<T> {
+  method<S extends T>() => S;
+}
diff --git a/tests/dart2js/bounds_check_test.dart b/tests/dart2js/bounds_check_test.dart
new file mode 100644
index 0000000..99223c8
--- /dev/null
+++ b/tests/dart2js/bounds_check_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+main() {
+  var a = [0, 1];
+  a[-1]; //                         //# 01: runtime error
+  a[-1] = 4; //                     //# 02: runtime error
+  a[2]; //                          //# 03: runtime error
+  a[2] = 4; //                      //# 04: runtime error
+  checkIndex(a, -1); //             //# 05: runtime error
+  checkIndexedAssignment(a, -1); // //# 06: runtime error
+  checkIndex(a, 2); //              //# 07: runtime error
+  checkIndexedAssignment(a, 2); //  //# 08: runtime error
+  checkIndex(a, 0);
+  checkIndexedAssignment(a, 0);
+}
+
+checkIndex(a, b) {
+  a[b];
+}
+
+checkIndexedAssignment(a, b) {
+  a[b] = 1;
+}
diff --git a/tests/dart2js/break_test.dart b/tests/dart2js/break_test.dart
new file mode 100644
index 0000000..830fe73
--- /dev/null
+++ b/tests/dart2js/break_test.dart
@@ -0,0 +1,164 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+break1(int x, int y, int ew, int ez) {
+  int w = 1;
+  int z = 0;
+  bk1:
+  if (x == 2) {
+    z = 1;
+    if (y == 3) {
+      w = 2;
+      break bk1;
+    } else {
+      w = 3;
+    }
+  } else {
+    z = 2;
+    if (y == 3) {
+      w = 4;
+    } else {
+      w = 5;
+      break bk1;
+    }
+    break bk1;
+  }
+  Expect.equals(ew, w);
+  Expect.equals(ez, z);
+}
+
+break2(int x, int y, int ew, int ez) {
+  int w = 1;
+  int z = 0;
+  bk1:
+  do {
+    if (x == 2) {
+      z = 1;
+      if (y == 3) {
+        w = 2;
+        break bk1;
+      } else {
+        w = 3;
+      }
+    } else {
+      z = 2;
+      if (y == 3) {
+        w = 4;
+      } else {
+        w = 5;
+        break bk1;
+      }
+      break bk1;
+    }
+  } while (false);
+  Expect.equals(ew, w);
+  Expect.equals(ez, z);
+}
+
+break3(int x, int y, int ew, int ez) {
+  int w = 1;
+  int z = 0;
+  do {
+    if (x == 2) {
+      z = 1;
+      if (y == 3) {
+        w = 2;
+        break;
+      } else {
+        w = 3;
+      }
+    } else {
+      z = 2;
+      if (y == 3) {
+        w = 4;
+      } else {
+        w = 5;
+        break;
+      }
+      break;
+    }
+  } while (false);
+  Expect.equals(ew, w);
+  Expect.equals(ez, z);
+}
+
+obscureBreaks(x) {
+  bool result = true;
+  bar:
+  do {
+    if (x == 1) {
+      foo:
+      break;
+    } else if (x == 2) {
+      foo:
+      break bar;
+    } else if (x == 3) {
+      bar:
+      break;
+    } else if (x == 4) {
+      break bar;
+    } else {
+      result = false;
+    }
+  } while (false);
+  return result;
+}
+
+ifBreaks(x, y) {
+  int res = 2;
+  foo:
+  if (x == 1)
+    bar:
+    {
+      if (y == 2) {
+        res = 4;
+        break foo;
+      } else if (y == 3) {
+        res = 5;
+        break bar;
+      }
+      res = 3;
+    }
+  else
+    baz:
+    {
+      if (y == 2) {
+        res = 7;
+        break foo;
+      } else if (y == 3) {
+        res = 8;
+        break baz;
+      }
+      res = 6;
+    }
+  return res;
+}
+
+main() {
+  break1(2, 3, 2, 1);
+  break1(2, 4, 3, 1);
+  break1(3, 3, 4, 2);
+  break1(3, 4, 5, 2);
+  break2(2, 3, 2, 1);
+  break2(2, 4, 3, 1);
+  break2(3, 3, 4, 2);
+  break2(3, 4, 5, 2);
+  break3(2, 3, 2, 1);
+  break3(2, 4, 3, 1);
+  break3(3, 3, 4, 2);
+  break3(3, 4, 5, 2);
+  Expect.isTrue(obscureBreaks(1), "1");
+  Expect.isTrue(obscureBreaks(2), "2");
+  Expect.isTrue(obscureBreaks(3), "3");
+  Expect.isTrue(obscureBreaks(4), "4");
+  Expect.isFalse(obscureBreaks(5), "5");
+  Expect.equals(3, ifBreaks(1, 4));
+  Expect.equals(4, ifBreaks(1, 2));
+  Expect.equals(5, ifBreaks(1, 3));
+  Expect.equals(6, ifBreaks(2, 4));
+  Expect.equals(7, ifBreaks(2, 2));
+  Expect.equals(8, ifBreaks(2, 3));
+}
diff --git a/tests/dart2js/call_is_function_test.dart b/tests/dart2js/call_is_function_test.dart
new file mode 100644
index 0000000..8907cad
--- /dev/null
+++ b/tests/dart2js/call_is_function_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A {
+  call() {}
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is Function;
+
+main() {
+  Expect.isFalse(test(new A()));
+  Expect.isFalse(test(null));
+}
diff --git a/tests/dart2js/call_signature_test.dart b/tests/dart2js/call_signature_test.dart
new file mode 100644
index 0000000..20978d5
--- /dev/null
+++ b/tests/dart2js/call_signature_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// Regression test. Crash occurred when trying to create a signature function
+// for the non-live 'call' method on the live class 'A'.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  /// Weird signature to ensure it isn't match by any call selector.
+  call(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, {T t}) {}
+}
+
+class B<T> {
+  @pragma('dart2js:noInline')
+  m(f) => f is Function(T);
+}
+
+@pragma('dart2js:noInline')
+create() => new B<A<int>>();
+
+main() {
+  var o = create();
+  new A();
+  Expect.isTrue(o.m((A<int> i) => i));
+  Expect.isFalse(o.m((A<String> i) => i));
+}
diff --git a/tests/dart2js/call_uninlined_test.dart b/tests/dart2js/call_uninlined_test.dart
new file mode 100644
index 0000000..ab0e750
--- /dev/null
+++ b/tests/dart2js/call_uninlined_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class H {
+  call() {}
+}
+
+main() {
+  print(new H());
+  method();
+}
+
+method() {
+  local1() {}
+
+  local1(); // This call wrongfully triggers enqueueing of H.call in codegen.
+}
diff --git a/tests/dart2js/cfe_instance_constant_test.dart b/tests/dart2js/cfe_instance_constant_test.dart
new file mode 100644
index 0000000..0c202c1
--- /dev/null
+++ b/tests/dart2js/cfe_instance_constant_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.
+
+// Regression test for CFE constant evaluation. The evaluation of [Class9.field]
+// assumed that its initializer did not hold an unevaluated constant.
+
+import 'package:expect/expect.dart';
+
+const dynamic zero_ = const bool.fromEnvironment("x") ? null : 0;
+
+class Class9 {
+  final field = zero_;
+  const Class9();
+}
+
+const c0 = const bool.fromEnvironment("x") ? null : const Class9();
+
+main() {
+  Expect.equals(0, c0.field);
+}
diff --git a/tests/dart2js/checked_setter_test.dart b/tests/dart2js/checked_setter_test.dart
new file mode 100644
index 0000000..60ca4fa
--- /dev/null
+++ b/tests/dart2js/checked_setter_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A {
+  String field;
+}
+
+class B {
+  int field;
+}
+
+@pragma('dart2js:noInline')
+assign(d) {
+  d.field = 0;
+}
+
+main() {
+  Expect.throws(() => assign(new A()));
+  assign(new B()); //# 01: ok
+}
diff --git a/tests/dart2js/class_hierarchy_extends_clause_test.dart b/tests/dart2js/class_hierarchy_extends_clause_test.dart
new file mode 100644
index 0000000..b6131c9
--- /dev/null
+++ b/tests/dart2js/class_hierarchy_extends_clause_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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 A {}
+
+abstract class B<T> {
+  final Box<T> x = new Box<T>();
+}
+
+class C extends B<A> {}
+
+class Box<T> {
+  Box();
+
+  bool doCheck(Object o) => o is T;
+}
+
+main() {
+  var c = new C();
+  Expect.isFalse(c.x.doCheck(3));
+}
diff --git a/tests/dart2js/closure2_test.dart b/tests/dart2js/closure2_test.dart
new file mode 100644
index 0000000..fd8e726
--- /dev/null
+++ b/tests/dart2js/closure2_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  // A closure will be implemented as a class. Make sure everything is set up
+  // correctly when no other class is generated. In particular we need
+  // the Dart-Object class to be generated.
+  var f = () => 42;
+  Expect.equals(42, f());
+}
+
+main() {
+  closure0();
+}
diff --git a/tests/dart2js/closure3_test.dart b/tests/dart2js/closure3_test.dart
new file mode 100644
index 0000000..daea300
--- /dev/null
+++ b/tests/dart2js/closure3_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+main() {
+  var f = ({a: 3, b: 8}) {
+    return a + b;
+  };
+  Expect.equals(11, f());
+  Expect.equals(499, f(a: 3, b: 496));
+  Expect.equals(42, f(a: 20, b: 22));
+  Expect.equals(99, f(b: 66, a: 33));
+}
diff --git a/tests/dart2js/closure4_test.dart b/tests/dart2js/closure4_test.dart
new file mode 100644
index 0000000..08e00bd
--- /dev/null
+++ b/tests/dart2js/closure4_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  var fib;
+  fib = (i) {
+    if (i < 2) return i;
+    return fib(i - 1) + fib(i - 2);
+  };
+  Expect.equals(5, fib(5));
+}
+
+closure1() {
+  var decr1 = 0;
+  var decr2 = 0;
+  var fib;
+  fib = (i) {
+    if (i < 2) return i;
+    return fib(i - decr1) + fib(i - decr2);
+  };
+  decr1++;
+  decr2 += 2;
+  Expect.equals(5, fib(5));
+}
+
+closure2() {
+  var f;
+  f = (doReturnClosure) {
+    if (doReturnClosure) {
+      return () => f(false);
+    } else {
+      return 499;
+    }
+  };
+  var g = f(true);
+  Expect.equals(499, g());
+}
+
+main() {
+  closure0();
+  closure1();
+  closure2();
+}
diff --git a/tests/dart2js/closure5_test.dart b/tests/dart2js/closure5_test.dart
new file mode 100644
index 0000000..f135346
--- /dev/null
+++ b/tests/dart2js/closure5_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo() => 499;
+  bar({a: 1, b: 7, c: 99}) => a + b + c;
+  toto() => bar;
+  gee(f) => f(toto);
+}
+
+main() {
+  var a = new A();
+  var foo = a.foo;
+  Expect.equals(499, foo());
+  var bar = a.bar;
+  Expect.equals(107, bar());
+  Expect.equals(3, bar(a: 1, b: 1, c: 1));
+  Expect.equals(10, bar(c: 2));
+  var toto = a.toto;
+  var gee = a.gee;
+  Expect.equals(-10, gee((f) => f()(a: -1, b: -2, c: -7)));
+}
diff --git a/tests/dart2js/closure6_test.dart b/tests/dart2js/closure6_test.dart
new file mode 100644
index 0000000..a49b187
--- /dev/null
+++ b/tests/dart2js/closure6_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo;
+  bar() => foo(3, 99);
+  gee(f) => foo(fun: f);
+
+  get foo2 => foo;
+  bar2() => foo2(3, 99);
+  gee2(f) => foo2(fun: f);
+}
+
+main() {
+  var a = new A();
+  a.foo = () => 499;
+  Expect.equals(499, a.foo());
+  a.foo = (x, y) => x + y;
+  Expect.equals(102, a.bar());
+  a.foo = ({fun: null}) => fun(41);
+  Expect.equals(42, a.gee((x) => x + 1));
+
+  a.foo = () => 499;
+  Expect.equals(499, a.foo2());
+  a.foo = (x, y) => x + y;
+  Expect.equals(102, a.bar2());
+  a.foo = ({fun: null}) => fun(41);
+  Expect.equals(42, a.gee2((x) => x + 1));
+}
diff --git a/tests/dart2js/closure7_test.dart b/tests/dart2js/closure7_test.dart
new file mode 100644
index 0000000..bae471e
--- /dev/null
+++ b/tests/dart2js/closure7_test.dart
@@ -0,0 +1,60 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+var foo;
+bar() => foo(3, 99);
+gee(f) => foo(fun: f);
+
+get foo2 => foo;
+bar2() => foo2(3, 99);
+gee2(f) => foo2(fun: f);
+
+globalTest() {
+  foo = () => 499;
+  Expect.equals(499, foo());
+  foo = (x, y) => x + y;
+  Expect.equals(102, bar());
+  foo = ({fun: null}) => fun(41);
+  Expect.equals(42, gee((x) => x + 1));
+
+  foo = () => 499;
+  Expect.equals(499, foo2());
+  foo = (x, y) => x + y;
+  Expect.equals(102, bar2());
+  foo = ({fun: null}) => fun(41);
+  Expect.equals(42, gee2((x) => x + 1));
+}
+
+class A {
+  static var foo;
+  static bar() => foo(3, 99);
+  static gee(f) => foo(fun: f);
+
+  static get foo2 => foo;
+  static bar2() => foo2(3, 99);
+  static gee2(f) => foo2(fun: f);
+}
+
+staticTest() {
+  A.foo = () => 499;
+  Expect.equals(499, A.foo());
+  A.foo = (x, y) => x + y;
+  Expect.equals(102, A.bar());
+  A.foo = ({fun: null}) => fun(41);
+  Expect.equals(42, A.gee((x) => x + 1));
+
+  A.foo = () => 499;
+  Expect.equals(499, A.foo2());
+  A.foo = (x, y) => x + y;
+  Expect.equals(102, A.bar2());
+  A.foo = ({fun: null}) => fun(41);
+  Expect.equals(42, A.gee2((x) => x + 1));
+}
+
+main() {
+  globalTest();
+  staticTest();
+}
diff --git a/tests/dart2js/closure_capture2_test.dart b/tests/dart2js/closure_capture2_test.dart
new file mode 100644
index 0000000..4d22b10
--- /dev/null
+++ b/tests/dart2js/closure_capture2_test.dart
@@ -0,0 +1,44 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  // f and g will both capture a variable named 'x'. If we use the original
+  // name in the (shared) box then there will be troubles.
+  var f;
+  var g;
+  {
+    var x = 499;
+    f = () {
+      return x;
+    };
+    x++;
+  }
+  {
+    var x = 42;
+    g = () {
+      return x;
+    };
+    x++;
+  }
+  Expect.equals(500, f());
+  Expect.equals(43, g());
+}
+
+closure1() {
+  // f captures variable $0 which once could yield to troubles with HForeign if
+  // we did not mangle correctly.
+  var $1 = 499;
+  var f = () {
+    return $1;
+  };
+  $1++;
+  Expect.equals(500, f());
+}
+
+main() {
+  closure0();
+  closure1();
+}
diff --git a/tests/dart2js/closure_capture3_test.dart b/tests/dart2js/closure_capture3_test.dart
new file mode 100644
index 0000000..f74f7f5
--- /dev/null
+++ b/tests/dart2js/closure_capture3_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class Closure {
+  var x;
+  Closure(val) : this.x = val;
+
+  foo() {
+    return () {
+      return x;
+    };
+  }
+
+  bar() {
+    return () {
+      return toto();
+    };
+  }
+
+  toto() {
+    return x + 1;
+  }
+
+  nestedClosure() {
+    var f = () {
+      return x;
+    };
+    return () {
+      return f() + 2;
+    };
+  }
+}
+
+main() {
+  var c = new Closure(499);
+  var f = c.foo();
+  Expect.equals(499, f());
+  Expect.equals(500, c.bar()());
+  Expect.equals(501, c.nestedClosure()());
+}
diff --git a/tests/dart2js/closure_capture4_test.dart b/tests/dart2js/closure_capture4_test.dart
new file mode 100644
index 0000000..a16cb07
--- /dev/null
+++ b/tests/dart2js/closure_capture4_test.dart
@@ -0,0 +1,144 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  var input = [1, 2, 3];
+  var fs = [];
+  for (var x in input) {
+    fs.add(() {
+      return x;
+    });
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(2, fs[1]());
+  Expect.equals(3, fs[2]());
+}
+
+closure1() {
+  var input = [1, 2, 3];
+  var fs = [];
+  for (var x in input) {
+    fs.add(() {
+      return x;
+    });
+    x++;
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(2, fs[0]());
+  Expect.equals(3, fs[1]());
+  Expect.equals(4, fs[2]());
+}
+
+closure2() {
+  var input = [1, 2, 3];
+  var fs = [];
+  for (var i = 0; i < input.length; i++) {
+    var j = i;
+    fs.add(() {
+      return input[j];
+    });
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(2, fs[1]());
+  Expect.equals(3, fs[2]());
+}
+
+closure3() {
+  var input = [1, 2, 3];
+  var fs = [];
+  for (var i = 0; i < input.length; i++) {
+    var x = input[i];
+    fs.add(() {
+      return x;
+    });
+    x++;
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(2, fs[0]());
+  Expect.equals(3, fs[1]());
+  Expect.equals(4, fs[2]());
+}
+
+closure4() {
+  var input = [1, 2, 3];
+  var fs = [];
+  var x;
+  for (var i = 0; i < input.length; i++) {
+    x = input[i];
+    fs.add(() {
+      return x;
+    });
+    x++;
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(4, fs[0]());
+  Expect.equals(4, fs[1]());
+  Expect.equals(4, fs[2]());
+}
+
+closure5() {
+  var input = [1, 2, 3];
+  var fs = [];
+  var i = 0;
+  do {
+    var x = input[i];
+    fs.add(() {
+      return x;
+    });
+  } while (++i < input.length);
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(2, fs[1]());
+  Expect.equals(3, fs[2]());
+}
+
+closure6() {
+  var input = [1, 2, 3];
+  var fs = [];
+  var i = 0;
+  do {
+    var x = input[i];
+    fs.add(() {
+      return x;
+    });
+    x++;
+  } while (++i < input.length);
+  Expect.equals(3, fs.length);
+  Expect.equals(2, fs[0]());
+  Expect.equals(3, fs[1]());
+  Expect.equals(4, fs[2]());
+}
+
+closure7() {
+  var input = [1, 2, 3];
+  var fs = [];
+  var i = 0;
+  while (i < input.length) {
+    var x = input[i];
+    fs.add(() {
+      return x;
+    });
+    x++;
+    i++;
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(2, fs[0]());
+  Expect.equals(3, fs[1]());
+  Expect.equals(4, fs[2]());
+}
+
+main() {
+  closure0();
+  closure1();
+  closure2();
+  closure3();
+  closure4();
+  closure5();
+  closure6();
+  closure7();
+}
diff --git a/tests/dart2js/closure_capture5_test.dart b/tests/dart2js/closure_capture5_test.dart
new file mode 100644
index 0000000..c95bbc6
--- /dev/null
+++ b/tests/dart2js/closure_capture5_test.dart
@@ -0,0 +1,82 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  var fs = [];
+  for (var x = 1; x <= 3; x++) {
+    fs.add(() {
+      return x;
+    });
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(2, fs[1]());
+  Expect.equals(3, fs[2]());
+}
+
+closure1() {
+  var fs = [];
+  for (var x = 0; x < 6; x++) {
+    fs.add(() {
+      return x;
+    });
+    x++;
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(3, fs[1]());
+  Expect.equals(5, fs[2]());
+}
+
+closure2() {
+  var input = [1, 2, 3];
+  var fs = [];
+  for (var i = 0; i < input.length; i++) {
+    fs.add(() {
+      return input[i];
+    });
+  }
+  Expect.equals(3, fs.length);
+  Expect.equals(1, fs[0]());
+  Expect.equals(2, fs[1]());
+  Expect.equals(3, fs[2]());
+}
+
+closure3() {
+  var fs = [];
+  for (var i = 0;
+      i < 3;
+      (() {
+    fs.add(() => i);
+    i++;
+  })()) {
+    i++;
+  }
+  Expect.equals(2, fs.length);
+  Expect.equals(3, fs[0]());
+  Expect.equals(4, fs[1]());
+}
+
+closure4() {
+  var g;
+  for (var i = 0;
+      (() {
+    g = () => i;
+    return false;
+  })();
+      i++) {
+    Expect.equals(false, true);
+  }
+  Expect.equals(0, g());
+}
+
+main() {
+  closure0();
+  closure1();
+  closure2();
+  closure3();
+  closure4();
+}
diff --git a/tests/dart2js/closure_capture6_test.dart b/tests/dart2js/closure_capture6_test.dart
new file mode 100644
index 0000000..06f593f
--- /dev/null
+++ b/tests/dart2js/closure_capture6_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Simple test for free variable in two nested scopes.
+
+captureTwiceNested(x) {
+  // 'x' value captured at two levels.
+  return () => [x, () => x + 1];
+}
+
+main() {
+  var a = captureTwiceNested(1);
+  Expect.equals(1, a()[0]);
+  Expect.equals(2, a()[1]());
+}
diff --git a/tests/dart2js/closure_capture7_test.dart b/tests/dart2js/closure_capture7_test.dart
new file mode 100644
index 0000000..045f6a5
--- /dev/null
+++ b/tests/dart2js/closure_capture7_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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 A<T> {
+  List<List> xs;
+
+  void foo() {
+    // the inner closure only needs to capture 'this' if
+    // `A` needs runtime type information.
+    xs.map((x) => x.map((a) => a as T));
+  }
+}
+
+main() {
+  var a = new A<int>();
+  a.xs = [
+    [1, 2, 3],
+    [4, 5, 6]
+  ];
+  // just check that this doesn't crash
+  a.foo();
+}
diff --git a/tests/dart2js/closure_capture_test.dart b/tests/dart2js/closure_capture_test.dart
new file mode 100644
index 0000000..cc12c58
--- /dev/null
+++ b/tests/dart2js/closure_capture_test.dart
@@ -0,0 +1,111 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  var x = 499;
+  var f = () {
+    return x;
+  };
+  Expect.equals(499, f());
+}
+
+class A {
+  closure1() {
+    var x = 499;
+    var f = () {
+      return x;
+    };
+    Expect.equals(499, f());
+  }
+}
+
+applyFun(f) {
+  return f();
+}
+
+closure2() {
+  var x = 499;
+  Expect.equals(499, applyFun(() {
+    return x;
+  }));
+}
+
+closure3() {
+  var y = 400;
+  var f = (x) {
+    return y + x;
+  };
+  Expect.equals(499, f(99));
+}
+
+applyFun2(f) {
+  return f(400, 90);
+}
+
+closure4() {
+  var z = 9;
+  Expect.equals(499, applyFun2((x, y) {
+    return x + y + z;
+  }));
+}
+
+closure5() {
+  var x = 498;
+  var f = () {
+    return x;
+  };
+  x++;
+  Expect.equals(499, f());
+}
+
+class A2 {
+  closure6() {
+    var x = 498;
+    var f = () {
+      return x;
+    };
+    x++;
+    Expect.equals(499, f());
+  }
+}
+
+closure7() {
+  var x = 498;
+  var f = () {
+    return x;
+  };
+  x++;
+  Expect.equals(499, applyFun(f));
+}
+
+closure8() {
+  var y = 399;
+  var f = (x) {
+    return y + x;
+  };
+  y++;
+  Expect.equals(499, f(99));
+}
+
+closure9() {
+  var z = 9;
+  Expect.equals(499, applyFun2((x, y) {
+    return x + y + z;
+  }));
+}
+
+main() {
+  closure0();
+  new A().closure1();
+  closure2();
+  closure3();
+  closure4();
+  closure5();
+  new A2().closure6();
+  closure7();
+  closure8();
+  closure9();
+}
diff --git a/tests/dart2js/closure_signature_unneeded_test.dart b/tests/dart2js/closure_signature_unneeded_test.dart
new file mode 100644
index 0000000..88534c7
--- /dev/null
+++ b/tests/dart2js/closure_signature_unneeded_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A<T> {
+  @pragma('dart2js:noInline')
+  m() {
+    return (T t, String s) {};
+  }
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is void Function(int);
+
+main() {
+  Expect.isFalse(test(new A<int>().m()));
+}
diff --git a/tests/dart2js/closure_test.dart b/tests/dart2js/closure_test.dart
new file mode 100644
index 0000000..5ad4247
--- /dev/null
+++ b/tests/dart2js/closure_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+closure0() {
+  var f = () {
+    return 499;
+  };
+  Expect.equals(499, f());
+}
+
+class A {
+  closure1() {
+    var f = () {
+      return 499;
+    };
+    Expect.equals(499, f());
+  }
+}
+
+applyFun(f) {
+  return f();
+}
+
+closure2() {
+  Expect.equals(499, applyFun(() {
+    return 499;
+  }));
+}
+
+closure3() {
+  var f = (x) {
+    return 400 + x;
+  };
+  Expect.equals(499, f(99));
+}
+
+applyFun2(f) {
+  return f(400, 99);
+}
+
+closure4() {
+  Expect.equals(499, applyFun2((x, y) {
+    return x + y;
+  }));
+}
+
+main() {
+  closure0();
+  new A().closure1();
+  closure2();
+  closure3();
+  closure4();
+}
diff --git a/tests/dart2js/code_motion_exception_test.dart b/tests/dart2js/code_motion_exception_test.dart
new file mode 100644
index 0000000..95ed395
--- /dev/null
+++ b/tests/dart2js/code_motion_exception_test.dart
@@ -0,0 +1,112 @@
+// 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 "package:expect/expect.dart";
+
+// Test for correct order of exceptions in code with checks that could be moved
+// merged from successors into a dominator.
+
+get never => new DateTime.now().millisecondsSinceEpoch == 42;
+get always => new DateTime.now().millisecondsSinceEpoch > 42;
+
+// gA and gB have type [null|num], so they compile to a receiver check, and
+// argument check and then the operation.
+var gA; // [null|num]
+var gB; // [null|num]
+
+foo1(a, b) {
+  // The checks on a and b are not equivalent, so can't be merged.
+  if (never) {
+    return a ^ b;
+  } else {
+    return b ^ a;
+  }
+}
+
+call1() {
+  return foo1(gA, gB);
+}
+
+test1() {
+  gA = 1;
+  gB = 2;
+  Expect.equals(3, call1());
+
+  gA = null;
+  gB = null;
+  Expect.throws(call1, (e) => e is NoSuchMethodError, 'foo1($gA, $gB) NSME');
+
+  gA = 1;
+  gB = null;
+  Expect.throws(call1, (e) => e is NoSuchMethodError, 'foo1($gA, $gB) NSME');
+
+  gA = null;
+  gB = 2;
+  Expect.throws(call1, (e) => e is ArgumentError, 'foo1($gA, $gB) AE');
+}
+
+foo2a(a, b) {
+  // The common receiver check on [a] cannot be merged because the operation
+  // (selector) is different.
+  // The common argument check on [b] cannot be merged because it must happen
+  // after the receiver check.
+  if (never) {
+    return a ^ b;
+  } else {
+    return a & b;
+  }
+}
+
+foo2b(a, b) {
+  // Same a foo2a except which branch dynamically taken.
+  if (always) {
+    return a ^ b;
+  } else {
+    return a & b;
+  }
+}
+
+call2a() {
+  return foo2a(gA, gB);
+}
+
+call2b() {
+  return foo2b(gA, gB);
+}
+
+checkNSME(text) {
+  return (e) {
+    Expect.isTrue(e is NoSuchMethodError,
+        'expecting NoSuchMethodError, got "${e.runtimeType}"');
+    Expect.isTrue('$e'.contains(text), '"$e".contains("$text")');
+    return e is NoSuchMethodError;
+  };
+}
+
+test2() {
+  gA = 1;
+  gB = 2;
+  Expect.equals(0, call2a());
+  Expect.equals(3, call2b());
+
+  gA = null;
+  gB = null;
+  Expect.throws(call2a, checkNSME(r'$and'), 'foo2($gA, $gB) NSME');
+  Expect.throws(call2b, checkNSME(r'$xor'), 'foo2($gA, $gB) NSME');
+
+  gA = 1;
+  gB = null;
+  Expect.throws(call2a, (e) => e is ArgumentError, 'foo2($gA, $gB) AE');
+  Expect.throws(call2b, (e) => e is ArgumentError, 'foo2($gA, $gB) AE');
+
+  gA = null;
+  gB = 2;
+  Expect.throws(call2a, checkNSME(r'$and'), 'foo2($gA, $gB) NSME');
+  Expect.throws(call2b, checkNSME(r'$xor'), 'foo2($gA, $gB) NSME');
+}
+
+main() {
+  test1();
+  test2();
+}
diff --git a/tests/dart2js/compile_time_constant4_test.dart b/tests/dart2js/compile_time_constant4_test.dart
new file mode 100644
index 0000000..2349dc1
--- /dev/null
+++ b/tests/dart2js/compile_time_constant4_test.dart
@@ -0,0 +1,44 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+const x = "foo";
+const y = "foo";
+const g1 = x + "bar";
+const g2 = x
+  + null //  //# 01: compile-time error
+    ;
+const g3 = x
+  + 499 //  //# 02: compile-time error
+    ;
+const g4 = x
+  + 3.3 //  //# 03: compile-time error
+    ;
+const g5 = x
+  + true //  //# 04: compile-time error
+    ;
+const g6 = x
+  + false //  //# 05: compile-time error
+    ;
+const g7 = "foo"
+  + x[0] //  //# 06: compile-time error
+    ;
+const g8 = 1 + x.length;
+const g9 = x == y;
+
+use(x) => x;
+
+main() {
+  Expect.equals("foobar", g1);
+  Expect.isTrue(g9);
+  use(g1);
+  use(g2);
+  use(g3);
+  use(g4);
+  use(g5);
+  use(g6);
+  use(g7);
+  use(g8);
+}
diff --git a/tests/dart2js/compound_operator_index_test.dart b/tests/dart2js/compound_operator_index_test.dart
new file mode 100644
index 0000000..508a9e0
--- /dev/null
+++ b/tests/dart2js/compound_operator_index_test.dart
@@ -0,0 +1,76 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  List<int> list;
+  A(int a, int b) : list = <int>[a, b];
+  operator [](index) => list[index];
+  operator []=(index, value) => list[index] = value;
+}
+
+class B {
+  int value;
+  List trace;
+  B(this.trace) : value = 100;
+  operator [](index) {
+    trace.add(-3);
+    trace.add(index);
+    trace.add(this.value);
+    this.value = this.value + 1;
+    return this;
+  }
+
+  operator []=(index, value) {
+    trace.add(-5);
+    trace.add(index);
+    trace.add(value.value);
+    this.value = this.value + 1;
+  }
+
+  operator +(int value) {
+    trace.add(-4);
+    trace.add(this.value);
+    trace.add(value);
+    this.value = this.value + 1;
+    return this;
+  }
+}
+
+B getB(trace) {
+  trace.add(-1);
+  return new B(trace);
+}
+
+int getIndex(trace) {
+  trace.add(-2);
+  return 42;
+}
+
+main() {
+  A a = new A(1, 2);
+  Expect.equals(1, a[0]);
+  Expect.equals(2, a[1]);
+
+  Expect.equals(1, a[0]++);
+  Expect.equals(2, a[0]);
+
+  Expect.equals(2, a[0]--);
+  Expect.equals(1, a[0]);
+
+  Expect.equals(0, --a[0]);
+  Expect.equals(0, a[0]);
+
+  Expect.equals(1, ++a[0]);
+  Expect.equals(1, a[0]);
+
+  a[0] += 2;
+  Expect.equals(3, a[0]);
+
+  List trace = new List();
+  getB(trace)[getIndex(trace)] += 37;
+
+  Expect.listEquals([-1, -2, -3, 42, 100, -4, 101, 37, -5, 42, 102], trace);
+}
diff --git a/tests/dart2js/conditional_rewrite_test.dart b/tests/dart2js/conditional_rewrite_test.dart
new file mode 100644
index 0000000..57b0a42
--- /dev/null
+++ b/tests/dart2js/conditional_rewrite_test.dart
@@ -0,0 +1,60 @@
+// Copyright (c) 2015, 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";
+
+// Test that dart2js does not rewrite conditional into logical operators
+// in cases where it changes which falsy value is returned.
+
+posFalse(x, y) => x != null ? y : false;
+negFalse(x, y) => x != null ? !y : false;
+posNull(x, y) => x != null ? y : null;
+negNull(x, y) => x != null ? !y : null;
+
+main() {
+  Expect.equals(false, posFalse(null, false));
+  Expect.equals(false, negFalse(null, false));
+  Expect.equals(null, posNull(null, false));
+  Expect.equals(null, negNull(null, false));
+
+  Expect.equals(false, posFalse(null, true));
+  Expect.equals(false, negFalse(null, true));
+  Expect.equals(null, posNull(null, true));
+  Expect.equals(null, negNull(null, true));
+
+  Expect.equals(false, posFalse([], false));
+  Expect.equals(true, negFalse([], false));
+  Expect.equals(false, posNull([], false));
+  Expect.equals(true, negNull([], false));
+
+  Expect.equals(true, posFalse([], true));
+  Expect.equals(false, negFalse([], true));
+  Expect.equals(true, posNull([], true));
+  Expect.equals(false, negNull([], true));
+
+  if (isConditionCheckDisabled) {
+    Expect.equals(null, posFalse([], null));
+    Expect.equals(true, negFalse([], null));
+    Expect.equals(null, posNull([], null));
+    Expect.equals(true, negNull([], null));
+
+    var y = {};
+    Expect.identical(y, posFalse([], y));
+    Expect.equals(true, negFalse([], y));
+    Expect.identical(y, posNull([], y));
+    Expect.equals(true, negNull([], y));
+  }
+}
+
+bool get isConditionCheckDisabled {
+  bool b = null;
+  for (int i = 0; i < 3; i++) {
+    try {
+      b = !b;
+    } catch (e) {
+      return false;
+    }
+  }
+  return true;
+}
diff --git a/tests/dart2js/conditional_send_test.dart b/tests/dart2js/conditional_send_test.dart
new file mode 100644
index 0000000..d1a27c1
--- /dev/null
+++ b/tests/dart2js/conditional_send_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, 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-null-aware-operators
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class A {
+  int x;
+  m() => "a";
+}
+
+main(args) {
+  var a = confuse(true) ? null : new A();
+  a?.x = 3;
+  Expect.throws(() => a.m());
+}
diff --git a/tests/dart2js/conditional_test.dart b/tests/dart2js/conditional_test.dart
new file mode 100644
index 0000000..13cf988
--- /dev/null
+++ b/tests/dart2js/conditional_test.dart
@@ -0,0 +1,24 @@
+// 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 "package:expect/expect.dart";
+
+getZero() {
+  return 0;
+}
+
+main() {
+  int i = getZero();
+  int c = i == 0 ? i-- : i++;
+  Expect.equals(-1, i);
+  Expect.equals(0, c);
+
+  int d = i == 0 ? i-- : i++;
+  Expect.equals(0, i);
+  Expect.equals(-1, d);
+
+  int e = i == 0 ? --i : ++i;
+  Expect.equals(-1, i);
+  Expect.equals(-1, e);
+}
diff --git a/tests/dart2js/conflict_index_test.dart b/tests/dart2js/conflict_index_test.dart
new file mode 100644
index 0000000..46c74ea
--- /dev/null
+++ b/tests/dart2js/conflict_index_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+main() {
+  foo(true, [0]);
+  foo(false, "bar");
+}
+
+foo(check, listOrString) {
+  if (check) {
+    Expect.equals(0, listOrString[0]);
+    listOrString[0] = 1;
+    Expect.equals(1, listOrString[0]);
+  } else {
+    Expect.equals("foobar", "foo${listOrString}");
+  }
+}
diff --git a/tests/dart2js/consistent_add_error_test.dart b/tests/dart2js/consistent_add_error_test.dart
new file mode 100644
index 0000000..fd5840f
--- /dev/null
+++ b/tests/dart2js/consistent_add_error_test.dart
@@ -0,0 +1,162 @@
+// Copyright (c) 2015, 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";
+
+// Test that optimized '+' and slow path '+' produce the same error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntPlusNull {
+  static f1() {
+    return confuse(1) + confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) + null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a + null;
+  }
+
+  static f7() {
+    return 1 + null;
+  }
+
+  static test() {
+    check('IntPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class StringPlusNull {
+  static f1() {
+    return confuse('a') + confuse(null);
+  }
+
+  static f2() {
+    return confuse('a') + null;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(null);
+  }
+
+  static f4() {
+    return (confuse('a') as String) + null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + null;
+  }
+
+  static f7() {
+    return 'a' + null;
+  }
+
+  static test() {
+    check('StringPlusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntPlusString {
+  static f1() {
+    return confuse(1) + confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) + 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a + confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) + confuse('a');
+  }
+
+  static test() {
+    check('IntPlusString', f1, f2, f3, f4);
+  }
+}
+
+class StringPlusInt {
+  static f1() {
+    return confuse('a') + confuse(1);
+  }
+
+  static f2() {
+    return confuse('a') + 1;
+  }
+
+  static f3() {
+    return (confuse('a') as String) + confuse(1);
+  }
+
+  static f4() {
+    var a = confuse(true) ? 'a' : 'bc';
+    return a + confuse(1);
+  }
+
+  static test() {
+    check('StringPlusInt', f1, f2, f3, f4);
+  }
+}
+
+main() {
+  IntPlusNull.test();
+  StringPlusNull.test();
+  IntPlusString.test();
+  StringPlusInt.test();
+}
diff --git a/tests/dart2js/consistent_codeUnitAt_error_test.dart b/tests/dart2js/consistent_codeUnitAt_error_test.dart
new file mode 100644
index 0000000..536279b
--- /dev/null
+++ b/tests/dart2js/consistent_codeUnitAt_error_test.dart
@@ -0,0 +1,132 @@
+// Copyright (c) 2015, 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";
+
+// Test that optimized codeUnitAt and slow path codeUnitAt produce the same
+// error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+}
+
+class TooHigh {
+  static f1() {
+    return confuse('AB').codeUnitAt(3); // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    var i = confuse(3);
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    return a.codeUnitAt(3);
+  }
+
+  static test() {
+    check('TooHigh', f1, f2, f3);
+  }
+}
+
+class Negative {
+  static f1() {
+    return confuse('AB').codeUnitAt(-3); // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    var i = confuse(-3);
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    var i = confuse(true) ? -3 : 0;
+    return a.codeUnitAt(i);
+  }
+
+  static f4() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    return a.codeUnitAt(-3);
+  }
+
+  static test() {
+    check('Negative', f1, f2, f3, f4);
+  }
+}
+
+class Empty {
+  static f1() {
+    return confuse('').codeUnitAt(0); // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? '' : 'ABCDE'; // Empty String with unknown length.
+    var i = confuse(true) ? 0 : 1;
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? '' : 'ABCDE'; // Empty String with unknown length.
+    return a.codeUnitAt(0);
+  }
+
+  static test() {
+    check('Empty', f1, f2, f3);
+  }
+}
+
+class BadType {
+  static f1() {
+    return confuse('AB').codeUnitAt('a'); // dynamic receiver.
+  }
+
+  static f2() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    var i = confuse('a');
+    return a.codeUnitAt(i);
+  }
+
+  static f3() {
+    var a = confuse(true) ? 'AB' : 'ABCDE'; // String with unknown length.
+    return a.codeUnitAt(('a' as dynamic));
+  }
+
+  static test() {
+    check('BadType', f1, f2, f3);
+  }
+}
+
+main() {
+  TooHigh.test();
+  Negative.test();
+  Empty.test();
+  BadType.test();
+}
diff --git a/tests/dart2js/consistent_index_error_array_test.dart b/tests/dart2js/consistent_index_error_array_test.dart
new file mode 100644
index 0000000..6afa8a9
--- /dev/null
+++ b/tests/dart2js/consistent_index_error_array_test.dart
@@ -0,0 +1,155 @@
+// Copyright (c) 2015, 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 "dart:typed_data";
+
+// Test that optimized indexing and slow path indexing produce the same error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class TooHigh {
+  static load1() {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    try {
+      // dynamic receiver causes method to be called via interceptor.
+      return confuse(a)[3];
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    // 'a' is inferred as JSArray of unknown length so has optimized check.
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class Negative {
+  static load1() {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    try {
+      // dynamic receiver causes method to be called via interceptor.
+      return confuse(a)[-3];
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    // 'a' is inferred as JSArray of unknown length so has optimized check.
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class Empty {
+  static load1() {
+    var a = confuse(true) ? [] : [10, 11, 12, 13, 14];
+    try {
+      // dynamic receiver causes method to be called via interceptor.
+      return confuse(a)[-3];
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? [] : [10, 11, 12, 13, 14];
+    // 'a' is inferred as JSArray of unknown length so has optimized check.
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class BadType {
+  static load1() {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    try {
+      // dynamic receiver causes method to be called via interceptor.
+      return confuse(a)['a'];
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)('a');
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? [10, 11] : [10, 11, 12, 13, 14];
+    // 'a' is inferred as JSArray of unknown length so has optimized check.
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+main() {
+  TooHigh.test();
+  Negative.test();
+  Empty.test();
+  BadType.test();
+}
diff --git a/tests/dart2js/consistent_index_error_string_test.dart b/tests/dart2js/consistent_index_error_string_test.dart
new file mode 100644
index 0000000..45155ff
--- /dev/null
+++ b/tests/dart2js/consistent_index_error_string_test.dart
@@ -0,0 +1,151 @@
+// Copyright (c) 2015, 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 "dart:typed_data";
+
+// Test that optimized indexing and slow path indexing produce the same error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class TooHigh {
+  static load1() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    try {
+      return confuse(a)[3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    return a[i]; // 'a' is String of unknown length.
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    print("  A: '$e1'\n  B: '$e2'");
+    Expect.equals('$e1', '$e2');
+  }
+}
+
+class Negative {
+  static load1() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    try {
+      return confuse(a)[-3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    return a[i]; // 'a' is String of unknown length.
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    print("  A: '$e1'\n  B: '$e2'");
+    Expect.equals('$e1', '$e2');
+  }
+}
+
+class Empty {
+  static load1() {
+    var a = confuse(true) ? '' : 'ABCDE';
+    try {
+      return confuse(a)[-3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? '' : 'ABCDE';
+    return a[i]; // 'a' is String of unknown length.
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    print("  A: '$e1'\n  B: '$e2'");
+    Expect.equals('$e1', '$e2');
+  }
+}
+
+class BadType {
+  static load1() {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    try {
+      return confuse(a)['a']; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)('a');
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true) ? 'AB' : 'ABCDE';
+    return a[i]; // 'a' is String of unknown length.
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    print("  A: '$e1'\n  B: '$e2'");
+    Expect.equals('$e1', '$e2');
+  }
+}
+
+main() {
+  TooHigh.test();
+  Negative.test();
+  Empty.test();
+  BadType.test();
+}
diff --git a/tests/dart2js/consistent_index_error_typed_list_test.dart b/tests/dart2js/consistent_index_error_typed_list_test.dart
new file mode 100644
index 0000000..bf198c6
--- /dev/null
+++ b/tests/dart2js/consistent_index_error_typed_list_test.dart
@@ -0,0 +1,163 @@
+// Copyright (c) 2015, 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 "dart:typed_data";
+
+// Test that optimized indexing and slow path indexing produce the same error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class TooHigh {
+  static load1() {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    try {
+      return confuse(a)[3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class Negative {
+  static load1() {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    try {
+      return confuse(a)[-3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class Empty {
+  static load1() {
+    var a = confuse(true)
+        ? new Uint8List.fromList([])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    try {
+      return confuse(a)[-3]; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)(-3);
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true)
+        ? new Uint8List.fromList([])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+class BadType {
+  static load1() {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    try {
+      return confuse(a)['a']; // dynamic receiver for indexer.
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2() {
+    try {
+      confuse(load2x)('a');
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('unreached');
+  }
+
+  static load2x(i) {
+    var a = confuse(true)
+        ? new Uint8List.fromList([10, 11])
+        : new Uint8List.fromList([10, 11, 12, 13, 14]);
+    return a[i];
+  }
+
+  static test() {
+    var e1 = load1();
+    var e2 = load2();
+    Expect.equals('$e1', '$e2', '\n  A: "$e1"\n  B: "$e2"\n');
+  }
+}
+
+main() {
+  TooHigh.test();
+  Negative.test();
+  Empty.test();
+  BadType.test();
+}
diff --git a/tests/dart2js/consistent_null_add_error_test.dart b/tests/dart2js/consistent_null_add_error_test.dart
new file mode 100644
index 0000000..64ad07d
--- /dev/null
+++ b/tests/dart2js/consistent_null_add_error_test.dart
@@ -0,0 +1,81 @@
+// Copyright (c) 2015, 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";
+
+// Test that optimized 'null + x' and slow path '+' produce the same error.
+//
+// They don't, sometimes we generate null.$add, sometimes JSNull_methods.$add.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+}
+
+class NullPlusInt {
+  static f1() {
+    return confuse(null) + confuse(1);
+  }
+
+  static f2() {
+    return confuse(null) + 1;
+  }
+
+  static f3() {
+    return (confuse(null) as int) + confuse(1);
+  }
+
+  static f4() {
+    return (confuse(null) as int) + 1;
+  }
+
+  static f5() {
+    var a = null;
+    return a + confuse(1);
+  }
+
+  static f6() {
+    var a = null;
+    return a + 1;
+  }
+
+  static test() {
+    // Sometimes we generate null.$add, sometimes JSNull_methods.$add. The best
+    // we can do is check there is an error.
+    check('NullPlusInt', f1, f1);
+    check('NullPlusInt', f2, f2);
+    check('NullPlusInt', f3, f3);
+    check('NullPlusInt', f4, f4);
+    check('NullPlusInt', f5, f5);
+    check('NullPlusInt', f6, f6);
+  }
+}
+
+main() {
+  NullPlusInt.test();
+}
diff --git a/tests/dart2js/consistent_subtract_error_test.dart b/tests/dart2js/consistent_subtract_error_test.dart
new file mode 100644
index 0000000..a847937
--- /dev/null
+++ b/tests/dart2js/consistent_subtract_error_test.dart
@@ -0,0 +1,103 @@
+// Copyright (c) 2015, 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.
+
+/// dart2jsOptions=--omit-implicit-checks
+
+import "package:expect/expect.dart";
+
+// Test that optimized '-' and slow path '-' produce the same error.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void check2(String name, name1, f1, name2, f2) {
+  Error trap(part, f) {
+    try {
+      f();
+    } catch (e) {
+      return e;
+    }
+    Expect.fail('should throw: $name.$part');
+  }
+
+  var e1 = trap(name1, f1);
+  var e2 = trap(name2, f2);
+  var s1 = '$e1';
+  var s2 = '$e2';
+  Expect.equals(s1, s2, '\n  $name.$name1: "$s1"\n  $name.$name2: "$s2"\n');
+}
+
+void check(String name, f1, f2, [f3, f4, f5, f6, f7]) {
+  check2(name, 'f1', f1, 'f2', f2);
+  if (f3 != null) check2(name, 'f1', f1, 'f3', f3);
+  if (f4 != null) check2(name, 'f1', f1, 'f4', f4);
+  if (f5 != null) check2(name, 'f1', f1, 'f5', f5);
+  if (f6 != null) check2(name, 'f1', f1, 'f6', f6);
+  if (f7 != null) check2(name, 'f1', f1, 'f7', f7);
+}
+
+class IntMinusNull {
+  static f1() {
+    return confuse(1) - confuse(null);
+  }
+
+  static f2() {
+    return confuse(1) - null;
+  }
+
+  static f3() {
+    return (confuse(1) as int) - confuse(null);
+  }
+
+  static f4() {
+    return (confuse(1) as int) - null;
+  }
+
+  static f5() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a - confuse(null);
+  }
+
+  static f6() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a - null;
+  }
+
+  static f7() {
+    return 1 - null;
+  }
+
+  static test() {
+    check('IntMinusNull', f1, f2, f3, f4, f5, f6, f7);
+  }
+}
+
+class IntMinusString {
+  static f1() {
+    return confuse(1) - confuse('a');
+  }
+
+  static f2() {
+    return confuse(1) - 'a';
+  }
+
+  static f3() {
+    var a = confuse(true) ? 1 : 2; // Small int with unknown value.
+    return a - confuse('a');
+  }
+
+  static f4() {
+    return (confuse(1) as int) - confuse('a');
+  }
+
+  static test() {
+    check('IntMinusString', f1, f2, f3, f4);
+  }
+}
+
+main() {
+  IntMinusNull.test();
+  IntMinusString.test();
+}
diff --git a/tests/dart2js/consistent_type_error_test.dart b/tests/dart2js/consistent_type_error_test.dart
new file mode 100644
index 0000000..e687ba4
--- /dev/null
+++ b/tests/dart2js/consistent_type_error_test.dart
@@ -0,0 +1,203 @@
+// 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.
+
+// Test that type checks give consistent errors for the same types. In minified
+// mode this checks that the minified class names are consistently tagged.
+
+import 'package:expect/expect.dart';
+
+class Plain {}
+
+class Foo<U> {}
+
+class Test<T> {
+  @pragma('dart2js:noInline')
+  asT(o) => o as T;
+
+  @pragma('dart2js:noInline')
+  asFooT(o) => o as Foo<T>;
+
+  @pragma('dart2js:noInline')
+  testT(o) {
+    T result = o;
+  }
+
+  @pragma('dart2js:noInline')
+  testFooT(o) {
+    Foo<T> result = o;
+  }
+}
+
+capture(action()) {
+  try {
+    action();
+  } catch (e) {
+    print('$e');
+    return '$e';
+  }
+  Expect.fail('Action should have failed');
+}
+
+dynamic g;
+
+casts() {
+  g = Foo<String>();
+
+  Expect.equals(
+    capture(() => Test<Foo<Plain>>().asT(g)),
+    capture(() => g as Foo<Plain>),
+    "C1",
+  );
+
+  Expect.equals(
+    capture(() => g as Foo<Plain>),
+    capture(() => Test<Plain>().asFooT(g)),
+    "C2",
+  );
+
+  Expect.equals(
+    capture(() => Test<Plain>().asT(g)),
+    capture(() => g as Plain),
+    "C3",
+  );
+
+  g = Foo<Plain>();
+
+  Expect.equals(
+    capture(() => Test<Foo<String>>().asT(g)),
+    capture(() => g as Foo<String>),
+    "C4",
+  );
+
+  Expect.equals(
+    capture(() => g as Foo<String>),
+    capture(() => Test<String>().asFooT(g)),
+    "C5",
+  );
+
+  g = Plain();
+
+  Expect.equals(
+    capture(() => Test<String>().asT(g)),
+    capture(() => g as String),
+    "C6",
+  );
+
+  Expect.equals(
+    capture(() => Test<int>().asT(g)),
+    capture(() => g as int),
+    "C7",
+  );
+
+  Expect.equals(
+    capture(() => Test<double>().asT(g)),
+    capture(() => g as double),
+    "C8",
+  );
+
+  Expect.equals(
+    capture(() => Test<bool>().asT(g)),
+    capture(() => g as bool),
+    "C9",
+  );
+
+  Expect.equals(
+    capture(() => Test<List>().asT(g)),
+    capture(() => g as List),
+    "C10",
+  );
+}
+
+tests() {
+  g = Foo<String>();
+
+  Expect.equals(
+    capture(() => Test<Foo<Plain>>().testT(g)),
+    capture(() {
+      Foo<Plain> x = g;
+    }),
+    "T1",
+  );
+
+  Expect.equals(
+    capture(() {
+      Foo<Plain> x = g;
+    }),
+    capture(() => Test<Plain>().testFooT(g)),
+    "T2",
+  );
+
+  Expect.equals(
+    capture(() => Test<Plain>().testT(g)),
+    capture(() {
+      Plain x = g;
+    }),
+    "T3",
+  );
+
+  g = Foo<Plain>();
+
+  Expect.equals(
+    capture(() => Test<Foo<String>>().testT(g)),
+    capture(() {
+      Foo<String> x = g;
+    }),
+    "T4",
+  );
+
+  Expect.equals(
+    capture(() {
+      Foo<String> x = g;
+    }),
+    capture(() => Test<String>().testFooT(g)),
+    "T5",
+  );
+
+  g = Plain();
+
+  Expect.equals(
+    capture(() => Test<String>().testT(g)),
+    capture(() {
+      String x = g;
+    }),
+    "T6",
+  );
+
+  Expect.equals(
+    capture(() => Test<int>().testT(g)),
+    capture(() {
+      int x = g;
+    }),
+    "T7",
+  );
+
+  Expect.equals(
+    capture(() => Test<double>().testT(g)),
+    capture(() {
+      double x = g;
+    }),
+    "T8",
+  );
+
+  Expect.equals(
+    capture(() => Test<bool>().testT(g)),
+    capture(() {
+      bool x = g;
+    }),
+    "T9",
+  );
+
+  Expect.equals(
+    capture(() => Test<List>().testT(g)),
+    capture(() {
+      List x = g;
+    }),
+    "T10",
+  );
+}
+
+main() {
+  casts();
+  tests();
+}
diff --git a/tests/dart2js/constant_fold_number_dart2_j_s_test.dart b/tests/dart2js/constant_fold_number_dart2_j_s_test.dart
new file mode 100644
index 0000000..19e1912
--- /dev/null
+++ b/tests/dart2js/constant_fold_number_dart2_j_s_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+// where the semantics differ at compile-time (Dart) and runtime (JS).
+
+import "package:expect/expect.dart";
+
+foo() => 0.0;
+bar() => 0;
+
+main() {
+  Expect.equals(foo(), bar());
+  Expect.equals(0.0, 0);
+}
diff --git a/tests/dart2js/constant_folding2_test.dart b/tests/dart2js/constant_folding2_test.dart
new file mode 100644
index 0000000..b8fbee4
--- /dev/null
+++ b/tests/dart2js/constant_folding2_test.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:expect/expect.dart';
+
+get b => 499;
+@pragma('dart2js:noInline')
+get b_noInline => b;
+const b0 = 499 is FutureOr<int>;
+final b1 = 499 is FutureOr<int>;
+get b2 => 499 is FutureOr<int>;
+get b3 => b is FutureOr<int>;
+get b4 => b_noInline is FutureOr<int>;
+
+get c => 499;
+@pragma('dart2js:noInline')
+get c_noInline => c;
+const c0 = 499 is FutureOr<FutureOr<int>>;
+final c1 = 499 is FutureOr<FutureOr<int>>;
+get c2 => 499 is FutureOr<FutureOr<int>>;
+get c3 => c is FutureOr<FutureOr<int>>;
+get c4 => c_noInline is FutureOr<FutureOr<int>>;
+
+get d => 499.0;
+@pragma('dart2js:noInline')
+get d_noInline => d;
+const d0 = 499.0 is FutureOr<int>;
+final d1 = 499.0 is FutureOr<int>;
+get d2 => 499.0 is FutureOr<int>;
+get d3 => d is FutureOr<int>;
+get d4 => d_noInline is FutureOr<int>;
+
+get e => 499;
+@pragma('dart2js:noInline')
+get e_noInline => e;
+const e0 = 499 is FutureOr<double>;
+final e1 = 499 is FutureOr<double>;
+get e2 => 499 is FutureOr<double>;
+get e3 => e is FutureOr<double>;
+get e4 => e_noInline is FutureOr<double>;
+
+get f => 499;
+@pragma('dart2js:noInline')
+get f_noInline => f;
+const f0 = 499 is FutureOr<FutureOr<double>>;
+final f1 = 499 is FutureOr<FutureOr<double>>;
+get f2 => 499 is FutureOr<FutureOr<double>>;
+get f3 => f is FutureOr<FutureOr<double>>;
+get f4 => f_noInline is FutureOr<FutureOr<double>>;
+
+test(fromConst, fromFinal, fromImplicitConstant, fromInlined, fromRuntime) {
+  Expect.equals(fromRuntime, fromConst);
+  Expect.equals(fromRuntime, fromFinal);
+  Expect.equals(fromRuntime, fromInlined);
+  Expect.equals(fromRuntime, fromImplicitConstant);
+}
+
+main() {
+  test(b0, b1, b2, b3, b4);
+  test(c0, c1, c2, c3, c4);
+  test(d0, d1, d2, d3, d4);
+  test(e0, e1, e2, e3, e4);
+  test(f0, f1, f2, f3, f4);
+}
\ No newline at end of file
diff --git a/tests/dart2js/constant_folding_test.dart b/tests/dart2js/constant_folding_test.dart
new file mode 100644
index 0000000..b9b050b
--- /dev/null
+++ b/tests/dart2js/constant_folding_test.dart
@@ -0,0 +1,1283 @@
+// 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";
+
+void main() {
+  const BitNot(42, 4294967253).check();
+  const BitNot(4294967253, 42).check();
+  const BitNot(-42, 41).check();
+  const BitNot(-1, 0).check();
+  const BitNot(0, 0xFFFFFFFF).check();
+  const BitNot(4294967295, 0).check();
+  const BitNot(0x12121212121212, 0xEDEDEDED).check();
+  const BitNot(0x7fffffff00000000, 0xffffffff).check();
+  const BitNot(0x8000000000000000, 0xffffffff).check();
+
+  const Negate(0, -0).check();
+  const Negate(-0, 0).check();
+  const Negate(0.0, -0.0).check();
+  const Negate(-0.0, 0.0).check();
+  const Negate(-0.0, 0).check();
+  const Negate(-0, 0.0).check();
+  const Negate(0, -0.0).check();
+  const Negate(0.0, -0).check();
+  const Negate(1, -1).check();
+  const Negate(-1, 1).check();
+  const Negate(1.0, -1.0).check();
+  const Negate(-1.0, 1.0).check();
+  const Negate(3.14, -3.14).check();
+  const Negate(-3.14, 3.14).check();
+  const Negate(4294967295, -4294967295).check();
+  const Negate(-4294967295, 4294967295).check();
+  const Negate(4294967295.5, -4294967295.5).check();
+  const Negate(-4294967295.5, 4294967295.5).check();
+  const Negate(4294967296, -4294967296).check();
+  const Negate(-4294967296, 4294967296).check();
+  const Negate(4294967296.5, -4294967296.5).check();
+  const Negate(-4294967296.5, 4294967296.5).check();
+  const Negate(9007199254740991, -9007199254740991).check();
+  const Negate(-9007199254740991, 9007199254740991).check();
+  const Negate(9007199254740991.5, -9007199254740991.5).check();
+  const Negate(-9007199254740991.5, 9007199254740991.5).check();
+  const Negate(9007199254740992, -9007199254740992).check();
+  const Negate(-9007199254740992, 9007199254740992).check();
+  const Negate(9007199254740992.5, -9007199254740992.5).check();
+  const Negate(-9007199254740992.5, 9007199254740992.5).check();
+  const Negate(double.infinity, double.negativeInfinity).check();
+  const Negate(double.negativeInfinity, double.infinity).check();
+  const Negate(double.maxFinite, -double.maxFinite).check();
+  const Negate(-double.maxFinite, double.maxFinite).check();
+  const Negate(double.minPositive, -double.minPositive).check();
+  const Negate(-double.minPositive, double.minPositive).check();
+  const Negate(double.nan, double.nan).check();
+  const Negate(0x7fffffff00000000, -0x7fffffff00000000).check();
+  const Negate(-0x7fffffff00000000, 0x7fffffff00000000).check();
+  const Negate(0x8000000000000000, -0x8000000000000000).check();
+  const Negate(-0x8000000000000000, 0x8000000000000000).check();
+
+  const Not(true, false).check();
+  const Not(false, true).check();
+
+  const BitAnd(314159, 271828, 262404).check();
+  const BitAnd(271828, 314159, 262404).check();
+  const BitAnd(0, 0, 0).check();
+  const BitAnd(-1, 0, 0).check();
+  const BitAnd(-1, 314159, 314159).check();
+  const BitAnd(-1, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitAnd(0xff, -4, 0xfc).check();
+  const BitAnd(0, 0xFFFFFFFF, 0).check();
+  const BitAnd(0xFFFFFFFF, 0, 0).check();
+  const BitAnd(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitAnd(0x123456789ABC, 0xEEEEEEEEEEEE, 0x46688AAC).check();
+  const BitAnd(0x7fffffff00008000, 0x8000000000008000, 0x8000).check();
+  const BitAnd(0x8000000000008000, 0x7fffffff00008000, 0x8000).check();
+  const BitAnd(true, true, true).check();
+  const BitAnd(true, false, false).check();
+  const BitAnd(false, true, false).check();
+  const BitAnd(false, false, false).check();
+
+  const BitOr(314159, 271828, 323583).check();
+  const BitOr(271828, 314159, 323583).check();
+  const BitOr(0, 0, 0).check();
+  const BitOr(-8, 0, 0xFFFFFFF8).check();
+  const BitOr(-8, 271828, 0xFFFFFFFC).check();
+  const BitOr(-8, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitOr(0x1, -4, 0xFFFFFFFD).check();
+  const BitOr(0, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitOr(0xFFFFFFFF, 0, 0xFFFFFFFF).check();
+  const BitOr(0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitOr(0x123456789ABC, 0x111111111111, 0x57799BBD).check();
+  const BitOr(0x7000000080000000, 0x8000000000008000, 0x80008000).check();
+  const BitOr(0x8000000000008000, 0x7000000080000000, 0x80008000).check();
+  const BitOr(true, true, true).check();
+  const BitOr(true, false, true).check();
+  const BitOr(false, true, true).check();
+  const BitOr(false, false, false).check();
+
+  const BitXor(314159, 271828, 61179).check();
+  const BitXor(271828, 314159, 61179).check();
+  const BitXor(0, 0, 0).check();
+  const BitXor(-1, 0, 0xFFFFFFFF).check();
+  const BitXor(-256, 1, 0xFFFFFF01).check();
+  const BitXor(-256, -255, 1).check();
+  const BitXor(0, 0xFFFFFFFF, 0xFFFFFFFF).check();
+  const BitXor(0xFFFFFFFF, 0, 0xFFFFFFFF).check();
+  const BitXor(0xFFFFFFFF, 0xFFFFFFFF, 0).check();
+  const BitXor(0x123456789ABC, 0x111111111111, 0x47698BAD).check();
+  const BitXor(0x7000000012340000, 0x8000000011110000, 0x03250000).check();
+  const BitXor(0x8000000011110000, 0x7000000012340000, 0x03250000).check();
+  const BitXor(true, true, false).check();
+  const BitXor(true, false, true).check();
+  const BitXor(false, true, true).check();
+  const BitXor(false, false, false).check();
+
+  const ShiftLeft(42, 0, 42).check();
+  const ShiftLeft(42, 5, 1344).check();
+  const ShiftLeft(1, 31, 0x80000000).check();
+  const ShiftLeft(1, 32, 0).check();
+  const ShiftLeft(1, 100, 0).check();
+  const ShiftLeft(0, 0, 0).check();
+  const ShiftLeft(0, 5, 0).check();
+  const ShiftLeft(0, 31, 0).check();
+  const ShiftLeft(0, 32, 0).check();
+  const ShiftLeft(0, 100, 0).check();
+  const ShiftLeft(-1, 0, 0xFFFFFFFF).check();
+  const ShiftLeft(-1, 5, 0xFFFFFFE0).check();
+  const ShiftLeft(-1, 31, 0x80000000).check();
+  const ShiftLeft(-1, 32, 0).check();
+  const ShiftLeft(-1, 100, 0).check();
+  const ShiftLeft(0x7000000000008000, 0, 0x8000).check();
+  const ShiftLeft(0x7000000000008000, 1, 0x10000).check();
+  const ShiftLeft(0x7000000000008000, 16, 0x80000000).check();
+  const ShiftLeft(0x7000000000008000, 17, 0x0).check();
+  const ShiftLeft(0x8000000000008000, 0, 0x8000).check();
+  const ShiftLeft(0x8000000000008000, 1, 0x10000).check();
+  const ShiftLeft(0x8000000000008000, 16, 0x80000000).check();
+  const ShiftLeft(0x8000000000008000, 17, 0x0).check();
+
+  const ShiftRight(8675309, 0, 8675309).check();
+  const ShiftRight(8675309, 5, 271103).check();
+  const ShiftRight(0xFEDCBA98, 0, 0xFEDCBA98).check();
+  const ShiftRight(0xFEDCBA98, 5, 0x07F6E5D4).check();
+  const ShiftRight(0xFEDCBA98, 31, 1).check();
+  const ShiftRight(0xFEDCBA98, 32, 0).check();
+  const ShiftRight(0xFEDCBA98, 100, 0).check();
+  const ShiftRight(0xFFFFFEDCBA98, 0, 0xFEDCBA98).check();
+  const ShiftRight(0xFFFFFEDCBA98, 5, 0x07F6E5D4).check();
+  const ShiftRight(0xFFFFFEDCBA98, 31, 1).check();
+  const ShiftRight(0xFFFFFEDCBA98, 32, 0).check();
+  const ShiftRight(0xFFFFFEDCBA98, 100, 0).check();
+  const ShiftRight(-1, 0, 0xFFFFFFFF).check();
+  const ShiftRight(-1, 5, 0xFFFFFFFF).check();
+  const ShiftRight(-1, 31, 0xFFFFFFFF).check();
+  const ShiftRight(-1, 32, 0xFFFFFFFF).check();
+  const ShiftRight(-1, 100, 0xFFFFFFFF).check();
+  const ShiftRight(-1073741824, 0, 0xC0000000).check();
+  const ShiftRight(-1073741824, 5, 0xFE000000).check();
+  const ShiftRight(-1073741824, 31, 0xFFFFFFFF).check();
+  const ShiftRight(-1073741824, 32, 0xFFFFFFFF).check();
+  const ShiftRight(-1073741824, 100, 0xFFFFFFFF).check();
+  const ShiftRight(0x7000000000008000, 0, 0x8000).check();
+  const ShiftRight(0x7000000000008000, 1, 0x4000).check();
+  const ShiftRight(0x7000000000008000, 15, 0x1).check();
+  const ShiftRight(0x7000000000008000, 16, 0).check();
+  const ShiftRight(0x8000000000008000, 0, 0x8000).check();
+  const ShiftRight(0x8000000000008000, 1, 0x4000).check();
+  const ShiftRight(0x8000000000008000, 15, 0x1).check();
+  const ShiftRight(0x8000000000008000, 16, 0).check();
+
+  const BooleanAnd(true, true, true).check();
+  const BooleanAnd(true, false, false).check();
+  const BooleanAnd(false, true, false).check();
+  const BooleanAnd(false, false, false).check();
+  const BooleanAnd(false, null, false).check();
+
+  const BooleanOr(true, true, true).check();
+  const BooleanOr(true, false, true).check();
+  const BooleanOr(false, true, true).check();
+  const BooleanOr(false, false, false).check();
+  const BooleanOr(true, null, true).check();
+
+  const Subtract(314159, 271828, 42331).check();
+  const Subtract(271828, 314159, -42331).check();
+  const Subtract(0, 0, 0).check();
+  const Subtract(0, 42, -42).check();
+  const Subtract(0, -42, 42).check();
+  const Subtract(42, 0, 42).check();
+  const Subtract(42, 42, 0).check();
+  const Subtract(42, -42, 84).check();
+  const Subtract(-42, 0, -42).check();
+  const Subtract(-42, 42, -84).check();
+  const Subtract(-42, -42, 0).check();
+  const Subtract(4294967295, -1, 4294967296).check();
+  const Subtract(4294967296, -1, 4294967297).check();
+  const Subtract(9007199254740991, -1, 9007199254740992).check();
+  const Subtract(9007199254740992, -1, 9007199254740992).check();
+  const Subtract(9007199254740992, -100, 9007199254741092).check();
+  const Subtract(-4294967295, 1, -4294967296).check();
+  const Subtract(-4294967296, 1, -4294967297).check();
+  const Subtract(-9007199254740991, 1, -9007199254740992).check();
+  const Subtract(-9007199254740992, 1, -9007199254740992).check();
+  const Subtract(-9007199254740992, 100, -9007199254741092).check();
+  const Subtract(
+          0x7fffffff00000000, -0x7fffffff00000000, 2 * 0x7fffffff00000000)
+      .check();
+  const Subtract(4.2, 1.5, 2.7).check();
+  const Subtract(1.5, 4.2, -2.7).check();
+  const Subtract(1.5, 0, 1.5).check();
+  const Subtract(0, 1.5, -1.5).check();
+  const Subtract(1.5, 1.5, 0.0).check();
+  const Subtract(-1.5, -1.5, 0.0).check();
+  const Subtract(0.0, 0.0, 0.0).check();
+  const Subtract(0.0, -0.0, 0.0).check();
+  const Subtract(-0.0, 0.0, -0.0).check();
+  const Subtract(-0.0, -0.0, 0.0).check();
+  const Subtract(double.maxFinite, -double.maxFinite, double.infinity).check();
+  const Subtract(-double.maxFinite, double.maxFinite, double.negativeInfinity)
+      .check();
+  const Subtract(1.5, double.nan, double.nan).check();
+  const Subtract(double.nan, 1.5, double.nan).check();
+  const Subtract(double.nan, double.nan, double.nan).check();
+  const Subtract(double.nan, double.infinity, double.nan).check();
+  const Subtract(double.nan, double.negativeInfinity, double.nan).check();
+  const Subtract(double.infinity, double.nan, double.nan).check();
+  const Subtract(double.negativeInfinity, double.nan, double.nan).check();
+  const Subtract(double.infinity, double.maxFinite, double.infinity).check();
+  const Subtract(double.infinity, -double.maxFinite, double.infinity).check();
+  const Subtract(
+          double.negativeInfinity, double.maxFinite, double.negativeInfinity)
+      .check();
+  const Subtract(
+          double.negativeInfinity, -double.maxFinite, double.negativeInfinity)
+      .check();
+  const Subtract(1.5, double.infinity, double.negativeInfinity).check();
+  const Subtract(1.5, double.negativeInfinity, double.infinity).check();
+  const Subtract(double.infinity, double.infinity, double.nan).check();
+  const Subtract(double.infinity, double.negativeInfinity, double.infinity)
+      .check();
+  const Subtract(
+          double.negativeInfinity, double.infinity, double.negativeInfinity)
+      .check();
+  const Subtract(double.negativeInfinity, double.negativeInfinity, double.nan)
+      .check();
+  const Subtract(double.minPositive, double.minPositive, 0.0).check();
+  const Subtract(-double.minPositive, -double.minPositive, 0.0).check();
+
+  const Multiply(6, 7, 42).check();
+  const Multiply(-6, 7, -42).check();
+  const Multiply(6, -7, -42).check();
+  const Multiply(-6, -7, 42).check();
+  const Multiply(0, 0, 0).check();
+  const Multiply(0, 7, 0).check();
+  const Multiply(6, 0, 0).check();
+  const Multiply(65536, 65536, 4294967296).check();
+  const Multiply(4294967296, -1, -4294967296).check();
+  const Multiply(-1, 4294967296, -4294967296).check();
+  const Multiply(134217728, 134217728, 18014398509481984).check();
+  const Multiply(18014398509481984, -1, -18014398509481984).check();
+  const Multiply(-1, 18014398509481984, -18014398509481984).check();
+  const Multiply(9000000000000000, 9000000000000000, 8.1e31).check();
+  const Multiply(0x7fff000000000000, 0x8000000000000000, 8.506799558180535e37)
+      .check();
+  const Multiply(0x8000000000000000, 1.2, 11068046444225730000.0).check();
+  const Multiply(3.14, 2.72, 8.5408).check();
+  const Multiply(-3.14, 2.72, -8.5408).check();
+  const Multiply(3.14, -2.72, -8.5408).check();
+  const Multiply(-3.14, -2.72, 8.5408).check();
+  const Multiply(3.14, 0, 0.0).check();
+  const Multiply(0, 2.72, 0.0).check();
+  const Multiply(0.0, 0.0, 0.0).check();
+  const Multiply(0.0, -0.0, -0.0).check();
+  const Multiply(-0.0, 0.0, -0.0).check();
+  const Multiply(-0.0, -0.0, 0.0).check();
+  const Multiply(double.maxFinite, double.maxFinite, double.infinity).check();
+  const Multiply(double.maxFinite, -double.maxFinite, double.negativeInfinity)
+      .check();
+  const Multiply(-double.maxFinite, double.maxFinite, double.negativeInfinity)
+      .check();
+  const Multiply(-double.maxFinite, -double.maxFinite, double.infinity).check();
+  const Multiply(0, double.nan, double.nan).check();
+  const Multiply(double.nan, 0, double.nan).check();
+  const Multiply(double.nan, double.nan, double.nan).check();
+  const Multiply(0, double.infinity, double.nan).check();
+  const Multiply(double.infinity, 0, double.nan).check();
+  const Multiply(0, double.negativeInfinity, double.nan).check();
+  const Multiply(double.negativeInfinity, 0, double.nan).check();
+  const Multiply(-0.0, double.infinity, double.nan).check();
+  const Multiply(double.infinity, -0.0, double.nan).check();
+  const Multiply(-0.0, double.negativeInfinity, double.nan).check();
+  const Multiply(double.negativeInfinity, -0.0, double.nan).check();
+  const Multiply(double.infinity, double.infinity, double.infinity).check();
+  const Multiply(
+          double.infinity, double.negativeInfinity, double.negativeInfinity)
+      .check();
+  const Multiply(
+          double.negativeInfinity, double.infinity, double.negativeInfinity)
+      .check();
+  const Multiply(
+          double.negativeInfinity, double.negativeInfinity, double.infinity)
+      .check();
+  const Multiply(double.minPositive, 0.5, 0.0).check();
+  const Multiply(double.minPositive, -0.5, -0.0).check();
+  const Multiply(-double.minPositive, 0.5, -0.0).check();
+  const Multiply(-double.minPositive, -0.5, 0.0).check();
+  const Multiply(1e-300, -1e-300, -0.0).check();
+  const Multiply(double.minPositive, double.infinity, double.infinity).check();
+  const Multiply(
+          double.minPositive, double.negativeInfinity, double.negativeInfinity)
+      .check();
+  const Multiply(double.minPositive, double.maxFinite, 8.881784197001251e-16)
+      .check();
+
+  const Modulo(27, 314159, 27).check();
+  const Modulo(27, 1, 0).check();
+  const Modulo(27, -1, 0).check();
+  const Modulo(-27, 1, 0).check();
+  const Modulo(-27, -1, 0).check();
+  const Modulo(314159, 27, 14).check();
+  const Modulo(314159, -27, 14).check();
+  const Modulo(-314159, 27, 13).check();
+  const Modulo(-314159, -27, 13).check();
+  const Modulo(4294967295, 4294967296, 4294967295).check();
+  const Modulo(4294967295, -4294967296, 4294967295).check();
+  const Modulo(-4294967295, 4294967296, 1).check();
+  const Modulo(-4294967295, -4294967296, 1).check();
+  const Modulo(9007199254740991, 9007199254740992, 9007199254740991).check();
+  const Modulo(9007199254740991, -9007199254740992, 9007199254740991).check();
+  const Modulo(-9007199254740991, 9007199254740992, 1).check();
+  const Modulo(-9007199254740991, -9007199254740992, 1).check();
+  const Modulo(2.71828, 3.14159, 2.71828).check();
+  const Modulo(2.71828, 1, 0.71828).check();
+  const Modulo(2.71828, -1, 0.71828).check();
+  const Modulo(-2.71828, 1, 0.28171999999999997).check();
+  const Modulo(-2.71828, -1, 0.28171999999999997).check();
+  const Modulo(27.1828, 3.14159, 2.0500800000000012).check();
+  const Modulo(27.1828, -3.14159, 2.0500800000000012).check();
+  const Modulo(-27.1828, 3.14159, 1.0915099999999986).check();
+  const Modulo(-27.1828, -3.14159, 1.0915099999999986).check();
+  const Modulo(42, double.nan, double.nan).check();
+  const Modulo(double.nan, 42, double.nan).check();
+  const Modulo(0, double.nan, double.nan).check();
+  const Modulo(double.nan, double.nan, double.nan).check();
+  const Modulo(double.infinity, double.nan, double.nan).check();
+  const Modulo(double.nan, double.infinity, double.nan).check();
+  const Modulo(0.0, double.infinity, 0).check();
+  const Modulo(-0.0, double.infinity, 0).check();
+  const Modulo(0.0, double.negativeInfinity, 0).check();
+  const Modulo(-0.0, double.negativeInfinity, 0).check();
+  const Modulo(42, double.infinity, 42).check();
+  const Modulo(-42, double.infinity, double.infinity).check();
+  const Modulo(42, double.negativeInfinity, 42).check();
+  const Modulo(-42, double.negativeInfinity, double.infinity).check();
+  const Modulo(double.infinity, 42, double.nan).check();
+  const Modulo(double.infinity, -42, double.nan).check();
+  const Modulo(double.negativeInfinity, 42, double.nan).check();
+  const Modulo(double.negativeInfinity, -42, double.nan).check();
+  const Modulo(double.infinity, double.infinity, double.nan).check();
+  const Modulo(double.negativeInfinity, double.infinity, double.nan).check();
+  const Modulo(double.infinity, double.negativeInfinity, double.nan).check();
+  const Modulo(double.negativeInfinity, double.negativeInfinity, double.nan)
+      .check();
+
+  const TruncatingDivide(27, 314159, 0).check();
+  const TruncatingDivide(27, 1, 27).check();
+  const TruncatingDivide(27, -1, -27).check();
+  const TruncatingDivide(-27, 1, -27).check();
+  const TruncatingDivide(-27, -1, 27).check();
+  const TruncatingDivide(314159, 27, 11635).check();
+  const TruncatingDivide(314159, -27, -11635).check();
+  const TruncatingDivide(-314159, 27, -11635).check();
+  const TruncatingDivide(-314159, -27, 11635).check();
+  const TruncatingDivide(4294967295, 4294967296, 0).check();
+  const TruncatingDivide(4294967295, -4294967296, 0).check();
+  const TruncatingDivide(-4294967295, 4294967296, 0).check();
+  const TruncatingDivide(-4294967295, -4294967296, 0).check();
+  const TruncatingDivide(9007199254740991, 9007199254740992, 0).check();
+  const TruncatingDivide(9007199254740991, -9007199254740992, 0).check();
+  const TruncatingDivide(-9007199254740991, 9007199254740992, 0).check();
+  const TruncatingDivide(-9007199254740991, -9007199254740992, 0).check();
+  const TruncatingDivide(4294967295, 0.5, 8589934590).check();
+  const TruncatingDivide(4294967295, -0.5, -8589934590).check();
+  const TruncatingDivide(-4294967295, 0.5, -8589934590).check();
+  const TruncatingDivide(-4294967295, -0.5, 8589934590).check();
+  const TruncatingDivide(9007199254740991, 0.5, 18014398509481982).check();
+  const TruncatingDivide(9007199254740991, -0.5, -18014398509481982).check();
+  const TruncatingDivide(-9007199254740991, 0.5, -18014398509481982).check();
+  const TruncatingDivide(-9007199254740991, -0.5, 18014398509481982).check();
+  const TruncatingDivide(0x8000000000000000, -1, -0x8000000000000000).check();
+  const TruncatingDivide(0x6000000000000000, 0.5, 0xC000000000000000).check();
+  const TruncatingDivide(2.71828, 3.14159, 0).check();
+  const TruncatingDivide(2.71828, 1, 2).check();
+  const TruncatingDivide(2.71828, -1, -2).check();
+  const TruncatingDivide(-2.71828, 1, -2).check();
+  const TruncatingDivide(-2.71828, -1, 2).check();
+  const TruncatingDivide(27.1828, 3.14159, 8).check();
+  const TruncatingDivide(27.1828, -3.14159, -8).check();
+  const TruncatingDivide(-27.1828, 3.14159, -8).check();
+  const TruncatingDivide(-27.1828, -3.14159, 8).check();
+  const TruncatingDivide(0.0, double.infinity, 0).check();
+  const TruncatingDivide(-0.0, double.infinity, 0).check();
+  const TruncatingDivide(0.0, double.negativeInfinity, 0).check();
+  const TruncatingDivide(-0.0, double.negativeInfinity, 0).check();
+  const TruncatingDivide(42, double.infinity, 0).check();
+  const TruncatingDivide(-42, double.infinity, 0).check();
+  const TruncatingDivide(42, double.negativeInfinity, 0).check();
+  const TruncatingDivide(-42, double.negativeInfinity, 0).check();
+
+  const Divide(27, 3, 9).check();
+  const Divide(27, 1, 27).check();
+  const Divide(27, -1, -27).check();
+  const Divide(-27, 1, -27).check();
+  const Divide(-27, -1, 27).check();
+  const Divide(0, 1, 0).check();
+  const Divide(0, -1, -0.0).check();
+  const Divide(-0.0, 1, -0.0).check();
+  const Divide(-0.0, -1, 0).check();
+  const Divide(314159, 27, 11635.518518518518).check();
+  const Divide(314159, -27, -11635.518518518518).check();
+  const Divide(-314159, 27, -11635.518518518518).check();
+  const Divide(-314159, -27, 11635.518518518518).check();
+  const Divide(4294967295, 4294967296, 0.9999999997671694).check();
+  const Divide(4294967295, -4294967296, -0.9999999997671694).check();
+  const Divide(-4294967295, 4294967296, -0.9999999997671694).check();
+  const Divide(-4294967295, -4294967296, 0.9999999997671694).check();
+  const Divide(9007199254740991, 9007199254740992, 0.9999999999999999).check();
+  const Divide(9007199254740991, -9007199254740992, -0.9999999999999999)
+      .check();
+  const Divide(-9007199254740991, 9007199254740992, -0.9999999999999999)
+      .check();
+  const Divide(-9007199254740991, -9007199254740992, 0.9999999999999999)
+      .check();
+  const Divide(4294967296, 4294967295, 1.0000000002328306).check();
+  const Divide(4294967296, -4294967295, -1.0000000002328306).check();
+  const Divide(-4294967296, 4294967295, -1.0000000002328306).check();
+  const Divide(-4294967296, -4294967295, 1.0000000002328306).check();
+  const Divide(9007199254740992, 9007199254740991, 1.0000000000000002).check();
+  const Divide(9007199254740992, -9007199254740991, -1.0000000000000002)
+      .check();
+  const Divide(-9007199254740992, 9007199254740991, -1.0000000000000002)
+      .check();
+  const Divide(-9007199254740992, -9007199254740991, 1.0000000000000002)
+      .check();
+  const Divide(4294967295, 0.5, 8589934590).check();
+  const Divide(4294967295, -0.5, -8589934590).check();
+  const Divide(-4294967295, 0.5, -8589934590).check();
+  const Divide(-4294967295, -0.5, 8589934590).check();
+  const Divide(9007199254740991, 0.5, 18014398509481982).check();
+  const Divide(9007199254740991, -0.5, -18014398509481982).check();
+  const Divide(-9007199254740991, 0.5, -18014398509481982).check();
+  const Divide(-9007199254740991, -0.5, 18014398509481982).check();
+  const Divide(2.71828, 3.14159, 0.8652561282662601).check();
+  const Divide(2.71828, 1, 2.71828).check();
+  const Divide(2.71828, -1, -2.71828).check();
+  const Divide(-2.71828, 1, -2.71828).check();
+  const Divide(-2.71828, -1, 2.71828).check();
+  const Divide(27.1828, 3.14159, 8.652561282662601).check();
+  const Divide(27.1828, -3.14159, -8.652561282662601).check();
+  const Divide(-27.1828, 3.14159, -8.652561282662601).check();
+  const Divide(-27.1828, -3.14159, 8.652561282662601).check();
+  const Divide(1, 0, double.infinity).check();
+  const Divide(1, -0.0, double.negativeInfinity).check();
+  const Divide(-1, 0, double.negativeInfinity).check();
+  const Divide(-1, -0.0, double.infinity).check();
+  const Divide(0, 0, double.nan).check();
+  const Divide(0, -0.0, double.nan).check();
+  const Divide(-0.0, 0, double.nan).check();
+  const Divide(-0.0, -0.0, double.nan).check();
+  const Divide(double.infinity, 0, double.infinity).check();
+  const Divide(double.infinity, -0.0, double.negativeInfinity).check();
+  const Divide(double.negativeInfinity, 0, double.negativeInfinity).check();
+  const Divide(double.negativeInfinity, -0.0, double.infinity).check();
+  const Divide(double.nan, 0, double.nan).check();
+  const Divide(double.nan, -0.0, double.nan).check();
+  const Divide(double.nan, 1, double.nan).check();
+  const Divide(1, double.nan, double.nan).check();
+  const Divide(0, double.nan, double.nan).check();
+  const Divide(double.nan, double.nan, double.nan).check();
+  const Divide(double.nan, double.infinity, double.nan).check();
+  const Divide(double.infinity, double.nan, double.nan).check();
+  const Divide(double.negativeInfinity, double.nan, double.nan).check();
+  const Divide(double.infinity, 1, double.infinity).check();
+  const Divide(double.infinity, -1, double.negativeInfinity).check();
+  const Divide(double.negativeInfinity, 1, double.negativeInfinity).check();
+  const Divide(double.negativeInfinity, -1, double.infinity).check();
+  const Divide(0, double.infinity, 0).check();
+  const Divide(0, double.negativeInfinity, -0.0).check();
+  const Divide(-0.0, double.infinity, -0.0).check();
+  const Divide(-0.0, double.negativeInfinity, 0).check();
+  const Divide(1, double.infinity, 0).check();
+  const Divide(1, double.negativeInfinity, -0.0).check();
+  const Divide(-1, double.infinity, -0.0).check();
+  const Divide(-1, double.negativeInfinity, 0).check();
+  const Divide(double.infinity, double.infinity, double.nan).check();
+  const Divide(double.minPositive, double.maxFinite, 0).check();
+  const Divide(double.minPositive, -double.maxFinite, -0.0).check();
+  const Divide(-double.minPositive, double.maxFinite, -0.0).check();
+  const Divide(-double.minPositive, -double.maxFinite, 0).check();
+  const Divide(double.maxFinite, double.minPositive, double.infinity).check();
+  const Divide(double.maxFinite, -double.minPositive, double.negativeInfinity)
+      .check();
+  const Divide(-double.maxFinite, double.minPositive, double.negativeInfinity)
+      .check();
+  const Divide(-double.maxFinite, -double.minPositive, double.infinity).check();
+
+  const Add("", "", "").check();
+  const Add("foo", "", "foo").check();
+  const Add("", "bar", "bar").check();
+  const Add("foo", "bar", "foobar").check();
+  const Add(314159, 271828, 585987).check();
+  const Add(314159, -271828, 42331).check();
+  const Add(-314159, 271828, -42331).check();
+  const Add(-314159, -271828, -585987).check();
+  const Add(0, 0, 0).check();
+  const Add(0, 42, 42).check();
+  const Add(0, -42, -42).check();
+  const Add(42, 0, 42).check();
+  const Add(42, 42, 84).check();
+  const Add(42, -42, 0).check();
+  const Add(-42, 0, -42).check();
+  const Add(-42, 42, 0).check();
+  const Add(-42, -42, -84).check();
+  const Add(4294967295, 1, 4294967296).check();
+  const Add(4294967296, 1, 4294967297).check();
+  const Add(9007199254740991, 1, 9007199254740992).check();
+  const Add(9007199254740992, 1, 9007199254740992).check();
+  const Add(9007199254740992, 100, 9007199254741092).check();
+  const Add(-4294967295, -1, -4294967296).check();
+  const Add(-4294967296, -1, -4294967297).check();
+  const Add(-9007199254740991, -1, -9007199254740992).check();
+  const Add(-9007199254740992, -1, -9007199254740992).check();
+  const Add(-9007199254740992, -100, -9007199254741092).check();
+  const Add(4.2, 1.5, 5.7).check();
+  const Add(4.2, -1.5, 2.7).check();
+  const Add(-4.2, 1.5, -2.7).check();
+  const Add(-4.2, -1.5, -5.7).check();
+  const Add(1.5, 0, 1.5).check();
+  const Add(0, 1.5, 1.5).check();
+  const Add(1.5, -1.5, 0.0).check();
+  const Add(-1.5, 1.5, 0.0).check();
+  const Add(0.0, 0.0, 0.0).check();
+  const Add(0.0, -0.0, 0.0).check();
+  const Add(-0.0, 0.0, 0.0).check();
+  const Add(-0.0, -0.0, -0.0).check();
+  const Add(double.maxFinite, double.maxFinite, double.infinity).check();
+  const Add(-double.maxFinite, -double.maxFinite, double.negativeInfinity)
+      .check();
+  const Add(1.5, double.nan, double.nan).check();
+  const Add(double.nan, 1.5, double.nan).check();
+  const Add(double.nan, double.nan, double.nan).check();
+  const Add(double.nan, double.infinity, double.nan).check();
+  const Add(double.nan, double.negativeInfinity, double.nan).check();
+  const Add(double.infinity, double.nan, double.nan).check();
+  const Add(double.negativeInfinity, double.nan, double.nan).check();
+  const Add(double.infinity, -double.maxFinite, double.infinity).check();
+  const Add(double.infinity, double.maxFinite, double.infinity).check();
+  const Add(double.negativeInfinity, -double.maxFinite, double.negativeInfinity)
+      .check();
+  const Add(double.negativeInfinity, double.maxFinite, double.negativeInfinity)
+      .check();
+  const Add(1.5, double.negativeInfinity, double.negativeInfinity).check();
+  const Add(1.5, double.infinity, double.infinity).check();
+  const Add(double.infinity, double.infinity, double.infinity).check();
+  const Add(double.infinity, double.negativeInfinity, double.nan).check();
+  const Add(double.negativeInfinity, double.infinity, double.nan).check();
+  const Add(double.negativeInfinity, double.negativeInfinity,
+          double.negativeInfinity)
+      .check();
+  const Add(double.minPositive, -double.minPositive, 0.0).check();
+  const Add(-double.minPositive, double.minPositive, 0.0).check();
+
+  const Less(double.nan, double.nan, false).check();
+  const Less(double.nan, double.infinity, false).check();
+  const Less(double.infinity, double.nan, false).check();
+  const Less(double.nan, double.maxFinite, false).check();
+  const Less(double.maxFinite, double.nan, false).check();
+  const Less(double.nan, -double.maxFinite, false).check();
+  const Less(-double.maxFinite, double.nan, false).check();
+  const Less(double.nan, double.negativeInfinity, false).check();
+  const Less(double.negativeInfinity, double.nan, false).check();
+  const Less(double.negativeInfinity, double.negativeInfinity, false).check();
+  const Less(double.negativeInfinity, -double.maxFinite, true).check();
+  const Less(-double.maxFinite, double.negativeInfinity, false).check();
+  const Less(-double.maxFinite, -double.maxFinite, false).check();
+  const Less(-double.maxFinite, -9007199254740992, true).check();
+  const Less(-9007199254740992, -double.maxFinite, false).check();
+  const Less(-9007199254740992, -9007199254740992, false).check();
+  const Less(-9007199254740992, -4294967296, true).check();
+  const Less(-4294967296, -9007199254740992, false).check();
+  const Less(-4294967296, -4294967296, false).check();
+  const Less(-4294967296, -42, true).check();
+  const Less(-42, -4294967296, false).check();
+  const Less(-42, -42, false).check();
+  const Less(-42, -42.0, false).check();
+  const Less(-42.0, -42, false).check();
+  const Less(-42.0, -42.0, false).check();
+  const Less(-42, -3.14, true).check();
+  const Less(-3.14, -42, false).check();
+  const Less(-3.14, -3.14, false).check();
+  const Less(-3.14, -double.minPositive, true).check();
+  const Less(-double.minPositive, -3.14, false).check();
+  const Less(-double.minPositive, -double.minPositive, false).check();
+  const Less(-double.minPositive, -0.0, true).check();
+  const Less(-0.0, -double.minPositive, false).check();
+  const Less(-0.0, -0.0, false).check();
+  const Less(0, 0, false).check();
+  const Less(0.0, 0.0, false).check();
+  const Less(-0.0, 0, false).check();
+  const Less(0, -0.0, false).check();
+  const Less(-0.0, 0.0, false).check();
+  const Less(0.0, -0.0, false).check();
+  const Less(0, 0.0, false).check();
+  const Less(0.0, 0, false).check();
+  const Less(0.0, double.minPositive, true).check();
+  const Less(double.minPositive, 0.0, false).check();
+  const Less(double.minPositive, double.minPositive, false).check();
+  const Less(double.minPositive, 3.14, true).check();
+  const Less(3.14, double.minPositive, false).check();
+  const Less(3.14, 3.14, false).check();
+  const Less(3.14, 42, true).check();
+  const Less(42, 3.14, false).check();
+  const Less(42.0, 42.0, false).check();
+  const Less(42, 42.0, false).check();
+  const Less(42.0, 42, false).check();
+  const Less(42, 42, false).check();
+  const Less(42, 4294967296, true).check();
+  const Less(4294967296, 42, false).check();
+  const Less(4294967296, 4294967296, false).check();
+  const Less(4294967296, 9007199254740992, true).check();
+  const Less(9007199254740992, 4294967296, false).check();
+  const Less(9007199254740992, 9007199254740992, false).check();
+  const Less(9007199254740992, double.maxFinite, true).check();
+  const Less(double.maxFinite, 9007199254740992, false).check();
+  const Less(double.maxFinite, double.maxFinite, false).check();
+  const Less(double.maxFinite, double.infinity, true).check();
+  const Less(double.infinity, double.maxFinite, false).check();
+  const Less(double.infinity, double.infinity, false).check();
+  const Less(0x7fffffff00000000, 0x8000000000000000, true).check();
+  const Less(0x8000000000000000, 0x7fffffff00000000, false).check();
+
+  const LessEqual(double.nan, double.nan, false).check();
+  const LessEqual(double.nan, double.infinity, false).check();
+  const LessEqual(double.infinity, double.nan, false).check();
+  const LessEqual(double.nan, double.maxFinite, false).check();
+  const LessEqual(double.maxFinite, double.nan, false).check();
+  const LessEqual(double.nan, -double.maxFinite, false).check();
+  const LessEqual(-double.maxFinite, double.nan, false).check();
+  const LessEqual(double.nan, double.negativeInfinity, false).check();
+  const LessEqual(double.negativeInfinity, double.nan, false).check();
+  const LessEqual(double.negativeInfinity, double.negativeInfinity, true)
+      .check();
+  const LessEqual(double.negativeInfinity, -double.maxFinite, true).check();
+  const LessEqual(-double.maxFinite, double.negativeInfinity, false).check();
+  const LessEqual(-double.maxFinite, -double.maxFinite, true).check();
+  const LessEqual(-double.maxFinite, -9007199254740992, true).check();
+  const LessEqual(-9007199254740992, -double.maxFinite, false).check();
+  const LessEqual(-9007199254740992, -9007199254740992, true).check();
+  const LessEqual(-9007199254740992, -4294967296, true).check();
+  const LessEqual(-4294967296, -9007199254740992, false).check();
+  const LessEqual(-4294967296, -4294967296, true).check();
+  const LessEqual(-4294967296, -42, true).check();
+  const LessEqual(-42, -4294967296, false).check();
+  const LessEqual(-42, -42, true).check();
+  const LessEqual(-42, -42.0, true).check();
+  const LessEqual(-42.0, -42, true).check();
+  const LessEqual(-42.0, -42.0, true).check();
+  const LessEqual(-42, -3.14, true).check();
+  const LessEqual(-3.14, -42, false).check();
+  const LessEqual(-3.14, -3.14, true).check();
+  const LessEqual(-3.14, -double.minPositive, true).check();
+  const LessEqual(-double.minPositive, -3.14, false).check();
+  const LessEqual(-double.minPositive, -double.minPositive, true).check();
+  const LessEqual(-double.minPositive, -0.0, true).check();
+  const LessEqual(-0.0, -double.minPositive, false).check();
+  const LessEqual(-0.0, -0.0, true).check();
+  const LessEqual(0, 0, true).check();
+  const LessEqual(0.0, 0.0, true).check();
+  const LessEqual(-0.0, 0, true).check();
+  const LessEqual(0, -0.0, true).check();
+  const LessEqual(-0.0, 0.0, true).check();
+  const LessEqual(0.0, -0.0, true).check();
+  const LessEqual(0, 0.0, true).check();
+  const LessEqual(0.0, 0, true).check();
+  const LessEqual(0.0, double.minPositive, true).check();
+  const LessEqual(double.minPositive, 0.0, false).check();
+  const LessEqual(double.minPositive, double.minPositive, true).check();
+  const LessEqual(double.minPositive, 3.14, true).check();
+  const LessEqual(3.14, double.minPositive, false).check();
+  const LessEqual(3.14, 3.14, true).check();
+  const LessEqual(3.14, 42, true).check();
+  const LessEqual(42, 3.14, false).check();
+  const LessEqual(42.0, 42.0, true).check();
+  const LessEqual(42, 42.0, true).check();
+  const LessEqual(42.0, 42, true).check();
+  const LessEqual(42, 42, true).check();
+  const LessEqual(42, 4294967296, true).check();
+  const LessEqual(4294967296, 42, false).check();
+  const LessEqual(4294967296, 4294967296, true).check();
+  const LessEqual(4294967296, 9007199254740992, true).check();
+  const LessEqual(9007199254740992, 4294967296, false).check();
+  const LessEqual(9007199254740992, 9007199254740992, true).check();
+  const LessEqual(9007199254740992, double.maxFinite, true).check();
+  const LessEqual(double.maxFinite, 9007199254740992, false).check();
+  const LessEqual(double.maxFinite, double.maxFinite, true).check();
+  const LessEqual(double.maxFinite, double.infinity, true).check();
+  const LessEqual(double.infinity, double.maxFinite, false).check();
+  const LessEqual(double.infinity, double.infinity, true).check();
+  const LessEqual(0x7fffffff00000000, 0x8000000000000000, true).check();
+  const LessEqual(0x8000000000000000, 0x7fffffff00000000, false).check();
+
+  const Greater(double.nan, double.nan, false).check();
+  const Greater(double.nan, double.infinity, false).check();
+  const Greater(double.infinity, double.nan, false).check();
+  const Greater(double.nan, double.maxFinite, false).check();
+  const Greater(double.maxFinite, double.nan, false).check();
+  const Greater(double.nan, -double.maxFinite, false).check();
+  const Greater(-double.maxFinite, double.nan, false).check();
+  const Greater(double.nan, double.negativeInfinity, false).check();
+  const Greater(double.negativeInfinity, double.nan, false).check();
+  const Greater(double.negativeInfinity, double.negativeInfinity, false)
+      .check();
+  const Greater(double.negativeInfinity, -double.maxFinite, false).check();
+  const Greater(-double.maxFinite, double.negativeInfinity, true).check();
+  const Greater(-double.maxFinite, -double.maxFinite, false).check();
+  const Greater(-double.maxFinite, -9007199254740992, false).check();
+  const Greater(-9007199254740992, -double.maxFinite, true).check();
+  const Greater(-9007199254740992, -9007199254740992, false).check();
+  const Greater(-9007199254740992, -4294967296, false).check();
+  const Greater(-4294967296, -9007199254740992, true).check();
+  const Greater(-4294967296, -4294967296, false).check();
+  const Greater(-4294967296, -42, false).check();
+  const Greater(-42, -4294967296, true).check();
+  const Greater(-42, -42, false).check();
+  const Greater(-42, -42.0, false).check();
+  const Greater(-42.0, -42, false).check();
+  const Greater(-42.0, -42.0, false).check();
+  const Greater(-42, -3.14, false).check();
+  const Greater(-3.14, -42, true).check();
+  const Greater(-3.14, -3.14, false).check();
+  const Greater(-3.14, -double.minPositive, false).check();
+  const Greater(-double.minPositive, -3.14, true).check();
+  const Greater(-double.minPositive, -double.minPositive, false).check();
+  const Greater(-double.minPositive, -0.0, false).check();
+  const Greater(-0.0, -double.minPositive, true).check();
+  const Greater(-0.0, -0.0, false).check();
+  const Greater(0, 0, false).check();
+  const Greater(0.0, 0.0, false).check();
+  const Greater(-0.0, 0, false).check();
+  const Greater(0, -0.0, false).check();
+  const Greater(-0.0, 0.0, false).check();
+  const Greater(0.0, -0.0, false).check();
+  const Greater(0, 0.0, false).check();
+  const Greater(0.0, 0, false).check();
+  const Greater(0.0, double.minPositive, false).check();
+  const Greater(double.minPositive, 0.0, true).check();
+  const Greater(double.minPositive, double.minPositive, false).check();
+  const Greater(double.minPositive, 3.14, false).check();
+  const Greater(3.14, double.minPositive, true).check();
+  const Greater(3.14, 3.14, false).check();
+  const Greater(3.14, 42, false).check();
+  const Greater(42, 3.14, true).check();
+  const Greater(42.0, 42.0, false).check();
+  const Greater(42, 42.0, false).check();
+  const Greater(42.0, 42, false).check();
+  const Greater(42, 42, false).check();
+  const Greater(42, 4294967296, false).check();
+  const Greater(4294967296, 42, true).check();
+  const Greater(4294967296, 4294967296, false).check();
+  const Greater(4294967296, 9007199254740992, false).check();
+  const Greater(9007199254740992, 4294967296, true).check();
+  const Greater(9007199254740992, 9007199254740992, false).check();
+  const Greater(9007199254740992, double.maxFinite, false).check();
+  const Greater(double.maxFinite, 9007199254740992, true).check();
+  const Greater(double.maxFinite, double.maxFinite, false).check();
+  const Greater(double.maxFinite, double.infinity, false).check();
+  const Greater(double.infinity, double.maxFinite, true).check();
+  const Greater(double.infinity, double.infinity, false).check();
+  const Greater(0x7fffffff00000000, 0x8000000000000000, false).check();
+  const Greater(0x8000000000000000, 0x7fffffff00000000, true).check();
+
+  const GreaterEqual(double.nan, double.nan, false).check();
+  const GreaterEqual(double.nan, double.infinity, false).check();
+  const GreaterEqual(double.infinity, double.nan, false).check();
+  const GreaterEqual(double.nan, double.maxFinite, false).check();
+  const GreaterEqual(double.maxFinite, double.nan, false).check();
+  const GreaterEqual(double.nan, -double.maxFinite, false).check();
+  const GreaterEqual(-double.maxFinite, double.nan, false).check();
+  const GreaterEqual(double.nan, double.negativeInfinity, false).check();
+  const GreaterEqual(double.negativeInfinity, double.nan, false).check();
+  const GreaterEqual(double.negativeInfinity, double.negativeInfinity, true)
+      .check();
+  const GreaterEqual(double.negativeInfinity, -double.maxFinite, false).check();
+  const GreaterEqual(-double.maxFinite, double.negativeInfinity, true).check();
+  const GreaterEqual(-double.maxFinite, -double.maxFinite, true).check();
+  const GreaterEqual(-double.maxFinite, -9007199254740992, false).check();
+  const GreaterEqual(-9007199254740992, -double.maxFinite, true).check();
+  const GreaterEqual(-9007199254740992, -9007199254740992, true).check();
+  const GreaterEqual(-9007199254740992, -4294967296, false).check();
+  const GreaterEqual(-4294967296, -9007199254740992, true).check();
+  const GreaterEqual(-4294967296, -4294967296, true).check();
+  const GreaterEqual(-4294967296, -42, false).check();
+  const GreaterEqual(-42, -4294967296, true).check();
+  const GreaterEqual(-42, -42, true).check();
+  const GreaterEqual(-42, -42.0, true).check();
+  const GreaterEqual(-42.0, -42, true).check();
+  const GreaterEqual(-42.0, -42.0, true).check();
+  const GreaterEqual(-42, -3.14, false).check();
+  const GreaterEqual(-3.14, -42, true).check();
+  const GreaterEqual(-3.14, -3.14, true).check();
+  const GreaterEqual(-3.14, -double.minPositive, false).check();
+  const GreaterEqual(-double.minPositive, -3.14, true).check();
+  const GreaterEqual(-double.minPositive, -double.minPositive, true).check();
+  const GreaterEqual(-double.minPositive, -0.0, false).check();
+  const GreaterEqual(-0.0, -double.minPositive, true).check();
+  const GreaterEqual(-0.0, -0.0, true).check();
+  const GreaterEqual(0, 0, true).check();
+  const GreaterEqual(0.0, 0.0, true).check();
+  const GreaterEqual(-0.0, 0, true).check();
+  const GreaterEqual(0, -0.0, true).check();
+  const GreaterEqual(-0.0, 0.0, true).check();
+  const GreaterEqual(0.0, -0.0, true).check();
+  const GreaterEqual(0, 0.0, true).check();
+  const GreaterEqual(0.0, 0, true).check();
+  const GreaterEqual(0.0, double.minPositive, false).check();
+  const GreaterEqual(double.minPositive, 0.0, true).check();
+  const GreaterEqual(double.minPositive, double.minPositive, true).check();
+  const GreaterEqual(double.minPositive, 3.14, false).check();
+  const GreaterEqual(3.14, double.minPositive, true).check();
+  const GreaterEqual(3.14, 3.14, true).check();
+  const GreaterEqual(3.14, 42, false).check();
+  const GreaterEqual(42, 3.14, true).check();
+  const GreaterEqual(42.0, 42.0, true).check();
+  const GreaterEqual(42, 42.0, true).check();
+  const GreaterEqual(42.0, 42, true).check();
+  const GreaterEqual(42, 42, true).check();
+  const GreaterEqual(42, 4294967296, false).check();
+  const GreaterEqual(4294967296, 42, true).check();
+  const GreaterEqual(4294967296, 4294967296, true).check();
+  const GreaterEqual(4294967296, 9007199254740992, false).check();
+  const GreaterEqual(9007199254740992, 4294967296, true).check();
+  const GreaterEqual(9007199254740992, 9007199254740992, true).check();
+  const GreaterEqual(9007199254740992, double.maxFinite, false).check();
+  const GreaterEqual(double.maxFinite, 9007199254740992, true).check();
+  const GreaterEqual(double.maxFinite, double.maxFinite, true).check();
+  const GreaterEqual(double.maxFinite, double.infinity, false).check();
+  const GreaterEqual(double.infinity, double.maxFinite, true).check();
+  const GreaterEqual(double.infinity, double.infinity, true).check();
+  const GreaterEqual(0x7fffffff00000000, 0x8000000000000000, false).check();
+  const GreaterEqual(0x8000000000000000, 0x7fffffff00000000, true).check();
+
+  const Equals(null, null, true).check();
+  const Equals(null, "", false).check();
+  const Equals("", null, false).check();
+  const Equals("", "", true).check();
+  const Equals(true, true, true).check();
+  const Equals(false, false, true).check();
+  const Equals(true, false, false).check();
+  const Equals(false, true, false).check();
+  const Equals(0, false, false).check();
+  const Equals(true, 1, false).check();
+  const Equals(double.nan, double.nan, false).check();
+  const Equals(0, 0, true).check();
+  const Equals(0.0, 0.0, true).check();
+  const Equals(-0.0, -0.0, true).check();
+  const Equals(0, 0.0, true).check();
+  const Equals(0.0, 0, true).check();
+  const Equals(0, -0.0, true).check();
+  const Equals(-0.0, 0, true).check();
+  const Equals(0.0, -0.0, true).check();
+  const Equals(-0.0, 0.0, true).check();
+  const Equals(1, 1, true).check();
+  const Equals(1.0, 1.0, true).check();
+  const Equals(1, 1.0, true).check();
+  const Equals(1.0, 1, true).check();
+  const Equals(double.infinity, double.infinity, true).check();
+  const Equals(double.infinity, double.negativeInfinity, false).check();
+  const Equals(double.negativeInfinity, double.infinity, false).check();
+  const Equals(double.negativeInfinity, double.negativeInfinity, true).check();
+  const Equals(0x8000000000000000, 0x8000000000000000, true).check();
+  const Equals(0x8000000000000000, -9223372036854775808, false).check();
+
+  const Identity(null, null, true).check();
+  const Identity(null, "", false).check();
+  const Identity("", null, false).check();
+  const Identity("", "", true).check();
+  const Identity(true, true, true).check();
+  const Identity(false, false, true).check();
+  const Identity(true, false, false).check();
+  const Identity(false, true, false).check();
+  const Identity(0, false, false).check();
+  const Identity(true, 1, false).check();
+  const Identity(double.nan, double.nan, false).check();
+  const Identity(0, 0, true).check();
+  const Identity(0.0, 0.0, true).check();
+  const Identity(-0.0, -0.0, true).check();
+  const Identity(0, 0.0, true).check();
+  const Identity(0.0, 0, true).check();
+  const Identity(0, -0.0, true).check();
+  const Identity(-0.0, 0, true).check();
+  const Identity(0.0, -0.0, true).check();
+  const Identity(-0.0, 0.0, true).check();
+  const Identity(1, 1, true).check();
+  const Identity(1.0, 1.0, true).check();
+  const Identity(1, 1.0, true).check();
+  const Identity(1.0, 1, true).check();
+  const Identity(double.infinity, double.infinity, true).check();
+  const Identity(double.infinity, double.negativeInfinity, false).check();
+  const Identity(double.negativeInfinity, double.infinity, false).check();
+  const Identity(double.negativeInfinity, double.negativeInfinity, true)
+      .check();
+  const Identity(0x8000000000000000, 0x8000000000000000, true).check();
+  const Identity(0x8000000000000000, -9223372036854775808, false).check();
+
+  const IfNull(null, null, null).check();
+  const IfNull(null, 1, 1).check();
+  const IfNull("foo", 1, "foo").check();
+  const IfNull("foo", null, "foo").check();
+}
+
+/// Wraps [Expect.equals] to accommodate JS equality semantics.
+///
+/// Naively using [Expect.equals] causes JS values to be compared with `===`.
+/// This can yield some unintended results:
+///
+/// * Since `NaN === NaN` is `false`, [Expect.equals] will throw even if both
+///   values are `NaN`. Therefore, we check for `NaN` specifically.
+/// * Since `0.0 === -0.0` is `true`, [Expect.equals] will fail to throw if one
+///   constant evaluation results in `0` or `0.0` and the other results in
+///   `-0.0`. Therefore, we additionally check that both values have the same
+///   sign in this case.
+void jsEquals(expected, actual, [String reason = null]) {
+  if (expected is num && actual is num) {
+    if (expected.isNaN && actual.isNaN) return;
+  }
+
+  Expect.equals(expected, actual, reason);
+
+  if (expected == 0 && actual == 0) {
+    Expect.equals(
+        expected.isNegative,
+        actual.isNegative,
+        (reason == null ? "" : "$reason ") +
+            "${expected.toString()} and "
+            "${actual.toString()} have different signs.");
+  }
+}
+
+abstract class TestOp {
+  final expected;
+  final result;
+
+  const TestOp(this.expected, this.result);
+
+  @pragma('dart2js:noInline')
+  checkAll(evalResult) {
+    jsEquals(expected, result,
+        "Frontend constant evaluation does not yield expected value.");
+    jsEquals(expected, evalResult,
+        "Backend constant evaluation does not yield expected value.");
+    jsEquals(expected, eval(), "eval() does not yield expected value.");
+  }
+
+  eval();
+}
+
+class BitNot extends TestOp {
+  final arg;
+
+  const BitNot(this.arg, expected) : super(expected, ~arg);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => ~arg;
+}
+
+class Negate extends TestOp {
+  final arg;
+
+  const Negate(this.arg, expected) : super(expected, -arg);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => -arg;
+}
+
+class Not extends TestOp {
+  final arg;
+
+  const Not(this.arg, expected) : super(expected, !arg);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => !arg;
+}
+
+class BitAnd extends TestOp {
+  final arg1;
+  final arg2;
+
+  const BitAnd(this.arg1, this.arg2, expected) : super(expected, arg1 & arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 & arg2;
+}
+
+class BitOr extends TestOp {
+  final arg1;
+  final arg2;
+
+  const BitOr(this.arg1, this.arg2, expected) : super(expected, arg1 | arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 | arg2;
+}
+
+class BitXor extends TestOp {
+  final arg1;
+  final arg2;
+
+  const BitXor(this.arg1, this.arg2, expected) : super(expected, arg1 ^ arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 ^ arg2;
+}
+
+class ShiftLeft extends TestOp {
+  final arg1;
+  final arg2;
+
+  const ShiftLeft(this.arg1, this.arg2, expected)
+      : super(expected, arg1 << arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 << arg2;
+}
+
+class ShiftRight extends TestOp {
+  final arg1;
+  final arg2;
+
+  const ShiftRight(this.arg1, this.arg2, expected)
+      : super(expected, arg1 >> arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 >> arg2;
+}
+
+class BooleanAnd extends TestOp {
+  final arg1;
+  final arg2;
+
+  const BooleanAnd(this.arg1, this.arg2, expected)
+      : super(expected, arg1 && arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 && arg2;
+}
+
+class BooleanOr extends TestOp {
+  final arg1;
+  final arg2;
+
+  const BooleanOr(this.arg1, this.arg2, expected)
+      : super(expected, arg1 || arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 || arg2;
+}
+
+class Subtract extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Subtract(this.arg1, this.arg2, expected) : super(expected, arg1 - arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 - arg2;
+}
+
+class Multiply extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Multiply(this.arg1, this.arg2, expected) : super(expected, arg1 * arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 * arg2;
+}
+
+class Modulo extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Modulo(this.arg1, this.arg2, expected) : super(expected, arg1 % arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 % arg2;
+}
+
+class TruncatingDivide extends TestOp {
+  final arg1;
+  final arg2;
+
+  const TruncatingDivide(this.arg1, this.arg2, expected)
+      : super(expected, arg1 ~/ arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 ~/ arg2;
+}
+
+class Divide extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Divide(this.arg1, this.arg2, expected) : super(expected, arg1 / arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @override
+  @pragma('dart2js:tryInline')
+  eval() => arg1 / arg2;
+}
+
+class Add extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Add(this.arg1, this.arg2, expected) : super(expected, arg1 + arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 + arg2;
+}
+
+class Less extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Less(this.arg1, this.arg2, expected) : super(expected, arg1 < arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 < arg2;
+}
+
+class LessEqual extends TestOp {
+  final arg1;
+  final arg2;
+
+  const LessEqual(this.arg1, this.arg2, expected)
+      : super(expected, arg1 <= arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 <= arg2;
+}
+
+class Greater extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Greater(this.arg1, this.arg2, expected) : super(expected, arg1 > arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 > arg2;
+}
+
+class GreaterEqual extends TestOp {
+  final arg1;
+  final arg2;
+
+  const GreaterEqual(this.arg1, this.arg2, expected)
+      : super(expected, arg1 >= arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 >= arg2;
+}
+
+class Equals extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Equals(this.arg1, this.arg2, expected) : super(expected, arg1 == arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 == arg2;
+}
+
+class Identity extends TestOp {
+  final arg1;
+  final arg2;
+
+  const Identity(this.arg1, this.arg2, expected)
+      : super(expected, identical(arg1, arg2));
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => identical(arg1, arg2);
+}
+
+class IfNull extends TestOp {
+  final arg1;
+  final arg2;
+
+  const IfNull(this.arg1, this.arg2, expected) : super(expected, arg1 ?? arg2);
+
+  @pragma('dart2js:tryInline')
+  check() => checkAll(eval());
+
+  @pragma('dart2js:tryInline')
+  eval() => arg1 ?? arg2;
+}
diff --git a/tests/dart2js/constant_javascript_semantics2_test.dart b/tests/dart2js/constant_javascript_semantics2_test.dart
new file mode 100644
index 0000000..6ca6693
--- /dev/null
+++ b/tests/dart2js/constant_javascript_semantics2_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Make sure we use JavaScript semantics when compiling compile-time constants.
+// In this case we test that the value-range analysis uses JavaScript semantics
+// too.
+
+int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
+
+foo() {
+  var a = const [1, 2];
+  var i = 0x100000000;
+  if (inscrutable(i) == 0) {
+    i = 0x100000001;
+  }
+  i = 0xFFFFFFFFF & i; // In JS semantics [:i:] will be truncated to 32 bits.
+  i = 0x100000001 - i;
+  return a[i];
+}
+
+main() {
+  Expect.throws(() => foo(), (e) => e is RangeError);
+}
diff --git a/tests/dart2js/constant_javascript_semantics3_test.dart b/tests/dart2js/constant_javascript_semantics3_test.dart
new file mode 100644
index 0000000..2cdf6b0
--- /dev/null
+++ b/tests/dart2js/constant_javascript_semantics3_test.dart
@@ -0,0 +1,38 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Make sure we use JavaScript semantics when compiling compile-time constants.
+// In this case we test that the value-range analysis uses JavaScript semantics
+// too.
+
+int inscrutable(int x) {
+  if (x == 0) return 0;
+  return x | inscrutable(x & (x - 1));
+}
+
+foo() {
+  var a = const [1, 2, 3, 4];
+  var i = 8007199254740992;
+  if (inscrutable(i) == 0) {
+    i++;
+  }
+  i += 1000000000000000;
+  // [i] is now at its maximum 53 bit value. The following increments will not
+  // have any effect.
+  i++;
+  i++;
+  i++;
+  i -= 1000000000000000;
+  i--;
+  i--;
+  i--;
+  i -= 8007199254740992; // In JS semantics [i] would be -3, now.
+  return a[i];
+}
+
+main() {
+  Expect.throws(() => foo(), (e) => e is RangeError);
+}
diff --git a/tests/dart2js/constant_javascript_semantics4_test.dart b/tests/dart2js/constant_javascript_semantics4_test.dart
new file mode 100644
index 0000000..9d19957
--- /dev/null
+++ b/tests/dart2js/constant_javascript_semantics4_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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.
+
+// Make sure we use JavaScript semantics when compiling compile-time constants.
+
+// In checked mode, this return will not fail. If the compiler thinks
+// it will, then dead code will remove the throw in the main method.
+int getInt() {
+  return -0.0;
+}
+
+main() {
+  getInt();
+  throw 'Should fail';
+}
diff --git a/tests/dart2js/constant_javascript_semantics_test.dart b/tests/dart2js/constant_javascript_semantics_test.dart
new file mode 100644
index 0000000..1a09423
--- /dev/null
+++ b/tests/dart2js/constant_javascript_semantics_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Make sure we use JavaScript semantics when compiling compile-time constants.
+
+const x = 1234567890123456789;
+const y = 1234567890123456788;
+const z = x - y;
+
+const a = 1.0;
+const b = a << 3; // //# 01: compile-time error
+
+const c = -0.0;
+const d = c << 1; // //# 02: compile-time error
+
+foo() => 12345678901234567891 - 12345678901234567890;
+
+main() {
+  Expect.equals(0, z);
+  Expect.equals(0, x - y);
+  Expect.equals(0, foo());
+  Expect.isTrue(x is double);
+  Expect.isTrue(x is int);
+  Expect.equals(8, b); // //# 01: continued
+  Expect.equals(8, 1.0 << 3); // //# 03: static type warning
+  Expect.isTrue(1 == 1.0);
+  Expect.equals(0, d); // //# 02: continued
+  Expect.equals(0, -0.0 << 1); // //# 04: static type warning
+  // Make sure the 1 is not shifted into the 32 bit range.
+  Expect.equals(0, 0x100000000 >> 3);
+  // The dynamic int-check also allows -0.0.
+  Expect.isTrue((-0.0) is int);
+}
diff --git a/tests/dart2js/constant_javascript_semantics_test5.dart b/tests/dart2js/constant_javascript_semantics_test5.dart
new file mode 100644
index 0000000..e2275ea
--- /dev/null
+++ b/tests/dart2js/constant_javascript_semantics_test5.dart
@@ -0,0 +1,36 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Make sure we can assert(const Foo() != null) in const initializers.
+class Color {
+  const Color(this.value);
+  final int value;
+}
+
+class ColorHaver {
+  const ColorHaver({this.color = const Color(0xFF000000)})
+      : assert(color != null);
+  final Color color;
+}
+
+const c = const ColorHaver(color: const Color(0xFF00FF00));
+
+enum Enum {
+  a,
+  b,
+}
+
+class EnumHaver {
+  const EnumHaver({this.myEnum: Enum.a}) : assert(myEnum != null);
+  final Enum myEnum;
+}
+
+const e = const EnumHaver(myEnum: Enum.b);
+
+main() {
+  Expect.equals(c.value, 0xFF00FF00);
+  Expect.equals(e.myEnum, Enum.b);
+}
diff --git a/tests/dart2js/constant_truncate_test.dart b/tests/dart2js/constant_truncate_test.dart
new file mode 100644
index 0000000..9d2c4de
--- /dev/null
+++ b/tests/dart2js/constant_truncate_test.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 file.
+
+const a0 = 0 ~/ 0; //# a0: compile-time error
+const a1 = 0.0 ~/ 0; //# a1: compile-time error
+const a2 = -0.0 ~/ 0; //# a2: compile-time error
+const a3 = double.nan ~/ 0; //# a3: compile-time error
+const a4 = double.infinity ~/ 0; //# a4: compile-time error
+const a5 = double.negativeInfinity ~/ 0; //# a5: compile-time error
+
+const b0 = 0 ~/ 0.0; //# b0: compile-time error
+const b1 = 0.0 ~/ 0.0; //# b1: compile-time error
+const b2 = -0.0 ~/ 0.0; //# b2: compile-time error
+const b3 = double.nan ~/ 0.0; //# b3: compile-time error
+const b4 = double.infinity ~/ 0.0; //# b4: compile-time error
+const b5 = double.negativeInfinity ~/ 0.0; //# b5: compile-time error
+
+const c0 = 0 ~/ -0.0; //# c0: compile-time error
+const c1 = 0.0 ~/ -0.0; //# c1: compile-time error
+const c2 = -0.0 ~/ -0.0; //# c2: compile-time error
+const c3 = double.nan ~/ -0.0; //# c3: compile-time error
+const c4 = double.infinity ~/ -0.0; //# c4: compile-time error
+const c5 = double.negativeInfinity ~/ -0.0; //# c5: compile-time error
+
+const d0 = 0 ~/ double.nan; //# d0: compile-time error
+const d1 = 0.0 ~/ double.nan; //# d1: compile-time error
+const d2 = -0.0 ~/ double.nan; //# d2: compile-time error
+const d3 = double.nan ~/ double.nan; //# d3: compile-time error
+const d4 = double.infinity ~/ double.nan; //# d4: compile-time error
+const d5 = double.negativeInfinity ~/ double.nan; //# d5: compile-time error
+
+const e0 = 0 ~/ double.infinity; //# e0: ok
+const e1 = 0.0 ~/ double.infinity; //# e1: ok
+const e2 = -0.0 ~/ double.infinity; //# e2: ok
+const e3 = double.nan ~/ double.infinity; //# e3: compile-time error
+const e4 = double.infinity ~/ double.infinity; //# e4: compile-time error
+const e5 = double.negativeInfinity ~/ double.infinity; //# e5: compile-time error
+
+const f0 = 0 ~/ double.negativeInfinity; //# f0: ok
+const f1 = 0.0 ~/ double.negativeInfinity; //# f1: ok
+const f2 = -0.0 ~/ double.negativeInfinity; //# f2: ok
+const f3 = double.nan ~/ double.negativeInfinity; //# f3: compile-time error
+const f4 = double.infinity ~/ double.negativeInfinity; //# f4: compile-time error
+const f5 = double.negativeInfinity ~/ double.negativeInfinity; //# f5: compile-time error
+
+main() {
+  test(0, 0, () => a0); //# a0: continued
+  test(0.0, 0, () => a1); //# a1: continued
+  test(-0.0, 0, () => a2); //# a2: continued
+  test(double.nan, 0, () => a3); //# a3: continued
+  test(double.infinity, 0, () => a4); //# a4: continued
+  test(double.negativeInfinity, 0, () => a5); //# a5: continued
+
+  test(0, 0.0, () => b0); //# b0: continued
+  test(0.0, 0.0, () => b1); //# b1: continued
+  test(-0.0, 0.0, () => b2); //# b2: continued
+  test(double.nan, 0.0, () => b3); //# b3: continued
+  test(double.infinity, 0.0, () => b4); //# b4: continued
+  test(double.negativeInfinity, 0.0, () => b5); //# b5: continued
+
+  test(0, -0.0, () => c0); //# c0: continued
+  test(0.0, -0.0, () => c1); //# c1: continued
+  test(-0.0, -0.0, () => c2); //# c2: continued
+  test(double.nan, -0.0, () => c3); //# c3: continued
+  test(double.infinity, -0.0, () => c4); //# c4: continued
+  test(double.negativeInfinity, -0.0, () => c5); //# c5: continued
+
+  test(0, double.nan, () => d0); //# d0: continued
+  test(0.0, double.nan, () => d1); //# d1: continued
+  test(-0.0, double.nan, () => d2); //# d2: continued
+  test(double.nan, double.nan, () => d3); //# d3: continued
+  test(double.infinity, double.nan, () => d4); //# d4: continued
+  test(double.negativeInfinity, double.nan, () => d5); //# d5: continued
+
+  test(0, double.infinity, () => e0); //# e0: continued
+  test(0.0, double.infinity, () => e1); //# e1: continued
+  test(-0.0, double.infinity, () => e2); //# e2: continued
+  test(double.nan, double.infinity, () => e3); //# e3: continued
+  test(double.infinity, double.infinity, () => e4); //# e4: continued
+  test(double.negativeInfinity, double.infinity, () => e5); //# e5: continued
+
+  test(0, double.negativeInfinity, () => f0); //# f0: continued
+  test(0.0, double.negativeInfinity, () => f1); //# f1: continued
+  test(-0.0, double.negativeInfinity, () => f2); //# f2: continued
+  test(double.nan, double.negativeInfinity, () => f3); //# f3: continued
+  test(double.infinity, double.negativeInfinity, () => f4); //# f4: continued
+  test(double.negativeInfinity, double.negativeInfinity, () => f5); //# f5: continued
+}
+
+void test(num a, num b, num Function() f) {
+  num result;
+  try {
+    result = a ~/ b;
+    print('$a ~/ $b = $result');
+  } catch (e) {
+    print('$a ~/ $b throws $e');
+    throws(f);
+    return;
+  }
+  expect(f(), result);
+}
+
+void expect(expected, actual) {
+  if (expected != actual) {
+    throw 'Expected $expected, actual $actual';
+  }
+}
+
+void throws(num Function() f) {
+  try {
+    f();
+  } catch (e) {
+    return;
+  }
+  throw 'Expected exception';
+}
diff --git a/tests/dart2js/crash_library_metadata.dart b/tests/dart2js/crash_library_metadata.dart
new file mode 100644
index 0000000..b274687
--- /dev/null
+++ b/tests/dart2js/crash_library_metadata.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, 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.
+
+@Constant()
+library foo;
+
+class Constant {
+  const Constant();
+}
diff --git a/tests/dart2js/dart2js_2.status b/tests/dart2js/dart2js_2.status
new file mode 100644
index 0000000..9faa92a
--- /dev/null
+++ b/tests/dart2js/dart2js_2.status
@@ -0,0 +1,48 @@
+# 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 ]
+dummy_compiler_test: SkipByDesign # Issue 30773. Test should be migrated as a unit test of dart2js, is only intended to test self-hosting.
+
+[ $runtime == jsshell ]
+deferred/load_in_correct_order_test: SkipByDesign # jsshell preamble does not support this test.
+
+[ $compiler == dart2js && $mode == debug ]
+operator_test: Skip
+string_interpolation_test: Skip
+
+[ $compiler == dart2js && $runtime == chrome && $system == windows ]
+class_test: Slow, Pass # Issue 25940
+closure_capture3_test: Slow, Pass # Issue 25940
+closure_capture5_test: Slow, Pass # Issue 25940
+conditional_test: Slow, Pass # Issue 25940
+consistent_codeUnitAt_error_test: Slow, Pass # Issue 25940
+constant_javascript_semantics2_test: Slow, Pass # Issue 25940
+deferred_split_test: Slow, Pass # Issue 25940
+
+[ $compiler == dart2js && $runtime == chrome && $csp ]
+deferred/load_in_correct_order_test: SkipByDesign # Purposely uses `eval`
+
+[ $compiler == dart2js && $runtime == ff && $system == windows ]
+consistent_index_error_string_test: Slow, Pass # Issue 25940
+
+[ $compiler == dart2js && $csp ]
+deferred_custom_loader_test: SkipByDesign # Issue 25683
+deferred_fail_and_retry_test: SkipByDesign # Uses eval to simulate failed loading.
+
+[ $compiler == dart2js && !$host_checked ]
+dummy_compiler_test: Slow, Pass # Issue 32439. self-hosting doesn't work with CFE yet.
+
+[ $compiler == dart2js && $minified ]
+code_motion_exception_test: Skip # Requires unminified operator names.
+
+[ $compiler == dart2js && ($runtime == ff || $runtime == jsshell || $runtime == safari) ]
+code_motion_exception_test: Skip # Required V8 specific format of JavaScript errors.
+
+[ $compiler == dart2js && ($browser || $host_checked) ]
+dummy_compiler_test: SkipByDesign # Issue 30773. Test should be migrated as a unit test of dart2js, is only intended to test self-hosting.
+
+[ $compiler == none && $runtime == vm ]
+new_from_env_test: SkipByDesign # dart2js only test
+unconditional_dartio_import_test: SkipByDesign # dart2js only test
diff --git a/tests/dart2js/data_uri_test.dart b/tests/dart2js/data_uri_test.dart
new file mode 100644
index 0000000..90191c2
--- /dev/null
+++ b/tests/dart2js/data_uri_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+import "data:,var%20x=#_a._b;var%20y=#a._b;var%20z=#_b;";
+
+main() {
+  print(x);
+  print(x == #_a._b);
+  print(y);
+  print(y == #a._b);
+  print(z);
+  print(z == #_b);
+}
diff --git a/tests/dart2js/deferred/34219_bounds_lib1.dart b/tests/dart2js/deferred/34219_bounds_lib1.dart
new file mode 100644
index 0000000..81bf0ae
--- /dev/null
+++ b/tests/dart2js/deferred/34219_bounds_lib1.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// Part of 34219_bounds_test.dart
+
+import '34219_bounds_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+  new GeneratedMessage();
+  g = (<T extends SystemMessage>(T a, T b) => a == b);
+}
diff --git a/tests/dart2js/deferred/34219_bounds_lib2.dart b/tests/dart2js/deferred/34219_bounds_lib2.dart
new file mode 100644
index 0000000..7726460
--- /dev/null
+++ b/tests/dart2js/deferred/34219_bounds_lib2.dart
@@ -0,0 +1,7 @@
+// 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.
+
+// Part of 34219_bounds_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/dart2js/deferred/34219_bounds_lib3.dart b/tests/dart2js/deferred/34219_bounds_lib3.dart
new file mode 100644
index 0000000..a567162
--- /dev/null
+++ b/tests/dart2js/deferred/34219_bounds_lib3.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Part of 34219_bounds_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_bounds_lib2.dart';
+
+test3() {
+  new GeneratedMessage();
+}
diff --git a/tests/dart2js/deferred/34219_bounds_test.dart b/tests/dart2js/deferred/34219_bounds_test.dart
new file mode 100644
index 0000000..89373fb
--- /dev/null
+++ b/tests/dart2js/deferred/34219_bounds_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+
+// Tests that generic function type bounds are walked as dependencies of a
+// closure. If the generic function bounds are not visited, SystemMessage is
+// placed in the main unit while it's superclass GeneratedMessage is placed in a
+// deferred part.
+
+import '34219_bounds_lib1.dart' deferred as lib1;
+import '34219_bounds_lib3.dart' deferred as lib3;
+
+main() async {
+  await lib1.loadLibrary();
+  lib1.test1();
+  await lib3.loadLibrary();
+  lib3.test3();
+  if (lib1.g is bool Function(Object, Object)) print('!');
+}
diff --git a/tests/dart2js/deferred/34219_signature_lib1.dart b/tests/dart2js/deferred/34219_signature_lib1.dart
new file mode 100644
index 0000000..b3493bd
--- /dev/null
+++ b/tests/dart2js/deferred/34219_signature_lib1.dart
@@ -0,0 +1,16 @@
+// 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.
+
+// Part of 34219_signature_test.dart
+
+import '34219_signature_lib2.dart';
+
+class SystemMessage extends GeneratedMessage {}
+
+var g;
+
+test1() {
+  new GeneratedMessage();
+  g = (SystemMessage a, SystemMessage b) => a == b;
+}
diff --git a/tests/dart2js/deferred/34219_signature_lib2.dart b/tests/dart2js/deferred/34219_signature_lib2.dart
new file mode 100644
index 0000000..e702fe6
--- /dev/null
+++ b/tests/dart2js/deferred/34219_signature_lib2.dart
@@ -0,0 +1,7 @@
+// 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.
+
+// Part of 34219_signature_test.dart
+
+class GeneratedMessage {}
diff --git a/tests/dart2js/deferred/34219_signature_lib3.dart b/tests/dart2js/deferred/34219_signature_lib3.dart
new file mode 100644
index 0000000..35915d5
--- /dev/null
+++ b/tests/dart2js/deferred/34219_signature_lib3.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Part of 34219_signature_test.dart
+//
+// This library places GeneratedMessage into a different partition to
+// SystemMessage.
+
+import '34219_signature_lib2.dart';
+
+test3() {
+  new GeneratedMessage();
+}
diff --git a/tests/dart2js/deferred/34219_signature_test.dart b/tests/dart2js/deferred/34219_signature_test.dart
new file mode 100644
index 0000000..6be2be6
--- /dev/null
+++ b/tests/dart2js/deferred/34219_signature_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+
+// Tests that closure signatures are walked as dependencies of a closure. If the
+// signature of the closure is not visited, SystemMessage is placed in the main
+// unit while it's superclass GeneratedMessage is placed in a deferred part.
+
+import '34219_signature_lib1.dart' deferred as lib1;
+import '34219_signature_lib3.dart' deferred as lib3;
+
+main() async {
+  await lib1.loadLibrary();
+  lib1.test1();
+  await lib3.loadLibrary();
+  lib3.test3();
+  if (lib1.g is bool Function(Object, Object)) print('!');
+}
diff --git a/tests/dart2js/deferred/default_arg_is_tearoff_lib.dart b/tests/dart2js/deferred/default_arg_is_tearoff_lib.dart
new file mode 100644
index 0000000..b3e8677
--- /dev/null
+++ b/tests/dart2js/deferred/default_arg_is_tearoff_lib.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, 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.
+
+defaultArg() => "";
+myFunction([argumentName = defaultArg]) => argumentName();
diff --git a/tests/dart2js/deferred/default_arg_is_tearoff_test.dart b/tests/dart2js/deferred/default_arg_is_tearoff_test.dart
new file mode 100644
index 0000000..64c0c20
--- /dev/null
+++ b/tests/dart2js/deferred/default_arg_is_tearoff_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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.
+
+/// Regression test for https://github.com/dart-lang/sdk/issues/30002.
+///
+/// The compiler used to keep all metadata (other than type information) in one
+/// global table that was shipped with the main output unit.  For most metadata
+/// this was OK because it was refering to strings and other simple constants.
+/// However, we also allow to refer to tear-offs of top-level functions. When
+/// that top-level function was assigned to a deferred fragment, the metadata
+/// initialization would simply fail.
+import 'default_arg_is_tearoff_lib.dart' deferred as lib;
+
+main() => lib.loadLibrary().then((_) {
+      // Call via Function.apply to ensure he metadata is generated
+      Function.apply(lib.myFunction, []);
+    });
diff --git a/tests/dart2js/deferred/deferred_class_library.dart b/tests/dart2js/deferred/deferred_class_library.dart
new file mode 100644
index 0000000..03dad35
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_class_library.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, 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.
+
+// Imported by deferred_class_test.dart.
+
+library deferred_class_library;
+
+class MyClass {
+  const MyClass();
+
+  foo(x) {
+    print('MyClass.foo($x)');
+    return (x - 3) ~/ 2;
+  }
+}
+
+class Constant {
+  final value;
+  const Constant(this.value);
+
+  operator ==(other) => other is Constant && value == other.value;
+  get hashCode => 0;
+}
diff --git a/tests/dart2js/deferred/deferred_class_library2.dart b/tests/dart2js/deferred/deferred_class_library2.dart
new file mode 100644
index 0000000..fecca53
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_class_library2.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2014, 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.
+
+// Imported by deferred_class_test.dart.
+
+library deferred_class_library2;
+
+class MyClass {
+  const MyClass();
+
+  foo(x) {
+    print('MyClass.foo($x)');
+    return (x - 3) ~/ 2;
+  }
+}
+
+class Constant {
+  final value;
+  const Constant(this.value);
+
+  operator ==(other) => other is Constant && value == other.value;
+  get hashCode => 0;
+}
+
+const C1 = const Constant(499);
+const C2 = const [const Constant(99)];
+
+foo([x = const Constant(42)]) => x;
+bar() => const Constant(777);
+
+class Gee {
+  get value => c.value;
+  final c;
+
+  Gee([this.c = const Constant(111)]);
+  const Gee.n321([this.c = const Constant(321)]);
+  Gee.n135({arg: const Constant(135)}) : this.c = arg;
+  const Gee.n246({arg: const Constant(246)}) : this.c = arg;
+  const Gee.n888() : this.c = const Constant(888);
+  const Gee.constant(this.c);
+}
+
+class Gee2 extends Gee {
+  Gee2() : super(const Constant(979));
+  const Gee2.n321() : super.n321();
+  const Gee2.n151() : super.constant(const Constant(151));
+  const Gee2.n888() : super.n888();
+}
diff --git a/tests/dart2js/deferred/deferred_class_test.dart b/tests/dart2js/deferred/deferred_class_test.dart
new file mode 100644
index 0000000..eb6c836
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_class_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2013, 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+import 'deferred_class_library.dart' deferred as lib;
+
+bool isError(e) => e is Error;
+
+main() {
+  var x;
+  Expect.throws(() {
+    x = new lib.MyClass();
+  }, isError);
+  Expect.isNull(x);
+  int counter = 0;
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(1, ++counter);
+    print('deferred_class_library was loaded');
+    x = new lib.MyClass();
+    Expect.equals(42, x.foo(87));
+    asyncEnd();
+  });
+  Expect.equals(0, counter);
+  Expect.isNull(x);
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(2, ++counter);
+    print('deferred_class_library was loaded');
+    x = new lib.MyClass();
+    Expect.equals(42, x.foo(87));
+    asyncEnd();
+  });
+  Expect.equals(0, counter);
+  Expect.isNull(x);
+  Expect.throws(() {
+    x = new lib.MyClass();
+  }, isError);
+  Expect.isNull(x);
+}
diff --git a/tests/dart2js/deferred/deferred_constant2_test.dart b/tests/dart2js/deferred/deferred_constant2_test.dart
new file mode 100644
index 0000000..6ea3752
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_constant2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+import 'deferred_class_library2.dart' deferred as lib;
+
+main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(499, lib.C1.value);
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/deferred/deferred_constant3_test.dart b/tests/dart2js/deferred/deferred_constant3_test.dart
new file mode 100644
index 0000000..14add53
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_constant3_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'dart:async';
+
+import 'deferred_class_library2.dart' deferred as lib;
+
+main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(499, lib.C1.value);
+    Expect.equals(99, lib.C2[0].value);
+    Expect.equals(42, lib.foo().value);
+    Expect.equals(777, lib.bar().value);
+    Expect.equals(111, new lib.Gee().value);
+    Expect.equals(321, new lib.Gee.n321().value);
+    Expect.equals(135, new lib.Gee.n135().value);
+    Expect.equals(246, new lib.Gee.n246().value);
+    Expect.equals(888, new lib.Gee.n888().value);
+    Expect.equals(979, new lib.Gee2().value);
+    Expect.equals(321, new lib.Gee2.n321().value);
+    Expect.equals(151, new lib.Gee2.n151().value);
+    Expect.equals(888, new lib.Gee2.n888().value);
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/deferred/deferred_constant4_test.dart b/tests/dart2js/deferred/deferred_constant4_test.dart
new file mode 100644
index 0000000..af903f4
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_constant4_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2014, 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'deferred_class_library2.dart' deferred as lib;
+
+main() {
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    // Only Gee2.n888 to make sure no other constant pulls in its super.
+    Expect.equals(888, new lib.Gee2.n888().value);
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/deferred/deferred_constant_dependency_evaluation_test.dart b/tests/dart2js/deferred/deferred_constant_dependency_evaluation_test.dart
new file mode 100644
index 0000000..49d9558
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_constant_dependency_evaluation_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, 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.
+
+// This is a regression test for dartbug.com/26406. We test that the deferred
+// loader analyzer doesn't trip over constant expression evaluation.
+//
+// Today the task uses constant values to calculate dependencies, and only uses
+// those values that were previously computed by resolution. A change to compute
+// the value on-demmand made the deferred task evaluate more expressions,
+// including expressions with free variables (which can't be evaluated). See the
+// dartbug.com/26406 for details on how we plan to make the task more robust.
+
+// import is only used to trigger the deferred task
+import 'deferred_class_library.dart' deferred as lib;
+
+class A {
+  final int x;
+
+  const A(bool foo)
+      // The deferred task would crash trying to compute the value here, where
+      // [foo] is a free variable.
+      : x = foo ? 1 : 0;
+}
+
+main() => const A(true);
diff --git a/tests/dart2js/deferred/deferred_function_library.dart b/tests/dart2js/deferred/deferred_function_library.dart
new file mode 100644
index 0000000..0eaebc7
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_function_library.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, 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.
+
+// Imported by deferred_function_test.dart and
+// deferred_semantics_test.dart.
+
+library deferred_function_library;
+
+foo(x) {
+  print('foo($x)');
+  return 42;
+}
diff --git a/tests/dart2js/deferred/deferred_function_test.dart b/tests/dart2js/deferred/deferred_function_test.dart
new file mode 100644
index 0000000..88fcbaf
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_function_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, 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 that loading of a library (with top-level functions only) can
+// be deferred.
+
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+
+import 'deferred_function_library.dart' deferred as lib;
+
+bool isError(e) => e is Error;
+
+readFoo() {
+  return lib.foo;
+}
+
+main() {
+  Expect.throws(() {
+    lib.foo('a');
+  }, isError);
+  Expect.throws(readFoo, isError);
+  int counter = 0;
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(1, ++counter);
+    print('lazy was loaded');
+    Expect.equals(42, lib.foo('b'));
+    Expect.isNotNull(readFoo());
+    asyncEnd();
+  });
+  Expect.equals(0, counter);
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.equals(2, ++counter);
+    print('lazy was loaded');
+    Expect.equals(42, lib.foo('b'));
+    Expect.isNotNull(readFoo());
+    asyncEnd();
+  });
+  Expect.equals(0, counter);
+  Expect.throws(() {
+    lib.foo('a');
+  }, isError);
+  Expect.throws(readFoo, isError);
+}
diff --git a/tests/dart2js/deferred/deferred_metadata_lib.dart b/tests/dart2js/deferred/deferred_metadata_lib.dart
new file mode 100644
index 0000000..2bb5573
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_metadata_lib.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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 Annotation {
+  final annotationField;
+  const Annotation([this.annotationField]);
+}
+
+class X {
+  @Annotation()
+  int xvalue = 3;
+}
+
+foo() {
+  X x = new X();
+  return x.xvalue++;
+}
diff --git a/tests/dart2js/deferred/deferred_metadata_test.dart b/tests/dart2js/deferred/deferred_metadata_test.dart
new file mode 100644
index 0000000..03c1b50
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_metadata_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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.
+
+/// Regression tests to ensure that member metadata is not considered by the
+/// deferred loading algorithm, unless mirrors are available.
+///
+/// This test was failing in the past because the deferred-loading algorithm was
+/// adding entities to the K-element-map after we had closed the world and we
+/// had created the J-element-map.  Later, when we convert the K annotation to
+/// its J conterpart, we couldn't find it in the conversion maps because it was
+/// added too late.
+///
+/// If we add support for mirrors in the future, we just need to ensure that
+/// such K annotations are discovered during resolution, before the deferred
+/// loading phase.
+
+import 'deferred_metadata_lib.dart' deferred as d show foo;
+
+main() async {
+  await d.loadLibrary();
+  print(d.foo());
+}
diff --git a/tests/dart2js/deferred/deferred_mirrors2_lib2.dart b/tests/dart2js/deferred/deferred_mirrors2_lib2.dart
new file mode 100644
index 0000000..93f32a0
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_mirrors2_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, 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.
+
+library lib2;
+
+import 'deferred_mirrors2_lazy.dart' deferred as admin;
diff --git a/tests/dart2js/deferred/deferred_mirrors2_lib4.dart b/tests/dart2js/deferred/deferred_mirrors2_lib4.dart
new file mode 100644
index 0000000..2ab9a2a
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_mirrors2_lib4.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2014, 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 'deferred_mirrors2_lib5.dart' show Injectable;
+
+@Injectable()
+class A {}
diff --git a/tests/dart2js/deferred/deferred_mirrors2_lib5.dart b/tests/dart2js/deferred/deferred_mirrors2_lib5.dart
new file mode 100644
index 0000000..f970ed0
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_mirrors2_lib5.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, 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 Injectable {
+  const Injectable();
+}
diff --git a/tests/dart2js/deferred/deferred_overlapping_lib1.dart b/tests/dart2js/deferred/deferred_overlapping_lib1.dart
new file mode 100644
index 0000000..7b2bac9
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_overlapping_lib1.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, 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 "deferred_overlapping_lib3.dart";
+
+class C1 extends C3 {}
diff --git a/tests/dart2js/deferred/deferred_overlapping_lib2.dart b/tests/dart2js/deferred/deferred_overlapping_lib2.dart
new file mode 100644
index 0000000..5937171
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_overlapping_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2014, 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 "deferred_overlapping_lib3.dart";
+
+class C2 extends C3 {}
diff --git a/tests/dart2js/deferred/deferred_overlapping_lib3.dart b/tests/dart2js/deferred/deferred_overlapping_lib3.dart
new file mode 100644
index 0000000..7a87b7b
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_overlapping_lib3.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2014, 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 C3 {}
diff --git a/tests/dart2js/deferred/deferred_overlapping_test.dart b/tests/dart2js/deferred/deferred_overlapping_test.dart
new file mode 100644
index 0000000..f626d58
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_overlapping_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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 "deferred_overlapping_lib1.dart" deferred as lib1;
+import "deferred_overlapping_lib2.dart" deferred as lib2;
+
+// lib1.C1 and lib2.C2 has a shared base class It will go in its own hunk.
+// If lib1 or lib2s hunks are loaded before the common hunk, the program
+// will fail because the base class does not exist.
+void main() {
+  lib1.loadLibrary().then((_) {
+    var a = new lib1.C1();
+    lib2.loadLibrary().then((_) {
+      var b = new lib2.C2();
+    });
+  });
+}
diff --git a/tests/dart2js/deferred/deferred_unused_classes_test.dart b/tests/dart2js/deferred/deferred_unused_classes_test.dart
new file mode 100644
index 0000000..95da996
--- /dev/null
+++ b/tests/dart2js/deferred/deferred_unused_classes_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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 that deferred loader analyzer doesn't trip over unused classes.
+
+import "package:expect/expect.dart";
+import 'dart:async';
+
+import 'deferred_class_library.dart' deferred as lib;
+
+class Base {}
+
+class DerivedNotUsed extends Base {}
+
+main() {}
diff --git a/tests/dart2js/deferred/interface_type_variable_lib.dart b/tests/dart2js/deferred/interface_type_variable_lib.dart
new file mode 100644
index 0000000..fb18b05
--- /dev/null
+++ b/tests/dart2js/deferred/interface_type_variable_lib.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2017, 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 A {}
+
+class I<T> {}
+
+// C needs to include "N", otherwise checking for `is I<A>` will likely cause
+// problems
+class C extends A implements I<N> {}
+
+class N extends A {}
+
+doCheck(x) => x is I<A>;
diff --git a/tests/dart2js/deferred/interface_type_variable_test.dart b/tests/dart2js/deferred/interface_type_variable_test.dart
new file mode 100644
index 0000000..db4b4f2
--- /dev/null
+++ b/tests/dart2js/deferred/interface_type_variable_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, 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 'interface_type_variable_lib.dart' deferred as lib;
+
+/// Regression test: if a type variable is used, but not instantiated, it still
+/// needs to be mapped to the deferred unit where it is used.
+///
+/// If not, we may include it in the main unit and may not see that the base
+/// class is not added to the main unit.
+main() {
+  lib.loadLibrary().then((_) {
+    lib.doCheck(dontInline(new lib.C()));
+  });
+}
+
+@pragma('dart2js:noInline')
+dontInline(x) => x;
diff --git a/tests/dart2js/deferred/multiple_default_arg_lib1.dart b/tests/dart2js/deferred/multiple_default_arg_lib1.dart
new file mode 100644
index 0000000..32ed7e6
--- /dev/null
+++ b/tests/dart2js/deferred/multiple_default_arg_lib1.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, 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.
+
+defaultArg1() => 1;
+defaultArg2() => 2;
+myFunction1({argumentName1: defaultArg1, argumentName2: defaultArg2}) =>
+    "${argumentName1()} - ${argumentName2()}";
diff --git a/tests/dart2js/deferred/multiple_default_arg_lib2.dart b/tests/dart2js/deferred/multiple_default_arg_lib2.dart
new file mode 100644
index 0000000..eff81f4
--- /dev/null
+++ b/tests/dart2js/deferred/multiple_default_arg_lib2.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2017, 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.
+
+defaultArg3() => 3;
+defaultArg4() => 4;
+myFunction2({argumentName3: defaultArg3, argumentName4: defaultArg4}) =>
+    "${argumentName3()} - ${argumentName4()}";
diff --git a/tests/dart2js/deferred/multiple_default_arg_lib3.dart b/tests/dart2js/deferred/multiple_default_arg_lib3.dart
new file mode 100644
index 0000000..dab89a4
--- /dev/null
+++ b/tests/dart2js/deferred/multiple_default_arg_lib3.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, 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.
+
+defaultArg3() => "3b";
+defaultArg4() => "4b";
+myFunction3(positional1, positional2,
+        {argumentName3: defaultArg3, argumentName4: defaultArg4}) =>
+    "$positional1 $positional2 ${argumentName3()} - ${argumentName4()}";
+
+myFunction4(positional1, positional2,
+        {argumentName5: const X(5), argumentName6}) =>
+    argumentName5.value;
+
+class X {
+  final int value;
+  const X(this.value);
+}
+
+const value3 = const X(3);
diff --git a/tests/dart2js/deferred/multiple_default_arg_test.dart b/tests/dart2js/deferred/multiple_default_arg_test.dart
new file mode 100644
index 0000000..37681b9
--- /dev/null
+++ b/tests/dart2js/deferred/multiple_default_arg_test.dart
@@ -0,0 +1,51 @@
+// Copyright (c) 2017, 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.
+
+/// This test is indirectly testing invariants of the generated code of dart2js.
+/// It ensures that indices to metadata information from **multiple** deferred
+/// fragments is kept separate, but that when they are loaded (and the metadata
+/// array is merged) all accesses to the metadata array is done correctly.
+///
+/// This kind of metadata is generated when using Function.apply to
+/// store default values and parameter names.
+import 'multiple_default_arg_lib1.dart' deferred as lib1;
+import 'multiple_default_arg_lib2.dart' deferred as lib2;
+import 'multiple_default_arg_lib3.dart' deferred as lib3;
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+main() {
+  asyncTest(() async {
+    await lib1.loadLibrary();
+    await lib2.loadLibrary();
+
+    Expect.equals(
+        Function.apply(lib1.myFunction1, [], {#argumentName1: () => "A"}),
+        "A - 2");
+
+    Expect.equals(
+        Function.apply(lib2.myFunction2, [], {#argumentName4: () => "B"}),
+        "3 - B");
+
+    await lib3.loadLibrary();
+
+    Expect.equals(
+        Function.apply(
+            lib3.myFunction3, ["x", "y"], {#argumentName4: () => "C"}),
+        "x y 3b - C");
+
+    Expect.equals(
+        Function.apply(lib3.myFunction3, ["x", "y"], {}), "x y 3b - 4b");
+
+    Expect.equals(Function.apply(lib3.myFunction4, ["x", "y"], {}), 5);
+    Expect.equals(
+        Function.apply(
+            lib3.myFunction4, ["x", "y"], {#argumentName5: new lib3.X(4)}),
+        4);
+    Expect.equals(
+        Function.apply(
+            lib3.myFunction4, ["x", "y"], {#argumentName5: lib3.value3}),
+        3);
+  });
+}
diff --git a/tests/dart2js/deferred/reflect_multiple_annotations_lib1.dart b/tests/dart2js/deferred/reflect_multiple_annotations_lib1.dart
new file mode 100644
index 0000000..89e8e90
--- /dev/null
+++ b/tests/dart2js/deferred/reflect_multiple_annotations_lib1.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2017, 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.
+
+topLevelF() => 1;
+
+@MetaA("one")
+@MetaA(topLevelF)
+myFunction1(@MetaA("param") f1) {
+  return f1;
+  return f1;
+}
+
+class MetaA {
+  final value;
+  const MetaA(this.value);
+
+  static isCheck(v) => v is MetaA;
+
+  String toString() => "MetaA($value)";
+}
diff --git a/tests/dart2js/deferred/reflect_multiple_annotations_lib2.dart b/tests/dart2js/deferred/reflect_multiple_annotations_lib2.dart
new file mode 100644
index 0000000..1c46957
--- /dev/null
+++ b/tests/dart2js/deferred/reflect_multiple_annotations_lib2.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2017, 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.
+
+@MetaB("lib")
+library foo;
+
+@MetaB("class")
+class A {}
+
+class MetaB {
+  final value;
+  const MetaB(this.value);
+
+  String toString() => "MetaB($value)";
+}
diff --git a/tests/dart2js/deferred/reflect_multiple_default_arg_lib1.dart b/tests/dart2js/deferred/reflect_multiple_default_arg_lib1.dart
new file mode 100644
index 0000000..e87a387
--- /dev/null
+++ b/tests/dart2js/deferred/reflect_multiple_default_arg_lib1.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, 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.
+
+defaultArg1() => 1;
+myFunction1([argumentName1 = defaultArg1]) => argumentName1();
diff --git a/tests/dart2js/deferred/reflect_multiple_default_arg_lib2.dart b/tests/dart2js/deferred/reflect_multiple_default_arg_lib2.dart
new file mode 100644
index 0000000..f35642a
--- /dev/null
+++ b/tests/dart2js/deferred/reflect_multiple_default_arg_lib2.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2017, 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.
+
+defaultArg2() => 2;
+myFunction2([argumentName2 = defaultArg2]) => argumentName2();
diff --git a/tests/dart2js/deferred/shared_constant_a.dart b/tests/dart2js/deferred/shared_constant_a.dart
new file mode 100644
index 0000000..388f0d3
--- /dev/null
+++ b/tests/dart2js/deferred/shared_constant_a.dart
@@ -0,0 +1,10 @@
+// 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.
+
+import 'shared_constant_shared.dart' deferred as d;
+
+doA() async {
+  await d.loadLibrary();
+  return d.constant;
+}
diff --git a/tests/dart2js/deferred/shared_constant_b.dart b/tests/dart2js/deferred/shared_constant_b.dart
new file mode 100644
index 0000000..177f50e
--- /dev/null
+++ b/tests/dart2js/deferred/shared_constant_b.dart
@@ -0,0 +1,10 @@
+// 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.
+
+import 'shared_constant_shared.dart' deferred as d;
+
+doB() async {
+  await d.loadLibrary();
+  return d.constant;
+}
diff --git a/tests/dart2js/deferred/shared_constant_c.dart b/tests/dart2js/deferred/shared_constant_c.dart
new file mode 100644
index 0000000..b64972e
--- /dev/null
+++ b/tests/dart2js/deferred/shared_constant_c.dart
@@ -0,0 +1,8 @@
+// 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.
+
+class C {
+  const C();
+  method() => print("1");
+}
diff --git a/tests/dart2js/deferred/shared_constant_shared.dart b/tests/dart2js/deferred/shared_constant_shared.dart
new file mode 100644
index 0000000..a801718
--- /dev/null
+++ b/tests/dart2js/deferred/shared_constant_shared.dart
@@ -0,0 +1,7 @@
+// 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.
+
+import 'shared_constant_c.dart';
+
+const constant = const C(); // using `var` eludes the problem.
diff --git a/tests/dart2js/deferred/shared_constant_test.dart b/tests/dart2js/deferred/shared_constant_test.dart
new file mode 100644
index 0000000..3614147
--- /dev/null
+++ b/tests/dart2js/deferred/shared_constant_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+/// Regression test for issue https://github.com/dart-lang/sdk/issues/31306.
+///
+/// When 1 constant was imported in two libraries by using the same exact
+/// deferred import URI, the deferred-constant initializer was incorrectly moved
+/// to the main output unit.
+
+import 'shared_constant_a.dart';
+import 'shared_constant_b.dart';
+
+main() async {
+  (await doA()).method();
+  await doB();
+}
diff --git a/tests/dart2js/deferred/type_literal_lib.dart b/tests/dart2js/deferred/type_literal_lib.dart
new file mode 100644
index 0000000..867c399
--- /dev/null
+++ b/tests/dart2js/deferred/type_literal_lib.dart
@@ -0,0 +1,7 @@
+// 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.
+
+class A {}
+
+class B {}
diff --git a/tests/dart2js/deferred/type_literal_test.dart b/tests/dart2js/deferred/type_literal_test.dart
new file mode 100644
index 0000000..25e2c32
--- /dev/null
+++ b/tests/dart2js/deferred/type_literal_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// Regression test for Issue #33890.
+//
+// This fails if type literal constants are not deferred, but their RTI
+// representation is. This test however will not detect if we accidentally start
+// building the RTI representation in the main deferred unit (which is what was
+// happening before the bug was introduced).
+
+import 'type_literal_lib.dart' deferred as a;
+import 'package:expect/expect.dart';
+
+main() async {
+  await a.loadLibrary();
+  Expect.isFalse(confuse(a.A) == confuse(a.B));
+}
+
+@pragma('dart2js:noInline')
+confuse(x) => x;
diff --git a/tests/dart2js/deferred/typedef_lib.dart b/tests/dart2js/deferred/typedef_lib.dart
new file mode 100644
index 0000000..2bccab5
--- /dev/null
+++ b/tests/dart2js/deferred/typedef_lib.dart
@@ -0,0 +1,10 @@
+// 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.
+
+class A {}
+
+class B {}
+
+typedef C(A a);
+typedef D(B a);
diff --git a/tests/dart2js/deferred/typedef_test.dart b/tests/dart2js/deferred/typedef_test.dart
new file mode 100644
index 0000000..fa4cc1f
--- /dev/null
+++ b/tests/dart2js/deferred/typedef_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Regression test for Issue #33890.
+//
+// This fails if type literal constants are not deferred, but their RTI
+// representation is. This test however will not detect if we accidentally start
+// building the RTI representation in the main deferred unit (which is what was
+// happening before the bug was introduced).
+
+import 'typedef_lib.dart' deferred as a;
+import 'package:expect/expect.dart';
+
+main() async {
+  await a.loadLibrary();
+  print(a.A); // unclear why without this the definition of A and B gets pulled
+  print(a.B); // into the main output unit.
+  Expect.isFalse(confuse(a.C) == confuse(a.D));
+}
+
+@pragma('dart2js:noInline')
+confuse(x) => x;
diff --git a/tests/dart2js/deferred/uninstantiated_type_variable_lib.dart b/tests/dart2js/deferred/uninstantiated_type_variable_lib.dart
new file mode 100644
index 0000000..2af788d
--- /dev/null
+++ b/tests/dart2js/deferred/uninstantiated_type_variable_lib.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, 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.
+
+// All of these types are considered instantiated because we create an instance
+// of [C].
+
+class A {}
+
+class Box<T> {
+  int value;
+}
+
+class B<T> extends A {
+  final box = new Box<T>();
+}
+
+class C extends B<N> {}
+
+// N is not instantiated, but used as a type argument in C and indirectly in a
+// Box<N>.
+// If we don't mark it as part of the output unit of C, we accidentally add it
+// to the main output unit. However, A is in the output unit of C so we fail
+// when trying to finalize the declaration of N while loading the main output
+// unit.
+class N extends A {}
diff --git a/tests/dart2js/deferred/uninstantiated_type_variable_test.dart b/tests/dart2js/deferred/uninstantiated_type_variable_test.dart
new file mode 100644
index 0000000..3bd8b77
--- /dev/null
+++ b/tests/dart2js/deferred/uninstantiated_type_variable_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2017, 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 'uninstantiated_type_variable_lib.dart' deferred as lib;
+
+/// Regression test: if a type variable is used, but not instantiated, it still
+/// needs to be mapped to the deferred unit where it is used.
+///
+/// If not, we may include it in the main unit and may not see that the base
+/// class is not added to the main unit.
+main() {
+  lib.loadLibrary().then((_) {
+    dontInline(new lib.C()).box.value;
+  });
+}
+
+@pragma('dart2js:noInline')
+dontInline(x) => x;
diff --git a/tests/dart2js/deferred_fail_and_retry_lib.dart b/tests/dart2js/deferred_fail_and_retry_lib.dart
new file mode 100644
index 0000000..48fbce6
--- /dev/null
+++ b/tests/dart2js/deferred_fail_and_retry_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/dart2js/deferred_fail_and_retry_test.dart b/tests/dart2js/deferred_fail_and_retry_test.dart
new file mode 100644
index 0000000..5dc34c5
--- /dev/null
+++ b/tests/dart2js/deferred_fail_and_retry_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2015, 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 that when a deferred import fails to load, it is possible to retry.
+
+import "deferred_fail_and_retry_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:js" as js;
+
+main() {
+  // We patch document.body.appendChild to change the script src on first
+  // invocation.
+  js.context.callMethod("eval", [
+    """
+    if (self.document) {
+      oldAppendChild = document.body.appendChild;
+      document.body.appendChild = function(element) {
+        element.src = "non_existing.js";
+        document.body.appendChild = oldAppendChild;
+        document.body.appendChild(element);
+      }
+    }
+    if (self.load) {
+      oldLoad = load;
+      load = function(uri) {
+        load = oldLoad;
+        load("non_existing.js");
+      }
+    }
+  """
+  ]);
+
+  asyncStart();
+  lib.loadLibrary().then((_) {
+    Expect.fail("Library should not have loaded");
+  }, onError: (error) {
+    lib.loadLibrary().then((_) {
+      Expect.equals("loaded", lib.foo());
+    }, onError: (error) {
+      Expect.fail("Library should have loaded this time");
+    }).whenComplete(() {
+      asyncEnd();
+    });
+  });
+}
diff --git a/tests/dart2js/deferred_function_types1_test.dart b/tests/dart2js/deferred_function_types1_test.dart
new file mode 100644
index 0000000..91c9075
--- /dev/null
+++ b/tests/dart2js/deferred_function_types1_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+}
diff --git a/tests/dart2js/deferred_function_types2_test.dart b/tests/dart2js/deferred_function_types2_test.dart
new file mode 100644
index 0000000..4336421
--- /dev/null
+++ b/tests/dart2js/deferred_function_types2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+}
diff --git a/tests/dart2js/deferred_function_types3_test.dart b/tests/dart2js/deferred_function_types3_test.dart
new file mode 100644
index 0000000..98a6de8
--- /dev/null
+++ b/tests/dart2js/deferred_function_types3_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method3() is Object Function(Null));
+  Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(Null));
+  Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+}
diff --git a/tests/dart2js/deferred_function_types4_test.dart b/tests/dart2js/deferred_function_types4_test.dart
new file mode 100644
index 0000000..fc78d96
--- /dev/null
+++ b/tests/dart2js/deferred_function_types4_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(Null));
+  Expect.isTrue(lib2.method4() is Object Function(Null, Null));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method3() is Object Function(Null));
+  Expect.isFalse(lib1.method3() is Object Function(Null, Null));
+}
diff --git a/tests/dart2js/deferred_function_types5_test.dart b/tests/dart2js/deferred_function_types5_test.dart
new file mode 100644
index 0000000..998d678
--- /dev/null
+++ b/tests/dart2js/deferred_function_types5_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.test3(lib1.method3()));
+  Expect.isFalse(lib1.method3() is Object Function(String));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(String, String));
+  Expect.isTrue(lib2.test4(lib2.method4()));
+}
diff --git a/tests/dart2js/deferred_function_types6_test.dart b/tests/dart2js/deferred_function_types6_test.dart
new file mode 100644
index 0000000..2423b52
--- /dev/null
+++ b/tests/dart2js/deferred_function_types6_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method4() is Object Function(String, String));
+  Expect.isTrue(lib2.test4(lib2.method4()));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.test3(lib1.method3()));
+  Expect.isFalse(lib1.method3() is Object Function(String));
+}
diff --git a/tests/dart2js/deferred_function_types7_test.dart b/tests/dart2js/deferred_function_types7_test.dart
new file mode 100644
index 0000000..fe7c49e
--- /dev/null
+++ b/tests/dart2js/deferred_function_types7_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+  Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+  Expect.isTrue(lib1.test5(lib1.method5));
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+  Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+  Expect.isTrue(lib2.test6(lib2.method6));
+}
diff --git a/tests/dart2js/deferred_function_types8_test.dart b/tests/dart2js/deferred_function_types8_test.dart
new file mode 100644
index 0000000..7222ef5
--- /dev/null
+++ b/tests/dart2js/deferred_function_types8_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+import 'deferred_function_types_lib1.dart' deferred as lib1;
+import 'deferred_function_types_lib2.dart' deferred as lib2;
+
+main() async {
+  await lib2.loadLibrary();
+  Expect.isFalse(lib2.method2() is int Function(int));
+  Expect.isTrue(lib2.method2() is String Function(String));
+  Expect.isFalse(lib2.method6 is Object Function(Null, String, int));
+  Expect.isTrue(lib2.method6 is Object Function(Null, int, String));
+  Expect.isTrue(lib2.test6(lib2.method6));
+  await lib1.loadLibrary();
+  Expect.isTrue(lib1.method1() is int Function(int));
+  Expect.isFalse(lib1.method1() is String Function(String));
+  Expect.isTrue(lib1.method5 is Object Function(Null, String, int));
+  Expect.isFalse(lib1.method5 is Object Function(Null, int, String));
+  Expect.isTrue(lib1.test5(lib1.method5));
+}
diff --git a/tests/dart2js/deferred_function_types_lib1.dart b/tests/dart2js/deferred_function_types_lib1.dart
new file mode 100644
index 0000000..8a3a06f
--- /dev/null
+++ b/tests/dart2js/deferred_function_types_lib1.dart
@@ -0,0 +1,19 @@
+// 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.
+
+method1() {
+  return (int i) => i;
+}
+
+class Class1 {}
+
+method3() {
+  return (Class1 c) => c;
+}
+
+test3(o) => o is Class1 Function(Class1);
+
+method5(Class1 c, String s, int i) {}
+
+test5(o) => o is Function(Class1, String, int);
diff --git a/tests/dart2js/deferred_function_types_lib2.dart b/tests/dart2js/deferred_function_types_lib2.dart
new file mode 100644
index 0000000..a209dac
--- /dev/null
+++ b/tests/dart2js/deferred_function_types_lib2.dart
@@ -0,0 +1,19 @@
+// 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.
+
+method2() {
+  return (String s) => s;
+}
+
+class Class2 {}
+
+method4() {
+  return (Class2 c1, Class2 c2) => c1;
+}
+
+test4(o) => o is Class2 Function(Class2, Class2);
+
+method6(Class2 c, int i, String s) {}
+
+test6(o) => o is Function(Class2, int, String);
diff --git a/tests/dart2js/deferred_inheritance_lib1.dart b/tests/dart2js/deferred_inheritance_lib1.dart
new file mode 100644
index 0000000..8e7e9a5f
--- /dev/null
+++ b/tests/dart2js/deferred_inheritance_lib1.dart
@@ -0,0 +1,3 @@
+import 'deferred_inheritance_lib2.dart';
+
+class C extends A {}
diff --git a/tests/dart2js/deferred_inheritance_lib2.dart b/tests/dart2js/deferred_inheritance_lib2.dart
new file mode 100644
index 0000000..a869c28
--- /dev/null
+++ b/tests/dart2js/deferred_inheritance_lib2.dart
@@ -0,0 +1 @@
+class A {}
diff --git a/tests/dart2js/deferred_inheritance_test.dart b/tests/dart2js/deferred_inheritance_test.dart
new file mode 100644
index 0000000..2443682
--- /dev/null
+++ b/tests/dart2js/deferred_inheritance_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2016, 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.
+
+/// Regression test for --fast-startup. The compiler used to emit inherit calls
+/// on each fragment even for classes that were already loaded on a different
+/// fragment. As a result, the inheritance chain was overwritten in non-chrome
+/// browsers (by using __proto__, we evaded this issue in Chrome).
+library deferred_inheritance_test;
+
+import 'deferred_inheritance_lib2.dart';
+import 'deferred_inheritance_lib1.dart' deferred as d;
+
+import 'package:expect/expect.dart';
+
+class B extends A {}
+
+/// If the check `y is A` is generated as `y.$isA` then the issue is not
+/// exposed. We use `AssumeDynamic` to ensure that we generate as `y instanceof
+/// A` in JS.
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+check(y) => Expect.isTrue(y is A);
+
+main() {
+  check(new B());
+  d.loadLibrary().then((_) {
+    check(new d.C());
+    check(new B()); // This fails if we overwrite the inheritance chain.
+  });
+}
diff --git a/tests/dart2js/deferred_split_lib1.dart b/tests/dart2js/deferred_split_lib1.dart
new file mode 100644
index 0000000..195357a
--- /dev/null
+++ b/tests/dart2js/deferred_split_lib1.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+// Library loaded eagerly by deferred_split_test.dart
+
+class A<T> {}
diff --git a/tests/dart2js/deferred_split_lib2.dart b/tests/dart2js/deferred_split_lib2.dart
new file mode 100644
index 0000000..d690e31
--- /dev/null
+++ b/tests/dart2js/deferred_split_lib2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, 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.
+
+// Deferred library loaded by deferred_split_test.dart
+
+import 'deferred_split_lib1.dart';
+
+createA() => new A();
diff --git a/tests/dart2js/deferred_split_test.dart b/tests/dart2js/deferred_split_test.dart
new file mode 100644
index 0000000..0459349
--- /dev/null
+++ b/tests/dart2js/deferred_split_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+/// Regression for issue 23853: we used to incorrectly split and put a type in a
+/// deferred hunk if the type was used explicitly in the deferred library and
+/// was used only in a generic type in the main library.
+library compiler.test.dart2js_extra.deferred_split_test;
+
+import 'deferred_split_lib1.dart';
+import 'deferred_split_lib2.dart' deferred as b;
+
+class TypeLiteral<T> {
+  Type get type => T;
+}
+
+main() {
+  // This line failed with a runtime error prior to the fix:
+  new TypeLiteral<A<Object>>().type;
+
+  b.loadLibrary().then((_) => b.createA());
+}
diff --git a/tests/dart2js/deferred_tearoff_load_library_lib.dart b/tests/dart2js/deferred_tearoff_load_library_lib.dart
new file mode 100644
index 0000000..472c977
--- /dev/null
+++ b/tests/dart2js/deferred_tearoff_load_library_lib.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.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/dart2js/deferred_tearoff_load_library_test.dart b/tests/dart2js/deferred_tearoff_load_library_test.dart
new file mode 100644
index 0000000..5dbcf88
--- /dev/null
+++ b/tests/dart2js/deferred_tearoff_load_library_test.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.
+
+// Test that tearoffs of `loadLibrary` work properly.
+//
+// The CFE chooses a non identifier name for `loadLibrary` methods, this test
+// ensures that not only we properly escape the name of the method but also the
+// name of the derived tearoff closure.
+import "deferred_tearoff_load_library_lib.dart" deferred as lib;
+
+import "package:async_helper/async_helper.dart";
+
+@pragma('dart2js:noInline')
+get tearoff => lib.loadLibrary;
+
+main() {
+  asyncStart();
+  tearoff().then((_) => asyncEnd());
+}
diff --git a/tests/dart2js/deferred_with_cross_origin_lib.dart b/tests/dart2js/deferred_with_cross_origin_lib.dart
new file mode 100644
index 0000000..48fbce6
--- /dev/null
+++ b/tests/dart2js/deferred_with_cross_origin_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/dart2js/deferred_with_cross_origin_test.dart b/tests/dart2js/deferred_with_cross_origin_test.dart
new file mode 100644
index 0000000..51c10cf
--- /dev/null
+++ b/tests/dart2js/deferred_with_cross_origin_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+// Test that code loaded via deferred imports uses the same crossorigin value as
+// the main page.
+
+import "deferred_with_cross_origin_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals(null, scripts.first.crossOrigin);
+  scripts.first.crossOrigin = "anonymous";
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains("generated_compilations"))
+        .toList();
+    Expect.equals(2, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("anonymous", script.crossOrigin);
+    }
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/deferred_with_csp_nonce2_test.dart b/tests/dart2js/deferred_with_csp_nonce2_test.dart
new file mode 100644
index 0000000..5d6f596
--- /dev/null
+++ b/tests/dart2js/deferred_with_csp_nonce2_test.dart
@@ -0,0 +1,38 @@
+// 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.
+
+// Test that code loaded via deferred imports uses the same nonce value as the
+// main page.
+
+import "deferred_with_csp_nonce_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals('', scripts.first.nonce ?? '');
+  Expect.equals('', scripts.first.getAttribute('nonce') ?? '');
+  scripts.first.setAttribute("nonce", "an-example-nonce-string");
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains(".part.js"))
+        .toList();
+    Expect.equals(1, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("an-example-nonce-string", script.nonce);
+      Expect.equals("an-example-nonce-string", script.getAttribute('nonce'));
+    }
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/deferred_with_csp_nonce_lib.dart b/tests/dart2js/deferred_with_csp_nonce_lib.dart
new file mode 100644
index 0000000..48fbce6
--- /dev/null
+++ b/tests/dart2js/deferred_with_csp_nonce_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+foo() {
+  return "loaded";
+}
diff --git a/tests/dart2js/deferred_with_csp_nonce_test.dart b/tests/dart2js/deferred_with_csp_nonce_test.dart
new file mode 100644
index 0000000..2725df8
--- /dev/null
+++ b/tests/dart2js/deferred_with_csp_nonce_test.dart
@@ -0,0 +1,38 @@
+// 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.
+
+// Test that code loaded via deferred imports uses the same nonce value as the
+// main page.
+
+import "deferred_with_csp_nonce_lib.dart" deferred as lib;
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+import "dart:html";
+
+main() {
+  asyncStart();
+
+  var scripts = document
+      .querySelectorAll<ScriptElement>('script')
+      .where((s) => s.src.contains("generated_compilations"))
+      .toList();
+  Expect.equals(1, scripts.length);
+  Expect.equals('', scripts.first.nonce ?? '');
+  Expect.equals('', scripts.first.getAttribute('nonce') ?? '');
+  scripts.first.nonce = "an-example-nonce-string";
+
+  lib.loadLibrary().then((_) {
+    print(lib.foo());
+    var scripts = document
+        .querySelectorAll<ScriptElement>('script')
+        .where((s) => s.src.contains(".part.js"))
+        .toList();
+    Expect.equals(1, scripts.length);
+    for (var script in scripts) {
+      Expect.equals("an-example-nonce-string", script.nonce);
+      Expect.equals("an-example-nonce-string", script.getAttribute('nonce'));
+    }
+    asyncEnd();
+  });
+}
diff --git a/tests/dart2js/do_test.dart b/tests/dart2js/do_test.dart
new file mode 100644
index 0000000..2b7abc0
--- /dev/null
+++ b/tests/dart2js/do_test.dart
@@ -0,0 +1,60 @@
+// 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 "package:expect/expect.dart";
+
+void do1() {
+  bool cond = true;
+  var result = 0;
+  var x = 0;
+  do {
+    if (x == 10) cond = false;
+    result += x;
+    x = x + 1;
+  } while (cond);
+  Expect.equals(55, result);
+}
+
+void do2() {
+  var t = 0;
+  var i = 0;
+  do {
+    t = t + 10;
+    i++;
+  } while (i == 0);
+  Expect.equals(10, t);
+}
+
+void do3() {
+  var i = 0;
+  do {
+    i++;
+  } while (false);
+  Expect.equals(1, i);
+}
+
+void do4() {
+  var cond1 = true;
+  var result = 0;
+  var i = 0;
+  do {
+    if (i == 9) cond1 = false;
+    var cond2 = true;
+    var j = 0;
+    do {
+      if (j == 9) cond2 = false;
+      result = result + 1;
+      j = j + 1;
+    } while (cond2);
+    i = i + 1;
+  } while (cond1);
+  Expect.equals(100, result);
+}
+
+void main() {
+  do1();
+  do2();
+  do3();
+  do4();
+}
diff --git a/tests/dart2js/dummy_compiler_test.dart b/tests/dart2js/dummy_compiler_test.dart
new file mode 100644
index 0000000..53d4c20
--- /dev/null
+++ b/tests/dart2js/dummy_compiler_test.dart
@@ -0,0 +1,68 @@
+// 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.
+
+// Tests that the dart2js compiler can be run in a js engine.  This ensures that
+// the internal compiler APIs have no dependency on dart:io.
+library dummy_compiler;
+
+import 'dart:async';
+
+import 'package:async_helper/async_helper.dart';
+import 'package:compiler/compiler.dart';
+
+import 'mock_libraries.dart';
+
+String libProvider(Uri uri) {
+  if (uri.path.endsWith(".platform")) {
+    return DEFAULT_PLATFORM_CONFIG;
+  }
+  if (uri.path.endsWith("/core.dart")) {
+    return buildLibrarySource(DEFAULT_CORE_LIBRARY);
+  } else if (uri.path.endsWith('core_patch.dart')) {
+    return DEFAULT_PATCH_CORE_SOURCE;
+  } else if (uri.path.endsWith('internal.dart')) {
+    return buildLibrarySource(DEFAULT_INTERNAL_LIBRARY);
+  } else if (uri.path.endsWith('interceptors.dart')) {
+    return buildLibrarySource(DEFAULT_INTERCEPTORS_LIBRARY);
+  } else if (uri.path.endsWith('js_helper.dart')) {
+    return buildLibrarySource(DEFAULT_JS_HELPER_LIBRARY);
+  } else if (uri.path.endsWith('/async.dart')) {
+    return buildLibrarySource(DEFAULT_ASYNC_LIBRARY);
+  } else {
+    return "library lib${uri.path.replaceAll('/', '.')};";
+  }
+}
+
+Future<String> provider(Uri uri) {
+  String source;
+  if (uri.scheme == "main") {
+    source = "main() {}";
+  } else if (uri.scheme == "lib") {
+    source = libProvider(uri);
+  } else {
+    throw "unexpected URI $uri";
+  }
+  return new Future.value(source);
+}
+
+void handler(Uri uri, int begin, int end, String message, Diagnostic kind) {
+  if (uri == null) {
+    print('$kind: $message');
+  } else {
+    print('$uri:$begin:$end: $kind: $message');
+  }
+}
+
+main() {
+  asyncStart();
+  Future<CompilationResult> result = compile(new Uri(scheme: 'main'),
+      new Uri(scheme: 'lib', path: '/'), provider, handler);
+  result.then((CompilationResult result) {
+    if (!result.isSuccess) {
+      throw 'Compilation failed';
+    }
+  }, onError: (e, s) {
+    throw 'Compilation failed: $e\n$s';
+  }).then(asyncSuccess);
+}
diff --git a/tests/dart2js/dynamic_bounds_check_test.dart b/tests/dart2js/dynamic_bounds_check_test.dart
new file mode 100644
index 0000000..9593aea
--- /dev/null
+++ b/tests/dart2js/dynamic_bounds_check_test.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:expect/expect.dart";
+
+class Foo {}
+
+class Bar {}
+
+class Test {
+  void test<T extends Foo>() {}
+}
+
+void main() {
+  dynamic x = Test();
+  Expect.throws(() {
+    x.test<Bar>();
+  });
+}
diff --git a/tests/dart2js/dynamic_invocation_test.dart b/tests/dart2js/dynamic_invocation_test.dart
new file mode 100644
index 0000000..28bfdb3
--- /dev/null
+++ b/tests/dart2js/dynamic_invocation_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class C1 {
+  int call(int a, int b) => a + b;
+}
+
+class C2 {
+  int call(int a, int b, int c) => a + b + c;
+}
+
+class D {
+  dynamic f1 = new C1();
+  dynamic f2 = new C2();
+}
+
+@pragma('dart2js:noInline')
+id(o) => o;
+
+main() {
+  dynamic d1 = id(new D());
+  Expect.equals(d1.f1(1, 2), 3); //# 01: ok
+  Expect.equals(d1.f2(1, 2, 3), 6); //# 02: ok
+  D d2 = id(new D());
+  Expect.equals(d2.f1(2, 3), 5); //# 03: ok
+  Expect.equals(d2.f2(2, 3, 4), 9); //# 04: ok
+}
diff --git a/tests/dart2js/dynamic_type_literal_test.dart b/tests/dart2js/dynamic_type_literal_test.dart
new file mode 100644
index 0000000..3231717
--- /dev/null
+++ b/tests/dart2js/dynamic_type_literal_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks
+
+// Test generation of 'dynamic' type literals.
+
+import "package:expect/expect.dart";
+
+void main() {
+  Expect.isTrue(dynamic is Type);
+  Expect.isFalse(dynamic == Type);
+}
diff --git a/tests/dart2js/effectively_constant_fields_test.dart b/tests/dart2js/effectively_constant_fields_test.dart
new file mode 100644
index 0000000..6c9c18b
--- /dev/null
+++ b/tests/dart2js/effectively_constant_fields_test.dart
@@ -0,0 +1,74 @@
+// 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';
+
+_field4() => 4;
+
+class Class1 {
+  var field1 = 0;
+
+  @pragma('dart2js:noElision')
+  var field2 = 1;
+
+  var field3 = 2;
+
+  var field4 = _field4;
+}
+
+@pragma('dart2js:noInline')
+method1(Class1 c) {
+  return c.field1;
+}
+
+@pragma('dart2js:noInline')
+method2(Class1 c) {
+  return c.field2;
+}
+
+class Class2 {
+  var field3 = 3;
+}
+
+@pragma('dart2js:noInline')
+method3(c) {
+  return c.field3;
+}
+
+class Class3 extends Class1 {
+  @pragma('dart2js:noInline')
+  method4() {
+    return super.field1;
+  }
+}
+
+class Class4 extends Class1 {
+  @pragma('dart2js:noInline')
+  method5() {
+    return super.field4();
+  }
+}
+
+@pragma('dart2js:noInline')
+method6(Class1 c) {
+  return c.field1;
+}
+
+@pragma('dart2js:noInline')
+method7(Class1 c) {
+  return c.field4();
+}
+
+main() {
+  Expect.equals(0, method1(new Class1()));
+  Expect.equals(1, method2(new Class1()));
+  Expect.equals(2, method3(new Class1()));
+  Expect.equals(3, method3(new Class2()));
+  Expect.equals(0, new Class3().method4());
+  Expect.equals(4, new Class4().method5());
+  Expect.equals(0, method6(new Class1()));
+  Expect.throws(() => method6(null));
+  Expect.equals(4, method7(new Class1()));
+  Expect.throws(() => method7(null));
+}
diff --git a/tests/dart2js/effectively_constant_instance_field_test.dart b/tests/dart2js/effectively_constant_instance_field_test.dart
new file mode 100644
index 0000000..94020a2
--- /dev/null
+++ b/tests/dart2js/effectively_constant_instance_field_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+import 'package:expect/expect.dart';
+
+class C {
+  const C();
+}
+
+class A {
+  var field = const C();
+}
+
+class B {
+  var field;
+}
+
+@pragma('dart2js:noInline')
+test(o) => o.field;
+
+main() {
+  Expect.isNotNull(test(new A()));
+  Expect.isNull(test(new B()));
+}
diff --git a/tests/dart2js/empty_method_test.dart b/tests/dart2js/empty_method_test.dart
new file mode 100644
index 0000000..7bd2791
--- /dev/null
+++ b/tests/dart2js/empty_method_test.dart
@@ -0,0 +1,5 @@
+// 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.
+
+void main() {}
diff --git a/tests/dart2js/eof_line_ending_test.dart b/tests/dart2js/eof_line_ending_test.dart
new file mode 100644
index 0000000..b30e886
--- /dev/null
+++ b/tests/dart2js/eof_line_ending_test.dart
@@ -0,0 +1,10 @@
+// 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.

+
+// Regression test derived from language/issue_1578_test.dart with Windows

+// line encoding.

+

+main() {}

+

+]~<)$ //# 01: compile-time error

diff --git a/tests/dart2js/equals_test.dart b/tests/dart2js/equals_test.dart
new file mode 100644
index 0000000..c4a5309
--- /dev/null
+++ b/tests/dart2js/equals_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+void main() {
+  var x = 3;
+  if (x == x) {
+    print('good');
+  } else {
+    throw "x != x with x == 3";
+  }
+  dynamic y = x;
+  if (true) {
+    y = 10;
+  }
+  if (x == y) throw "3 == 10";
+  if (y == true) throw "10 == true";
+  if (y == "str") throw "3 == 'str'";
+  if (true == 'str') throw "true == 'str'";
+  if (true) y = false;
+  if (y == false) {
+    print('good');
+  } else {
+    throw "false != false";
+  }
+}
diff --git a/tests/dart2js/expose_this1_test.dart b/tests/dart2js/expose_this1_test.dart
new file mode 100644
index 0000000..84d3e70
--- /dev/null
+++ b/tests/dart2js/expose_this1_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2017, 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.
+
+// Regression test for dart2js inference. Class.field6b should be known to be
+// potentially `null`.
+
+import 'package:expect/expect.dart';
+
+class Class6 {
+  var field6a;
+  var field6b;
+
+  Class6() : field6a = 42 {
+    field6b = field6a;
+  }
+}
+
+class SubClass6 extends Class6 {
+  var field6b;
+
+  SubClass6() : field6b = 42;
+
+  get access => super.field6b;
+}
+
+subclassField2() {
+  new Class6();
+  return new SubClass6().access;
+}
+
+main() {
+  Expect.isTrue(subclassField2() == null);
+}
diff --git a/tests/dart2js/expose_this2_test.dart b/tests/dart2js/expose_this2_test.dart
new file mode 100644
index 0000000..d83abda
--- /dev/null
+++ b/tests/dart2js/expose_this2_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2017, 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.
+
+// Regression test for dart2js inference. Class9.field9b should be known to be
+// potentially `null`.
+
+import 'package:expect/expect.dart';
+
+class Class9 {
+  var field9a;
+  var field9b;
+
+  Class9() : field9a = 42 {
+    field9b = field9a;
+  }
+}
+
+class SubClass9a extends Class9 {
+  var field9b;
+
+  SubClass9a() : field9b = 42;
+
+  get access => super.field9b;
+}
+
+class SubClass9b extends Class9 {}
+
+subclassField5() {
+  new Class9();
+  new SubClass9b();
+  return new SubClass9a().access;
+}
+
+main() {
+  Expect.isTrue(subclassField5() == null);
+}
diff --git a/tests/dart2js/field_access_test.dart b/tests/dart2js/field_access_test.dart
new file mode 100644
index 0000000..044baf4
--- /dev/null
+++ b/tests/dart2js/field_access_test.dart
@@ -0,0 +1,88 @@
+// 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.
+
+// Test the all variants of field/property access/update are emitted.
+//
+// This is needed because getter/setters are now registered as read from and
+// written to, respectively, instead of being invoked.
+
+var field1a;
+
+var field1b;
+
+var field1c;
+
+@pragma('dart2js:noInline')
+get field2a => 42;
+
+@pragma('dart2js:noInline')
+set field2a(_) {}
+
+@pragma('dart2js:noInline')
+get field2b => 42;
+
+@pragma('dart2js:noInline')
+set field2b(_) {}
+
+@pragma('dart2js:noInline')
+get field2c => 42;
+
+@pragma('dart2js:noInline')
+set field2c(_) {}
+
+class Class {
+  @pragma('dart2js:noElision')
+  var field1a;
+
+  var field1b;
+
+  var field1c;
+
+  @pragma('dart2js:noInline')
+  get field2a => 42;
+
+  @pragma('dart2js:noInline')
+  set field2a(_) {}
+
+  @pragma('dart2js:noInline')
+  get field2b => 42;
+
+  @pragma('dart2js:noInline')
+  set field2b(_) {}
+
+  @pragma('dart2js:noInline')
+  get field2c => 42;
+
+  set field2c(_) {}
+
+  var field3a = 0;
+
+  var field3b;
+
+  @pragma('dart2js:noInline')
+  Class([this.field3b]);
+
+  @pragma('dart2js:noInline')
+  test() {
+    field1a;
+    field1b = 42;
+    field1c = field1c;
+
+    field2a;
+    field2b = 42;
+    field2c = field2c;
+  }
+}
+
+main() {
+  field1a;
+  field1b = 42;
+  field1c = field1c;
+
+  field2a;
+  field2b = 42;
+  field2c = field2c;
+
+  new Class().test();
+}
diff --git a/tests/dart2js/field_in_constructor_test.dart b/tests/dart2js/field_in_constructor_test.dart
new file mode 100644
index 0000000..29d1d66
--- /dev/null
+++ b/tests/dart2js/field_in_constructor_test.dart
@@ -0,0 +1,16 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  var a;
+  A() {
+    a = 2;
+  }
+}
+
+main() {
+  Expect.equals(2, new A().a);
+}
diff --git a/tests/dart2js/field_initializer_test.dart b/tests/dart2js/field_initializer_test.dart
new file mode 100644
index 0000000..b06f763
--- /dev/null
+++ b/tests/dart2js/field_initializer_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  static var a;
+  static var b = c;
+  static const c = 499;
+  static const d = c;
+  static const e = d;
+  static const f = B.g;
+  static const h = true;
+  static const i = false;
+  static const j = n;
+  static const k = 4.99;
+  static const l = null;
+  static const m = l;
+  static const n = 42;
+}
+
+class B {
+  static const g = A.c;
+}
+
+testInitialValues() {
+  Expect.equals(null, A.a);
+  Expect.equals(499, A.b);
+  Expect.equals(499, A.c);
+  Expect.equals(499, A.d);
+  Expect.equals(499, A.e);
+  Expect.equals(499, A.f);
+  Expect.equals(499, B.g);
+  Expect.equals(true, A.h);
+  Expect.equals(false, A.i);
+  Expect.equals(42, A.j);
+  Expect.equals(4.99, A.k);
+  Expect.equals(null, A.l);
+  Expect.equals(null, A.m);
+  Expect.equals(42, A.n);
+}
+
+testMutation() {
+  A.a = 499;
+  Expect.equals(499, A.a);
+  A.b = 42;
+  Expect.equals(42, A.b);
+  Expect.equals(499, A.c);
+  Expect.equals(499, A.a);
+}
+
+main() {
+  testInitialValues();
+  testMutation();
+}
diff --git a/tests/dart2js/fields_test.dart b/tests/dart2js/fields_test.dart
new file mode 100644
index 0000000..95c2ca3
--- /dev/null
+++ b/tests/dart2js/fields_test.dart
@@ -0,0 +1,33 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  A() {}
+  int x;
+
+  foo() {
+    x = 42;
+    Expect.equals(42, x);
+    x = 0;
+    Expect.equals(0, x);
+  }
+}
+
+class B extends A {}
+
+main() {
+  A a = new A();
+  a.foo();
+  Expect.equals(0, a.x);
+  a.x = 4;
+  Expect.equals(4, a.x);
+  a.x += 1;
+  Expect.equals(5, a.x);
+
+  B b = new B();
+  b.foo();
+  Expect.equals(0, b.x);
+}
diff --git a/tests/dart2js/first_class_types_hashcode_test.dart b/tests/dart2js/first_class_types_hashcode_test.dart
new file mode 100644
index 0000000..06e43bd
--- /dev/null
+++ b/tests/dart2js/first_class_types_hashcode_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Check that Type instances work with maps. This behavior is not required by
+// the specification.
+
+class A {}
+
+class B<T> {}
+
+main() {
+  Map<Type, String> map = new Map<Type, String>();
+  Type a = new A().runtimeType;
+  Type b1 = new B<int>().runtimeType;
+  Type b2 = new B<String>().runtimeType;
+  map[a] = 'A';
+  map[b1] = 'B<int>';
+  map[b2] = 'B<String>';
+  Expect.equals('A', map[new A().runtimeType]);
+  Expect.equals('B<int>', map[new B<int>().runtimeType]);
+  Expect.equals('B<String>', map[new B<String>().runtimeType]);
+}
diff --git a/tests/dart2js/fixed_type_argument_implements_test.dart b/tests/dart2js/fixed_type_argument_implements_test.dart
new file mode 100644
index 0000000..f0c397e
--- /dev/null
+++ b/tests/dart2js/fixed_type_argument_implements_test.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.
+
+// Test that we emit the relation between B and A even when B is only live
+// as a type argument through the supertype of D.
+
+class A {}
+
+class B implements A {}
+
+class C<T> {}
+
+class D implements C<B> {}
+
+main() {
+  C<A> c = new D();
+  test(c);
+}
+
+@pragma('dart2js:noInline')
+void test(C<A> c) {}
diff --git a/tests/dart2js/fixed_type_argument_test.dart b/tests/dart2js/fixed_type_argument_test.dart
new file mode 100644
index 0000000..74ac892
--- /dev/null
+++ b/tests/dart2js/fixed_type_argument_test.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.
+
+// Test that we emit the relation between B and A even when B is only live
+// as a type argument through the superclass of D.
+
+class A {}
+
+class B implements A {}
+
+class C<T> {
+  @pragma('dart2js:noInline')
+  method(void Function(T) f) {}
+}
+
+class D extends C<B> {}
+
+main() {
+  C<A> c = new D();
+  c.method((A a) {});
+}
diff --git a/tests/dart2js/foo7_test.dart b/tests/dart2js/foo7_test.dart
new file mode 100644
index 0000000..dc93acf
--- /dev/null
+++ b/tests/dart2js/foo7_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+void main() {
+  print(foo());
+}
+
+int foo() {
+  return 3 + 4;
+}
diff --git a/tests/dart2js/for_in_test.dart b/tests/dart2js/for_in_test.dart
new file mode 100644
index 0000000..8f0eb15
--- /dev/null
+++ b/tests/dart2js/for_in_test.dart
@@ -0,0 +1,93 @@
+// 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 "package:expect/expect.dart";
+
+// Test foreach (aka. for-in) functionality.
+
+testIterator(List expect, Iterable input) {
+  int i = 0;
+  for (var value in input) {
+    Expect.isTrue(i < expect.length);
+    Expect.equals(expect[i], value);
+    i += 1;
+  }
+  Expect.equals(expect.length, i);
+
+  i = 0;
+  var value2;
+  for (value2 in input) {
+    Expect.isTrue(i < expect.length);
+    Expect.equals(expect[i], value2);
+    i += 1;
+  }
+  Expect.equals(expect.length, i);
+}
+
+class MyIterable<T> extends IterableBase<T> {
+  final List<T> values;
+  MyIterable(List<T> values) : this.values = values;
+  Iterator<T> get iterator {
+    return new MyListIterator<T>(values);
+  }
+}
+
+class MyListIterator<T> implements Iterator<T> {
+  final List<T> values;
+  int index;
+  MyListIterator(List<T> values)
+      : this.values = values,
+        index = -1;
+
+  bool moveNext() => ++index < values.length;
+  T get current => (0 <= index && index < values.length) ? values[index] : null;
+}
+
+void main() {
+  testIterator([], []);
+  testIterator([], new MyIterable([]));
+  testIterator([1], [1]);
+  testIterator([1], new MyIterable([1]));
+  testIterator([1, 2, 3], [1, 2, 3]);
+  testIterator([1, 2, 3], new MyIterable([1, 2, 3]));
+  testIterator(["a", "b", "c"], ["a", "b", "c"]);
+  testIterator(["a", "b", "c"], new MyIterable(["a", "b", "c"]));
+
+  // Several nested for-in's.
+  for (var x in [
+    [
+      ["a"]
+    ]
+  ]) {
+    for (var y in x) {
+      for (var z in y) {
+        Expect.equals("a", z);
+      }
+    }
+  }
+
+  // Simultaneous iteration of the same iterable.
+  for (var iterable in [
+    [1, 2, 3],
+    new MyIterable([1, 2, 3])
+  ]) {
+    int result = 0;
+    for (var x in iterable) {
+      for (var y in iterable) {
+        result += x * y;
+      }
+    }
+    Expect.equals(36, result);
+  }
+
+  // Using the same variable (showing that the expression is evaluated
+  // in the outer scope).
+  int result = 0;
+  var x = [1, 2, 3];
+  for (var x in x) {
+    result += x;
+  }
+  Expect.equals(6, result);
+}
diff --git a/tests/dart2js/for_test.dart b/tests/dart2js/for_test.dart
new file mode 100644
index 0000000..fc910be
--- /dev/null
+++ b/tests/dart2js/for_test.dart
@@ -0,0 +1,89 @@
+// 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 "package:expect/expect.dart";
+
+void for1() {
+  var cond = true;
+  var result = 0;
+  for (var x = 0; cond; x = x + 1) {
+    if (x == 10) cond = false;
+    result = result + x;
+  }
+  Expect.equals(55, result);
+}
+
+void for2() {
+  var t = 0;
+  for (var i = 0; i == 0; i = i + 1) {
+    t = t + 10;
+  }
+  Expect.equals(10, t);
+}
+
+void for3() {
+  for (var i = 0; i == 1; i = i + 1) {
+    Expect.fail('unreachable');
+  }
+}
+
+void for4() {
+  var cond1 = true;
+  var result = 0;
+  for (var i = 0; cond1; i = i + 1) {
+    if (i == 9) cond1 = false;
+    var cond2 = true;
+    for (var j = 0; cond2; j = j + 1) {
+      if (j == 9) cond2 = false;
+      result = result + 1;
+    }
+  }
+  Expect.equals(100, result);
+}
+
+void for5() {
+  var i;
+  var sum = 0;
+  for (i = 0; i < 5; i++) {
+    sum += i;
+  }
+  Expect.equals(5, i);
+  Expect.equals(10, sum);
+}
+
+void for6() {
+  var i = 0;
+  var sum = 0;
+  for (; i < 5; i++) {
+    sum += i;
+  }
+  Expect.equals(5, i);
+  Expect.equals(10, sum);
+
+  sum = 0;
+  i = 0;
+  for (; i < 5;) {
+    sum += i;
+    i++;
+  }
+  Expect.equals(5, i);
+  Expect.equals(10, sum);
+
+  sum = 0;
+  for (i = 0; i < 5;) {
+    sum += i;
+    i++;
+  }
+  Expect.equals(5, i);
+  Expect.equals(10, sum);
+}
+
+void main() {
+  for1();
+  for2();
+  for3();
+  for4();
+  for5();
+  for6();
+}
diff --git a/tests/dart2js/function_parameters_test.dart b/tests/dart2js/function_parameters_test.dart
new file mode 100644
index 0000000..1632fb6
--- /dev/null
+++ b/tests/dart2js/function_parameters_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+void main() {
+  print(foo(3) + foo(4));
+}
+
+int foo(int a) {
+  return a;
+}
diff --git a/tests/dart2js/function_typed_arguments_test.dart b/tests/dart2js/function_typed_arguments_test.dart
new file mode 100644
index 0000000..f18daee
--- /dev/null
+++ b/tests/dart2js/function_typed_arguments_test.dart
@@ -0,0 +1,104 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+// Test type tests of function types used a type argument.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+}
+
+class B1<T> {}
+
+class C1 extends B1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(new A<void Function(C1)>()));
+  Expect.isTrue(_test1(new A<void Function(B1<int>)>())); //# 01: ok
+  Expect.isFalse(_test1(new A<void Function(B1<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test1(f) => f is A<void Function(C1)>;
+
+class B2<T> {}
+
+class C2 extends B2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isTrue(_test2(new A<C2 Function()>()));
+  Expect.isFalse(_test2(new A<B2<int> Function()>()));
+  Expect.isFalse(_test2(new A<B2<String> Function()>()));
+}
+
+@pragma('dart2js:noInline')
+_test2(f) => f is A<C2 Function()>;
+
+class B3<T> {}
+
+class C3 extends B3<int> {}
+
+@pragma('dart2js:noInline')
+test3() {
+  Expect.isFalse(_test3(new A<void Function(C3)>()));
+  Expect.isTrue(_test3(new A<void Function(B3<int>)>()));
+  Expect.isFalse(_test3(new A<void Function(B3<String>)>()));
+}
+
+@pragma('dart2js:noInline')
+_test3(f) => f is A<void Function(B3<int>)>;
+
+class B4<T> {}
+
+class C4 extends B4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(new A<C4 Function()>()));
+  Expect.isTrue(_test4(new A<B4<int> Function()>()));
+  Expect.isFalse(_test4(new A<B4<String> Function()>()));
+}
+
+@pragma('dart4js:noInline')
+_test4(f) => f is A<B4<int> Function()>;
+
+class B5<T> {}
+
+class C5 extends B5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(new A<void Function(C5 Function())>()));
+  Expect.isTrue(_test5(new A<void Function(B5<int> Function())>())); //# 02: ok
+  Expect.isFalse(_test5(new A<void Function(B5<String> Function())>()));
+}
+
+@pragma('dart2js:noInline')
+_test5(f) => f is A<void Function(C5 Function())>;
+
+class B6<T> {}
+
+class C6 extends B6<int> {}
+
+@pragma('dart2js:noInline')
+test6() {
+  Expect.isTrue(_test6(new A<void Function(void Function(C6))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<int>))>()));
+  Expect.isFalse(_test6(new A<void Function(void Function(B6<String>))>()));
+}
+
+@pragma('dart2js:noInline')
+_test6(f) => f is A<void Function(void Function(C6))>;
diff --git a/tests/dart2js/generator_elided_parameter_test.dart b/tests/dart2js/generator_elided_parameter_test.dart
new file mode 100644
index 0000000..60bf18b
--- /dev/null
+++ b/tests/dart2js/generator_elided_parameter_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.
+
+/// Test that optional arguments of methods with a generator are forwarded
+/// properly when optional parameters are elided.
+///
+/// This is a regression test for issue #35924
+import "package:expect/expect.dart";
+
+// The type parameter forces us to create a generator body. The call from the
+// method to the body needs to correctly handle elided parameters.
+Future<T> foo<T>(T Function(int, int, int) toT,
+    {int p1: 0, int p2: 1, int p3: 2}) async {
+  await null;
+  return toT(p1, p2, p3);
+}
+
+main() async {
+  Expect.equals(await foo<String>((a, b, c) => "$a $b $c", p2: 4), "0 4 2");
+}
diff --git a/tests/dart2js/generic_bounds_test.dart b/tests/dart2js/generic_bounds_test.dart
new file mode 100644
index 0000000..0b9cacb
--- /dev/null
+++ b/tests/dart2js/generic_bounds_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B extends A {}
+
+class C {}
+
+class D<T> {}
+
+class E<T> extends D<T> {}
+
+class F<T> {}
+
+void f1<T extends A>() {
+  print('f1<$T>');
+}
+
+void f2<S, T extends D<S>>() {
+  print('f2<$S,$T>');
+}
+
+main() {
+  dynamic f = f1;
+  f<A>();
+  f<B>();
+  Expect.throws(() => f<C>(), (e) {
+    print(e);
+    return true;
+  });
+  f();
+  f = f2;
+  f<A, D<A>>();
+  f<A, E<A>>();
+  Expect.throws(() => f<A, F<A>>(), (e) {
+    print(e);
+    return true;
+  });
+  f();
+}
diff --git a/tests/dart2js/generic_class_is_test.dart b/tests/dart2js/generic_class_is_test.dart
new file mode 100644
index 0000000..6026b8d
--- /dev/null
+++ b/tests/dart2js/generic_class_is_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class A1 implements A<C1> {}
+
+class B<T> {
+  @pragma('dart2js:noInline')
+  method(var t) => t is T;
+}
+
+class C {}
+
+class C1 implements C {}
+
+class C2 implements C {}
+
+main() {
+  Expect.isTrue(new B<List<A<C>>>().method(new List<A1>()));
+  Expect.isFalse(new B<List<A<C2>>>().method(new List<A1>()));
+}
diff --git a/tests/dart2js/generic_in_mixin_field_test.dart b/tests/dart2js/generic_in_mixin_field_test.dart
new file mode 100644
index 0000000..6018432
--- /dev/null
+++ b/tests/dart2js/generic_in_mixin_field_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// Ensure that we prepare type variables for inlined mixin fields.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class Mixin<T> {
+  var field = new A<T>();
+
+  m1() => field is A<int>;
+  m2() => field is A<String>;
+}
+
+class SuperClass<T> extends Object with Mixin<T> {}
+
+class Class extends SuperClass<int> {}
+
+@pragma('dart2js:noInline')
+createClass() => new Class();
+
+main() {
+  var c = createClass();
+  Expect.isTrue(c.m1());
+  Expect.isFalse(c.m2());
+}
diff --git a/tests/dart2js/generic_in_redirect_test.dart b/tests/dart2js/generic_in_redirect_test.dart
new file mode 100644
index 0000000..35e4564
--- /dev/null
+++ b/tests/dart2js/generic_in_redirect_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+// Ensure that we prepare type variables for inlined redirecting constructor
+// calls.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class SuperClass<T> {
+  var field;
+
+  SuperClass() : this._(new A<T>());
+
+  SuperClass._(this.field);
+
+  m1() => field is A<int>;
+  m2() => field is A<String>;
+}
+
+class Class extends SuperClass<int> {}
+
+@pragma('dart2js:noInline')
+createClass() => new Class();
+
+main() {
+  var c = createClass();
+  Expect.isTrue(c.m1());
+  Expect.isFalse(c.m2());
+}
diff --git a/tests/dart2js/generic_in_super_test.dart b/tests/dart2js/generic_in_super_test.dart
new file mode 100644
index 0000000..79bc8c9
--- /dev/null
+++ b/tests/dart2js/generic_in_super_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// Ensure that we prepare type variables for inlined super constructor calls.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class SuperSuperClass<T> {
+  var field;
+
+  SuperSuperClass(this.field);
+
+  m1() => field is A<int>;
+  m2() => field is A<String>;
+}
+
+class SuperClass<T> extends SuperSuperClass<T> {
+  SuperClass() : super(new A<T>());
+}
+
+class Class extends SuperClass<int> {}
+
+@pragma('dart2js:noInline')
+createClass() => new Class();
+
+main() {
+  var c = createClass();
+  Expect.isTrue(c.m1());
+  Expect.isFalse(c.m2());
+}
diff --git a/tests/dart2js/generic_instantiation1_test.dart b/tests/dart2js/generic_instantiation1_test.dart
new file mode 100644
index 0000000..fcfb79f
--- /dev/null
+++ b/tests/dart2js/generic_instantiation1_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+int f<T>(T a) => null;
+
+typedef int F<R>(R a);
+
+class B<S> {
+  F<S> c;
+
+  B() : c = f;
+}
+
+main() {
+  new B<int>().c(0);
+}
diff --git a/tests/dart2js/generic_instantiation2_test.dart b/tests/dart2js/generic_instantiation2_test.dart
new file mode 100644
index 0000000..047d221
--- /dev/null
+++ b/tests/dart2js/generic_instantiation2_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks
+
+int f<T>(T a) => null;
+
+typedef int F<R>(R a);
+
+class B<S> {
+  F<S> c;
+
+  B() : c = f;
+}
+
+main() {
+  new B<int>().c(0);
+}
diff --git a/tests/dart2js/generic_instantiation3_test.dart b/tests/dart2js/generic_instantiation3_test.dart
new file mode 100644
index 0000000..3152565
--- /dev/null
+++ b/tests/dart2js/generic_instantiation3_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+bool f<T, S>(T a, S b) => a is S;
+
+typedef bool F<P, Q>(P a, Q b);
+
+class B<X, Y> {
+  F<X, Y> c;
+
+  B() : c = f;
+}
+
+main() {
+  Expect.isTrue(new B<int, int>().c(0, 0));
+  Expect.isFalse(new B<int, String>().c(0, ''));
+}
diff --git a/tests/dart2js/generic_instantiation4_test.dart b/tests/dart2js/generic_instantiation4_test.dart
new file mode 100644
index 0000000..d5f8eb9
--- /dev/null
+++ b/tests/dart2js/generic_instantiation4_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks
+
+import 'package:expect/expect.dart';
+
+bool f<T, S>(T a, S b) => a is S;
+
+typedef bool F<P, Q>(P a, Q b);
+
+class B<X, Y> {
+  F<X, Y> c;
+
+  B() : c = f;
+}
+
+main() {
+  Expect.isTrue(new B<int, int>().c(0, 0));
+  Expect.isFalse(new B<int, String>().c(0, ''));
+}
diff --git a/tests/dart2js/generic_method_dynamic_is_test.dart b/tests/dart2js/generic_method_dynamic_is_test.dart
new file mode 100644
index 0000000..ff95b2b
--- /dev/null
+++ b/tests/dart2js/generic_method_dynamic_is_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B implements A {}
+
+class C<T> {}
+
+class D {}
+
+class E {
+  @pragma('dart2js:noInline')
+  m<T>() => new C<T>();
+}
+
+class F {
+  @pragma('dart2js:noInline')
+  m<T>() => false;
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is C<A>;
+
+main() {
+  dynamic o =
+      new DateTime.now().millisecondsSinceEpoch == 0 ? new F() : new E();
+  Expect.isTrue(test(o.m<B>()));
+  Expect.isFalse(test(o.m<D>()));
+}
diff --git a/tests/dart2js/generic_method_dynamic_type_test.dart b/tests/dart2js/generic_method_dynamic_type_test.dart
new file mode 100644
index 0000000..ab7221d
--- /dev/null
+++ b/tests/dart2js/generic_method_dynamic_type_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class C<CT> {
+  foo<FT extends CT>() => CT;
+
+  BT bar<BT extends CT>(BT x) => x;
+  CT map<MT extends CT>(MT x) => x;
+}
+
+main() {
+  dynamic o = new C<num>();
+
+  Expect.equals('<T1 extends num>() => dynamic', o.foo.runtimeType.toString());
+
+  // Instantiations
+  int Function(int) f1 = new C<num>().bar;
+  num Function(int) f2 = new C<num>().map;
+
+  Expect.equals('(int) => int', f1.runtimeType.toString());
+  Expect.equals('(int) => num', f2.runtimeType.toString());
+}
diff --git a/tests/dart2js/generic_method_static_is_test.dart b/tests/dart2js/generic_method_static_is_test.dart
new file mode 100644
index 0000000..c05be8c
--- /dev/null
+++ b/tests/dart2js/generic_method_static_is_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A {}
+
+class B implements A {}
+
+class C<T> {}
+
+class D {}
+
+@pragma('dart2js:noInline')
+m<T>() => new C<T>();
+
+@pragma('dart2js:noInline')
+test(o) => o is C<A>;
+
+main() {
+  Expect.isTrue(test(m<B>()));
+  Expect.isFalse(test(m<D>()));
+}
diff --git a/tests/dart2js/generic_type_error_message_test.dart b/tests/dart2js/generic_type_error_message_test.dart
new file mode 100644
index 0000000..e9ff104
--- /dev/null
+++ b/tests/dart2js/generic_type_error_message_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Foo<T extends num> {}
+
+class Bar<T extends num> {}
+
+class Baz<T extends num> {}
+
+@pragma('dart2js:disableFinal')
+main() {
+  test(new Foo(), Foo, expectTypeArguments: false);
+  test(new Bar() as Bar<num>, Bar, expectTypeArguments: false);
+  Baz<num> b = new Baz();
+  dynamic c = b;
+  test(c as Baz<num>, Baz, expectTypeArguments: true);
+}
+
+void test(dynamic object, Type type, {bool expectTypeArguments}) {
+  bool caught = false;
+  try {
+    print(type);
+    object as List<String>;
+  } catch (e) {
+    String expected = '$type';
+    if (!expectTypeArguments) {
+      expected = expected.substring(0, expected.indexOf('<'));
+    }
+    expected = '$expected';
+    Expect.isTrue(e.toString().contains(expected),
+        'Expected "$expected" in the message: $e');
+    caught = true;
+    print(e);
+  }
+  Expect.isTrue(caught);
+}
diff --git a/tests/dart2js/generics_factories_test.dart b/tests/dart2js/generics_factories_test.dart
new file mode 100644
index 0000000..5ca2d59
--- /dev/null
+++ b/tests/dart2js/generics_factories_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2013, 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 that factories are marked as needing rti.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  foo(o) => o is T;
+  factory A.c() => new B<T>();
+  A();
+}
+
+class B<T> extends A<T> {}
+
+class C {}
+
+class D {}
+
+main() {
+  Expect.isTrue(new A<C>.c().foo(new C()));
+  Expect.isFalse(new A<C>.c().foo(new D()));
+}
diff --git a/tests/dart2js/generics_is_check1_test.dart b/tests/dart2js/generics_is_check1_test.dart
new file mode 100644
index 0000000..24d01e5
--- /dev/null
+++ b/tests/dart2js/generics_is_check1_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class Hest<X> {}
+
+main() {
+  var x = new Hest<int>();
+  Expect.isTrue(x is Hest<int>);
+  Expect.isFalse(x is Hest<String>);
+}
diff --git a/tests/dart2js/getter_element_test.dart b/tests/dart2js/getter_element_test.dart
new file mode 100644
index 0000000..9238e8f
--- /dev/null
+++ b/tests/dart2js/getter_element_test.dart
@@ -0,0 +1,31 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static main() {
+    testOther();
+    new A().testSelf();
+  }
+
+  static testOther() {
+    var o = new A();
+    o.instf = 0;
+    o.instf += 1;
+    Expect.equals(1, o.instf);
+  }
+
+  testSelf() {
+    instf = 0;
+    instf += 1;
+    Expect.equals(1, instf);
+  }
+
+  var instf;
+}
+
+main() {
+  A.main();
+}
diff --git a/tests/dart2js/getters_setters_test.dart b/tests/dart2js/getters_setters_test.dart
new file mode 100644
index 0000000..139f366
--- /dev/null
+++ b/tests/dart2js/getters_setters_test.dart
@@ -0,0 +1,128 @@
+// 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 "package:expect/expect.dart";
+
+class GettersSettersTest {
+  static int foo;
+
+  static get bar {
+    return foo;
+  }
+
+  static set bar(newValue) {
+    foo = newValue;
+  }
+
+  static testMain() {
+    A a = new A();
+    a.x = 2;
+    Expect.equals(2, a.x);
+    Expect.equals(2, a.x_);
+
+    // Test inheritance.
+    a = new B();
+    a.x = 4;
+    Expect.equals(4, a.x);
+    Expect.equals(4, a.x_);
+
+    // Test overriding.
+    C c = new C();
+    c.x = 8;
+    Expect.equals(8, c.x);
+    Expect.equals(0, c.x_);
+    Expect.equals(8, c.y_);
+
+    // Test keyed getters and setters.
+    a.x_ = 0;
+    Expect.equals(2, a[2]);
+    a[2] = 4;
+    Expect.equals(6, a[0]);
+
+    // Test assignment operators.
+    a.x_ = 0;
+    a[2] += 8;
+    Expect.equals(12, a[0]);
+
+    // Test calling a function that internally uses getters.
+    Expect.equals(true, a.isXPositive());
+
+    // Test static fields.
+    foo = 42;
+    Expect.equals(42, foo);
+    Expect.equals(42, bar);
+    A.foo = 43;
+    Expect.equals(43, A.foo);
+    Expect.equals(43, A.bar);
+
+    bar = 42;
+    Expect.equals(42, foo);
+    Expect.equals(42, bar);
+    A.bar = 43;
+    Expect.equals(43, A.foo);
+    Expect.equals(43, A.bar);
+  }
+}
+
+class A {
+  A();
+  int x_;
+  static int foo;
+
+  static get bar {
+    return foo;
+  }
+
+  static set bar(newValue) {
+    foo = newValue;
+  }
+
+  int get x {
+    return x_;
+  }
+
+  void set x(int value) {
+    x_ = value;
+  }
+
+  bool isXPositive() {
+    return x > 0;
+  }
+
+  int operator [](int index) {
+    return x_ + index;
+  }
+
+  void operator []=(int index, int value) {
+    x_ = index + value;
+  }
+
+  int getX_() {
+    return x_;
+  }
+}
+
+class B extends A {
+  B();
+}
+
+class C extends A {
+  int y_;
+
+  C() {
+    this.x_ = 0;
+  }
+
+  int get x {
+    return y_;
+  }
+
+  void set x(int value) {
+    y_ = value;
+  }
+}
+
+main() {
+  GettersSettersTest.testMain();
+}
diff --git a/tests/dart2js/hash_code_test.dart b/tests/dart2js/hash_code_test.dart
new file mode 100644
index 0000000..cb6789c
--- /dev/null
+++ b/tests/dart2js/hash_code_test.dart
@@ -0,0 +1,88 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// dart2js specific test to make sure hashCode on intercepted types behaves as
+// intended.
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class Hasher {
+  hash(x) => confuse(x).hashCode;
+}
+
+// Hashing via [hash] should be forced to use the general interceptor, but the
+// local x.hashCode calls might be optimized.
+var hash = new Hasher().hash;
+
+check(value1, value2, {identityHashCode}) {
+  var h1 = hash(value1);
+  var h2 = hash(value2);
+  Expect.isTrue(h1 is int);
+  Expect.isTrue(h2 is int);
+
+  // Quality check - the values should be SMIs for efficient arithmetic.
+  Expect.equals((h1 & 0x3fffffff), h1);
+  Expect.equals((h2 & 0x3fffffff), h2);
+
+  // If we're checking the (randomized) identity hash code function,
+  // we cannot guarantee anything about the actual hash code values.
+  if (identityHashCode) return;
+
+  // We expect that the hash function is reasonable quality - there
+  // are some difference in the low bits.
+  Expect.isFalse(h1 == h2);
+  Expect.isFalse((h1 & 0xf) == (h2 & 0xf));
+}
+
+bools() {
+  check(true, false, identityHashCode: false);
+
+  Expect.equals(true.hashCode, hash(true)); // First can be optimized.
+  Expect.equals(false.hashCode, hash(false));
+}
+
+ints() {
+  var i1 = 100;
+  var i2 = 101;
+  check(i1, i2, identityHashCode: false);
+  Expect.equals(i1.hashCode, hash(i1));
+  Expect.equals(i2.hashCode, hash(i2));
+}
+
+lists() {
+  var list1 = [];
+  var list2 = [];
+  check(list1, list2, identityHashCode: true);
+
+  Expect.equals(list1.hashCode, hash(list1));
+  Expect.equals(list2.hashCode, hash(list2));
+}
+
+strings() {
+  var str1 = 'a';
+  var str2 = 'b';
+  var str3 = 'c';
+  check(str1, str2, identityHashCode: false);
+  check(str1, str3, identityHashCode: false);
+  check(str2, str3, identityHashCode: false);
+
+  Expect.equals(str1.hashCode, hash(str1));
+  Expect.equals(str2.hashCode, hash(str2));
+  Expect.equals(str3.hashCode, hash(str3));
+
+  Expect.equals(0xA2E9442, 'a'.hashCode);
+  Expect.equals(0x0DB819B, 'b'.hashCode);
+  Expect.equals(0xEBA5D59, 'c'.hashCode);
+}
+
+main() {
+  bools();
+  ints();
+  lists();
+  strings();
+}
diff --git a/tests/dart2js/identical_trace_test.dart b/tests/dart2js/identical_trace_test.dart
new file mode 100644
index 0000000..8fc86cb
--- /dev/null
+++ b/tests/dart2js/identical_trace_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, 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';
+
+main() {
+  var st1;
+  try {
+    try {
+      throw 'bad';
+    } catch (e, st) {
+      st1 = st;
+      rethrow;
+    }
+    Expect.fail('Exception expected');
+  } catch (e, st2) {
+    Expect.equals(st1, st2);
+    Expect.identical(st1, st2);
+    return;
+  }
+  Expect.fail('Exception expected');
+}
diff --git a/tests/dart2js/if_in_loop_test.dart b/tests/dart2js/if_in_loop_test.dart
new file mode 100644
index 0000000..af3590d
--- /dev/null
+++ b/tests/dart2js/if_in_loop_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test for bug in code generation of if-with-aborting-branch-inside-loop.
+
+foo(p, q) {
+  var w = 10;
+  do {
+    if (p) {
+      w = 20;
+    } else {
+      w = 30;
+      return w;
+    }
+  } while (q);
+  return w;
+}
+
+main() {
+  Expect.equals(30, foo(false, true));
+  Expect.equals(30, foo(false, false));
+  Expect.equals(20, foo(true, false));
+}
diff --git a/tests/dart2js/if_null2_test.dart b/tests/dart2js/if_null2_test.dart
new file mode 100644
index 0000000..32b8f7e
--- /dev/null
+++ b/tests/dart2js/if_null2_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+/// Regression for #24134: inference was not tracking ??= correctly.
+library dart2js.if_null2_test;
+
+import "package:expect/expect.dart";
+
+main() {
+  var map;
+  map ??= {};
+  Expect.equals(0, map.length);
+  Expect.isTrue(map.length == 0);
+}
diff --git a/tests/dart2js/if_null3_test.dart b/tests/dart2js/if_null3_test.dart
new file mode 100644
index 0000000..558ca20
--- /dev/null
+++ b/tests/dart2js/if_null3_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2015, 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.
+
+/// Regression for #24135: inference was not tracking `[]??=` correctly.
+library dart2js.if_null3_test;
+
+import "package:expect/expect.dart";
+
+void main() {
+  var map;
+  (((map ??= {})['key1'] ??= {})['key2'] ??= {})['key3'] = 'value';
+  Expect.equals('{key1: {key2: {key3: value}}}', '$map');
+}
diff --git a/tests/dart2js/if_null_test.dart b/tests/dart2js/if_null_test.dart
new file mode 100644
index 0000000..8b16c6b
--- /dev/null
+++ b/tests/dart2js/if_null_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2015, 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";
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main(args) {
+  dynamic x = new A();
+  var y;
+
+  // Checks that inference doesn't incorrectly treat this as a normal
+  // assignment (where only B is a possible value after the assignment).
+  dynamic c = x ??= new B();
+  var z = x;
+  Expect.equals('a', x.m());
+  Expect.equals('a', z.m());
+  Expect.equals('a', c.m());
+  if (confuse(true)) y = x;
+  Expect.equals('a', y.m());
+
+  // Similar test, within fields.
+  new C();
+  new D();
+}
+
+class A {
+  m() => 'a';
+}
+
+class B {
+  m() => 'b';
+}
+
+class C {
+  var y;
+  C() {
+    y = new A();
+    var c = y ??= new B();
+    Expect.equals('a', y.m());
+    Expect.equals('a', c.m());
+  }
+}
+
+class D {
+  var y;
+  D() {
+    this.y = new A();
+    var c = this.y ??= new B();
+    Expect.equals('a', y.m());
+    Expect.equals('a', c.m());
+  }
+}
diff --git a/tests/dart2js/if_test.dart b/tests/dart2js/if_test.dart
new file mode 100644
index 0000000..3c1670b
--- /dev/null
+++ b/tests/dart2js/if_test.dart
@@ -0,0 +1,60 @@
+// 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 "package:expect/expect.dart";
+
+int if1() {
+  if (true) {
+    return 499;
+  }
+  return 3;
+}
+
+int if2() {
+  if (true) {
+    return 499;
+  }
+}
+
+int if3() {
+  if (false) {
+    return 42;
+  } else {
+    if (true) {
+      return 499;
+    }
+    Expect.fail('unreachable');
+  }
+}
+
+int if4() {
+  if (true) {
+    return 499;
+  } else {
+    return 42;
+  }
+}
+
+int if5() {
+  if (true) {
+    if (false) return 42;
+  } else {}
+  return 499;
+}
+
+int if6() {
+  if (true) {
+    if (false) return 42;
+  }
+  return 499;
+}
+
+void main() {
+  Expect.equals(499, if1());
+  Expect.equals(499, if2());
+  Expect.equals(499, if3());
+  Expect.equals(499, if4());
+  Expect.equals(499, if5());
+  Expect.equals(499, if6());
+}
diff --git a/tests/dart2js/index_test.dart b/tests/dart2js/index_test.dart
new file mode 100644
index 0000000..890d71a
--- /dev/null
+++ b/tests/dart2js/index_test.dart
@@ -0,0 +1,43 @@
+// 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 "package:expect/expect.dart";
+
+main() {
+  var a = [0];
+  Expect.equals(0, a[0]);
+
+  a = [1, 2];
+  Expect.equals(1, a[0]);
+  Expect.equals(2, a[1]);
+
+  a[0] = 42;
+  Expect.equals(42, a[0]);
+  Expect.equals(2, a[1]);
+
+  a[1] = 43;
+  Expect.equals(42, a[0]);
+  Expect.equals(43, a[1]);
+
+  a[1] += 2;
+  Expect.equals(45, a[1]);
+  a[1] -= a[1];
+  Expect.equals(0, a[1]);
+
+  var b = a[1]++;
+  Expect.equals(1, a[1]);
+  Expect.equals(0, b);
+
+  b = ++a[1];
+  Expect.equals(2, a[1]);
+  Expect.equals(2, b);
+
+  b = a[1]--;
+  Expect.equals(1, a[1]);
+  Expect.equals(2, b);
+
+  b = --a[1];
+  Expect.equals(0, a[1]);
+  Expect.equals(0, b);
+}
diff --git a/tests/dart2js/indirect_type_literal_test.dart b/tests/dart2js/indirect_type_literal_test.dart
new file mode 100644
index 0000000..8929796
--- /dev/null
+++ b/tests/dart2js/indirect_type_literal_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import "package:expect/expect.dart";
+
+class A<T> {}
+
+class B<T extends num> {}
+
+class Indirect<T> {
+  Type get type => T;
+}
+
+void main() {
+  Expect.equals(A, new Indirect<A>().type);
+  Expect.equals(A, new Indirect<A<dynamic>>().type);
+  Expect.notEquals(A, new Indirect<A<num>>().type);
+  Expect.equals(B, new Indirect<B>().type);
+  Expect.equals(B, new Indirect<B<num>>().type);
+  Expect.notEquals(B, new Indirect<B<int>>().type);
+}
diff --git a/tests/dart2js/inference_super_set_call_test.dart b/tests/dart2js/inference_super_set_call_test.dart
new file mode 100644
index 0000000..19e1a06
--- /dev/null
+++ b/tests/dart2js/inference_super_set_call_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js: we incorrectly modeled `super.x = rhs` as a
+// call and not an assignment, so the type of the expression was incorrectly
+// assumed to be the return type of the setter rather than the type of the rhs.
+import 'package:expect/expect.dart';
+
+abstract class A {
+  set x(v) {}
+  set z(v) {}
+  set y(v) => 'hi';
+}
+
+class S extends A {
+  var _x; //      was bad: inferred as null, than [null | int]
+  dynamic _y = ''; // was bad: inferred as String, rather than [String | int]
+  var _z; //      was ok : inferred as [null | int]
+
+  set x(v) {
+    _x = super.x = v;
+  }
+
+  set z(v) {
+    super.z = v;
+    _z = v;
+  }
+
+  set y(v) {
+    _y = super.y = v;
+  }
+
+  get isXNull => _x == null;
+  get isZNull => _z == null;
+}
+
+main() {
+  var s = new S()
+    ..x = 2
+    ..y = 2
+    ..z = 2;
+  Expect.equals(false, s.isXNull); //      was incorrectly optimized to 'true'
+  Expect.equals(false, s._y is String); // was incorrectly optimized to 'true'
+  Expect.equals(false, s.isZNull); //      prints false
+}
diff --git a/tests/dart2js/inferrer_is_int_test.dart b/tests/dart2js/inferrer_is_int_test.dart
new file mode 100644
index 0000000..c1cb1af
--- /dev/null
+++ b/tests/dart2js/inferrer_is_int_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, 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 that dart2js's inferrer and code optimizers know a double
+// literal might become an int at runtime.
+
+import "package:expect/expect.dart";
+import '../language_2/compiler_annotations.dart';
+
+@DontInline()
+callWithStringAndDouble(value) {
+  () => 42;
+  if (value is! int) throw new ArgumentError(value);
+  return 42;
+}
+
+@DontInline()
+callWithDouble(value) {
+  () => 42;
+  if (value is! int) throw new ArgumentError(value);
+  return 42;
+}
+
+main() {
+  Expect.throws(
+      () => callWithStringAndDouble('foo'), (e) => e is ArgumentError);
+  Expect.equals(42, callWithStringAndDouble(0.0));
+  Expect.equals(42, callWithDouble(0.0));
+}
diff --git a/tests/dart2js/injected_cast_test.dart b/tests/dart2js/injected_cast_test.dart
new file mode 100644
index 0000000..3ab671c
--- /dev/null
+++ b/tests/dart2js/injected_cast_test.dart
@@ -0,0 +1,46 @@
+// 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';
+
+var field;
+
+class Class {
+  @pragma('dart2js:noInline')
+  method(int i, int j, int k) {}
+}
+
+@pragma('dart2js:noInline')
+test1(dynamic c, num n) {
+  if (c is Class) {
+    c.method(field = 41, n, field = 42);
+  }
+}
+
+@pragma('dart2js:noInline')
+test2(dynamic c, num n) {
+  if (c is! Class) return;
+  c.method(field = 86, n, field = 87);
+}
+
+main() {
+  try {
+    test1(new Class(), 0.5);
+    field = 123;
+    field = 123;
+  } catch (e) {}
+  // CFE inserts the implicit cast directly on the argument expression, making
+  // it fail before later arguments are evaluated.
+  Expect.equals(41, field);
+
+  try {
+    test2(new Class(), 0.5);
+    field = 321;
+    field = 321;
+  } catch (e) {}
+  // dart2js inserts implicit casts, but does so after evaluating all arguments
+  // to ensure semantics match what it would be like to check the types when
+  // entering the callee.
+  Expect.equals(87, field);
+}
diff --git a/tests/dart2js/inline_generic_test.dart b/tests/dart2js/inline_generic_test.dart
new file mode 100644
index 0000000..a5a8c38
--- /dev/null
+++ b/tests/dart2js/inline_generic_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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 that inlining of constructors with `double` as type argument registers
+/// that double is need for checking passed values.
+
+class C<T> implements D<T> {
+  T a;
+
+  C.gen(this.a);
+}
+
+class D<T> {
+  factory D.fact(T a) => new C<T>.gen(a);
+}
+
+main() {
+  new C<double>.gen(0.5); //# 01: ok
+  new D<double>.fact(0.5); //# 02: ok
+  <double>[].add(0.5); //# 03: ok
+  <int, double>{}[0] = 0.5; //# 04: ok
+}
diff --git a/tests/dart2js/inline_position_crash_source.dart b/tests/dart2js/inline_position_crash_source.dart
new file mode 100644
index 0000000..67194b8
--- /dev/null
+++ b/tests/dart2js/inline_position_crash_source.dart
@@ -0,0 +1,56 @@
+// 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.
+
+part of inline_position_crash_test;
+
+/*******************************************************************************
+ * Long comment to make positions in this file exceed those in
+ * 'inline_position_crash_source.dart'.
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ */
+class Super {
+  final fisk;
+  Super() : fisk = (() => null);
+}
diff --git a/tests/dart2js/inline_position_crash_test.dart b/tests/dart2js/inline_position_crash_test.dart
new file mode 100644
index 0000000..54f58b2
--- /dev/null
+++ b/tests/dart2js/inline_position_crash_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+library inline_position_crash_test;
+
+part 'inline_position_crash_source.dart';
+
+class Sub extends Super {
+  Sub() : super();
+}
+
+main() {
+  new Sub();
+}
diff --git a/tests/dart2js/instantiation_stub_2_test.dart b/tests/dart2js/instantiation_stub_2_test.dart
new file mode 100644
index 0000000..1376011
--- /dev/null
+++ b/tests/dart2js/instantiation_stub_2_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+
+import 'package:expect/expect.dart';
+
+List<T> foo<T>([T a1, T a2, T a3, T a4, T a5, T a6, T a7]) =>
+    <T>[a1, a2, a3, a4, a5, a6, a7];
+
+class CC {
+  List<T> bar<T, U, V>([T a1, T a2, T a3, T a4, T a5, T a6]) =>
+      <T>[a1, a2, a3, a4, a5, a6];
+}
+
+main() {
+  // We expect a call$1$5 entry for foo, accessed nowhere else in the program
+  // except via the call$5 entry on the instantiation.
+  List<int> Function(int, int, int, int, int) f = foo;
+  Expect.equals(4, f(1, 2, 3, 4, 5)[3]);
+
+  // We expect a bar$3$4 entry for bar, accessed nowhere else in the program
+  // except via the call$4 entry on the instantiation.
+  var o = new CC();
+  List<String> Function(String, String, String, String) g = o.bar;
+  Expect.equals('abcdnullnull', g('a', 'b', 'c', 'd').join(''));
+}
diff --git a/tests/dart2js/instantiation_stub_test.dart b/tests/dart2js/instantiation_stub_test.dart
new file mode 100644
index 0000000..23003bc
--- /dev/null
+++ b/tests/dart2js/instantiation_stub_test.dart
@@ -0,0 +1,53 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+// This needs one-arg instantiation.
+@pragma('dart2js:noInline')
+T f1a<T>(T t) => t;
+
+// This needs no instantiation because it is not closurized.
+@pragma('dart2js:noInline')
+T f1b<T>(T t1, T t2) => t1;
+
+class Class {
+  // This needs two-arg instantiation.
+  @pragma('dart2js:noInline')
+  bool f2a<T, S>(T t, S s) => t == s;
+
+  // This needs no instantiation because it is not closurized.
+  @pragma('dart2js:noInline')
+  bool f2b<T, S>(T t, S s1, S s2) => t == s1;
+}
+
+@pragma('dart2js:noInline')
+int method1(int i, int Function(int) f) => f(i);
+
+@pragma('dart2js:noInline')
+bool method2(int a, int b, bool Function(int, int) f) => f(a, b);
+
+@pragma('dart2js:noInline')
+int method3(int a, int b, int c, int Function(int, int, int) f) => f(a, b, c);
+
+main() {
+  // This needs three-arg instantiation.
+  T local1<T, S, U>(T t, S s, U u) => t;
+
+  // This needs no instantiation because but a local function is always
+  // closurized so we assume it does.
+  T local2<T, S, U>(T t, S s, U u1, U u2) => t;
+
+  Expect.equals(42, method1(42, f1a));
+  Expect.equals(f1b(42, 87), 42);
+
+  Class c = new Class();
+  Expect.isFalse(method2(0, 1, c.f2a));
+  Expect.isFalse(c.f2b(42, 87, 123));
+
+  Expect.equals(0, method3(0, 1, 2, local1));
+  Expect.equals(42, local2(42, 87, 123, 256));
+}
diff --git a/tests/dart2js/int_index_test.dart b/tests/dart2js/int_index_test.dart
new file mode 100644
index 0000000..629338b
--- /dev/null
+++ b/tests/dart2js/int_index_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+main() {
+  var a = [0, 1];
+  a[1.2]; //                      //# 01: compile-time error
+  a[1.2] = 4; //                  //# 02: compile-time error
+  checkIndex(a, 1.4); //# 03: runtime error
+  checkIndexedAssignment(a, 1.4); //# 04: runtime error
+  checkIndex(a, 0);
+  checkIndexedAssignment(a, 0);
+}
+
+checkIndex(a, b) {
+  a[b];
+}
+
+checkIndexedAssignment(a, b) {
+  a[b] = 1;
+}
diff --git a/tests/dart2js/interceptor_named_arguments_test.dart b/tests/dart2js/interceptor_named_arguments_test.dart
new file mode 100644
index 0000000..407ac93
--- /dev/null
+++ b/tests/dart2js/interceptor_named_arguments_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2015, 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 that the proper one-shot interceptor is used for different
+// combinations of named arguments.
+import "package:expect/expect.dart";
+
+// Use dart:html to get interceptors into play.
+import "dart:html";
+
+// [createFragment] has the same signature as in [Element].
+class Other {
+  createFragment(html, {validator, treeSanitizer}) {
+    int result = 0;
+    result += validator == null ? 0 : 2;
+    result += treeSanitizer == null ? 0 : 1;
+    return result;
+  }
+}
+
+@pragma('dart2js:noInline')
+bool wontTell(bool x) => x;
+
+// Ensure that we use the interceptor only once per context so that we
+// actually get a one-shot interceptor. This is a little brittle...
+@pragma('dart2js:noInline')
+testA(thing) {
+  Expect.equals(0, thing.createFragment(null));
+}
+
+@pragma('dart2js:noInline')
+testB(thing) {
+  Expect.equals(2, thing.createFragment(null, validator: 1));
+}
+
+@pragma('dart2js:noInline')
+testC(thing) {
+  Expect.equals(1, thing.createFragment(null, treeSanitizer: 1));
+}
+
+@pragma('dart2js:noInline')
+testD(thing) {
+  Expect.equals(3, thing.createFragment(null, validator: 1, treeSanitizer: 1));
+}
+
+main() {
+  // Ensure we get interceptors into play.
+  var thing = wontTell(true) ? new Other() : new DivElement();
+  testA(thing);
+  testB(thing);
+  testC(thing);
+  testD(thing);
+}
diff --git a/tests/dart2js/interface_type_optimization_test.dart b/tests/dart2js/interface_type_optimization_test.dart
new file mode 100644
index 0000000..0beb4f4
--- /dev/null
+++ b/tests/dart2js/interface_type_optimization_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+main() {
+  var a = new A();
+  Expect.equals(42, a.foo(42));
+  var b = new B();
+  Expect.equals(42 - 87, b.foo(42));
+
+  // Make sure we do not try to track the parameter type of the
+  // argument passed to test.
+  Expect.equals("is !A", test(0));
+  Expect.equals("is !A", test("fisk"));
+
+  // Passing b to test should lead to an exception because the string
+  // we end up passing to B.foo does not implement the - operator.
+  Expect.throws(() => test(b), (e) => e is NoSuchMethodError);
+}
+
+// TODO(kasperl): Make sure this does not get inlined.
+test(x) {
+  if (x is A) {
+    // The selector we use for this call site has the receiver type A
+    // because of data flow analysis. We have to make sure that we
+    // realize that this does not rule out calling B.foo because B
+    // implements A.
+    return x.foo("hest");
+  } else {
+    return "is !A";
+  }
+}
+
+class A {
+  foo(var x) => x;
+}
+
+class B implements A {
+  foo(var x) => x - 87;
+}
diff --git a/tests/dart2js/internal/40296_test.dart b/tests/dart2js/internal/40296_test.dart
new file mode 100644
index 0000000..989b6f7
--- /dev/null
+++ b/tests/dart2js/internal/40296_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+@JS()
+library test;
+
+import 'dart:async';
+import 'dart:_interceptors';
+import 'dart:js' as js;
+import 'package:expect/expect.dart';
+import 'package:js/js.dart';
+
+const String JS_CODE = """
+function A() {
+  this.x = 1;
+}
+self.foo = new A();
+""";
+
+@JS('A')
+@anonymous
+class Foo {}
+
+@JS('foo')
+external dynamic get foo;
+
+main() {
+  js.context.callMethod('eval', [JS_CODE]);
+  Expect.isTrue(foo is FutureOr<Foo>);
+  Expect.isTrue(foo is JSObject);
+}
diff --git a/tests/dart2js/internal/deferred/deferred_custom_loader_lib.dart b/tests/dart2js/internal/deferred/deferred_custom_loader_lib.dart
new file mode 100644
index 0000000..e863607
--- /dev/null
+++ b/tests/dart2js/internal/deferred/deferred_custom_loader_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2016, 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.
+
+foo() => 499;
diff --git a/tests/dart2js/internal/deferred/deferred_custom_loader_test.dart b/tests/dart2js/internal/deferred/deferred_custom_loader_test.dart
new file mode 100644
index 0000000..d1f358e
--- /dev/null
+++ b/tests/dart2js/internal/deferred/deferred_custom_loader_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2016, 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:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'dart:_foreign_helper' show JS;
+
+import 'deferred_custom_loader_lib.dart' deferred as def;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // In d8 we don't have any way to load the content of the file, so just use
+  // the preamble's loader.
+  if (!self.dartDeferredLibraryLoader) {
+    self.dartDeferredLibraryLoader = function(uri, success, error) {
+      var req = new XMLHttpRequest();
+      req.addEventListener("load", function() {
+        eval(this.responseText);
+        success();
+      });
+      req.open("GET", uri);
+      req.send();
+    };
+ }
+})()
+""");
+}
+
+runTest() async {
+  setup();
+  await def.loadLibrary();
+  Expect.equals(499, def.foo());
+}
+
+main() {
+  asyncStart();
+  runTest().then((_) => asyncEnd());
+}
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib1.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib1.dart
new file mode 100644
index 0000000..01480aa
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib1.dart
@@ -0,0 +1,12 @@
+import 'load_in_correct_order_lib4.dart';
+import 'load_in_correct_order_lib5.dart';
+import 'load_in_correct_order_lib7.dart';
+
+class C1 {
+  final a;
+  final b;
+  final q = c7;
+  const C1(this.a, this.b);
+}
+
+const c1 = const C1(c4, c5);
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib2.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib2.dart
new file mode 100644
index 0000000..4beadab
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib2.dart
@@ -0,0 +1,12 @@
+import 'load_in_correct_order_lib5.dart';
+import 'load_in_correct_order_lib6.dart';
+import 'load_in_correct_order_lib7.dart';
+
+class C2 {
+  final c;
+  final d;
+  final q = c7;
+  const C2(this.c, this.d);
+}
+
+const c2 = const C2(c5, c6);
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib3.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib3.dart
new file mode 100644
index 0000000..1676e8f
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib3.dart
@@ -0,0 +1,12 @@
+import 'load_in_correct_order_lib4.dart';
+import 'load_in_correct_order_lib6.dart';
+import 'load_in_correct_order_lib7.dart';
+
+class C3 {
+  final e;
+  final f;
+  final q = c7;
+  const C3(this.e, this.f);
+}
+
+const c3 = const C3(c4, c6);
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib4.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib4.dart
new file mode 100644
index 0000000..4d52cac
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib4.dart
@@ -0,0 +1,6 @@
+class C4 {
+  final value = 499;
+  const C4();
+
+
+const c4 = const C4();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart
new file mode 100644
index 0000000..2a97336
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib5.dart
@@ -0,0 +1,6 @@
+class C5 {
+  final value = 500;
+  const C5();
+
+
+const c5 = const C5();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart
new file mode 100644
index 0000000..57fc252
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib6.dart
@@ -0,0 +1,6 @@
+class C6 {
+  final value = 501;
+  const C6();
+
+
+const c6 = const C6();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart b/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart
new file mode 100644
index 0000000..33794df
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_lib7.dart
@@ -0,0 +1,6 @@
+class C7 {
+  final value = 502;
+  const C7();
+
+
+const c7 = const C7();
diff --git a/tests/dart2js/internal/deferred/load_in_correct_order_test.dart b/tests/dart2js/internal/deferred/load_in_correct_order_test.dart
new file mode 100644
index 0000000..dc6727d
--- /dev/null
+++ b/tests/dart2js/internal/deferred/load_in_correct_order_test.dart
@@ -0,0 +1,149 @@
+// Copyright (c) 2017, 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.
+
+/// This test creates a scenario to simulate what happens if hunks are loaded
+/// out of order. The compiler should initialize hunks in order regardless, but
+/// may do so in parallel while some hunks are not loaded yet.
+///
+/// To create a good number of hunks we created an import graph with 3 deferred
+/// imports and 7 libraries, we made pair-wise dependencies to be able to create
+/// 2^3 (8) partitions of the program (including the main hunk) that end up
+/// corresponding to the libraries themselves. In particular, the import graph
+/// looks like this:
+///
+///   main ---> 1, 2, 3  (deferred)
+///      1 --->         4, 5,    7
+///      2 --->            5, 6, 7
+///      3 --->         4,    6, 7
+///
+/// So each library maps to a deferred hunk:
+///   library 1 = hunk of code only used by 1
+///   library 2 = hunk of code only used by 2
+///   library 3 = hunk of code only used by 3
+///   library 4 = hunk of code shared by 1 & 3
+///   library 5 = hunk of code shared by 1 & 2
+///   library 6 = hunk of code shared by 2 & 3
+///   library 7 = hunk of shared by 1, 2 & 3
+///
+/// In the future we may optimize and combine hunks, at that point this test
+/// needs to be rewritten.
+import 'package:async_helper/async_helper.dart';
+import 'package:expect/expect.dart';
+import 'dart:async';
+
+import 'dart:_foreign_helper' show JS;
+
+import 'load_in_correct_order_lib1.dart' deferred as d1;
+import 'load_in_correct_order_lib2.dart' deferred as d2;
+import 'load_in_correct_order_lib3.dart' deferred as d3;
+
+main() {
+  asyncStart();
+  runTest().then((_) => asyncEnd());
+}
+
+runTest() async {
+  setup();
+  await d1.loadLibrary();
+  Expect.equals(499, d1.c1.a.value);
+
+  // The logic below expects loadLibrary calls to happen on a new microtask.
+  await new Future(() {});
+  await d2.loadLibrary();
+  Expect.equals(500, d2.c2.c.value);
+
+  await new Future(() {});
+  await d3.loadLibrary();
+  Expect.equals(501, d3.c3.f.value);
+}
+
+void setup() {
+  JS('', r"""
+(function() {
+// In d8 we don't have any way to load the content of the file via XHR, but we
+// can use the "load" instruction. A hook is already defined in d8 for this
+// reason.
+self.isD8 = !!self.dartDeferredLibraryLoader;
+
+self.uris = [];
+self.successCallbacks = [];
+self.total = 0;
+self.content = {};
+
+// This test has 3 loadLibrary calls, this array contains how many hunks will be
+// loaded by each call.
+self.currentLoadLibraryCall = 0;
+self.filesPerLoadLibraryCall = [4, 2, 1];
+
+// Download uri via an XHR
+self.download = function(uri) {
+  var req = new XMLHttpRequest();
+  req.addEventListener("load", function() {
+    self.content[uri] = this.responseText;
+    self.increment();
+  });
+  req.open("GET", uri);
+  req.send();
+};
+
+// Note that a new hunk is already avaiable to be loaded, wait until all
+// expected hunks are available and then evaluate their contents to actually
+// load them.
+self.increment = function() {
+  self.total++;
+  if (self.total == self.filesPerLoadLibraryCall[self.currentLoadLibraryCall]) {
+    self.doActualLoads();
+  }
+};
+
+// Hook to control how we load hunks (we force them to be out of order).
+self.dartDeferredLibraryLoader = function(uri, success, error) {
+  self.uris.push(uri);
+  self.successCallbacks.push(success);
+  if (isD8) {
+    self.increment();
+  } else {
+    self.download(uri);
+  }
+};
+
+// Do the actual load of the hunk and call the corresponding success callback.
+self.doLoad = function(i) {
+  self.setTimeout(function () {
+  var uri = self.uris[i];
+  if (self.isD8) {
+    load(uri);
+  } else {
+    eval(self.content[uri]);
+  }
+  (self.successCallbacks[i])();
+  }, 0);
+};
+
+// Do all the loads for a load library call. On the first load library call,
+// purposely load the hunks out of order.
+self.doActualLoads = function() {
+  self.currentLoadLibraryCall++;
+  if (self.total == 4) {
+    self.doLoad(3); // load purposely out of order!
+    self.doLoad(0);
+    self.doLoad(1);
+    self.doLoad(2);
+  } else {
+    for (var i = 0; i < self.total; i++) {
+      self.doLoad(i);
+    }
+  }
+  setTimeout(self.reset, 0);
+};
+
+/// Reset the internal state to prepare for a new load library call.
+self.reset = function() {
+  self.total = 0;
+  self.uris = [];
+  self.successCallbacks = [];
+};
+})()
+""");
+}
diff --git a/tests/dart2js/internal/extract_type_arguments_1_test.dart b/tests/dart2js/internal/extract_type_arguments_1_test.dart
new file mode 100644
index 0000000..edabc67
--- /dev/null
+++ b/tests/dart2js/internal/extract_type_arguments_1_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+
+import 'package:expect/expect.dart';
+import 'dart:_internal' show extractTypeArguments;
+
+class C<T> {}
+
+main() {
+  test(new C<int>(), int);
+  test(new C<String>(), String);
+}
+
+test(dynamic a, T) {
+  Expect.equals(T, extractTypeArguments<C>(a, <T>() => T));
+}
diff --git a/tests/dart2js/internal/extract_type_arguments_2_test.dart b/tests/dart2js/internal/extract_type_arguments_2_test.dart
new file mode 100644
index 0000000..0b27a12
--- /dev/null
+++ b/tests/dart2js/internal/extract_type_arguments_2_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+
+import 'package:expect/expect.dart';
+import 'dart:_internal' show extractTypeArguments;
+
+class CC<A, B, C, D, E> {}
+
+class X {}
+
+main() {
+  test(new CC<X, X, X, X, int>(), int);
+  test(new CC<X, X, X, X, String>(), String);
+}
+
+test(dynamic a, T) {
+  Expect.equals(T, extractTypeArguments<CC>(a, <_1, _2, _3, _4, T>() => T));
+}
diff --git a/tests/dart2js/internal/extract_type_arguments_3_test.dart b/tests/dart2js/internal/extract_type_arguments_3_test.dart
new file mode 100644
index 0000000..f446cfa
--- /dev/null
+++ b/tests/dart2js/internal/extract_type_arguments_3_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+
+import 'package:expect/expect.dart';
+import 'dart:_internal' show extractTypeArguments;
+
+main() {
+  Expect.equals(int, extractTypeArguments<List>('hello'.codeUnits, <T>() => T));
+}
diff --git a/tests/dart2js/internal/lax_runtime_type_closure_to_string1_test.dart b/tests/dart2js/internal/lax_runtime_type_closure_to_string1_test.dart
new file mode 100644
index 0000000..40b9f69
--- /dev/null
+++ b/tests/dart2js/internal/lax_runtime_type_closure_to_string1_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+import 'dart:_foreign_helper' show JS_GET_FLAG;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  local1() {}
+  local2(int i) => i;
+
+  var toString = '${local1.runtimeType}';
+  if ('$Object' == 'Object') {
+    // `true` if non-minified.
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      Expect.equals("Closure", toString);
+    } else {
+      Expect.equals("main_local1", toString);
+    }
+  }
+  print(toString);
+  local2(0);
+  new Class();
+}
diff --git a/tests/dart2js/internal/lax_runtime_type_closure_to_string2_test.dart b/tests/dart2js/internal/lax_runtime_type_closure_to_string2_test.dart
new file mode 100644
index 0000000..6425113
--- /dev/null
+++ b/tests/dart2js/internal/lax_runtime_type_closure_to_string2_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+import 'dart:_foreign_helper' show JS_GET_FLAG;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  local1<T>() {}
+  local2<T>(t) => t;
+
+  var toString = '${local1.runtimeType}';
+  if ('$Object' == 'Object') {
+    // `true` if non-minified.
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      Expect.equals("Closure", toString);
+    } else {
+      Expect.equals("main_local1", toString);
+    }
+  }
+  print(toString);
+  local2(0);
+  new Class();
+}
diff --git a/tests/dart2js/internal/lax_runtime_type_closure_to_string7_test.dart b/tests/dart2js/internal/lax_runtime_type_closure_to_string7_test.dart
new file mode 100644
index 0000000..6d77543
--- /dev/null
+++ b/tests/dart2js/internal/lax_runtime_type_closure_to_string7_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+import 'dart:_foreign_helper' show JS_GET_FLAG;
+
+class Class<T> {
+  Class();
+}
+
+@pragma('dart2js:noInline')
+test<Q>() {
+  Q local1(Q) {}
+  local2(int i) => i;
+
+  var toString = '${local1.runtimeType}';
+  if ('$Object' == 'Object') {
+    // `true` if non-minified.
+    if (JS_GET_FLAG('USE_NEW_RTI')) {
+      Expect.equals("Closure", toString);
+    } else {
+      Expect.equals("test_local1", toString);
+    }
+  }
+  print(toString);
+  local2(0);
+  new Class();
+}
+
+main() {
+  test<int>();
+  test<String>();
+}
diff --git a/tests/dart2js/internal/mock_libraries.dart b/tests/dart2js/internal/mock_libraries.dart
new file mode 100644
index 0000000..1667032
--- /dev/null
+++ b/tests/dart2js/internal/mock_libraries.dart
@@ -0,0 +1,474 @@
+// Copyright (c) 2014, 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.
+
+// Library for creating mock versions of platform and internal libraries.
+
+library mock_libraries;
+
+const DEFAULT_PLATFORM_CONFIG = """
+[libraries]
+core:core/core.dart
+async:async/async.dart
+_js_helper:_internal/js_runtime/lib/js_helper.dart
+_interceptors:_internal/js_runtime/lib/interceptors.dart
+_internal:internal/internal.dart
+""";
+
+String buildLibrarySource(Map<String, String> elementMap,
+    [Map<String, String> additionalElementMap = const <String, String>{}]) {
+  Map<String, String> map = new Map<String, String>.from(elementMap);
+  if (additionalElementMap != null) {
+    map.addAll(additionalElementMap);
+  }
+  StringBuffer sb = new StringBuffer();
+  map.values.forEach((String element) {
+    sb.write('$element\n');
+  });
+  return sb.toString();
+}
+
+const Map<String, String> DEFAULT_CORE_LIBRARY = const <String, String>{
+  '<imports>': '''
+import 'dart:_internal' as internal;
+''',
+  'bool': 'class bool {}',
+  'Comparator': 'abstract class Comparator<T> {}',
+  'DateTime': r'''
+      class DateTime {
+        DateTime(year);
+        DateTime.utc(year);
+      }''',
+  'Deprecated': r'''
+      class Deprecated extends Object {
+        final String expires;
+        const Deprecated(this.expires);
+      }''',
+  'deprecated': 'const Object deprecated = const Deprecated("next release");',
+  'double': r'''
+      abstract class double extends num {
+        static var nan = 0;
+        static parse(s) {}
+      }''',
+  'Function': r'''
+      class Function {
+        static apply(Function fn, List positional, [Map named]) => null;
+      }''',
+  'identical': 'bool identical(Object a, Object b) { return true; }',
+  'int': 'abstract class int extends num { }',
+  'Iterable': '''
+      abstract class Iterable<E> {
+          Iterator<E> get iterator => null;
+      }''',
+  'Iterator': '''
+      abstract class Iterator<E> {
+          E get current => null;
+      }''',
+  'LinkedHashMap': r'''
+      class LinkedHashMap<K, V> implements Map<K, V> {
+      }''',
+  'List': r'''
+      class List<E> extends Iterable<E> {
+        var length;
+        List([length]);
+        List.filled(length, element);
+        E get first => null;
+        E get last => null;
+        E get single => null;
+        E removeLast() => null;
+        E removeAt(i) => null;
+        E elementAt(i) => null;
+        E singleWhere(f) => null;
+      }''',
+  'Map': 'abstract class Map<K,V> {}',
+  'Null': 'class Null {}',
+  'num': r'''
+      abstract class num {
+        operator +(_);
+        operator *(_);
+        operator -();
+      }''',
+  'print': 'print(var obj) {}',
+  'proxy': 'const proxy = 0;',
+  'Object': r'''
+      class Object {
+        const Object();
+        operator ==(other) { return true; }
+        get hashCode => throw "Object.hashCode not implemented.";
+        String toString() { return null; }
+        noSuchMethod(im) { throw im; }
+      }''',
+  'StackTrace': 'abstract class StackTrace {}',
+  'String': 'class String implements Pattern {}',
+  'Symbol': '''
+      abstract class Symbol {
+        const factory Symbol(String name) = internal.Symbol;
+      }
+      ''',
+  'Type': 'class Type {}',
+  'Pattern': 'abstract class Pattern {}',
+  '_genericNoSuchMethod': '_genericNoSuchMethod(a,b,c,d,e) {}',
+  '_unresolvedConstructorError': '_unresolvedConstructorError(a,b,c,d,e) {}',
+  '_malformedTypeError': '_malformedTypeError(message) {}',
+};
+
+const Map<String, String> DEFAULT_INTERNAL_LIBRARY = const <String, String>{
+  '<imports>': '''
+import 'dart:core' as core;
+''',
+  'Symbol': '''
+class Symbol implements core.Symbol {
+  final core.String _name;
+
+  const Symbol(this._name);
+  Symbol.validated(this._name);
+}
+''',
+};
+
+const String DEFAULT_PATCH_CORE_SOURCE = r'''
+import 'dart:_js_helper';
+import 'dart:_interceptors';
+import 'dart:async';
+
+@patch
+class LinkedHashMap<K, V> {
+  factory LinkedHashMap._empty() => null;
+  factory LinkedHashMap._literal(elements) => null;
+  static _makeEmpty() => null;
+  static _makeLiteral(elements) => null;
+}
+''';
+
+const Map<String, String> DEFAULT_JS_HELPER_LIBRARY = const <String, String>{
+  'assertTest': 'assertTest(a) {}',
+  'assertThrow': 'assertThrow(a) {}',
+  'assertHelper': 'assertHelper(a) {}',
+  'assertUnreachable': 'assertUnreachable() {}',
+  'assertIsSubtype': 'assertIsSubtype(subtype, supertype, message) {}',
+  'assertSubtype': 'assertSubtype(object, isField, checks, asField) {}',
+  'assertSubtypeOfRuntimeType': 'assertSubtypeOfRuntimeType(object, type) {}',
+  'asyncHelper': 'asyncHelper(object, asyncBody, completer) {}',
+  'boolConversionCheck': 'boolConversionCheck(x) {}',
+  'boolTypeCast': 'boolTypeCast(value) {}',
+  'boolTypeCheck': 'boolTypeCheck(value) {}',
+  'checkSubtype': 'checkSubtype(object, isField, checks, asField) {}',
+  'checkSubtypeOfRuntimeType': 'checkSubtypeOfRuntimeType(o, t) {}',
+  'BoundClosure': r'''abstract class BoundClosure extends Closure {
+    var self;
+    var target;
+    var receiver;
+  }''',
+  'buildFunctionType': r'''buildFunctionType(returnType, parameterTypes,
+                            optionalParameterTypes) {
+            return new RuntimeFunctionType();
+          }''',
+  'buildInterfaceType': '''buildInterfaceType(rti, typeArguments) {
+                             if (rti == null) return new RuntimeTypePlain();
+                             return new RuntimeTypeGeneric();
+                           }''',
+  'buildNamedFunctionType':
+      r'''buildNamedFunctionType(returnType, parameterTypes,
+                                 namedParameters) {
+            return new RuntimeFunctionType();
+          }''',
+  'checkFunctionSubtype':
+      r'''checkFunctionSubtype(var target, String signatureName,
+                               String contextName, var context,
+                               var typeArguments) {}''',
+  'checkMalformedType': 'checkMalformedType(value, message) {}',
+  'checkInt': 'checkInt(value) {}',
+  'checkNum': 'checkNum(value) {}',
+  'checkString': 'checkString(value) {}',
+  'Closure': 'abstract class Closure implements Function { }',
+  'closureFromTearOff':
+      r'''closureFromTearOff(receiver, functions, reflectionInfo,
+                             isStatic, jsArguments, name) {}''',
+  'computeSignature':
+      'computeSignature(var signature, var context, var contextName) {}',
+  'ConstantMap': 'class ConstantMap<K, V> {}',
+  'ConstantProtoMap': 'class ConstantProtoMap<K, V> {}',
+  'ConstantStringMap': 'class ConstantStringMap<K, V> {}',
+  'createInvocationMirror': 'createInvocationMirror(a0, a1, a2, a3, a4, a5) {}',
+  'createRuntimeType': 'createRuntimeType(a) {}',
+  'doubleTypeCast': 'doubleTypeCast(value) {}',
+  'doubleTypeCheck': 'doubleTypeCheck(value) {}',
+  'functionSubtypeCast':
+      r'''functionSubtypeCast(Object object, String signatureName,
+                              String contextName, var context) {}''',
+  'functionTypeTestMetaHelper': r'''
+      functionTypeTestMetaHelper() {
+        buildFunctionType(null, null, null);
+        buildNamedFunctionType(null, null, null);
+        buildInterfaceType(null, null);
+      }''',
+  'functionTypeTest': r'functionTypeTest(f, t) {}',
+  'functionTypeCast': r'functionTypeCast(f, t) { return f; }',
+  'functionTypeCheck': r'functionTypeCheck(f, t) { return f; }',
+  'futureOrTest': r'futureOrTest(f, t) {}',
+  'futureOrCast': r'futureOrCast(f, t) { return f; }',
+  'futureOrCheck': r'futureOrCheck(f, t) { return f; }',
+  'getFallThroughError': 'getFallThroughError() {}',
+  'getIsolateAffinityTag': 'getIsolateAffinityTag(_) {}',
+  'getRuntimeTypeArgumentIntercepted':
+      'getRuntimeTypeArgumentIntercepted(interceptor, target, substitutionName, index) {}',
+  'getRuntimeTypeArgument':
+      'getRuntimeTypeArgument(target, substitutionName, index) {}',
+  'getRuntimeTypeArguments':
+      'getRuntimeTypeArguments(target, substitutionName) {}',
+  'getRuntimeTypeInfo': 'getRuntimeTypeInfo(a) {}',
+  'getTraceFromException': 'getTraceFromException(exception) {}',
+  'getTypeArgumentByIndex': 'getTypeArgumentByIndex(target, index) {}',
+  'GeneralConstantMap': 'class GeneralConstantMap {}',
+  'iae': 'iae(x) { throw x; } ioore(x) { throw x; }',
+  'Instantiation1': 'class Instantiation1<T1> extends Closure {}',
+  'Instantiation2': 'class Instantiation2<T1,T2> extends Closure {}',
+  'Instantiation3': 'class Instantiation3<T1,T2,T3> extends Closure {}',
+  'interceptedTypeCast': 'interceptedTypeCast(value, property) {}',
+  'interceptedTypeCheck': 'interceptedTypeCheck(value, property) {}',
+  'intTypeCast': 'intTypeCast(value) {}',
+  'intTypeCheck': 'intTypeCheck(value) {}',
+  'isJsIndexable': 'isJsIndexable(a, b) {}',
+  'JavaScriptIndexingBehavior': 'abstract class JavaScriptIndexingBehavior {}',
+  'JSInvocationMirror': r'''
+  class JSInvocationMirror {
+    get typeArguments => null;
+  }''',
+  'listSuperNativeTypeCast': 'listSuperNativeTypeCast(value) {}',
+  'listSuperNativeTypeCheck': 'listSuperNativeTypeCheck(value) {}',
+  'listSuperTypeCast': 'listSuperTypeCast(value) {}',
+  'listSuperTypeCheck': 'listSuperTypeCheck(value) {}',
+  'listTypeCast': 'listTypeCast(value) {}',
+  'listTypeCheck': 'listTypeCheck(value) {}',
+  'makeLiteralMap': 'makeLiteralMap(List keyValuePairs) {}',
+  'Native': 'class Native {}',
+  'NoInline': 'class NoInline {}',
+  'ForceInline': 'class ForceInline {}',
+  'NoSideEffects': 'class NoSideEffects {}',
+  'NoThrows': 'class NoThrows {}',
+  'numberOrStringSuperNativeTypeCast':
+      'numberOrStringSuperNativeTypeCast(value) {}',
+  'numberOrStringSuperNativeTypeCheck':
+      'numberOrStringSuperNativeTypeCheck(value) {}',
+  'numberOrStringSuperTypeCast': 'numberOrStringSuperTypeCast(value) {}',
+  'numberOrStringSuperTypeCheck': 'numberOrStringSuperTypeCheck(value) {}',
+  'numTypeCast': 'numTypeCast(value) {}',
+  'numTypeCheck': 'numTypeCheck(value) {}',
+  '_Patch': 'class _Patch { final tag; const _Patch(this.tag); }',
+  'patch': 'const patch = const _Patch(null);',
+  'patch_full': 'const patch_full = const _Patch("full");',
+  'patch_lazy': 'const patch_lazy = const _Patch("lazy");',
+  'patch_startup': 'const patch_startup = const _Patch("startup");',
+  'propertyTypeCast': 'propertyTypeCast(x) {}',
+  'propertyTypeCheck': 'propertyTypeCheck(value, property) {}',
+  'requiresPreamble': 'requiresPreamble() {}',
+  'RuntimeFunctionType': 'class RuntimeFunctionType {}',
+  'RuntimeTypeGeneric': 'class RuntimeTypeGeneric {}',
+  'RuntimeTypePlain': 'class RuntimeTypePlain {}',
+  'runtimeTypeToString': 'runtimeTypeToString(type, {onTypeVariable(i)}) {}',
+  'S': 'S() {}',
+  'setRuntimeTypeInfo': 'setRuntimeTypeInfo(a, b) {}',
+  'stringSuperNativeTypeCast': 'stringSuperNativeTypeCast(value) {}',
+  'stringSuperNativeTypeCheck': 'stringSuperNativeTypeCheck(value) {}',
+  'stringSuperTypeCast': 'stringSuperTypeCast(value) {}',
+  'stringSuperTypeCheck': 'stringSuperTypeCheck(value) {}',
+  'stringTypeCast': 'stringTypeCast(x) {}',
+  'stringTypeCheck': 'stringTypeCheck(x) {}',
+  'subtypeCast': 'subtypeCast(object, isField, checks, asField) {}',
+  'subtypeOfRuntimeTypeCast': 'subtypeOfRuntimeTypeCast(object, type) {}',
+  'throwAbstractClassInstantiationError':
+      'throwAbstractClassInstantiationError(className) {}',
+  'checkConcurrentModificationError':
+      'checkConcurrentModificationError(collection) {}',
+  'throwConcurrentModificationError':
+      'throwConcurrentModificationError(collection) {}',
+  'throwCyclicInit': 'throwCyclicInit(staticName) {}',
+  'throwExpression': 'throwExpression(e) {}',
+  'throwNoSuchMethod':
+      'throwNoSuchMethod(obj, name, arguments, expectedArgumentNames) {}',
+  'throwRuntimeError': 'throwRuntimeError(message) {}',
+  'throwUnsupportedError': 'throwUnsupportedError(message) {}',
+  'throwTypeError': 'throwTypeError(message) {}',
+  'TypeImpl': 'class TypeImpl {}',
+  'TypeVariable': '''class TypeVariable {
+    final Type owner;
+    final String name;
+    final int bound;
+    const TypeVariable(this.owner, this.name, this.bound);
+  }''',
+  'unwrapException': 'unwrapException(e) {}',
+  'voidTypeCheck': 'voidTypeCheck(value) {}',
+  'wrapException': 'wrapException(x) { return x; }',
+  'badMain': 'badMain() { throw "bad main"; }',
+  'missingMain': 'missingMain() { throw "missing main"; }',
+  'mainHasTooManyParameters': 'mainHasTooManyParameters() '
+      '{ throw "main has too many parameters"; }',
+};
+
+const Map<String, String> DEFAULT_FOREIGN_HELPER_LIBRARY =
+    const <String, String>{
+  'JS': r'''
+      dynamic JS(String typeDescription, String codeTemplate,
+        [var arg0, var arg1, var arg2, var arg3, var arg4, var arg5, var arg6,
+         var arg7, var arg8, var arg9, var arg10, var arg11]) {}''',
+};
+
+const Map<String, String> DEFAULT_INTERCEPTORS_LIBRARY = const <String, String>{
+  'findIndexForNativeSubclassType': 'findIndexForNativeSubclassType(type) {}',
+  'getDispatchProperty': 'getDispatchProperty(o) {}',
+  'getInterceptor': 'getInterceptor(x) {}',
+  'getNativeInterceptor': 'getNativeInterceptor(x) {}',
+  'initializeDispatchProperty': 'initializeDispatchProperty(f,p,i) {}',
+  'initializeDispatchPropertyCSP': 'initializeDispatchPropertyCSP(f,p,i) {}',
+  'Interceptor': r'''
+      class Interceptor {
+        toString() {}
+        bool operator==(other) => identical(this, other);
+        get hashCode => throw "Interceptor.hashCode not implemented.";
+        noSuchMethod(im) { throw im; }
+      }''',
+  'JSArray': r'''
+          class JSArray<E> extends Interceptor implements List<E>, JSIndexable {
+            JSArray();
+            factory JSArray.typed(a) => a;
+            var length;
+            operator[](index) => this[index];
+            operator[]=(index, value) { this[index] = value; }
+            add(value) { this[length] = value; }
+            insert(index, value) {}
+            E get first => this[0];
+            E get last => this[0];
+            E get single => this[0];
+            E removeLast() => this[0];
+            E removeAt(index) => this[0];
+            E elementAt(index) => this[0];
+            E singleWhere(f) => this[0];
+            Iterator<E> get iterator => null;
+          }''',
+  'JSBool': 'class JSBool extends Interceptor implements bool {}',
+  'JSDouble': 'class JSDouble extends JSNumber implements double {}',
+  'JSExtendableArray': 'class JSExtendableArray extends JSMutableArray {}',
+  'JSFixedArray': 'class JSFixedArray extends JSMutableArray {}',
+  'JSFunction':
+      'abstract class JSFunction extends Interceptor implements Function {}',
+  'JSIndexable': r'''
+      abstract class JSIndexable {
+        get length;
+        operator[](index);
+      }''',
+  'JSInt': r'''
+       class JSInt extends JSNumber implements int {
+         operator~() => this;
+       }''',
+  'JSMutableArray':
+      'class JSMutableArray extends JSArray implements JSMutableIndexable {}',
+  'JSUnmodifiableArray': 'class JSUnmodifiableArray extends JSArray {}',
+  'JSMutableIndexable':
+      'abstract class JSMutableIndexable extends JSIndexable {}',
+  'JSPositiveInt': 'class JSPositiveInt extends JSInt {}',
+  'JSNull': r'''
+      class JSNull extends Interceptor {
+        bool operator==(other) => identical(null, other);
+        get hashCode => throw "JSNull.hashCode not implemented.";
+        String toString() => 'Null';
+        Type get runtimeType => null;
+        noSuchMethod(x) => super.noSuchMethod(x);
+      }''',
+  'JSNumber': r'''
+      class JSNumber extends Interceptor implements num {
+        // All these methods return a number to please type inferencing.
+        operator-() => (this is JSInt) ? 42 : 42.2;
+        operator +(other) => (this is JSInt) ? 42 : 42.2;
+        operator -(other) => (this is JSInt) ? 42 : 42.2;
+        operator ~/(other) => _tdivFast(other);
+        operator /(other) => (this is JSInt) ? 42 : 42.2;
+        operator *(other) => (this is JSInt) ? 42 : 42.2;
+        operator %(other) => (this is JSInt) ? 42 : 42.2;
+        operator <<(other) => _shlPositive(other);
+        operator >>(other) {
+          return _shrBothPositive(other) + _shrReceiverPositive(other) +
+            _shrOtherPositive(other);
+        }
+        operator |(other) => 42;
+        operator &(other) => 42;
+        operator ^(other) => 42;
+
+        operator >(other) => !identical(this, other);
+        operator >=(other) => !identical(this, other);
+        operator <(other) => !identical(this, other);
+        operator <=(other) => !identical(this, other);
+        operator ==(other) => identical(this, other);
+        get hashCode => throw "JSNumber.hashCode not implemented.";
+
+        // We force side effects on _tdivFast to mimic the shortcomings of
+        // the effect analysis: because the `_tdivFast` implementation of
+        // the core library has calls that may not already be analyzed,
+        // the analysis will conclude that `_tdivFast` may have side
+        // effects.
+        _tdivFast(other) => new List()..length = 42;
+        _shlPositive(other) => 42;
+        _shrBothPositive(other) => 42;
+        _shrReceiverPositive(other) => 42;
+        _shrOtherPositive(other) => 42;
+
+        abs() => (this is JSInt) ? 42 : 42.2;
+        remainder(other) => (this is JSInt) ? 42 : 42.2;
+        truncate() => 42;
+      }''',
+  'JSString': r'''
+      class JSString extends Interceptor implements String, JSIndexable {
+        split(pattern) => [];
+        int get length => 42;
+        operator[](index) {}
+        toString() {}
+        operator+(other) => this;
+        codeUnitAt(index) => 42;
+      }''',
+  'JSUInt31': 'class JSUInt31 extends JSUInt32 {}',
+  'JSUInt32': 'class JSUInt32 extends JSPositiveInt {}',
+  'ObjectInterceptor': 'class ObjectInterceptor {}',
+  'JavaScriptObject': 'class JavaScriptObject {}',
+  'PlainJavaScriptObject': 'class PlainJavaScriptObject {}',
+  'UnknownJavaScriptObject': 'class UnknownJavaScriptObject {}',
+  'JavaScriptFunction': 'class JavaScriptFunction {}',
+};
+
+const Map<String, String> DEFAULT_ASYNC_LIBRARY = const <String, String>{
+  'DeferredLibrary': 'class DeferredLibrary {}',
+  'Future': '''
+      class Future<T> {
+        Future.value([value]);
+      }
+      ''',
+  'Stream': 'class Stream<T> {}',
+  'Completer': 'class Completer<T> {}',
+  'StreamIterator': 'class StreamIterator<T> {}',
+};
+
+/// These members are only needed when async/await is used.
+const Map<String, String> ASYNC_AWAIT_LIBRARY = const <String, String>{
+  '_wrapJsFunctionForAsync': '_wrapJsFunctionForAsync(f) {}',
+  '_asyncHelper': '_asyncHelper(o, f, c) {}',
+  '_SyncStarIterable': 'class _SyncStarIterable {}',
+  '_IterationMarker': 'class _IterationMarker {}',
+  '_AsyncStarStreamController': 'class _AsyncStarStreamController {}',
+  '_asyncStarHelper': '_asyncStarHelper(x, y, z) {}',
+  '_streamOfController': '_streamOfController(x) {}',
+};
+
+const String DEFAULT_MIRRORS_SOURCE = r'''
+import 'dart:_js_mirrors' as js;
+class Comment {}
+class MirrorSystem {}
+class MirrorsUsed {
+  final targets;
+  const MirrorsUsed({this.targets});
+}
+void reflectType(Type t) => js.disableTreeShaking();
+''';
+
+const String DEFAULT_JS_MIRRORS_SOURCE = r'''
+disableTreeShaking(){}
+preserveMetadata(){}
+preserveLibraryNames(){}
+''';
diff --git a/tests/dart2js/internal/platform_environment_variable1_test.dart b/tests/dart2js/internal/platform_environment_variable1_test.dart
new file mode 100644
index 0000000..35d67bd
--- /dev/null
+++ b/tests/dart2js/internal/platform_environment_variable1_test.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.
+
+// SharedOptions=-Ddart2js.test.platform.environment.variable=hello
+
+import 'dart:_js_helper' show testingGetPlatformEnvironmentVariable;
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals('hello', testingGetPlatformEnvironmentVariable());
+}
diff --git a/tests/dart2js/internal/platform_environment_variable2_test.dart b/tests/dart2js/internal/platform_environment_variable2_test.dart
new file mode 100644
index 0000000..5cb56e9
--- /dev/null
+++ b/tests/dart2js/internal/platform_environment_variable2_test.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.
+
+// No -D options.
+
+import 'dart:_js_helper' show testingGetPlatformEnvironmentVariable;
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals('not-specified', testingGetPlatformEnvironmentVariable());
+}
diff --git a/tests/dart2js/internal/rti/bind_test.dart b/tests/dart2js/internal/rti/bind_test.dart
new file mode 100644
index 0000000..4e38ba6
--- /dev/null
+++ b/tests/dart2js/internal/rti/bind_test.dart
@@ -0,0 +1,56 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+void checkRtiIdentical(Object rti1, Object rti2) {
+  var format = rti.testingRtiToString;
+  Expect.isTrue(
+      identical(rti1, rti2), 'identical(${format(rti1)}, ${format(rti2)}');
+}
+
+void checkToString(String expected, Object rti1) {
+  String result = rti.testingRtiToString(rti1);
+  if (expected == result) return;
+  Expect.equals(expected, result.replaceAll('minified:', ''));
+}
+
+test1() {
+  var universe = rti.testingCreateUniverse();
+
+  // Extend environment in one step
+  var env1a = rti.testingUniverseEval(universe, 'Foo');
+  var args1 = rti.testingUniverseEval(universe, '@<aaa,bbb>');
+  var env1b = rti.testingEnvironmentBind(universe, env1a, args1);
+
+  var rti1 = rti.testingEnvironmentEval(universe, env1b, 'AAA<0,1,2>');
+  checkToString('AAA<Foo, aaa, bbb>', rti1);
+
+  Expect.equals(
+      'binding(interface("Foo"), [interface("aaa"), interface("bbb")])',
+      rti.testingRtiToDebugString(env1b));
+
+  // Extend environment in two steps
+  var env2a = rti.testingUniverseEval(universe, 'Foo');
+  var args2a = rti.testingUniverseEval(universe, 'aaa');
+  var env2b = rti.testingEnvironmentBind(universe, env2a, args2a);
+  var args2b = rti.testingUniverseEval(universe, 'bbb');
+  var env2c = rti.testingEnvironmentBind(universe, env2b, args2b);
+
+  var rti2 = rti.testingEnvironmentEval(universe, env2c, 'AAA<0,1,2>');
+  checkToString('AAA<Foo, aaa, bbb>', rti2);
+
+  Expect.equals('binding(interface("Foo"), [interface("aaa")])',
+      rti.testingRtiToDebugString(env2b));
+  Expect.equals(
+      'binding(interface("Foo"), [interface("aaa"), interface("bbb")])',
+      rti.testingRtiToDebugString(env2c));
+
+  checkRtiIdentical(env1b, env2c);
+}
+
+main() {
+  test1();
+}
diff --git a/tests/dart2js/internal/rti/bound_environment_test.dart b/tests/dart2js/internal/rti/bound_environment_test.dart
new file mode 100644
index 0000000..67f8ec3
--- /dev/null
+++ b/tests/dart2js/internal/rti/bound_environment_test.dart
@@ -0,0 +1,80 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+void checkRtiIdentical(Object rti1, Object rti2) {
+  var format = rti.testingRtiToString;
+  Expect.isTrue(
+      identical(rti1, rti2), 'identical(${format(rti1)}, ${format(rti2)}');
+}
+
+void checkToString(String expected, Object rti1) {
+  String result = rti.testingRtiToString(rti1);
+  if (expected == result) return;
+  Expect.equals(expected, result.replaceAll('minified:', ''));
+}
+
+test1() {
+  var universe = rti.testingCreateUniverse();
+
+  var env = rti.testingUniverseEval(universe, 'Foo<bool><int>');
+  var rti1 = rti.testingUniverseEval(universe, 'int');
+  var rti2 = rti.testingEnvironmentEval(universe, env, '1');
+
+  checkToString('int', rti1);
+  checkToString('int', rti2);
+  checkRtiIdentical(rti1, rti2);
+
+  var rti3 = rti.testingEnvironmentEval(universe, env, 'AAA<0,1,2>');
+  checkToString('AAA<Foo<bool>, int, bool>', rti3);
+}
+
+test2() {
+  var universe = rti.testingCreateUniverse();
+
+  // Generic class with one nested single-parameter function scope.
+  //   vs.
+  // Unparameterized class with two nested single-parameter function scopes.
+  var env1 = rti.testingUniverseEval(universe, 'Foo<bool><int>');
+  var env2 = rti.testingUniverseEval(universe, 'Foo;<bool><int>');
+
+  var rti1 = rti.testingEnvironmentEval(universe, env1, 'AAA<0,1,2>');
+  var rti2 = rti.testingEnvironmentEval(universe, env2, 'AAA<0,1,2>');
+  checkToString('AAA<Foo<bool>, int, bool>', rti1);
+  checkToString('AAA<Foo, bool, int>', rti2);
+}
+
+test3() {
+  var universe = rti.testingCreateUniverse();
+  var env = rti.testingUniverseEval(universe, 'CCC<aaa,bbb><ccc,@>');
+  var rti1 = rti.testingEnvironmentEval(universe, env, 'AAA<0,1,2,3,4>');
+  checkToString('AAA<CCC<aaa, bbb>, ccc, dynamic, aaa, bbb>', rti1);
+}
+
+test4() {
+  var universe = rti.testingCreateUniverse();
+  var env = rti.testingUniverseEval(universe, '@<aaa,bbb>');
+  var rti1 = rti.testingEnvironmentEval(universe, env, 'AAA<0,1,2>');
+  checkToString('AAA<dynamic, aaa, bbb>', rti1);
+}
+
+test5() {
+  var universe = rti.testingCreateUniverse();
+  var env1 = rti.testingUniverseEval(universe, '@<aaa><bbb><ccc>');
+  var env2 = rti.testingUniverseEval(universe, '@;<aaa><bbb><ccc>');
+  var rti1 = rti.testingEnvironmentEval(universe, env1, 'AAA<0,1,2,3>');
+  var rti2 = rti.testingEnvironmentEval(universe, env2, 'AAA<0,1,2,3>');
+  checkToString('AAA<dynamic, aaa, bbb, ccc>', rti1);
+  checkRtiIdentical(rti1, rti2);
+}
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+}
diff --git a/tests/dart2js/internal/rti/canonical_recipe_test.dart b/tests/dart2js/internal/rti/canonical_recipe_test.dart
new file mode 100644
index 0000000..856ca7a
--- /dev/null
+++ b/tests/dart2js/internal/rti/canonical_recipe_test.dart
@@ -0,0 +1,28 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+final universe = rti.testingCreateUniverse();
+
+main() {
+  test('@', '@');
+  test('~', '~');
+  test('0&', '0&');
+  test('1&', '1&');
+  test('int', 'int');
+  test('int/', 'int/');
+  test('List<int>', 'List<int>');
+  test('Foo<bool,Bar<int,double>>', 'Foo<bool,Bar<int,double>>');
+  test('@;<int,bool>', '@<int><bool>');
+}
+
+String canonicalize(String recipe) {
+  var t = rti.testingUniverseEval(universe, recipe);
+  return rti.testingCanonicalRecipe(t);
+}
+
+void test(String expected, String recipe) =>
+    Expect.equals(expected, canonicalize(recipe));
diff --git a/tests/dart2js/internal/rti/class_environment_test.dart b/tests/dart2js/internal/rti/class_environment_test.dart
new file mode 100644
index 0000000..4cf7d9e
--- /dev/null
+++ b/tests/dart2js/internal/rti/class_environment_test.dart
@@ -0,0 +1,50 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+void checkRtiIdentical(Object rti1, Object rti2) {
+  var format = rti.testingRtiToString;
+  Expect.isTrue(
+      identical(rti1, rti2), 'identical(${format(rti1)}, ${format(rti2)}');
+}
+
+void checkToString(String expected, Object rti1) {
+  String result = rti.testingRtiToString(rti1);
+  if (expected == result) return;
+  Expect.equals(expected, result.replaceAll('minified:', ''));
+}
+
+testInterface1() {
+  var universe = rti.testingCreateUniverse();
+
+  var env = rti.testingUniverseEval(universe, 'Foo<int>');
+  var rti1 = rti.testingUniverseEval(universe, 'int');
+  var rti2 = rti.testingEnvironmentEval(universe, env, '1');
+
+  checkToString('int', rti1);
+  checkToString('int', rti2);
+  checkRtiIdentical(rti1, rti2);
+}
+
+testInterface2() {
+  var universe = rti.testingCreateUniverse();
+
+  var env = rti.testingUniverseEval(universe, 'Foo<int,List<int>>');
+  var rti1 = rti.testingUniverseEval(universe, 'List<int>');
+  var rti2 = rti.testingEnvironmentEval(universe, env, '2');
+  var rti3 = rti.testingEnvironmentEval(universe, env, 'List<1>');
+
+  checkToString('List<int>', rti1);
+  checkToString('List<int>', rti2);
+  checkToString('List<int>', rti3);
+  checkRtiIdentical(rti1, rti2);
+  checkRtiIdentical(rti1, rti3);
+}
+
+main() {
+  testInterface1();
+  testInterface2();
+}
diff --git a/tests/dart2js/internal/rti/constant_type_test.dart b/tests/dart2js/internal/rti/constant_type_test.dart
new file mode 100644
index 0000000..cd08db5
--- /dev/null
+++ b/tests/dart2js/internal/rti/constant_type_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+
+class Thingy {
+  const Thingy();
+}
+
+class Generic<AA> {
+  const Generic();
+}
+
+@pragma('dart2js:noInline')
+void check<T>(o) {
+  Expect.isTrue(o is T);
+  Expect.isFalse(o is! T);
+}
+
+main() {
+  check<Thingy>(const Thingy());
+
+  check<Generic<int>>(const Generic<int>());
+
+  check<Generic<dynamic>>(const Generic<dynamic>());
+  check<Generic<Object>>(const Generic<Object>());
+  check<Generic<Object>>(const Generic<dynamic>());
+  check<Generic<dynamic>>(const Generic<Object>());
+
+  check<List<int>>(const [1]);
+  check<List<String>>(const ['one']);
+
+  check<Set<int>>(const {1, 2, 3});
+  check<Map<String, int>>(const {'one': 1});
+
+  check<Symbol>(#hello);
+}
diff --git a/tests/dart2js/internal/rti/recipe_syntax_test.dart b/tests/dart2js/internal/rti/recipe_syntax_test.dart
new file mode 100644
index 0000000..7d4be33
--- /dev/null
+++ b/tests/dart2js/internal/rti/recipe_syntax_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 'dart:_recipe_syntax';
+
+main() {
+  Recipe.testEquivalence();
+}
diff --git a/tests/dart2js/internal/rti/required_named_parameters_test.dart b/tests/dart2js/internal/rti/required_named_parameters_test.dart
new file mode 100644
index 0000000..309a381
--- /dev/null
+++ b/tests/dart2js/internal/rti/required_named_parameters_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.
+
+// Requirements=nnbd
+
+import 'dart:_rti' as rti;
+import 'dart:_foreign_helper' show JS;
+import "package:expect/expect.dart";
+
+const typeRulesJson = r'''
+{
+  "B": {"A": []},
+  "C": {"B": []}
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+
+main() {
+  var universe = rti.testingCreateUniverse();
+  rti.testingAddRules(universe, typeRules);
+
+  // Recipe is properly parsed
+  var rti1 = rti.testingUniverseEval(universe, "@(B,{a!B,b:B,c!B})");
+
+  // Subtype must be contravariant in its named parameter types
+  var rti2 = rti.testingUniverseEval(universe, "@(B,{a!A,b:B,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:A,c!B})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!C,b:B,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+  rti2 = rti.testingUniverseEval(universe, "@(B,{a!B,b:C,c!B})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit optional named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not omit required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may contain additional named optional parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may redeclare required parameters as optional.
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a:A,b:A,c:A})");
+  Expect.isTrue(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not redeclare optional parameters as required
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b!A,c!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Subtype may not declare new required named parameters
+  rti2 = rti.testingUniverseEval(universe, "@(A,{a!A,b:A,c!A,d!A})");
+  Expect.isFalse(rti.testingIsSubtype(universe, rti2, rti1));
+
+  // Rti.toString() appears as expected
+  Expect.equals('(B, {required B a, B b, required B c}) => dynamic',
+      rti.testingRtiToString(rti1));
+
+  // Rti debug string properly annotates all required parameters
+  Expect.equals(
+      2, 'required'.allMatches(rti.testingRtiToDebugString(rti1)).length);
+}
diff --git a/tests/dart2js/internal/rti/runtime_type_1_test.dart b/tests/dart2js/internal/rti/runtime_type_1_test.dart
new file mode 100644
index 0000000..a3bcf05
--- /dev/null
+++ b/tests/dart2js/internal/rti/runtime_type_1_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class GenericThingy<A, B> {
+  toString() => 'GenericThingy<$A, $B>';
+}
+
+main() {
+  var rti1 = rti.instanceType(1);
+  Expect.equals('JSInt', rti.testingRtiToString(rti1));
+
+  var rti2 = rti.instanceType('Hello');
+  Expect.equals('JSString', rti.testingRtiToString(rti2));
+
+  var rti3 = rti.instanceType(Thingy());
+  Expect.equals('Thingy', rti.testingRtiToString(rti3));
+
+  var rti4 = rti.instanceType(GenericThingy<String, int>());
+  Expect.equals('GenericThingy<String, int>', rti.testingRtiToString(rti4));
+}
diff --git a/tests/dart2js/internal/rti/runtime_type_2_test.dart b/tests/dart2js/internal/rti/runtime_type_2_test.dart
new file mode 100644
index 0000000..d8cd534
--- /dev/null
+++ b/tests/dart2js/internal/rti/runtime_type_2_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+Type grab<T>() => T;
+
+@pragma('dart2js:noInline')
+Type grabList<T>() => grab<List<T>>();
+
+main() {
+  Expect.equals('int', grab<int>().toString());
+
+  Expect.identical(int, grab<int>());
+  Expect.identical(dynamic, grab<dynamic>());
+  Expect.identical(Object, grab<Object>());
+  Expect.identical(Null, grab<Null>());
+
+  Expect.equals('List<int>', grabList<int>().toString());
+  Expect.equals('List<Null>', grabList<Null>().toString());
+
+  Expect.equals('List<dynamic>', (List).toString());
+
+  Expect.equals('dynamic', (dynamic).toString());
+  Expect.equals('Object', (Object).toString());
+  Expect.equals('Null', (Null).toString());
+
+  Expect.equals(List, grabList<dynamic>());
+}
diff --git a/tests/dart2js/internal/rti/runtime_type_3_test.dart b/tests/dart2js/internal/rti/runtime_type_3_test.dart
new file mode 100644
index 0000000..89b8c8b
--- /dev/null
+++ b/tests/dart2js/internal/rti/runtime_type_3_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.
+
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import "package:expect/expect.dart";
+import "dart:_foreign_helper" show JS;
+
+main() {
+  Expect.equals('JSArray<int>', <int>[].runtimeType.toString());
+
+  // TODO(35084): An 'any' type would make JS-interop easier to use.
+  Expect.equals('JSArray<dynamic>', JS('', '[]').runtimeType.toString());
+}
diff --git a/tests/dart2js/internal/rti/simple_2_test.dart b/tests/dart2js/internal/rti/simple_2_test.dart
new file mode 100644
index 0000000..e195451
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_2_test.dart
@@ -0,0 +1,128 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+void checkToString(String expected, Object rti1) {
+  String result = rti.testingRtiToString(rti1);
+  if (expected == result) return;
+  Expect.equals(expected, result.replaceAll('minified:', ''));
+}
+
+testDynamic() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, '@');
+  var rti2 = rti.testingUniverseEval(universe, ',,@,,');
+
+  Expect.isTrue(identical(rti1, rti2), 'dynamic should be identical');
+  Expect.isFalse(rti1 is String);
+  checkToString('dynamic', rti1);
+}
+
+testVoid() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, '~');
+  var rti2 = rti.testingUniverseEval(universe, ',,~,,');
+
+  Expect.isTrue(identical(rti1, rti2), 'void should be identical');
+  Expect.isFalse(rti1 is String);
+  checkToString('void', rti1);
+}
+
+testNever() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, '0&');
+  var rti2 = rti.testingUniverseEval(universe, '0&');
+
+  Expect.isTrue(identical(rti1, rti2), 'Never should be identical');
+  Expect.isFalse(rti1 is String);
+  checkToString('Never', rti1);
+}
+
+testAny() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, '1&');
+  var rti2 = rti.testingUniverseEval(universe, '1&');
+
+  Expect.isTrue(identical(rti1, rti2), "'any' should be identical");
+  Expect.isFalse(rti1 is String);
+  checkToString('any', rti1);
+}
+
+testTerminal() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, '@');
+  var rti2 = rti.testingUniverseEval(universe, '~');
+  var rti3 = rti.testingUniverseEval(universe, '0&');
+  var rti4 = rti.testingUniverseEval(universe, '1&');
+
+  Expect.isFalse(identical(rti1, rti2));
+  Expect.isFalse(identical(rti1, rti3));
+  Expect.isFalse(identical(rti1, rti4));
+  Expect.isFalse(identical(rti2, rti3));
+  Expect.isFalse(identical(rti2, rti4));
+  Expect.isFalse(identical(rti3, rti4));
+}
+
+testInterface1() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, 'int');
+  var rti2 = rti.testingUniverseEval(universe, ',,int,,');
+
+  Expect.isTrue(identical(rti1, rti2));
+  Expect.isFalse(rti1 is String);
+  checkToString('int', rti1);
+}
+
+testInterface2() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, 'Foo<int,bool>');
+  var rti2 = rti.testingUniverseEval(universe, 'Foo<int,bool>');
+
+  Expect.isTrue(identical(rti1, rti2));
+  Expect.isFalse(rti1 is String);
+  checkToString('Foo<int, bool>', rti1);
+}
+
+testInterface3() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, 'Foo<Bar<int>,Bar<bool>>');
+  var rti2 = rti.testingUniverseEval(universe, 'Foo<Bar<int>,Bar<bool>>');
+
+  Expect.isTrue(identical(rti1, rti2));
+  Expect.isFalse(rti1 is String);
+  checkToString('Foo<Bar<int>, Bar<bool>>', rti1);
+}
+
+testInterface4() {
+  var universe = rti.testingCreateUniverse();
+
+  var rti1 = rti.testingUniverseEval(universe, 'Foo<Foo<Foo<Foo<int>>>>');
+  var rti2 = rti.testingUniverseEval(universe, 'Foo<Foo<Foo<Foo<int>>>>');
+
+  Expect.isTrue(identical(rti1, rti2));
+  Expect.isFalse(rti1 is String);
+  checkToString('Foo<Foo<Foo<Foo<int>>>>', rti1);
+}
+
+main() {
+  testDynamic();
+  testVoid();
+  testNever();
+  testAny();
+  testTerminal();
+  testInterface1();
+  testInterface2();
+  testInterface3();
+  testInterface4();
+}
diff --git a/tests/dart2js/internal/rti/simple_is_function_type2_test.dart b/tests/dart2js/internal/rti/simple_is_function_type2_test.dart
new file mode 100644
index 0000000..06e490d
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_is_function_type2_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti
+
+import "package:expect/expect.dart";
+
+int fnInt2Int(int x) => x;
+int fnIntOptInt2Int(int x, [int y = 0]) => x + y;
+
+make1<A, B>(A a) {
+  return (B b) => a;
+}
+
+make2<A, B>(A a) {
+  A foo(B b) => a;
+  return foo;
+}
+
+class C<A> {
+  final A a;
+  C(this.a);
+  make<B>() => (B b) => a;
+  make2<B>() => (B b) => 'x';
+}
+
+main() {
+  Expect.isTrue(make1<int, int>(1) is int Function(int));
+  Expect.isTrue(make1<int, int>(1) is Object Function(int));
+  Expect.isTrue(make1<int, int>(1) is! String Function(int));
+  Expect.isTrue(make1<int, int>(1) is! int Function(String));
+
+  Expect.isTrue(make2<int, int>(1) is int Function(int));
+  Expect.isTrue(make2<int, int>(1) is Object Function(int));
+  Expect.isTrue(make2<int, int>(1) is! String Function(int));
+  Expect.isTrue(make2<int, int>(1) is! int Function(String));
+
+  Expect.isTrue(C<int>(1).make<String>() is int Function(String));
+  Expect.isTrue(C<int>(1).make<String>() is Object Function(String));
+  Expect.isTrue(C<int>(1).make<String>() is! String Function(int));
+
+  Expect.isTrue(C<int>(1).make2<int>() is String Function(int));
+  Expect.isTrue(C<int>(1).make2<int>() is Object Function(int));
+  Expect.isTrue(C<int>(1).make2<int>() is! int Function(String));
+  Expect.isTrue(C<int>(1).make2<int>() is! int Function(int));
+  Expect.isTrue(C<int>(1).make2<String>() is String Function(String));
+  Expect.isTrue(C<int>(1).make2<String>() is Object Function(String));
+  Expect.isTrue(C<int>(1).make2<String>() is! int Function(String));
+  Expect.isTrue(C<int>(1).make2<String>() is! String Function(int));
+}
diff --git a/tests/dart2js/internal/rti/simple_is_function_type3_test.dart b/tests/dart2js/internal/rti/simple_is_function_type3_test.dart
new file mode 100644
index 0000000..78c5469
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_is_function_type3_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti
+
+// Test that some closures are 'is Function'.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+confuse(x) => x;
+
+main() {
+  // static tear-off.
+  Expect.isTrue(confuse(main) is Function);
+
+  // instance tear-off.
+  Expect.isTrue(confuse([].add) is Function);
+
+  // function expression.
+  Expect.isTrue(confuse(() => 1) is Function);
+
+  // local function.
+  int add1(int x) => x;
+
+  Expect.isTrue(confuse(add1) is Function);
+
+  Expect.isFalse(confuse(null) is Function);
+  Expect.isFalse(confuse(1) is Function);
+}
diff --git a/tests/dart2js/internal/rti/simple_is_function_type_test.dart b/tests/dart2js/internal/rti/simple_is_function_type_test.dart
new file mode 100644
index 0000000..2f32edc
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_is_function_type_test.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.
+
+// dart2jsOptions=--experiment-new-rti
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+int fnInt2Int(int x) => x;
+int fnIntOptInt2Int(int x, [int y = 0]) => x + y;
+
+main() {
+  Expect.isTrue(fnInt2Int is int Function(int));
+
+  Expect.isTrue(fnInt2Int is void Function(int));
+  Expect.isFalse(fnInt2Int is int Function());
+
+  Expect.isTrue(fnIntOptInt2Int is int Function(int, [int]));
+
+  Expect.isTrue(fnIntOptInt2Int is int Function(int, int));
+  Expect.isTrue(fnIntOptInt2Int is int Function(int));
+}
diff --git a/tests/dart2js/internal/rti/simple_is_test.dart b/tests/dart2js/internal/rti/simple_is_test.dart
new file mode 100644
index 0000000..6b79c94
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_is_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti --no-minify
+
+import 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+class Thingy {}
+
+class Generic<AA> {
+  checkMethod(o) => o is AA;
+}
+
+@pragma('dart2js:noInline')
+void check<T>(o) {
+  Expect.isTrue(o is T);
+  Expect.isFalse(o is! T);
+}
+
+main() {
+  check<Thingy>(Thingy());
+
+  check<Generic<int>>(Generic<int>());
+
+  check<Generic<dynamic>>(Generic<dynamic>());
+  check<Generic<Object>>(Generic<Object>());
+  check<Generic<Object>>(Generic<dynamic>());
+  check<Generic<dynamic>>(Generic<Object>());
+
+  Expect.isTrue(Generic<Thingy>().checkMethod(Thingy()));
+  Expect.isTrue(Generic<Object>().checkMethod(Object()));
+  Expect.isTrue(Generic<Object>().checkMethod(Thingy()));
+  Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+  Expect.isTrue(Generic<dynamic>().checkMethod(Object()));
+
+  Expect.isFalse(Generic<Thingy>().checkMethod(123));
+  Expect.isFalse(Generic<Thingy>().checkMethod(Object()));
+}
diff --git a/tests/dart2js/internal/rti/simple_test.dart b/tests/dart2js/internal/rti/simple_test.dart
new file mode 100644
index 0000000..13a893e
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+main() {
+  var universe = rti.testingCreateUniverse();
+
+  // TODO(sra): Add call: rti.testingAddRules(universe, ???);
+
+  var dynamicRti1 = rti.testingUniverseEval(universe, '@');
+  var dynamicRti2 = rti.testingUniverseEval(universe, '@');
+
+  Expect.isTrue(identical(dynamicRti1, dynamicRti2));
+  Expect.isFalse(dynamicRti1 is String);
+  Expect.equals('dynamic', rti.testingRtiToString(dynamicRti1));
+}
diff --git a/tests/dart2js/internal/rti/simple_type_bound_test.dart b/tests/dart2js/internal/rti/simple_type_bound_test.dart
new file mode 100644
index 0000000..29a8761
--- /dev/null
+++ b/tests/dart2js/internal/rti/simple_type_bound_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+// dart2jsOptions=--experiment-new-rti
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+dynamic makeFunction(x) {
+  // Return a local function since that does not require any tear-off code.
+  dynamic foo<U extends V, V extends num>() {
+    // Returning x ensures this is a local function and will not be optimized to
+    // a static tear-off.
+    return x;
+  }
+
+  return foo;
+}
+
+@pragma('dart2js:noInline')
+void test(dynamic action, bool expectThrows) {
+  // Don't use Expect.throws because it is hard to call without implicit type
+  // checks.
+  try {
+    // There is no type check here, just a dynamic 'call' selector.
+    action();
+  } catch (e, st) {
+    if (expectThrows) return;
+    Expect.fail('Should throw');
+    return;
+  }
+  if (expectThrows) {
+    Expect.fail('Did not throw');
+  }
+}
+
+main() {
+  dynamic f = makeFunction(123);
+
+  test(() => f<String, int>(), true);
+  test(() => f<num, num>(), false);
+}
diff --git a/tests/dart2js/internal/rti/subtype_test.dart b/tests/dart2js/internal/rti/subtype_test.dart
new file mode 100644
index 0000000..e4222c4
--- /dev/null
+++ b/tests/dart2js/internal/rti/subtype_test.dart
@@ -0,0 +1,154 @@
+// 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 'dart:_foreign_helper' show JS, JS_GET_NAME, TYPE_REF;
+import 'dart:_js_embedded_names' show JsGetName;
+import 'dart:_rti' as rti;
+
+import 'subtype_utils.dart';
+
+final String objectName = JS_GET_NAME(JsGetName.OBJECT_CLASS_TYPE_NAME);
+final String futureName = JS_GET_NAME(JsGetName.FUTURE_CLASS_TYPE_NAME);
+final String nullName = JS_GET_NAME(JsGetName.NULL_CLASS_TYPE_NAME);
+
+const typeRulesJson = r'''
+{
+  "int": {"num": []},
+  "double": {"num": []},
+  "List": {"Iterable": ["1"]},
+  "CodeUnits": {
+    "List": ["int"],
+    "Iterable": ["int"]
+  }
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+
+main() {
+  rti.testingAddRules(universe, typeRules);
+  rti.testingUniverseEvalOverride(universe, objectName, TYPE_REF<Object>());
+  rti.testingUniverseEvalOverride(universe, nullName, TYPE_REF<Null>());
+  runTests();
+  runTests(); // Ensure caching didn't change anything.
+}
+
+void runTests() {
+  testInterfaces();
+  testTopTypes();
+  testNull();
+  testBottom();
+  testFutureOr();
+  testFunctions();
+  testGenericFunctions();
+}
+
+void testInterfaces() {
+  strictSubtype('List<CodeUnits>', 'Iterable<List<int>>');
+  strictSubtype('CodeUnits', 'Iterable<num>');
+  strictSubtype('Iterable<int>', 'Iterable<num>');
+  unrelated('int', 'CodeUnits');
+  equivalent('double', 'double');
+  equivalent('List<int>', 'List<int>');
+}
+
+void testTopTypes() {
+  strictSubtype('List<int>', objectName);
+  equivalent(objectName, objectName);
+  equivalent('@', '@');
+  equivalent('~', '~');
+  equivalent('1&', '1&');
+  equivalent(objectName, '@');
+  equivalent(objectName, '~');
+  equivalent(objectName, '1&');
+  equivalent('@', '~');
+  equivalent('@', '1&');
+  equivalent('~', '1&');
+  equivalent('List<$objectName>', 'List<@>');
+  equivalent('List<$objectName>', 'List<~>');
+  equivalent('List<$objectName>', 'List<1&>');
+  equivalent('List<@>', 'List<~>');
+  equivalent('List<@>', 'List<1&>');
+  equivalent('List<~>', 'List<1&>');
+}
+
+void testNull() {
+  strictSubtype(nullName, 'int');
+  strictSubtype(nullName, 'Iterable<CodeUnits>');
+  strictSubtype(nullName, objectName);
+  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/');
+  strictSubtype('$futureName<int>', 'int/');
+  strictSubtype('int/', 'num/');
+  strictSubtype('int', 'num/');
+  strictSubtype('$futureName<int>', 'num/');
+  equivalent('@/', '~/');
+}
+
+void testFunctions() {
+  equivalent('~()', '~()');
+  equivalent('@()', '~()');
+  unrelated('int()', 'int(int)');
+  strictSubtype('int()', 'num()');
+  strictSubtype('~(num)', '~(int)');
+  strictSubtype('int(Iterable<num>)', 'num(CodeUnits)');
+
+  equivalent('~(int,@,num)', '~(int,@,num)');
+  equivalent('@(int,~,num)', '~(int,@,num)');
+  unrelated('int(int,double)', 'void(String)');
+  unrelated('int(int,double)', 'int(int)');
+  unrelated('int(int,double)', 'int(double)');
+  unrelated('int(int,double)', 'int(int,int)');
+  unrelated('int(int,double)', 'int(String,double)');
+  strictSubtype('int(int,double)', '~(int,double)');
+  strictSubtype('int(int,double)', 'num(int,double)');
+  strictSubtype('int(num,double)', 'int(int,double)');
+  strictSubtype('int(int,num)', 'int(int,double)');
+  strictSubtype('int(num,num)', 'int(int,double)');
+  strictSubtype('double(num,Iterable<num>,int/)', 'num(int,CodeUnits,int)');
+
+  equivalent('~([@])', '~([@])');
+  equivalent('~(int,[double])', '~(int,[double])');
+  equivalent('~(int,[double,CodeUnits])', '~(int,[double,CodeUnits])');
+  unrelated('~([int])', '~([double])');
+  unrelated('~(int,[int])', '~(int,[double])');
+  unrelated('~(int,[CodeUnits,int])', '~(int,[CodeUnits,double])');
+  strictSubtype('~([num])', '~([int])');
+  strictSubtype('~([num,num])', '~([int,double])');
+  strictSubtype('~([int,double])', '~(int,[double])');
+  strictSubtype('~([int,double,CodeUnits])', '~([int,double])');
+  strictSubtype('~([int,double,CodeUnits])', '~(int,[double])');
+
+  equivalent('~({foo:@})', '~({foo:@})');
+  unrelated('~({foo:@})', '~({bar:@})');
+  unrelated('~({foo:@,quux:@})', '~({bar:@,baz:@})');
+  unrelated('~(@,{foo:@})', '~(@,@)');
+  unrelated('~(@,{foo:@})', '~({bar:@,foo:@})');
+  equivalent('~({bar:int,foo:double})', '~({bar:int,foo:double})');
+  strictSubtype('~({bar:int,foo:double})', '~({bar:int})');
+  strictSubtype('~({bar:int,foo:double})', '~({foo:double})');
+  strictSubtype('~({bar:num,baz:num,foo:num})', '~({baz:int,foo:double})');
+}
+
+void testGenericFunctions() {
+  equivalent('~()<int>', '~()<int>');
+  unrelated('~()<int>', '~()<double>');
+  unrelated('~()<int>', '~()<int,int>');
+  unrelated('~()<int>', '~()<num>');
+  unrelated('~()<int,double>', '~()<double,int>');
+  strictSubtype('List<0^>()<int>', 'Iterable<0^>()<int>');
+  strictSubtype('~(Iterable<0^>)<int>', '~(List<0^>)<int>');
+
+  equivalent('~()<@>', '~()<~>');
+  equivalent('~()<List<@/>>', '~()<List<~/>>');
+  unrelated('~()<List<int/>>', '~()<List<num/>>');
+}
diff --git a/tests/dart2js/internal/rti/subtype_utils.dart b/tests/dart2js/internal/rti/subtype_utils.dart
new file mode 100644
index 0000000..dc4f608
--- /dev/null
+++ b/tests/dart2js/internal/rti/subtype_utils.dart
@@ -0,0 +1,31 @@
+// 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 'dart:_rti' as rti;
+import "package:expect/expect.dart";
+
+final universe = rti.testingCreateUniverse();
+
+String reason(String s, String t) => "$s <: $t";
+
+void strictSubtype(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void unrelated(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isFalse(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isFalse(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
+
+void equivalent(String s, String t) {
+  var sRti = rti.testingUniverseEval(universe, s);
+  var tRti = rti.testingUniverseEval(universe, t);
+  Expect.isTrue(rti.testingIsSubtype(universe, sRti, tRti), reason(s, t));
+  Expect.isTrue(rti.testingIsSubtype(universe, tRti, sRti), reason(t, s));
+}
diff --git a/tests/dart2js/internal/rti/variance_subtype_test.dart b/tests/dart2js/internal/rti/variance_subtype_test.dart
new file mode 100644
index 0000000..87685c1
--- /dev/null
+++ b/tests/dart2js/internal/rti/variance_subtype_test.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.
+
+// SharedOptions=--enable-experiment=variance
+
+import 'dart:_foreign_helper' show JS;
+import 'dart:_rti' as rti;
+
+import 'subtype_utils.dart';
+
+const typeRulesJson = r'''
+{
+  "int": {"num": []}
+}
+''';
+final typeRules = JS('=Object', 'JSON.parse(#)', typeRulesJson);
+
+const typeParameterVariancesJson = '''
+{
+  "Covariant": [${rti.Variance.covariant}],
+  "Contravariant": [${rti.Variance.contravariant}],
+  "Invariant": [${rti.Variance.invariant}],
+  "MultiVariant":[${rti.Variance.legacyCovariant}, ${rti.Variance.invariant},
+  ${rti.Variance.contravariant}, ${rti.Variance.covariant}]
+}
+''';
+final typeParameterVariances =
+    JS('=Object', 'JSON.parse(#)', typeParameterVariancesJson);
+
+main() {
+  rti.testingAddRules(universe, typeRules);
+  rti.testingAddTypeParameterVariances(universe, typeParameterVariances);
+  testInterfacesWithVariance();
+  testInterfacesWithVariance(); // Ensure caching didn't change anything.
+}
+
+void testInterfacesWithVariance() {
+  strictSubtype('LegacyCovariant<int>', 'LegacyCovariant<num>');
+  strictSubtype('Covariant<int>', 'Covariant<num>');
+  strictSubtype('Contravariant<num>', 'Contravariant<int>');
+  equivalent('Invariant<num>', 'Invariant<num>');
+  unrelated('Invariant<int>', 'Invariant<num>');
+  unrelated('Invariant<num>', 'Invariant<int>');
+  strictSubtype(
+      'MultiVariant<int,num,num,int>', 'MultiVariant<num,num,int,num>');
+}
diff --git a/tests/dart2js/invalid_annotation_test.dart b/tests/dart2js/invalid_annotation_test.dart
new file mode 100644
index 0000000..fe68503
--- /dev/null
+++ b/tests/dart2js/invalid_annotation_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for http://dartbug.com/23893
+//
+// Because annotations are parsed lazily, dart2js used to crash when an
+// annotation had a syntax error.
+
+@Deprecated("m"
+,, //                               //# 01: compile-time error
+    )
+class A {}
+
+main() => new A();
diff --git a/tests/dart2js/invoke_dynamic_test.dart b/tests/dart2js/invoke_dynamic_test.dart
new file mode 100644
index 0000000..65239f6
--- /dev/null
+++ b/tests/dart2js/invoke_dynamic_test.dart
@@ -0,0 +1,68 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  foo() {
+    return 499;
+  }
+
+  bar(x) {
+    return x + 499;
+  }
+
+  baz() {
+    return 54;
+  }
+
+  titi() {
+    return 123;
+  }
+}
+
+class B {
+  foo() {
+    return 42;
+  }
+
+  bar(x) {
+    return x + 42;
+  }
+
+  toto() {
+    return foo() + 42;
+  }
+}
+
+class C extends A {
+  foo() {
+    return 99;
+  }
+
+  bar(x) {
+    return x + 99;
+  }
+}
+
+void main() {
+  var a = new A();
+  Expect.equals(499, a.foo());
+  Expect.equals(500, a.bar(1));
+  var b = new B();
+  Expect.equals(42, b.foo());
+  Expect.equals(43, b.bar(1));
+  var c = new C();
+  Expect.equals(99, c.foo());
+  Expect.equals(100, c.bar(1));
+
+  Expect.equals(54, a.baz());
+  Expect.equals(54, c.baz());
+
+  // We don't call a.titi. This means that the compiler needs to trigger the
+  // compilation of A.titi by going through the super-chain.
+  Expect.equals(123, c.titi());
+
+  Expect.equals(84, b.toto());
+}
diff --git a/tests/dart2js/is_check_instanceof_test.dart b/tests/dart2js/is_check_instanceof_test.dart
new file mode 100644
index 0000000..7e9c8a4
--- /dev/null
+++ b/tests/dart2js/is_check_instanceof_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2015, 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 sometimes possible to compile is-checks to 'instanceof', when the class
+// is not in an 'implements' clause or used as a mixin.
+
+// This test verifies is-checks work with simple classes that have various
+// degrees of instantiation.
+
+class INSTANTIATED {} // instantiated and used in many ways
+
+class DEFERRED {} // instantiated after first check
+
+class UNUSED {} // used only in is-check
+
+class REMOVED {} // allocated but optimized out of program
+
+class DEFERRED_AND_REMOVED {} // allocated after first check and removed
+
+class USED_AS_TYPE_PARAMETER {} // only used as a type parameter
+
+class USED_AS_TESTED_TYPE_PARAMETER {} // only used as a type parameter
+
+class Check<T> {
+  bool check(x) => x is T;
+}
+
+class Check2<T> {
+  bool check(x) => x is USED_AS_TYPE_PARAMETER;
+}
+
+void main() {
+  var things = new List(3);
+  things.setRange(0, 3, [new INSTANTIATED(), 1, new Object()]);
+
+  var checkX = new Check<INSTANTIATED>();
+  var checkU1 = new Check<USED_AS_TESTED_TYPE_PARAMETER>();
+  var checkU2 = new Check<USED_AS_TYPE_PARAMETER>();
+
+  var removed = new REMOVED(); // This is optimized out.
+
+  // Tests that can be compiled to instanceof:
+  Expect.isTrue(things[0] is INSTANTIATED);
+  Expect.isFalse(things[1] is INSTANTIATED);
+  Expect.isFalse(things[1] is REMOVED);
+  Expect.isFalse(things[1] is DEFERRED_AND_REMOVED);
+  Expect.isFalse(things[1] is DEFERRED);
+  // Tests that might be optimized to false since there are no allocations:
+  Expect.isFalse(things[1] is UNUSED);
+  Expect.isFalse(things[1] is USED_AS_TYPE_PARAMETER);
+
+  Expect.isTrue(checkX.check(things[0]));
+  Expect.isFalse(checkX.check(things[1]));
+  Expect.isFalse(checkU1.check(things[1]));
+  Expect.isFalse(checkU2.check(things[1]));
+
+  var removed2 = new DEFERRED_AND_REMOVED(); // This is optimized out.
+
+  // First allocation of DEFERRED is after the above tests.
+  things.setRange(0, 3, [new INSTANTIATED(), 1, new DEFERRED()]);
+
+  // Tests that can be compiled to instanceof:
+  Expect.isTrue(things[0] is INSTANTIATED);
+  Expect.isFalse(things[1] is INSTANTIATED);
+  Expect.isFalse(things[1] is REMOVED);
+  Expect.isFalse(things[1] is DEFERRED_AND_REMOVED);
+  Expect.isFalse(things[1] is DEFERRED);
+  Expect.isTrue(things[2] is DEFERRED);
+  // Tests that might be optimized to false since there are no allocations:
+  Expect.isFalse(things[1] is UNUSED);
+  Expect.isFalse(things[1] is USED_AS_TYPE_PARAMETER);
+}
diff --git a/tests/dart2js/is_operator_test.dart b/tests/dart2js/is_operator_test.dart
new file mode 100644
index 0000000..bc18d7b9
--- /dev/null
+++ b/tests/dart2js/is_operator_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+main() {
+  var a = new A();
+  var b = new B();
+
+  Expect.isTrue(a is A);
+  Expect.isTrue(a is Object);
+  Expect.isTrue(!(a is B));
+
+  Expect.isTrue(b is A);
+  Expect.isTrue(b is Object);
+  Expect.isTrue(b is B);
+
+  Expect.equals("true", (a is A).toString());
+  Expect.equals("true", (a is Object).toString());
+  Expect.equals("false", (a is B).toString());
+
+  Expect.equals("true", (b is A).toString());
+  Expect.equals("true", (b is Object).toString());
+  Expect.equals("true", (b is B).toString());
+
+  var c = new A();
+  Expect.isTrue(c is Object);
+
+  c = new A();
+  Expect.equals("true", (c is Object).toString());
+}
diff --git a/tests/dart2js/issue36562_test.dart b/tests/dart2js/issue36562_test.dart
new file mode 100644
index 0000000..cd43f16
--- /dev/null
+++ b/tests/dart2js/issue36562_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+const int x = 0;
+
+const List<int> l = const [
+  1,
+  -x,
+];
+
+main() => print(l);
diff --git a/tests/dart2js/js_array_index_error_test.dart b/tests/dart2js/js_array_index_error_test.dart
new file mode 100644
index 0000000..8af893a
--- /dev/null
+++ b/tests/dart2js/js_array_index_error_test.dart
@@ -0,0 +1,326 @@
+// Copyright (c) 2015, 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 that optimized JSArray indexers generate the same error as dynamically
+// dispatched calls.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+Error getError(action(), name, part) {
+  try {
+    action();
+  } catch (e) {
+    return e;
+  }
+  Expect.fail('must throw: $name: $part');
+}
+
+indexErrorContainsIndex() {
+  makeFault(i) => () => confuse([])[i];
+
+  var name = 'index error contains index';
+  var e1 = getError(makeFault(1234), name, 'small');
+  var e2 = getError(makeFault(1234000), name, 'medium');
+  var e3 = getError(makeFault(1234000000000), name, 'large');
+
+  Expect.equals('$e1', '$e2'.replaceAll('000', ''));
+  Expect.equals('$e1', '$e3'.replaceAll('000', ''));
+  Expect.equals('$e1'.length + 3, '$e2'.length);
+  Expect.equals('$e1'.length + 9, '$e3'.length);
+}
+
+compare(name, fault1(), fault2(), fault3()) {
+  var e1 = getError(fault1, name, 'fault1');
+  var e2 = getError(fault2, name, 'fault2');
+  var e3 = getError(fault3, name, 'fault3');
+
+  Expect.equals('$e1', '$e2', '$name: fault1 vs fault2');
+  Expect.equals('$e1', '$e3', '$name: fault1 vs fault3');
+}
+
+// These tests are a bit tedious and avoid common helpers with higher order
+// functions to keep the type inference for each test independent from the
+// others.
+//
+// The 'constant' tests have a constant index which might permit different
+// optimizations to a variable index.  e.g. the compiler might determine HUGE is
+// always out of range since the maximum JavaScript Array length is 2^32.
+//
+// The 'variable' forms take the index as an argument.
+
+const int HUGE = 1000000000000;
+
+constantIndexEmpty() {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([])[0];
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    return a[0];
+  }
+
+  fault3() {
+    var a = confuse([]);
+    // Multiple indexing might go via shared interceptor.
+    return [a[0], a[1], a[2]];
+  }
+
+  compare('constant index on empty list', fault1, fault2, fault3);
+}
+
+constantIndexHugeEmpty() {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([])[HUGE];
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    return a[HUGE];
+  }
+
+  fault3() {
+    var a = confuse([]);
+    return [a[HUGE], a[1], a[2]];
+  }
+
+  compare(
+      'constant index on empty list with huge index', fault1, fault2, fault3);
+}
+
+constantIndexNonempty() {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([1])[1];
+
+  fault2() {
+    var a = [1];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    return a[1];
+  }
+
+  fault3() {
+    var a = confuse([1]);
+    // Multiple indexing might go via shared interceptor.
+    return [a[1], a[2], a[3]];
+  }
+
+  compare('constant index on non-empty list', fault1, fault2, fault3);
+}
+
+constantIndexHugeNonempty() {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([1])[HUGE];
+
+  fault2() {
+    var a = [1];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    return a[HUGE];
+  }
+
+  fault3() {
+    var a = confuse([1]);
+    // Multiple indexing might go via shared interceptor.
+    return [a[HUGE], a[1], a[2]];
+  }
+
+  compare('constant index on non-empty list with huge index', fault1, fault2,
+      fault3);
+}
+
+constantIndexSetEmpty() {
+  fault1() {
+    // Single dynamic receiver indexing might go via one-shot interceptor that
+    // might have an accelerated path.
+    confuse([])[0] = 0;
+  }
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    a[0] = 0;
+    return a;
+  }
+
+  fault3() {
+    var a = confuse([]);
+    // Multiple indexing might go via shared interceptor.
+    a[0] = 0;
+    a[1] = 0;
+    a[2] = 0;
+    return a;
+  }
+
+  compare('coinstant index-set on empty list', fault1, fault2, fault3);
+}
+
+constantIndexSetNonempty() {
+  fault1() {
+    // Single dynamic receiver indexing might go via one-shot interceptor that
+    // might have an accelerated path.
+    confuse([1])[1] = 0;
+  }
+
+  fault2() {
+    var a = [1];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    a[1] = 0;
+    return a;
+  }
+
+  fault3() {
+    var a = confuse([1]);
+    // Multiple indexing might go via shared interceptor.
+    a[0] = 0;
+    a[1] = 0;
+    a[2] = 0;
+    return a;
+  }
+
+  compare('constant index-set on non-empty list', fault1, fault2, fault3);
+}
+
+variableIndexEmpty(index, qualifier) {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([])[index];
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    return a[index];
+  }
+
+  fault3() {
+    var a = confuse([]);
+    // Multiple indexing might go via shared interceptor.
+    return [a[index], a[1], a[2]];
+  }
+
+  compare('general index on empty list $qualifier', fault1, fault2, fault3);
+}
+
+variableIndexNonempty(index, qualifier) {
+  // Single dynamic receiver indexing might go via one-shot interceptor that
+  // might have an accelerated path.
+  fault1() => confuse([1])[index];
+
+  fault2() {
+    var a = [1];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    return a[index];
+  }
+
+  fault3() {
+    var a = confuse([1]);
+    // Multiple indexing might go via shared interceptor.
+    return [a[index], a[1], a[2]];
+  }
+
+  compare(
+      'variable index on non-empty list $qualifier', fault1, fault2, fault3);
+}
+
+variableIndexSetEmpty(index, qualifier) {
+  fault1() {
+    var a = confuse([]);
+    // Single dynamic receiver indexing might go via one-shot interceptor that
+    // might have an accelerated path.
+    a[index] = 1;
+    return a;
+  }
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    a[index] = 1;
+    return a;
+  }
+
+  fault3() {
+    var a = confuse([]);
+    // Multiple indexing might go via shared interceptor.
+    a[index] = 1;
+    a[2] = 2;
+    a[3] = 3;
+    return a;
+  }
+
+  compare(
+      'variable index-set on empty list $qualifier', fault1, fault2, fault3);
+}
+
+variableIndexSetNonempty(index, qualifier) {
+  fault1() {
+    var a = confuse([1]);
+    // Single dynamic receiver indexing might go via one-shot interceptor that
+    // might have an accelerated path.
+    a[index] = 1;
+    return a;
+  }
+
+  fault2() {
+    var a = [1];
+    while (confuse(false)) a.add(1);
+    // Easily inferred type and open coded indexer.
+    a[index] = 1;
+    return a;
+  }
+
+  fault3() {
+    var a = confuse([1]);
+    // Multiple indexing might go via shared interceptor.
+    a[index] = 1;
+    a[2] = 2;
+    a[3] = 3;
+    return a;
+  }
+
+  compare('variable index-set on non-empty list $qualifier', fault1, fault2,
+      fault3);
+}
+
+main() {
+  indexErrorContainsIndex();
+
+  constantIndexEmpty();
+  constantIndexHugeEmpty();
+  constantIndexNonempty();
+  constantIndexHugeNonempty();
+  constantIndexSetEmpty();
+  constantIndexSetNonempty();
+
+  variableIndexEmpty(0, 'zero index');
+  variableIndexEmpty(10, 'small index');
+  variableIndexEmpty(-1, 'negative index');
+  variableIndexEmpty(HUGE, 'huge index');
+
+  variableIndexNonempty(10, 'small index');
+  variableIndexNonempty(-1, 'negative index');
+  variableIndexNonempty(HUGE, 'huge index');
+
+  variableIndexSetEmpty(0, 'zero index');
+  variableIndexSetEmpty(10, 'small index');
+  variableIndexSetEmpty(-1, 'negative index');
+  variableIndexSetEmpty(HUGE, 'huge index');
+
+  variableIndexSetNonempty(10, 'small index');
+  variableIndexSetNonempty(-1, 'negative index');
+  variableIndexSetNonempty(HUGE, 'huge index');
+}
diff --git a/tests/dart2js/js_array_removeLast_error_test.dart b/tests/dart2js/js_array_removeLast_error_test.dart
new file mode 100644
index 0000000..5241f55
--- /dev/null
+++ b/tests/dart2js/js_array_removeLast_error_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2015, 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 that optimized JSArray removeLast() calls generate the same error as
+// dynamically dispatched calls.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+Error getError(action()) {
+  try {
+    action();
+    Expect.fail('must throw');
+  } catch (e) {
+    return e;
+  }
+}
+
+main() {
+  fault1() {
+    return confuse([]).removeLast();
+  }
+
+  fault2() {
+    var a = [];
+    while (confuse(false)) a.add(1);
+    // This one should be optimized since [a] is a growable JSArray.
+    return a.removeLast();
+  }
+
+  var e1 = getError(fault1);
+  var e2 = getError(fault2);
+
+  Expect.equals('$e1', '$e2');
+}
diff --git a/tests/dart2js/js_array_sort_default_test.dart b/tests/dart2js/js_array_sort_default_test.dart
new file mode 100644
index 0000000..8f4e161
--- /dev/null
+++ b/tests/dart2js/js_array_sort_default_test.dart
@@ -0,0 +1,9 @@
+// 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.
+
+/// Tests that the default comparable function in JSArray.sort has a valid
+/// strong-mode type.
+void main() {
+  new List<dynamic>.from(['1', '2']).sort();
+}
diff --git a/tests/dart2js/js_interop_cast_test.dart b/tests/dart2js/js_interop_cast_test.dart
new file mode 100644
index 0000000..28c018a
--- /dev/null
+++ b/tests/dart2js/js_interop_cast_test.dart
@@ -0,0 +1,63 @@
+// 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.
+
+// Test that we don't crash on computing js-interop classes when metadata
+// constants contain implicit casts.
+//
+// We need the class hierarchy to perform the evaluation the implicit casts but
+// we also change the class hierarchy when we discover that a class is a
+// js-interop class. By mixing (valid) constants that contain implicit casts
+// with the @JS annotations that define classes to be js-interop, triggering
+// the use of the class hierarchy before all js-interop classes have been
+// registered, this test causes dart2js to crash with an assertion failure.
+
+@Constant(4)
+@JS()
+@Constant(5)
+library test;
+
+import 'package:js/js.dart';
+
+@Constant(-1)
+method() {}
+
+@Constant(0)
+@JS()
+@anonymous
+@Constant(1)
+class ClassA {
+  external factory ClassA();
+
+  @Constant(2)
+  external method();
+}
+
+class Constant {
+  final int field;
+
+  const Constant(dynamic value) : field = value;
+}
+
+@Constant(0)
+@JS()
+@anonymous
+@Constant(1)
+class ClassB {
+  external factory ClassB();
+
+  @Constant(2)
+  external method();
+}
+
+class ClassC {
+  method() {}
+}
+
+main() {
+  method();
+  dynamic c = new ClassC();
+  c.method();
+  new ClassA();
+  new ClassB();
+}
diff --git a/tests/dart2js/js_interop_implements_test.dart b/tests/dart2js/js_interop_implements_test.dart
new file mode 100644
index 0000000..a4c8a72
--- /dev/null
+++ b/tests/dart2js/js_interop_implements_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+// Test that methods implemented (not extended) in js-interop classes are still
+// considered live.
+
+@JS()
+library anonymous_js_test;
+
+import 'package:js/js.dart';
+
+@JS()
+@anonymous
+abstract class A {
+  external factory A();
+  external String get a;
+  external set a(String a);
+}
+
+@JS()
+@anonymous
+abstract class B implements A {
+  external factory B();
+  external String get b;
+  external set b(String b);
+}
+
+void main() {
+  final b = B();
+  // This setter is missing if we don't assume the receiver could be an
+  // unknown but concrete implementation of A.
+  b.a = 'Hi';
+  b.b = 'Hello';
+  if (b.a != 'Hi') throw 'b.a';
+  if (b.b != 'Hello') throw 'b.b';
+}
diff --git a/tests/dart2js/js_interop_no_elide_optional_arg_test.dart b/tests/dart2js/js_interop_no_elide_optional_arg_test.dart
new file mode 100644
index 0000000..5d6d913
--- /dev/null
+++ b/tests/dart2js/js_interop_no_elide_optional_arg_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2017, 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 that optional arguments of js-interop factory constructors are not
+/// elided.
+/// This is a regression test for issue 35916
+@JS()
+library test;
+
+import "package:js/js.dart";
+import "package:expect/expect.dart";
+
+@JS()
+@anonymous
+class Margins {
+  external factory Margins(
+      {int top, int start, int end, int right, int bottom, int left});
+  external int get top;
+  external int get right;
+  external int get left;
+  external int get bottom;
+}
+
+main() {
+  var m = new Margins(bottom: 21, left: 88, right: 20, top: 24);
+  Expect.equals(m.top, 24);
+  Expect.equals(m.bottom, 21);
+  Expect.equals(m.left, 88);
+  Expect.equals(m.right, 20);
+}
diff --git a/tests/dart2js/js_interop_optional_arg_test.dart b/tests/dart2js/js_interop_optional_arg_test.dart
new file mode 100644
index 0000000..4c50389
--- /dev/null
+++ b/tests/dart2js/js_interop_optional_arg_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2017, 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 that optional arguments of js-interop constructors are not passed
+/// explicitly when missing.
+///
+/// This is a regression test for issue 32697
+
+import "package:js/js.dart";
+import "package:expect/expect.dart";
+import "dart:js" as js;
+
+@JS('C')
+class C {
+  external C([a]);
+  external bool get isUndefined;
+}
+
+main() {
+  js.context.callMethod("eval", [
+    """
+  function C(a){
+    this.isUndefined = a === undefined;
+  };
+  """
+  ]);
+
+  Expect.isTrue(new C().isUndefined);
+}
diff --git a/tests/dart2js/js_interop_test.dart b/tests/dart2js/js_interop_test.dart
new file mode 100644
index 0000000..77478b1
--- /dev/null
+++ b/tests/dart2js/js_interop_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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:js/js.dart";
+import "package:expect/expect.dart";
+import "dart:js" as js;
+
+@JS('aFoo.bar')
+external dynamic get jsBar;
+
+main() {
+  js.context.callMethod("eval", [
+    """
+  function Foo(){
+    this.bar = 'Foo.bar';
+  };
+  aFoo = new Foo();
+  """
+  ]);
+
+  Expect.equals('Foo.bar', jsBar);
+}
diff --git a/tests/dart2js/jsinterop_test.dart b/tests/dart2js/jsinterop_test.dart
new file mode 100644
index 0000000..07798e5
--- /dev/null
+++ b/tests/dart2js/jsinterop_test.dart
@@ -0,0 +1,270 @@
+// 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.
+
+// TODO(johnniwinther): Share this test with ddc.
+
+// Test for positive and negative uses of js-interop declarations in a library
+// _with_ a @JS() annotation. This file is also used in
+// tests/compiler/dart2js/model/native_test.dart.
+
+@JS()
+library lib;
+
+import 'package:js/js.dart';
+
+var topLevelField;
+
+get topLevelGetter => null;
+
+set topLevelSetter(_) {}
+
+topLevelFunction() {}
+
+@JS('a') // JS_INTEROP_FIELD_NOT_SUPPORTED       //# 01: compile-time error
+var topLevelJsInteropField; //# 01: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 02: compile-time error
+get topLevelJsInteropGetter => null; //# 02: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 03: compile-time error
+set topLevelJsInteropSetter(_) {} //# 03: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 04: compile-time error
+topLevelJsInteropFunction() {} //# 04: continued
+
+external get externalTopLevelGetter;
+
+external set externalTopLevelSetter(_);
+
+external externalTopLevelFunction();
+
+@JS('a')
+external get externalTopLevelJsInteropGetter;
+
+@JS('b')
+external set externalTopLevelJsInteropSetter(_);
+
+@JS('c')
+external externalTopLevelJsInteropFunction();
+
+class Class {
+  Class.generative();
+  factory Class.fact() => null;
+
+  // NON_NATIVE_EXTERNAL               //# 08: compile-time error
+  external Class.externalGenerative(); //# 08: continued
+
+  // NON_NATIVE_EXTERNAL                 //# 09: compile-time error
+  external factory Class.externalFact(); //# 09: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 10: compile-time error
+  Class.jsInteropGenerative(); //# 10: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 11: compile-time error
+  factory Class.jsInteropFact() => null; //# 11: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 12: compile-time error
+  external Class.externalJsInteropGenerative(); //# 12: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 13: compile-time error
+  external factory Class.externalJsInteropFact(); //# 13: continued
+
+  var instanceField;
+  get instanceGetter => null;
+  set instanceSetter(_) {}
+  instanceMethod() {}
+
+  static var staticField;
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 14: compile-time error
+  var instanceJsInteropField; //# 14: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 15: compile-time error
+  get instanceJsInteropGetter => null; //# 15: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 16: compile-time error
+  set instanceJsInteropSetter(_) {} //# 16: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 17: compile-time error
+  instanceJsInteropMethod() {} //# 17: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 18: compile-time error
+  static var staticJsInteropField; //# 18: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 19: compile-time error
+  static get staticJsInteropGetter => null; //# 19: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 20: compile-time error
+  static set staticJsInteropSetter(_) {} //# 20: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 21: compile-time error
+  static staticJsInteropMethod() {} //# 21: continued
+
+  // NON_NATIVE_EXTERNAL               //# 22: compile-time error
+  external get externalInstanceGetter; //# 22: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 23: compile-time error
+  external set externalInstanceSetter(_); //# 23: continued
+
+  // NON_NATIVE_EXTERNAL             //# 24: compile-time error
+  external externalInstanceMethod(); //# 24: continued
+
+  // NON_NATIVE_EXTERNAL             //# 25: compile-time error
+  external static get externalStaticGetter; //# 25: continued
+
+  // NON_NATIVE_EXTERNAL                //# 26: compile-time error
+  external static set externalStaticSetter(_); //# 26: continued
+
+  // NON_NATIVE_EXTERNAL           //# 27: compile-time error
+  external static externalStaticMethod(); //# 27: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 28: compile-time error
+  external get externalInstanceJsInteropGetter; //# 28: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 29: compile-time error
+  external set externalInstanceJsInteropSetter(_); //# 29: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 30: compile-time error
+  external externalInstanceJsInteropMethod(); //# 30: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 31: compile-time error
+  external static get externalStaticJsInteropGetter; //# 31: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 32: compile-time error
+  external static set externalStaticJsInteropSetter(_); //# 32: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 33: compile-time error
+  external static externalStaticJsInteropMethod(); //# 33: continued
+}
+
+@JS('d')
+class JsInteropClass {
+  // GENERIC //# 34: compile-time error
+  JsInteropClass.generative(); //# 34: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 35: compile-time error
+  factory JsInteropClass.fact() => null; //# 35: continued
+
+  external JsInteropClass.externalGenerative();
+  external factory JsInteropClass.externalFact();
+
+  @JS('a') // GENERIC //# 36: compile-time error
+  JsInteropClass.jsInteropGenerative(); //# 36: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 37: compile-time error
+  factory JsInteropClass.jsInteropFact() => null; //# 37: continued
+
+  @JS('a')
+  external JsInteropClass.externalJsInteropGenerative();
+
+  @JS('a')
+  external factory JsInteropClass.externalJsInteropFact();
+
+  // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 38: compile-time error
+  var instanceField; //# 38: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 39: compile-time error
+  get instanceGetter => null; //# 39: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 40: compile-time error
+  set instanceSetter(_) {} //# 40: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 41: compile-time error
+  instanceMethod() {} //# 41: continued
+
+  // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 42: compile-time error
+  static var staticField; //# 42: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 43: compile-time error
+  static get staticGetter => null; //# 43: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 44: compile-time error
+  static set staticSetter(_) {} //# 44: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 45: compile-time error
+  static staticMethod() {} //# 45: continued
+
+  @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 46: compile-time error
+  var instanceJsInteropField; //# 46: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 48: compile-time error
+  get instanceJsInteropGetter => null; //# 48: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 49: compile-time error
+  set instanceJsInteropSetter(_) {} //# 49: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 50: compile-time error
+  instanceJsInteropMethod() {} //# 50: continued
+
+  @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 51: compile-time error
+  static var staticJsInteropField; //# 51: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 52: compile-time error
+  static get staticJsInteropGetter => null; //# 52: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 53: compile-time error
+  static set staticJsInteropSetter(_) {} //# 53: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 54: compile-time error
+  static staticJsInteropMethod() {} //# 54: continued
+
+  external get externalInstanceGetter;
+  external set externalInstanceSetter(_);
+  external externalInstanceMethod();
+
+  external static get externalStaticGetter;
+  external static set externalStaticSetter(_);
+  external static externalStaticMethod();
+
+  @JS('a')
+  external get externalInstanceJsInteropGetter;
+
+  @JS('a')
+  external set externalInstanceJsInteropSetter(_);
+
+  @JS('a')
+  external externalInstanceJsInteropMethod();
+
+  @JS('a')
+  external static get externalStaticJsInteropGetter;
+
+  @JS('a')
+  external static set externalStaticJsInteropSetter(_);
+
+  @JS('a')
+  external static externalStaticJsInteropMethod();
+}
+
+main() {
+  if (false) {
+    topLevelSetter = topLevelField = topLevelGetter;
+    topLevelFunction();
+    externalTopLevelSetter = externalTopLevelGetter;
+    externalTopLevelFunction();
+    externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
+    externalTopLevelJsInteropFunction();
+    Class c1 = new Class.generative();
+    new Class.fact();
+    c1.instanceSetter = c1.instanceField = c1.instanceGetter;
+    c1.instanceMethod();
+    Class.staticSetter = Class.staticField = Class.staticGetter;
+    Class.staticMethod();
+    JsInteropClass c2 = new JsInteropClass.externalGenerative();
+    new JsInteropClass.externalFact();
+    new JsInteropClass.externalJsInteropGenerative();
+    new JsInteropClass.externalJsInteropFact();
+    c2.externalInstanceSetter = c2.externalInstanceGetter;
+    c2.externalInstanceMethod();
+    c2.externalInstanceJsInteropSetter = c2.externalInstanceJsInteropGetter;
+    c2.externalInstanceJsInteropMethod();
+    JsInteropClass.externalStaticSetter = JsInteropClass.externalStaticGetter;
+    JsInteropClass.externalStaticMethod();
+    JsInteropClass.externalStaticJsInteropSetter =
+        JsInteropClass.externalStaticJsInteropGetter;
+    JsInteropClass.externalStaticJsInteropMethod();
+  }
+}
diff --git a/tests/dart2js/label_test.dart b/tests/dart2js/label_test.dart
new file mode 100644
index 0000000..d31cb35
--- /dev/null
+++ b/tests/dart2js/label_test.dart
@@ -0,0 +1,62 @@
+// 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.
+
+// A break label must be declared where it's used.
+undeclaredBreakLabel1() {
+  foo: { break bar; break foo; } // //# 01: compile-time error
+}
+
+undeclaredBreakLabel2() {
+  foo: while (true) { break bar; break foo; } // //# 02: compile-time error
+}
+
+// An unlabeled break must be inside a loop or switch.
+noBreakTarget() {
+  foo: if (true) { break; break foo; } // //# 03: compile-time error
+}
+
+// A continue label must be declared where it's used.
+undeclaredContinueLabel() {
+  foo: for (;;) { continue bar; break foo; } // //# 04: compile-time error
+}
+
+// An unlabeled continue must be inside a loop.
+noContinueTarget() {
+  foo: if (true) continue; else break foo; // //# 05: compile-time error
+}
+
+// A continue label must point to a continue-able statement.
+wrongContinueLabel() {
+  foo: if (true) continue foo; // //# 06: compile-time error
+}
+
+// Labels are not captured by closures.
+noncaptureLabel() {
+  foo: { //                   //# 07: compile-time error
+    (() { break foo; })(); // //# 07: continued
+    break foo; //             //# 07: continued
+  } //                        //# 07: continued
+}
+
+// Implicit break targets are not captured by closures.
+noncaptureBreak() {
+  while(true) (() { break; })(); // //# 08: compile-time error
+}
+
+// Implicit continue targets are not captured by closures.
+noncaptureContinue() {
+  while(true) (() { continue; })(); // //# 09: compile-time error
+}
+
+main() {
+  undeclaredBreakLabel1();
+  undeclaredBreakLabel2();
+  noBreakTarget();
+  undeclaredContinueLabel();
+  noContinueTarget();
+  wrongContinueLabel();
+  noncaptureLabel();
+  noncaptureBreak();
+  noncaptureContinue();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals1_test.dart b/tests/dart2js/lax_runtime_type_closure_equals1_test.dart
new file mode 100644
index 0000000..8f9836f
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals1_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  local1a() {}
+
+  local1b() {}
+
+  local2(int i, String s) => i;
+
+  Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+  Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+  new Class();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals2_test.dart b/tests/dart2js/lax_runtime_type_closure_equals2_test.dart
new file mode 100644
index 0000000..56afe25
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals2_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  T local1a<T>() => null;
+
+  T local1b<T>() => null;
+
+  T local2<T>(T t, String s) => t;
+
+  Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+  Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+  new Class();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals3_test.dart b/tests/dart2js/lax_runtime_type_closure_equals3_test.dart
new file mode 100644
index 0000000..673211e
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals3_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+String method() => null;
+
+class Class1<T> {
+  Class1();
+
+  method() {
+    T local1a() => null;
+
+    T local1b() => null;
+
+    T local2(T t, String s) => t;
+
+    Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+    Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+    Expect.isFalse(local1a.runtimeType == method.runtimeType);
+  }
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  new Class1<int>().method();
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals4_test.dart b/tests/dart2js/lax_runtime_type_closure_equals4_test.dart
new file mode 100644
index 0000000..73b72b3
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals4_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1<T> {
+  Class1();
+
+  method1a() => null;
+
+  method1b() => null;
+
+  method2(t, s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals5_test.dart b/tests/dart2js/lax_runtime_type_closure_equals5_test.dart
new file mode 100644
index 0000000..ecad991
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals5_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1<T> {
+  Class1();
+
+  T method1a() => null;
+
+  T method1b() => null;
+
+  T method2(T t, String s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals6_test.dart b/tests/dart2js/lax_runtime_type_closure_equals6_test.dart
new file mode 100644
index 0000000..23641eb
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals6_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+method1a() => null;
+
+method1b() => null;
+
+method2(t, s) => t;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
+  Expect.isFalse(method1a.runtimeType == method2.runtimeType);
+  new Class<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals7_test.dart b/tests/dart2js/lax_runtime_type_closure_equals7_test.dart
new file mode 100644
index 0000000..129dcca
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals7_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+T method1a<T>() => null;
+
+T method1b<T>() => null;
+
+T method2<T>(T t, String s) => t;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
+  Expect.isFalse(method1a.runtimeType == method2.runtimeType);
+  new Class<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_equals8_test.dart b/tests/dart2js/lax_runtime_type_closure_equals8_test.dart
new file mode 100644
index 0000000..7a1142d
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_equals8_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1<S> {
+  Class1();
+
+  T method1a<T>() => null;
+
+  T method1b<T>() => null;
+
+  T method2<T>(T t, String s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_to_string3_test.dart b/tests/dart2js/lax_runtime_type_closure_to_string3_test.dart
new file mode 100644
index 0000000..1d244c0
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_to_string3_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string --experiment-new-rti
+
+import 'package:expect/expect.dart';
+
+class Class1<T> {
+  Class1();
+
+  T method() => null;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1<int> cls1 = new Class1<int>();
+  Expect.equals("() => erased", cls1.method.runtimeType.toString());
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_to_string4_test.dart b/tests/dart2js/lax_runtime_type_closure_to_string4_test.dart
new file mode 100644
index 0000000..c95cf29
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_to_string4_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  Class1();
+
+  T method<T>() => null;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1 cls1 = new Class1();
+  Expect.equals("<T1>() => T1", cls1.method.runtimeType.toString());
+  new Class2<int>();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_to_string5_test.dart b/tests/dart2js/lax_runtime_type_closure_to_string5_test.dart
new file mode 100644
index 0000000..cd87fa4
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_to_string5_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+method1() {}
+
+method2(int i) => i;
+
+main() {
+  Expect.equals("() => dynamic", '${method1.runtimeType}');
+  method2(0);
+  new Class();
+}
diff --git a/tests/dart2js/lax_runtime_type_closure_to_string6_test.dart b/tests/dart2js/lax_runtime_type_closure_to_string6_test.dart
new file mode 100644
index 0000000..899a217
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_closure_to_string6_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+method1<T>() {}
+
+method2<T>(t) => t;
+
+main() {
+  Expect.equals("<T1>() => dynamic", '${method1.runtimeType}');
+  method2(0);
+  new Class();
+}
diff --git a/tests/dart2js/lax_runtime_type_equals1_test.dart b/tests/dart2js/lax_runtime_type_equals1_test.dart
new file mode 100644
index 0000000..6ef574d
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_equals1_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return runtimeType == other.runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/lax_runtime_type_equals2_test.dart b/tests/dart2js/lax_runtime_type_equals2_test.dart
new file mode 100644
index 0000000..0883581
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_equals2_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return other.runtimeType == runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/lax_runtime_type_equals3_test.dart b/tests/dart2js/lax_runtime_type_equals3_test.dart
new file mode 100644
index 0000000..c9911a5
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_equals3_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return runtimeType == other?.runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/lax_runtime_type_equals4_test.dart b/tests/dart2js/lax_runtime_type_equals4_test.dart
new file mode 100644
index 0000000..bf77141
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_equals4_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return other?.runtimeType == runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/lax_runtime_type_instantiate_to_string_test.dart b/tests/dart2js/lax_runtime_type_instantiate_to_string_test.dart
new file mode 100644
index 0000000..26ba4e8
--- /dev/null
+++ b/tests/dart2js/lax_runtime_type_instantiate_to_string_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string
+
+import 'package:expect/expect.dart';
+
+main() {
+  T id<T>(T t) => t;
+  int Function(int) x = id;
+  var toString = "${x.runtimeType}";
+  if ('$Object' == 'Object') {
+    // `true` if non-minified.
+    // The signature of `id` is not otherwise needed so the instantiation
+    // wrapper doesn't have a function type.
+    Expect.equals("Instantiation1<dynamic>", toString);
+  }
+  print(toString);
+}
diff --git a/tests/dart2js/list_factory_test.dart b/tests/dart2js/list_factory_test.dart
new file mode 100644
index 0000000..b58c925
--- /dev/null
+++ b/tests/dart2js/list_factory_test.dart
@@ -0,0 +1,27 @@
+// 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 "package:expect/expect.dart";
+
+main() {
+  var a = new List(4);
+  Expect.equals(4, a.length);
+  a[0] = 42;
+  a[1] = 43;
+  a[2] = 44;
+  a[3] = 45;
+  for (int i = 0; i < a.length; i++) {
+    Expect.equals(42 + i, a[i]);
+  }
+
+  a = new List();
+  a.add(42);
+  a.add(43);
+  a.add(44);
+  a.add(45);
+  Expect.equals(4, a.length);
+  for (int i = 0; i < a.length; i++) {
+    Expect.equals(42 + i, a[i]);
+  }
+}
diff --git a/tests/dart2js/literal_string_juxtaposition_test.dart b/tests/dart2js/literal_string_juxtaposition_test.dart
new file mode 100644
index 0000000..e30bce9
--- /dev/null
+++ b/tests/dart2js/literal_string_juxtaposition_test.dart
@@ -0,0 +1,116 @@
+// 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.
+
+// Note: This test relies on LF line endings in the source file.
+
+import "package:expect/expect.dart";
+
+main() {
+  {
+    // Generates identical compile time constants.
+    var s1 = "abcdefgh";
+    var s2 = "abcd" "efgh";
+    var s3 = "ab" "cd" "ef" "gh";
+    var s4 = "a" "b" "c" "d" "e" "f" "g" "h";
+    var s5 = "a" 'b' r"c" r'd' """e""" '''f''' r"""g""" r'''h''';
+    Expect.isTrue(identical(s1, s2));
+    Expect.isTrue(identical(s1, s3));
+    Expect.isTrue(identical(s1, s4));
+    Expect.isTrue(identical(s1, s5));
+  }
+  {
+    // Separating whitespace isn't necessary for the tokenizer.
+    var s1 = "abcdefgh";
+    var s2 = "abcd" "efgh";
+    var s3 = "ab" "cd" "ef" "gh";
+    var s4 = "a" "b" "c" "d" "e" "f" "g" "h";
+    var s5 = "a" 'b' r"c" r'd' """e""" '''f''' r"""g""" r'''h''';
+    Expect.isTrue(identical(s1, s2));
+    Expect.isTrue(identical(s1, s3));
+    Expect.isTrue(identical(s1, s4));
+    Expect.isTrue(identical(s1, s5));
+    // "a""""""b""" should be tokenized as "a" """""b""", aka. "a" '""b'.
+    Expect.isTrue(identical('a""b', "a" """""b"""));
+    // """a""""""""b""" is 'a' '""b'.
+    Expect.isTrue(identical('a""b', """a""" """""b"""));
+    // Raw strings.
+    Expect.isTrue(identical('ab', "a" r"b"));
+    Expect.isTrue(identical('ab', r"a" "b"));
+    Expect.isTrue(identical('ab', r"a" r"b"));
+  }
+
+  // Newlines are just whitespace.
+  var ms1 = "abc"
+      "def"
+      "ghi"
+      "jkl";
+  Expect.isTrue(identical("abcdefghijkl", ms1));
+
+  // Works with multiline strings too.
+  var ms2 = """abc
+  def"""
+      """
+  ghi
+  jkl
+  """;
+  Expect.isTrue(
+      identical("abc\n  def  ghi\n  jkl\n  ", ms2), "Multiline: $ms2");
+
+  // Binds stronger than property access (it's considered one literal).
+  Expect.equals(5, "ab" "cde".length, "Associativity");
+
+  // Check that interpolations are handled correctly.
+  {
+    var x = "foo";
+    var y = 42;
+    var z = true;
+    String e1 = "$x$y$z";
+    Expect.equals(e1, "$x" "$y$z");
+    Expect.equals(e1, "$x$y" "$z");
+    Expect.equals(e1, "$x" "$y" "$z");
+    String e2 = "-$x-$y-$z-";
+    Expect.equals(e2, "-" "$x" "-" "$y" "-" "$z" "-", "a");
+    Expect.equals(e2, "-$x" "-" "$y" "-" "$z" "-", "b");
+    Expect.equals(e2, "-" "$x-" "$y" "-" "$z" "-", "c");
+    Expect.equals(e2, "-" "$x" "-$y" "-" "$z" "-", "d");
+    Expect.equals(e2, "-" "$x" "-" "$y-" "$z" "-", "e");
+    Expect.equals(e2, "-" "$x" "-" "$y" "-$z" "-", "f");
+    Expect.equals(e2, "-" "$x" "-" "$y" "-" "$z-", "g");
+    Expect.equals(e2, "-" "$x-$y" "-" "$z" "-", "h");
+    Expect.equals(e2, "-" "$x-$y-$z" "-", "i");
+
+    Expect.equals("-$x-$y-", "-" "$x" "-" "$y" "-");
+    Expect.equals("-$x-$y", "-" "$x" "-" "$y");
+    Expect.equals("-$x$y-", "-" "$x" "$y" "-");
+    Expect.equals("$x-$y-", "$x" "-" "$y" "-");
+
+    Expect.equals("$x$y", "$x" "$y");
+    Expect.equals("$x$y", "$x" "" "$y");
+    Expect.equals("$x$y", "$x" "" "" "$y");
+    Expect.equals("$x-$y", "$x" "-" "$y");
+    Expect.equals("$x-$y", "$x" "-" "" "$y");
+    Expect.equals("$x-$y", "$x" "" "-" "$y");
+    Expect.equals("$x-$y", "$x" "" "-" "" "$y");
+
+    Expect.equals("$x--$y", "$x" "-" "-" "$y");
+    Expect.equals("$x--$y", "$x" "-" "-" "" "$y");
+    Expect.equals("$x--$y", "$x" "-" "" "-" "$y");
+    Expect.equals("$x--$y", "$x" "" "-" "-" "$y");
+
+    Expect.equals("$x---$y", "$x" "-" "-" "-" "$y");
+    Expect.equals("$x---", "$x" "-" "-" "-");
+    Expect.equals("---$y", "-" "-" "-" "$y");
+
+    Expect.equals("$x-$y-$z", "${'$x' '-' '$y'}" "-" "$z");
+
+    Expect.equals(
+        r"-foo-42-true-", r"-" "$x" r"""-""" """$y""" r'-' '$z' r'''-''', "j");
+    Expect.equals(
+        r"-$x-42-true-", r"-" r"$x" r"""-""" """$y""" r'-' '$z' r'''-''', "k");
+    Expect.equals(
+        r"-foo-$y-true-", r"-" "$x" r"""-""" r"""$y""" r'-' '$z' r'''-''', "l");
+    Expect.equals(
+        r"-foo-42-$z-", r"-" "$x" r"""-""" """$y""" r'-' r'$z' r'''-''', "m");
+  }
+}
diff --git a/tests/dart2js/literals_test.dart b/tests/dart2js/literals_test.dart
new file mode 100644
index 0000000..0de857c
--- /dev/null
+++ b/tests/dart2js/literals_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+void main() {
+  print(3 + 4 + 5);
+  print(3.0 + 4.0 + 5.0);
+  print("fisk" " " "hest");
+  print(true);
+  print(false);
+}
diff --git a/tests/dart2js/local_function_call2_test.dart b/tests/dart2js/local_function_call2_test.dart
new file mode 100644
index 0000000..3199e66
--- /dev/null
+++ b/tests/dart2js/local_function_call2_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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.
+
+// Regression test for issue 31333.
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.throws(() => method() + 42, (e) => e is NoSuchMethodError);
+}
+
+method() {
+  var local = ({foo}) => 42;
+  local(foo: 1).isEven;
+  // Global type inference wrongfully refines `local` to have type JSInt.
+  return local;
+}
diff --git a/tests/dart2js/local_function_call_test.dart b/tests/dart2js/local_function_call_test.dart
new file mode 100644
index 0000000..8075492
--- /dev/null
+++ b/tests/dart2js/local_function_call_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Test that global type inference computes the correct type for .call on
+// a closure.
+
+import "package:expect/expect.dart";
+
+main() {
+  var f = (int n) => n + 1;
+  f.call(0);
+  Expect.equals(true, f.toString().startsWith("Closure"));
+}
diff --git a/tests/dart2js/local_function_generic_strong_test.dart b/tests/dart2js/local_function_generic_strong_test.dart
new file mode 100644
index 0000000..b622a6a
--- /dev/null
+++ b/tests/dart2js/local_function_generic_strong_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+method1() {
+  T local<T>(T t) => t;
+  return local;
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is S Function<S>(S);
+
+main() {
+  Expect.isTrue(test(method1()));
+}
diff --git a/tests/dart2js/local_function_signatures_strong_test.dart b/tests/dart2js/local_function_signatures_strong_test.dart
new file mode 100644
index 0000000..f1df515
--- /dev/null
+++ b/tests/dart2js/local_function_signatures_strong_test.dart
@@ -0,0 +1,114 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  method1() {
+    num local<T>(num n) => null;
+    return local;
+  }
+
+  method2() {
+    num local<T>(int n) => null;
+    return local;
+  }
+
+  method3() {
+    int local<T>(num n) => null;
+    return local;
+  }
+}
+
+class Class2 {
+  method4<T>() {
+    num local(T n) => null;
+    return local;
+  }
+}
+
+class Class3 {
+  method5<T>() {
+    T local(num n) => null;
+    return local;
+  }
+}
+
+class Class4 {
+  method6<T>() {
+    num local(num n, T t) => null;
+    return local;
+  }
+}
+
+method7<T>() {
+  num local(T n) => null;
+  return local;
+}
+
+method8<T>() {
+  T local(num n) => null;
+  return local;
+}
+
+method9<T>() {
+  num local(num n, T t) => null;
+  return local;
+}
+
+method10() {
+  num local<T>(T n) => null;
+  return local;
+}
+
+method11() {
+  T local<T>(num n) => null;
+  return local;
+}
+
+method12() {
+  num local<T>(num n, T t) => null;
+  return local;
+}
+
+num Function(num) //# 01: ok
+    method13() {
+  num local<T>(num n) => null;
+  return local;
+}
+
+num Function(num) //# 01: continued
+    method14() {
+  num local<T>(T n) => null;
+  return local;
+}
+
+num Function(num) //# 01: continued
+    method15() {
+  T local<T>(num n) => null;
+  return local;
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is num Function(num);
+
+main() {
+  Expect.isFalse(test(new Class1().method1()));
+  Expect.isFalse(test(new Class1().method2()));
+  Expect.isFalse(test(new Class1().method3()));
+  Expect.isTrue(test(new Class2().method4<num>()));
+  Expect.isTrue(test(new Class3().method5<num>()));
+  Expect.isFalse(test(new Class4().method6<num>()));
+  Expect.isTrue(test(method7<num>()));
+  Expect.isTrue(test(method8<num>()));
+  Expect.isFalse(test(method9()));
+  Expect.isFalse(test(method10()));
+  Expect.isFalse(test(method11()));
+  Expect.isFalse(test(method12()));
+  Expect.isTrue(test(method13())); //# 01: continued
+  Expect.isTrue(test(method14())); //# 01: continued
+  Expect.isTrue(test(method15())); //# 01: continued
+}
diff --git a/tests/dart2js/local_function_signatures_test.dart b/tests/dart2js/local_function_signatures_test.dart
new file mode 100644
index 0000000..11bfb83
--- /dev/null
+++ b/tests/dart2js/local_function_signatures_test.dart
@@ -0,0 +1,57 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  method1() {
+    num local(num n) => null;
+    return local;
+  }
+
+  method2() {
+    num local(int n) => null;
+    return local;
+  }
+
+  method3() {
+    Object local(num n) => null;
+    return local;
+  }
+}
+
+class Class2<T> {
+  method4() {
+    num local(T n) => null;
+    return local;
+  }
+}
+
+class Class3<T> {
+  method5() {
+    T local(num n) => null;
+    return local;
+  }
+}
+
+class Class4<T> {
+  method6() {
+    num local(num n, T t) => null;
+    return local;
+  }
+}
+
+@pragma('dart2js:noInline')
+test(o) => o is num Function(num);
+
+main() {
+  Expect.isTrue(test(new Class1().method1()));
+  Expect.isFalse(test(new Class1().method2()));
+  Expect.isFalse(test(new Class1().method3()));
+  Expect.isTrue(test(new Class2<num>().method4()));
+  Expect.isTrue(test(new Class3<num>().method5()));
+  Expect.isFalse(test(new Class4<num>().method6()));
+}
diff --git a/tests/dart2js/local_signature_test.dart b/tests/dart2js/local_signature_test.dart
new file mode 100644
index 0000000..eac7ab0
--- /dev/null
+++ b/tests/dart2js/local_signature_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+test1(o) => o is Function(int);
+
+@pragma('dart2js:noInline')
+test2(o) => o is Function<T>(T);
+
+class C<S> {
+  @pragma('dart2js:noInline')
+  test(bool expected) {
+    local1(int i) {}
+    local2<T>(T t) {}
+    local3(S s) {}
+
+    Expect.isTrue(test1(local1));
+    Expect.isFalse(test2(local1));
+
+    Expect.isFalse(test1(local2));
+    Expect.isTrue(test2(local2));
+
+    Expect.equals(expected, test1(local3));
+    Expect.isFalse(test2(local3));
+  }
+}
+
+main() {
+  new C<int>().test(true);
+  new C<double>().test(false);
+}
diff --git a/tests/dart2js/locals_test.dart b/tests/dart2js/locals_test.dart
new file mode 100644
index 0000000..3169124
--- /dev/null
+++ b/tests/dart2js/locals_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+void main() {
+  dynamic hello = 'Hello';
+  dynamic world = 'world';
+  dynamic s = 0;
+  s = world;
+  hello = 'Greetings';
+  print("$hello, $world!");
+}
diff --git a/tests/dart2js/logical_and_test.dart b/tests/dart2js/logical_and_test.dart
new file mode 100644
index 0000000..6337969
--- /dev/null
+++ b/tests/dart2js/logical_and_test.dart
@@ -0,0 +1,59 @@
+// 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 "package:expect/expect.dart";
+
+void and1() {
+  var b = true;
+  b = b && b;
+  Expect.equals(true, b);
+}
+
+void and2() {
+  var b = false;
+  b = b && b;
+  Expect.equals(false, b);
+}
+
+void and3() {
+  var b = true;
+  b = b && false;
+  Expect.equals(false, b);
+}
+
+void and4() {
+  var b = true;
+  b = b && true;
+  Expect.equals(true, b);
+}
+
+void and5() {
+  if (true && false) Expect.fail('unreachable');
+}
+
+void and6() {
+  var b = true;
+  if (true && true) b = false;
+  Expect.equals(false, b);
+}
+
+void and7() {
+  var b = false;
+  if (true && false) {
+    b = false;
+  } else {
+    b = true;
+  }
+  Expect.equals(true, b);
+}
+
+void main() {
+  and1();
+  and2();
+  and3();
+  and4();
+  and5();
+  and6();
+  and7();
+}
diff --git a/tests/dart2js/logical_or_test.dart b/tests/dart2js/logical_or_test.dart
new file mode 100644
index 0000000..b5923f0
--- /dev/null
+++ b/tests/dart2js/logical_or_test.dart
@@ -0,0 +1,61 @@
+// 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 "package:expect/expect.dart";
+
+void or1() {
+  var b = true;
+  b = b || b;
+  Expect.equals(true, b);
+}
+
+void or2() {
+  var b = false;
+  b = b || b;
+  Expect.equals(false, b);
+}
+
+void or3() {
+  var b = true;
+  b = b || false;
+  Expect.equals(true, b);
+}
+
+void or4() {
+  var b = true;
+  b = b || true;
+  Expect.equals(true, b);
+}
+
+void or5() {
+  if (true || false) {} else {
+    Expect.fail('unreachable');
+  }
+}
+
+void or6() {
+  var b = true;
+  if (true || true) b = false;
+  Expect.equals(false, b);
+}
+
+void or7() {
+  var b = false;
+  if (true || false) {
+    b = true;
+  } else {
+    b = false;
+  }
+  Expect.equals(true, b);
+}
+
+void main() {
+  or1();
+  or2();
+  or3();
+  or4();
+  or5();
+  or6();
+  or7();
+}
diff --git a/tests/dart2js/loop_if_phi_test.dart b/tests/dart2js/loop_if_phi_test.dart
new file mode 100644
index 0000000..044c40a
--- /dev/null
+++ b/tests/dart2js/loop_if_phi_test.dart
@@ -0,0 +1,15 @@
+// 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 "package:expect/expect.dart";
+
+void main() {
+  var prev = -1;
+  for (int i = 0; i < 2; i++) {
+    if (prev != -1) {
+      Expect.equals(0, prev);
+    }
+    prev = i;
+  }
+}
diff --git a/tests/dart2js/many_constants_test.dart b/tests/dart2js/many_constants_test.dart
new file mode 100644
index 0000000..f28e2ff
--- /dev/null
+++ b/tests/dart2js/many_constants_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2015, 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.
+
+// This program has many similar constants that should all have distinct
+// identities. They are sufficiently similar to have name collisions and need
+// ordering by constant value.
+
+import "package:expect/expect.dart";
+
+enum E { A, B, C, D }
+
+class Z {
+  final a, b, c, d, e, f;
+  const Z({this.a: 1, this.b: 1, this.c: 1, this.d: 1, this.e: 1, this.f: 1});
+}
+
+const c1 = const {};
+const c2 = const <int, int>{};
+const c3 = const <dynamic, int>{};
+const c4 = const <int, dynamic>{};
+const l1 = const [];
+const l2 = const <int>[];
+const l3 = const <String>[];
+const l4 = const <num>[];
+
+const ll1 = const [1, 2, 3, 4, 5, 6, 7];
+const ll2 = const [1, 8, 3, 4, 5, 6, 7];
+const ll3 = const [1, 2, 8, 4, 5, 6, 7];
+const ll4 = const [1, 2, 3, 4, 8, 6, 7];
+
+const m1 = const <dynamic, dynamic>{1: 1, 2: 2};
+const m2 = const <dynamic, dynamic>{1: 2, 2: 1};
+const m3 = const <dynamic, dynamic>{1: 1, 2: 1};
+const m4 = const <dynamic, dynamic>{1: 2, 2: 2};
+const m5 = const <dynamic, dynamic>{2: 1, 1: 2};
+const m6 = const <dynamic, dynamic>{2: 2, 1: 1};
+const m7 = const <dynamic, dynamic>{2: 1, 1: 1};
+const m8 = const <dynamic, dynamic>{2: 2, 1: 2};
+const m9 = const <int, int>{1: 1, 2: 2};
+const mA = const <int, int>{1: 2, 2: 1};
+const mB = const <int, int>{1: 1, 2: 1};
+const mC = const <int, int>{1: 2, 2: 2};
+
+const mE1 = const {E.A: E.B};
+const mE2 = const {E.A: E.C};
+const mE3 = const {E.A: 0, E.B: 0};
+const mE4 = const {E.A: 0, E.C: 0};
+const mE5 = const {E.A: 0, E.B: 0, E.C: 4};
+const mE6 = const {E.A: 0, E.B: 0, E.C: 2};
+const mE7 = const {E.A: 0, E.B: 0, E.C: 3};
+const mE8 = const {E.A: 0, E.B: 0, E.C: 1};
+
+const z1 = const Z(f: 3);
+const z2 = const Z(f: 2);
+const z3 = const Z(f: 1);
+const z4 = const Z(e: 2);
+const z5 = const Z(d: 3);
+const z6 = const Z(d: 2);
+
+makeAll() => {
+      'E.A': E.A,
+      'E.B': E.B,
+      'E.C': E.C,
+      'E.D': E.D,
+      'c1': c1,
+      'c2': c2,
+      'c3': c3,
+      'c4': c4,
+      'l1': l1,
+      'l2': l2,
+      'l3': l3,
+      'l4': l4,
+      'll1': ll1,
+      'll2': ll2,
+      'll3': ll3,
+      'l4': ll4,
+      'm1': m1,
+      'm2': m2,
+      'm3': m3,
+      'm4': m4,
+      'm5': m5,
+      'm6': m6,
+      'm7': m7,
+      'm8': m8,
+      'm9': m9,
+      'mA': mA,
+      'mB': mB,
+      'mC': mC,
+      'mE1': mE1,
+      'mE2': mE2,
+      'mE3': mE3,
+      'mE4': mE4,
+      'mE5': mE5,
+      'mE6': mE6,
+      'mE7': mE7,
+      'mE8': mE8,
+      'z1': z1,
+      'z2': z2,
+      'z3': z3,
+      'z4': z4,
+      'z5': z5,
+      'z6': z6,
+    };
+
+main() {
+  var all1 = makeAll();
+  var all2 = makeAll();
+
+  for (var name1 in all1.keys) {
+    var e1 = all1[name1];
+    for (var name2 in all2.keys) {
+      if (name1 == name2) continue;
+      var e2 = all2[name2];
+      Expect.isFalse(
+          identical(e1, e2), 'Different instances  $name1: $e1  $name2: $e2');
+    }
+  }
+}
diff --git a/tests/dart2js/many_fields_test.dart b/tests/dart2js/many_fields_test.dart
new file mode 100644
index 0000000..360ae34
--- /dev/null
+++ b/tests/dart2js/many_fields_test.dart
@@ -0,0 +1,223 @@
+// 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 "package:expect/expect.dart";
+
+// A plain class that implements many fields.
+class A {
+  var fieldA1 = 0x1;
+  var fieldA2 = 0x2;
+  var fieldA3 = 0x4;
+  var fieldA4 = 0x8;
+
+  var fieldB1 = 0x10;
+  var fieldB2 = 0x20;
+  var fieldB3 = 0x40;
+  var fieldB4 = 0x80;
+
+  var fieldC1 = 0x100;
+  var fieldC2 = 0x200;
+  var fieldC3 = 0x400;
+  var fieldC4 = 0x800;
+
+  var fieldD1 = 0x1000;
+  var fieldD2 = 0x2000;
+  var fieldD3 = 0x4000;
+  var fieldD4 = 0x8000;
+
+  var fieldXA1 = 0x1;
+  var fieldXA2 = 0x2;
+  var fieldXA3 = 0x4;
+  var fieldXA4 = 0x8;
+
+  var fieldXB1 = 0x10;
+  var fieldXB2 = 0x20;
+  var fieldXB3 = 0x40;
+  var fieldXB4 = 0x80;
+
+  var fieldXC1 = 0x1;
+  var fieldXC2 = 0x2;
+  var fieldXC3 = 0x4;
+  var fieldXC4 = 0x8;
+
+  var fieldXD1 = 0x10;
+  var fieldXD2 = 0x20;
+  var fieldXD3 = 0x40;
+  var fieldXD4 = 0x80;
+
+  var fieldYA1 = 0x1;
+  var fieldYA2 = 0x200;
+  var fieldYA3 = 0x400;
+  var fieldYA4 = 0x800;
+
+  var fieldYB1 = 0x10;
+  var fieldYB2 = 0x200;
+  var fieldYB3 = 0x400;
+  var fieldYB4 = 0x800;
+
+  var fieldYC1 = 0x100;
+  var fieldYC2 = 0x2000;
+  var fieldYC3 = 0x4000;
+  var fieldYC4 = 0x8000;
+
+  var fieldYD1 = 0x1000;
+  var fieldYD2 = 0x2000;
+  var fieldYD3 = 0x4000;
+  var fieldYD4 = 0x8000;
+}
+
+// Implementing the same fields using inheritance and a mixin.
+class B {
+  var fieldA1 = 0x0011;
+  var fieldA2 = 0x0002;
+  var fieldA3 = 0x0044;
+  var fieldA4 = 0x0008;
+
+  var fieldB1 = 0x0010;
+  var fieldB2 = 0x0220;
+  var fieldB3 = 0x0040;
+  var fieldB4 = 0x0880;
+
+  var fieldC1 = 0x0101;
+  var fieldC2 = 0x0200;
+  var fieldC3 = 0x0404;
+  var fieldC4 = 0x0810;
+
+  var fieldD1 = 0x1000;
+  var fieldD2 = 0x2204;
+  var fieldD3 = 0x4040;
+  var fieldD4 = 0x8801;
+}
+
+class C {
+  var fieldXA1 = 0x8001;
+  var fieldXA2 = 0x4002;
+  var fieldXA3 = 0x2004;
+  var fieldXA4 = 0x1008;
+
+  var fieldXB1 = 0x810;
+  var fieldXB2 = 0x420;
+  var fieldXB3 = 0x240;
+  var fieldXB4 = 0x180;
+
+  var fieldXC1 = 0x180;
+  var fieldXC2 = 0x240;
+  var fieldXC3 = 0x420;
+  var fieldXC4 = 0x810;
+
+  var fieldXD1 = 0x1008;
+  var fieldXD2 = 0x2004;
+  var fieldXD3 = 0x4002;
+  var fieldXD4 = 0x8001;
+}
+
+class D extends B with C {
+  var fieldYA1 = 0x8001;
+  var fieldYA2 = 0x4002;
+  var fieldYA3 = 0x2004;
+  var fieldYA4 = 0x0008;
+
+  var fieldYB1 = 0x810;
+  var fieldYB2 = 0x420;
+  var fieldYB3 = 0x240;
+  var fieldYB4 = 0x080;
+
+  var fieldYC1 = 0x180;
+  var fieldYC2 = 0x240;
+  var fieldYC3 = 0x420;
+  var fieldYC4 = 0x800;
+
+  var fieldYD1 = 0x1008;
+  var fieldYD2 = 0x2004;
+  var fieldYD3 = 0x4002;
+  var fieldYD4 = 0x8000;
+}
+
+// Mix in the mixin into the full implementation, shadowing some fields.
+class E extends A with C {}
+
+// Another mixin for block C.
+class F {
+  var fieldYA1 = 0x0001;
+  var fieldYA2 = 0x1022;
+  var fieldYA3 = 0x0004;
+  var fieldYA4 = 0x0088;
+
+  var fieldYB1 = 0x0410;
+  var fieldYB2 = 0x0022;
+  var fieldYB3 = 0x0040;
+  var fieldYB4 = 0x0880;
+
+  var fieldYC1 = 0x1001;
+  var fieldYC2 = 0x2200;
+  var fieldYC3 = 0x4400;
+  var fieldYC4 = 0x8800;
+
+  var fieldYD1 = 0x1108;
+  var fieldYD2 = 0x2200;
+  var fieldYD3 = 0x4044;
+  var fieldYD4 = 0x8001;
+}
+
+// Use two mixins in a single class.
+class G extends B with C, F {}
+
+bool checkFields(cls) {
+  var blockA = cls.fieldA1 ^
+      cls.fieldA2 ^
+      cls.fieldA3 ^
+      cls.fieldA4 ^
+      cls.fieldB1 ^
+      cls.fieldB2 ^
+      cls.fieldB3 ^
+      cls.fieldB4 ^
+      cls.fieldC1 ^
+      cls.fieldC2 ^
+      cls.fieldC3 ^
+      cls.fieldC4 ^
+      cls.fieldD1 ^
+      cls.fieldD2 ^
+      cls.fieldD3 ^
+      cls.fieldD4;
+  var blockB = cls.fieldXA1 ^
+      cls.fieldXA2 ^
+      cls.fieldXA3 ^
+      cls.fieldXA4 ^
+      cls.fieldXB1 ^
+      cls.fieldXB2 ^
+      cls.fieldXB3 ^
+      cls.fieldXB4 ^
+      cls.fieldXC1 ^
+      cls.fieldXC2 ^
+      cls.fieldXC3 ^
+      cls.fieldXC4 ^
+      cls.fieldXD1 ^
+      cls.fieldXD2 ^
+      cls.fieldXD3 ^
+      cls.fieldXD4;
+  var blockC = cls.fieldYA1 ^
+      cls.fieldYA2 ^
+      cls.fieldYA3 ^
+      cls.fieldYA4 ^
+      cls.fieldYB1 ^
+      cls.fieldYB2 ^
+      cls.fieldYB3 ^
+      cls.fieldYB4 ^
+      cls.fieldYC1 ^
+      cls.fieldYC2 ^
+      cls.fieldYC3 ^
+      cls.fieldYC4 ^
+      cls.fieldYD1 ^
+      cls.fieldYD2 ^
+      cls.fieldYD3 ^
+      cls.fieldYD4;
+  return blockA == 0xFFFF && blockB == 0x0000 && blockC == 0x1111;
+}
+
+main() {
+  var instances = [new A(), new D(), new E(), new G()];
+  for (var instance in instances) {
+    Expect.isTrue(checkFields(instance));
+  }
+}
diff --git a/tests/dart2js/many_instantiations_test.dart b/tests/dart2js/many_instantiations_test.dart
new file mode 100644
index 0000000..9ba578a
--- /dev/null
+++ b/tests/dart2js/many_instantiations_test.dart
@@ -0,0 +1,296 @@
+// 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.
+
+// Test generic instantiation with many type arguments.
+
+import 'package:expect/expect.dart';
+
+f1<T1>(T1 t1) => '$t1';
+f2<T1, T2>(T1 t1, T2 t2) => '$t1$t2';
+f3<T1, T2, T3>(T1 t1, T2 t2, T3 t3) => '$t1$t2$t3';
+f4<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4) => '$t1$t2$t3$t4';
+f5<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) => '$t1$t2$t3$t4$t5';
+f6<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) =>
+    '$t1$t2$t3$t4$t5$t6';
+f7<T1, T2, T3, T4, T5, T6, T7>(
+        T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) =>
+    '$t1$t2$t3$t4$t5$t6$t7';
+f8<T1, T2, T3, T4, T5, T6, T7, T8>(
+        T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8';
+f9<T1, T2, T3, T4, T5, T6, T7, T8, T9>(
+        T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9';
+f10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5,
+        T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10';
+f11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11>(T1 t1, T2 t2, T3 t3, T4 t4,
+        T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11';
+f12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12>(T1 t1, T2 t2, T3 t3,
+        T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12';
+f13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13';
+f14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14';
+f15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15';
+f16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16';
+f17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16,
+        T17 t17) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16$t17';
+f18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17,
+            T18>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16,
+        T17 t17,
+        T18 t18) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16$t17$t18';
+f19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17,
+            T18, T19>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16,
+        T17 t17,
+        T18 t18,
+        T19 t19) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16$t17$t18$t19';
+f20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17,
+            T18, T19, T20>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16,
+        T17 t17,
+        T18 t18,
+        T19 t19,
+        T20 t20) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16$t17$t18$t19$t20';
+f21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17,
+            T18, T19, T20, T21>(
+        T1 t1,
+        T2 t2,
+        T3 t3,
+        T4 t4,
+        T5 t5,
+        T6 t6,
+        T7 t7,
+        T8 t8,
+        T9 t9,
+        T10 t10,
+        T11 t11,
+        T12 t12,
+        T13 t13,
+        T14 t14,
+        T15 t15,
+        T16 t16,
+        T17 t17,
+        T18 t18,
+        T19 t19,
+        T20 t20,
+        T21 t21) =>
+    '$t1$t2$t3$t4$t5$t6$t7$t8$t9$t10$t11$t12$t13$t14$t15$t16$t17$t18$t19$t20$t21';
+
+m1(Function(int) f) => f(1);
+m2(Function(int, int) f) => f(1, 2);
+m3(Function(int, int, int) f) => f(1, 2, 3);
+m4(Function(int, int, int, int) f) => f(1, 2, 3, 4);
+m5(Function(int, int, int, int, int) f) => f(1, 2, 3, 4, 5);
+m6(Function(int, int, int, int, int, int) f) => f(1, 2, 3, 4, 5, 6);
+m7(Function(int, int, int, int, int, int, int) f) => f(1, 2, 3, 4, 5, 6, 7);
+m8(Function(int, int, int, int, int, int, int, int) f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8);
+m9(Function(int, int, int, int, int, int, int, int, int) f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9);
+m10(Function(int, int, int, int, int, int, int, int, int, int) f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
+m11(Function(int, int, int, int, int, int, int, int, int, int, int) f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11);
+m12(Function(int, int, int, int, int, int, int, int, int, int, int, int) f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12);
+m13(
+        Function(
+                int, int, int, int, int, int, int, int, int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13);
+m14(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14);
+m15(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
+m16(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
+m17(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17);
+m18(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18);
+m19(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19);
+m20(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20);
+m21(
+        Function(int, int, int, int, int, int, int, int, int, int, int, int,
+                int, int, int, int, int, int, int, int, int)
+            f) =>
+    f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+        21);
+
+main() {
+  Expect.equals('1', m1(f1));
+  Expect.equals('12', m2(f2));
+  Expect.equals('123', m3(f3));
+  Expect.equals('1234', m4(f4));
+  Expect.equals('12345', m5(f5));
+  Expect.equals('123456', m6(f6));
+  Expect.equals('1234567', m7(f7));
+  Expect.equals('12345678', m8(f8));
+  Expect.equals('123456789', m9(f9));
+  Expect.equals('12345678910', m10(f10));
+  Expect.equals('1234567891011', m11(f11));
+  Expect.equals('123456789101112', m12(f12));
+  Expect.equals('12345678910111213', m13(f13));
+  Expect.equals('1234567891011121314', m14(f14));
+  Expect.equals('123456789101112131415', m15(f15));
+  Expect.equals('12345678910111213141516', m16(f16));
+  Expect.equals('1234567891011121314151617', m17(f17));
+  Expect.equals('123456789101112131415161718', m18(f18));
+  Expect.equals('12345678910111213141516171819', m19(f19));
+  Expect.equals('1234567891011121314151617181920', m20(f20));
+  Expect.equals('123456789101112131415161718192021', m21(f21)); //# 01: ok
+}
diff --git a/tests/dart2js/map_to_set_test.dart b/tests/dart2js/map_to_set_test.dart
new file mode 100644
index 0000000..1bad856
--- /dev/null
+++ b/tests/dart2js/map_to_set_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Regression test for a missing RTI dependency between Map and JsLinkedHashMap.
+
+import 'package:expect/expect.dart';
+
+main() {
+  var c = new Class<double, int>();
+  var map = c.m();
+  var set = map.keys.toSet();
+  Expect.isFalse(set is Set<String>);
+}
+
+class Class<T, S> {
+  m() {
+    return <T, S>{};
+  }
+}
diff --git a/tests/dart2js/math_lib_prefix_test.dart b/tests/dart2js/math_lib_prefix_test.dart
new file mode 100644
index 0000000..318c0cf
--- /dev/null
+++ b/tests/dart2js/math_lib_prefix_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+library math_lib_prefix_test;
+
+import "package:expect/expect.dart";
+import 'dart:math' as foo;
+
+main() {
+  Expect.equals(2.0, foo.sqrt(4));
+  Expect.equals(2.25, foo.pow(1.5, 2.0));
+
+  int i = new foo.Random().nextInt(256);
+  double d = new foo.Random().nextDouble();
+  bool b = new foo.Random().nextBool();
+}
diff --git a/tests/dart2js/math_lib_test.dart b/tests/dart2js/math_lib_test.dart
new file mode 100644
index 0000000..a8124d1
--- /dev/null
+++ b/tests/dart2js/math_lib_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+library math_lib_test;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+main() {
+  Expect.equals(2.0, sqrt(4));
+  Expect.equals(2.25, pow(1.5, 2.0));
+
+  int i = new Random().nextInt(256);
+  double d = new Random().nextDouble();
+  bool b = new Random().nextBool();
+}
diff --git a/tests/dart2js/member_namespace_test.dart b/tests/dart2js/member_namespace_test.dart
new file mode 100644
index 0000000..ff65d20
--- /dev/null
+++ b/tests/dart2js/member_namespace_test.dart
@@ -0,0 +1,19 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static int a;
+  A();
+  static foo() {
+    // Make sure 'A' is not resolved to the constructor.
+    return A.a;
+  }
+}
+
+main() {
+  A.a = 42;
+  Expect.equals(42, A.foo());
+}
diff --git a/tests/dart2js/method_signatures_strong_test.dart b/tests/dart2js/method_signatures_strong_test.dart
new file mode 100644
index 0000000..3e3f256
--- /dev/null
+++ b/tests/dart2js/method_signatures_strong_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  num method1<T>(num n) => null;
+
+  num method2<T>(int n) => null;
+
+  int method3<T>(num n) => null;
+}
+
+class Class2 {
+  num method4<T>(T n) => null;
+}
+
+class Class3 {
+  T method5<T>(num n) => null;
+}
+
+class Class4 {
+  num method6<T>(num n, T t) => null;
+}
+
+num method7<T>(T n) => null;
+
+T method8<T>(num n) => null;
+
+num method9<T>(num n, T t) => null;
+
+@pragma('dart2js:noInline')
+test(o) => o is num Function(num);
+
+forceInstantiation(num Function(num) f) => f;
+
+main() {
+  Expect.isFalse(test(new Class1().method1));
+  Expect.isFalse(test(new Class1().method2));
+  Expect.isFalse(test(new Class1().method3));
+  Expect.isTrue(test(forceInstantiation(new Class2().method4)));
+  Expect.isTrue(test(forceInstantiation(new Class3().method5)));
+  Expect.isFalse(test(new Class4().method6));
+  Expect.isTrue(test(forceInstantiation(method7)));
+  Expect.isTrue(test(forceInstantiation(method8)));
+  Expect.isFalse(test(method9));
+}
diff --git a/tests/dart2js/method_signatures_test.dart b/tests/dart2js/method_signatures_test.dart
new file mode 100644
index 0000000..79d0c7f
--- /dev/null
+++ b/tests/dart2js/method_signatures_test.dart
@@ -0,0 +1,48 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  num method1(num n) => null;
+
+  num method2(int n) => null;
+
+  Object method3(num n) => null;
+}
+
+class Class2<T> {
+  num method4(T n) => null;
+}
+
+class Class3<T> {
+  T method5(num n) => null;
+}
+
+class Class4<T> {
+  num method6(num n, T t) => null;
+}
+
+num method7(num n) => null;
+
+num method8(int n) => null;
+
+Object method9(num n) => null;
+
+@pragma('dart2js:noInline')
+test(o) => o is num Function(num);
+
+main() {
+  Expect.isTrue(test(new Class1().method1));
+  Expect.isFalse(test(new Class1().method2));
+  Expect.isFalse(test(new Class1().method3));
+  Expect.isTrue(test(new Class2<num>().method4));
+  Expect.isTrue(test(new Class3<num>().method5));
+  Expect.isFalse(test(new Class4<num>().method6));
+  Expect.isTrue(test(method7));
+  Expect.isFalse(test(method8));
+  Expect.isFalse(test(method9));
+}
diff --git a/tests/dart2js/minus_zero2_test.dart b/tests/dart2js/minus_zero2_test.dart
new file mode 100644
index 0000000..02cf9f0
--- /dev/null
+++ b/tests/dart2js/minus_zero2_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 17210.
+
+import "package:expect/expect.dart";
+
+void main() {
+  // Dart2js must use "-0.0" as if it was 0. In particular, it must do its
+  // range-analysis correctly.
+  var list = [1, 2, 3];
+  if (new DateTime.now().millisecondsSinceEpoch == 42) list[1] = 4;
+  int sum = 0;
+  for (num i = -0.0; i < list.length; i++) {
+    sum += list[i];
+  }
+  Expect.equals(6, sum);
+}
diff --git a/tests/dart2js/minus_zero_test.dart b/tests/dart2js/minus_zero_test.dart
new file mode 100644
index 0000000..bc3c0b6
--- /dev/null
+++ b/tests/dart2js/minus_zero_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 17210.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+num minusZero() => -0;
+
+void main() {
+  // Dart2js must not infer that the type-intersection of int and -0.0 is empty.
+  // It must get an interceptor for the addition (`i += 3`), or use the native
+  // JS + operation.
+  int i = minusZero();
+  i += 3;
+  Expect.equals(3, i);
+}
diff --git a/tests/dart2js/mixin_subtype_test.dart b/tests/dart2js/mixin_subtype_test.dart
new file mode 100644
index 0000000..287776c
--- /dev/null
+++ b/tests/dart2js/mixin_subtype_test.dart
@@ -0,0 +1,53 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+class B {}
+
+class I {}
+
+class J {}
+
+mixin M1 on A, B implements I, J {}
+
+class M2 implements A, B, I, J {}
+
+class M3 implements A, B, I, J {}
+
+class M4 implements A, B, I, J {}
+
+class M5 implements A, B, I, J {}
+
+class C implements A, B {}
+
+class D1 = C with M1;
+
+class D2 = C with M2;
+
+class D3 = C with M3;
+
+class D4 extends C with M4 {}
+
+class D5 extends C with M5 {}
+
+class E5 extends D5 {}
+
+@pragma('dart2js:noInline')
+test(o) {}
+
+main() {
+  test(new M3());
+  test(new D2());
+  test(new D4());
+  test(new E5());
+  Expect.subtype<D1, M1>();
+  Expect.subtype<D2, M2>();
+  Expect.subtype<D3, M3>();
+  Expect.subtype<D4, M4>();
+  Expect.subtype<D5, M5>();
+  Expect.subtype<E5, M5>();
+}
diff --git a/tests/dart2js/mixin_type_variable_test.dart b/tests/dart2js/mixin_type_variable_test.dart
new file mode 100644
index 0000000..750e58d
--- /dev/null
+++ b/tests/dart2js/mixin_type_variable_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2017, 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.
+
+abstract class Bar<C> {
+  final List<C> _one = new List<C>();
+
+  final bool _two = Foo is C;
+}
+
+class Foo extends Object with Bar {}
+
+abstract class A<E> {}
+
+abstract class B<E> extends Object with A<E> {}
+
+class C extends B<int> {
+  final String _string;
+  C(this._string);
+}
+
+abstract class D<T> {}
+
+abstract class E<T> = Object with D<T>;
+
+class F extends E<int> {
+  final String _string;
+  F(this._string);
+}
+
+main() {
+  new Foo();
+  new C('e');
+  new F('e');
+}
diff --git a/tests/dart2js/multi_global_def_single_instantiation_test.dart b/tests/dart2js/multi_global_def_single_instantiation_test.dart
new file mode 100644
index 0000000..f118b61
--- /dev/null
+++ b/tests/dart2js/multi_global_def_single_instantiation_test.dart
@@ -0,0 +1,6 @@
+// Copyright (c) 2016, 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.
+
+var y, w, z, x = [], q, r = [];
+main() => [x, r];
diff --git a/tests/dart2js/named_mixin_runtime_type_test.dart b/tests/dart2js/named_mixin_runtime_type_test.dart
new file mode 100644
index 0000000..9059803
--- /dev/null
+++ b/tests/dart2js/named_mixin_runtime_type_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+abstract class A {}
+
+abstract class B {}
+
+class C = B with A;
+
+@pragma('dart2js:noInline')
+test(o) => o.runtimeType;
+
+main() {
+  Expect.equals(C, test(new C()));
+}
diff --git a/tests/dart2js/named_parameter_for_static_test.dart b/tests/dart2js/named_parameter_for_static_test.dart
new file mode 100644
index 0000000..4a4f817
--- /dev/null
+++ b/tests/dart2js/named_parameter_for_static_test.dart
@@ -0,0 +1,79 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+oneOptionalArgument(a, {b}) {
+  Expect.equals(1, a);
+  Expect.equals(2, b);
+}
+
+twoOptionalArguments({a, b}) {
+  Expect.equals(1, a);
+  Expect.equals(2, b);
+}
+
+main() {
+  twoOptionalArguments(a: 1, b: 2);
+  twoOptionalArguments(b: 2, a: 1);
+
+  oneOptionalArgument(1, b: 2);
+
+  new A.twoOptionalArguments(a: 1, b: 2);
+  new A.twoOptionalArguments(b: 2, a: 1);
+
+  new A.oneOptionalArgument(1, b: 2);
+
+  new B.one();
+  new B.two();
+  new B.three();
+
+  new B().B_one();
+  new B().B_two();
+  new B().B_three();
+}
+
+class A {
+  A.oneOptionalArgument(a, {b}) {
+    Expect.equals(1, a);
+    Expect.equals(2, b);
+  }
+
+  A.twoOptionalArguments({a, b}) {
+    Expect.equals(1, a);
+    Expect.equals(2, b);
+  }
+
+  A();
+
+  // A named constructor now conflicts with a method of the same name.
+  oneOptArg(a, {b}) {
+    Expect.equals(1, a);
+    Expect.equals(2, b);
+  }
+
+  twoOptArgs({a, b}) {
+    Expect.equals(1, a);
+    Expect.equals(2, b);
+  }
+}
+
+class B extends A {
+  B.one() : super.twoOptionalArguments(a: 1, b: 2);
+  B.two() : super.twoOptionalArguments(b: 2, a: 1);
+  B.three() : super.oneOptionalArgument(1, b: 2);
+
+  B();
+  B_one() {
+    super.twoOptArgs(a: 1, b: 2);
+  }
+
+  B_two() {
+    super.twoOptArgs(b: 2, a: 1);
+  }
+
+  B_three() {
+    super.oneOptArg(1, b: 2);
+  }
+}
diff --git a/tests/dart2js/named_parameter_test.dart b/tests/dart2js/named_parameter_test.dart
new file mode 100644
index 0000000..a5f0cf8
--- /dev/null
+++ b/tests/dart2js/named_parameter_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo({a, b}) {
+    Expect.equals(0, a);
+    Expect.equals(1, b);
+  }
+}
+
+main() {
+  A a = new A();
+  a.foo(a: 0, b: 1);
+  a.foo(b: 1, a: 0);
+}
diff --git a/tests/dart2js/nan_negate_test.dart b/tests/dart2js/nan_negate_test.dart
new file mode 100644
index 0000000..06adfd1
--- /dev/null
+++ b/tests/dart2js/nan_negate_test.dart
@@ -0,0 +1,119 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Don't convert !(a op b) to (a neg-op b) when a or b might be NaN.
+test(double n) {
+  // Force known type to double, preserves NaN.
+  n = 0.0 + n;
+  Expect.isFalse(n >= 0);
+  Expect.isTrue(!(n < 0));
+
+  Expect.isFalse(n <= 0);
+  Expect.isTrue(!(n > 0));
+
+  Expect.isFalse(n < 0);
+  Expect.isTrue(!(n >= 0));
+
+  Expect.isFalse(n > 0);
+  Expect.isTrue(!(n <= 0));
+
+  Expect.isFalse(n == 0);
+  Expect.isFalse(!(n != 0));
+
+  Expect.isTrue(n != 0);
+  Expect.isTrue(!(n == 0));
+
+  Expect.isFalse(identical(n, 0));
+  Expect.isFalse(!(!identical(n, 0)));
+
+  Expect.isTrue(!identical(n, 0));
+  Expect.isTrue(!(identical(n, 0)));
+
+  Expect.isFalse(0 >= n);
+  Expect.isTrue(!(0 < n));
+
+  Expect.isFalse(0 <= n);
+  Expect.isTrue(!(0 > n));
+
+  Expect.isFalse(0 < n);
+  Expect.isTrue(!(0 >= n));
+
+  Expect.isFalse(0 > n);
+  Expect.isTrue(!(0 <= n));
+
+  Expect.isFalse(0 == n);
+  Expect.isFalse(!(0 != n));
+
+  Expect.isTrue(0 != n);
+  Expect.isTrue(!(0 == n));
+
+  Expect.isFalse(identical(0, n));
+  Expect.isFalse(!(!identical(0, n)));
+
+  Expect.isTrue(!identical(0, n));
+  Expect.isTrue(!(identical(0, n)));
+}
+
+testConstant() {
+  Expect.isFalse(double.nan >= 0);
+  Expect.isTrue(!(double.nan < 0));
+
+  Expect.isFalse(double.nan <= 0);
+  Expect.isTrue(!(double.nan > 0));
+
+  Expect.isFalse(double.nan < 0);
+  Expect.isTrue(!(double.nan >= 0));
+
+  Expect.isFalse(double.nan > 0);
+  Expect.isTrue(!(double.nan <= 0));
+
+  Expect.isFalse(double.nan == 0);
+  Expect.isFalse(!(double.nan != 0));
+
+  Expect.isTrue(double.nan != 0);
+  Expect.isTrue(!(double.nan == 0));
+
+  Expect.isFalse(identical(double.nan, 0));
+  Expect.isFalse(!(!identical(double.nan, 0)));
+
+  Expect.isTrue(!identical(double.nan, 0));
+  Expect.isTrue(!(identical(double.nan, 0)));
+
+  Expect.isFalse(0 >= double.nan);
+  Expect.isTrue(!(0 < double.nan));
+
+  Expect.isFalse(0 <= double.nan);
+  Expect.isTrue(!(0 > double.nan));
+
+  Expect.isFalse(0 < double.nan);
+  Expect.isTrue(!(0 >= double.nan));
+
+  Expect.isFalse(0 > double.nan);
+  Expect.isTrue(!(0 <= double.nan));
+
+  Expect.isFalse(0 == double.nan);
+  Expect.isFalse(!(0 != double.nan));
+
+  Expect.isTrue(0 != double.nan);
+  Expect.isTrue(!(0 == double.nan));
+
+  Expect.isFalse(identical(0, double.nan));
+  Expect.isFalse(!(!identical(0, double.nan)));
+
+  Expect.isTrue(!identical(0, double.nan));
+  Expect.isTrue(!(identical(0, double.nan)));
+}
+
+main() {
+  test(hideConstant(27, double.nan));
+  testConstant();
+}
+
+double hideConstant(int n, double result) {
+  if (n == 1) return result;
+  if ((n & 1) == 0) return hideConstant(n >> 1, result);
+  return hideConstant(3 * n + 1, result);
+}
diff --git a/tests/dart2js/native/abstract_class_test.dart b/tests/dart2js/native/abstract_class_test.dart
new file mode 100644
index 0000000..6773385
--- /dev/null
+++ b/tests/dart2js/native/abstract_class_test.dart
@@ -0,0 +1,59 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Native classes can have subclasses that are not declared to the program.  The
+// subclasses are indistinguishable from the base class.  This means that
+// abstract native classes can appear to have instances.
+
+@Native("A")
+abstract class A {}
+
+@Native("B")
+abstract class B {
+  foo() native;
+}
+
+class C {}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A(){}
+  function B(){}
+  B.prototype.foo = function() { return 'B.foo'; };
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()
+""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+  var b = makeB();
+  var c = confuse(new C());
+
+  Expect.isTrue(a is A);
+  Expect.isFalse(b is A);
+  Expect.isFalse(c is A);
+
+  Expect.isFalse(a is B);
+  Expect.isTrue(b is B);
+  Expect.isFalse(c is B);
+
+  Expect.isFalse(a is C);
+  Expect.isFalse(b is C);
+  Expect.isTrue(c is C);
+
+  Expect.equals('B.foo', b.foo());
+}
diff --git a/tests/dart2js/native/bound_closure_super_test.dart b/tests/dart2js/native/bound_closure_super_test.dart
new file mode 100644
index 0000000..d97d8e1
--- /dev/null
+++ b/tests/dart2js/native/bound_closure_super_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, 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 calling convention of property extraction closures (super edition).
+library bound_closure_super_test;
+
+import 'package:expect/expect.dart';
+
+import 'bound_closure_test.dart' as bound_closure_test;
+
+import 'bound_closure_test.dart' show inscrutable, makeCC;
+
+main() {
+  // Calling main from bound_closure_test.dart to set up native code.
+  bound_closure_test.main();
+
+  var c = inscrutable(makeCC)();
+  var csfoo = inscrutable(c).superfoo;
+
+  Expect.equals('BB.foo(1, B)', csfoo(1));
+  Expect.equals('BB.foo(2, 3)', csfoo(2, 3));
+}
diff --git a/tests/dart2js/native/bound_closure_test.dart b/tests/dart2js/native/bound_closure_test.dart
new file mode 100644
index 0000000..3509722
--- /dev/null
+++ b/tests/dart2js/native/bound_closure_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+// Test calling convention of property extraction closures.
+
+class AA {
+  bar(a, [b = 'A']) => 'AA.bar($a, $b)'; // bar is plain dart convention.
+  foo(a, [b = 'A']) => 'AA.foo($a, $b)'; // foo has interceptor convention.
+}
+
+@Native("BB")
+class BB {
+  foo(a, [b = 'B']) native;
+}
+
+@Native("CC")
+class CC extends BB {
+  foo(a, [b = 'C']) native;
+
+  get superfoo => super.foo;
+}
+
+makeBB() native;
+makeCC() native;
+inscrutable(a) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function BB() {}
+  BB.prototype.foo = function(u, v) {
+    return 'BB.foo(' + u + ', ' + v + ')';
+  };
+
+  function CC() {}
+  CC.prototype.foo = function(u, v) {
+    return 'CC.foo(' + u + ', ' + v + ')';
+  };
+
+  makeBB = function(){return new BB()};
+  makeCC = function(){return new CC()};
+  inscrutable = function(a){return a;};
+
+  self.nativeConstructor(BB);
+  self.nativeConstructor(CC);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = inscrutable(new AA());
+  var b = inscrutable(makeBB());
+  var c = inscrutable(makeCC)();
+
+  Expect.equals('AA.bar(1, A)', inscrutable(a).bar(1));
+  Expect.equals('AA.bar(2, 3)', inscrutable(a).bar(2, 3));
+
+  Expect.equals('AA.foo(1, A)', inscrutable(a).foo(1));
+  Expect.equals('AA.foo(2, 3)', inscrutable(a).foo(2, 3));
+
+  Expect.equals('BB.foo(1, B)', inscrutable(b).foo(1));
+  Expect.equals('BB.foo(2, 3)', inscrutable(b).foo(2, 3));
+
+  Expect.equals('CC.foo(1, C)', inscrutable(c).foo(1));
+  Expect.equals('CC.foo(2, 3)', inscrutable(c).foo(2, 3));
+
+  var abar = inscrutable(a).bar;
+  var afoo = inscrutable(a).foo;
+  var bfoo = inscrutable(b).foo;
+  var cfoo = inscrutable(c).foo;
+
+  Expect.equals('AA.bar(1, A)', abar(1));
+  Expect.equals('AA.bar(2, 3)', abar(2, 3));
+
+  Expect.equals('AA.foo(1, A)', afoo(1));
+  Expect.equals('AA.foo(2, 3)', afoo(2, 3));
+
+  Expect.equals('BB.foo(1, B)', bfoo(1));
+  Expect.equals('BB.foo(2, 3)', bfoo(2, 3));
+
+  Expect.equals('CC.foo(1, C)', cfoo(1));
+  Expect.equals('CC.foo(2, 3)', cfoo(2, 3));
+}
diff --git a/tests/dart2js/native/browser_compat_1_prepatched_test.dart b/tests/dart2js/native/browser_compat_1_prepatched_test.dart
new file mode 100644
index 0000000..bfd62f5
--- /dev/null
+++ b/tests/dart2js/native/browser_compat_1_prepatched_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test for dartNativeDispatchHooksTransformer, getTag hook.
+
+@Native("T1A")
+class T1A {}
+
+@Native("T1B")
+class T1B {}
+
+@Native("T1C")
+class T1C {}
+
+makeT1A() native;
+makeT1B() native;
+makeT1C() native;
+
+int getTagCallCount() native;
+
+void setup() {
+  JS('', r'''
+(function(){
+  function T1A() { } //       Normal native class.
+  function T1CrazyB() { } //  Native class with different constructor name.
+
+  var T1fakeA = (function(){
+    function T1A() {} //      Native class with adversarial constructor name.
+    return T1A;
+  })();
+
+  // Make constructors visible on 'window' for prepatching.
+  if (typeof window == "undefined") window = {};
+  window.T1A = T1A;
+  window.T1CrazyB = T1CrazyB;
+
+  makeT1A = function(){return new T1A()};
+  makeT1B = function(){return new T1CrazyB()};
+  makeT1C = function(){return new T1fakeA()};
+
+  self.nativeConstructor(T1A);
+  self.nativeConstructor(T1CrazyB);
+  self.nativeConstructor(T1fakeA);
+
+  var getTagCount = 0;
+  getTagCallCount = function() { return getTagCount; };
+
+  function transformer1(hooks) {
+    var getTag = hooks.getTag;
+
+    function getTagNew(obj) {
+      ++getTagCount;
+
+      // If something looks like a different native type we can check in advance
+      // of the default algorithm.
+      if (obj instanceof T1fakeA) return "T1C";
+
+      var tag = getTag(obj);
+
+      // New constructor names can be mapped here.
+      if (tag == "T1CrazyB") return "T1B";
+
+      return tag;
+    }
+
+    hooks.getTag = getTagNew;
+  }
+
+  dartNativeDispatchHooksTransformer = [transformer1];
+})()''');
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var t1a = makeT1A();
+  var t1b = makeT1B();
+  var t1c = makeT1C();
+
+  Expect.equals(true, t1a is T1A, '$t1a is T1A');
+  Expect.equals(true, t1b is T1B, '$t1b is T1B');
+  Expect.equals(true, t1c is T1C, '$t1c is T1C');
+
+  Expect.equals(2, getTagCallCount());
+
+  Expect.equals(true, confuse(t1a) is T1A, '$t1a is T1A');
+  Expect.equals(true, confuse(t1b) is T1B, '$t1b is T1B');
+  Expect.equals(true, confuse(t1c) is T1C, '$t1c is T1C');
+
+  Expect.equals(2, getTagCallCount());
+}
diff --git a/tests/dart2js/native/browser_compat_1_unpatched_test.dart b/tests/dart2js/native/browser_compat_1_unpatched_test.dart
new file mode 100644
index 0000000..779b72a
--- /dev/null
+++ b/tests/dart2js/native/browser_compat_1_unpatched_test.dart
@@ -0,0 +1,98 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test for dartNativeDispatchHooksTransformer, getTag hook.
+// Same as browser_compat_1_prepatched_test but with prepatching disabled.
+
+@Native("T1A")
+class T1A {}
+
+@Native("T1B")
+class T1B {}
+
+@Native("T1C")
+class T1C {}
+
+makeT1A() native;
+makeT1B() native;
+makeT1C() native;
+
+int getTagCallCount() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function T1A() { } //       Normal native class.
+  function T1CrazyB() { }  // Native class with different constructor name.
+
+  var T1fakeA = (function(){
+    function T1A() {} //      Native class with adversarial constructor name.
+    return T1A;
+  })();
+
+  // Make constructors visible on 'window' for prepatching.
+  if (typeof window == "undefined") window = {};
+  window.T1A = T1A;
+  window.T1CrazyB = T1CrazyB;
+
+  makeT1A = function(){return new T1A()};
+  makeT1B = function(){return new T1CrazyB()};
+  makeT1C = function(){return new T1fakeA()};
+
+  self.nativeConstructor(T1A);
+  self.nativeConstructor(T1CrazyB);
+  self.nativeConstructor(T1fakeA);
+
+  var getTagCount = 0;
+  getTagCallCount = function() { return getTagCount; };
+
+  function transformer1(hooks) {
+    var getTag = hooks.getTag;
+
+    function getTagNew(obj) {
+      ++getTagCount;
+
+      // If something looks like a different native type we can check in advance
+      // of the default algorithm.
+      if (obj instanceof T1fakeA) return "T1C";
+
+      var tag = getTag(obj);
+
+      // New constructor names can be mapped here.
+      if (tag == "T1CrazyB") return "T1B";
+
+      return tag;
+    }
+
+    hooks.getTag = getTagNew;
+    // Disable prepatching.
+    hooks.prototypeForTag = function() { return null; }
+  }
+
+  dartNativeDispatchHooksTransformer = [transformer1];
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var t1a = makeT1A();
+  var t1b = makeT1B();
+  var t1c = makeT1C();
+
+  Expect.equals(true, t1a is T1A, '$t1a is T1A');
+  Expect.equals(true, t1b is T1B, '$t1b is T1B');
+  Expect.equals(true, t1c is T1C, '$t1c is T1C');
+
+  Expect.equals(3, getTagCallCount());
+
+  Expect.equals(true, confuse(t1a) is T1A, '$t1a is T1A');
+  Expect.equals(true, confuse(t1b) is T1B, '$t1b is T1B');
+  Expect.equals(true, confuse(t1c) is T1C, '$t1c is T1C');
+
+  Expect.equals(3, getTagCallCount());
+}
diff --git a/tests/dart2js/native/browser_compat_2_test.dart b/tests/dart2js/native/browser_compat_2_test.dart
new file mode 100644
index 0000000..aa8f131
--- /dev/null
+++ b/tests/dart2js/native/browser_compat_2_test.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test for dartNativeDispatchHooksTransformer
+//  - uncached, instance, leaf and interior caching modes.
+//  - composition of getTag.
+
+@Native("T1A")
+class T1A {
+  foo() native;
+}
+
+@Native("T1B")
+class T1B {
+  foo() native;
+}
+
+@Native("T1C")
+class T1C {
+  foo() native;
+}
+
+@Native("T1D")
+class T1D {
+  foo() native;
+}
+
+makeT1A() native;
+makeT1B() native;
+makeT1C() native;
+makeT1D() native;
+
+int getTagCallCount() native;
+void clearTagCallCount() native;
+
+void setup() {
+  JS('', r'''
+(function(){
+function T1A() { this.v = "a"; }
+function T1B() { this.v = "b"; }
+function T1C() { this.v = "c"; }
+function T1D() { this.v = "d"; }
+
+// T1B, T1C and T1D extend T1A in the implementation but not the declared types.
+// T1A must not be leaf-cached otherwise we will pick up the interceptor for T1A
+// when looking for the dispatch record for an uncached or not-yet-cached T1B,
+// T1C or T1D.
+T1B.prototype.__proto__ = T1A.prototype;
+T1C.prototype.__proto__ = T1A.prototype;
+T1D.prototype.__proto__ = T1A.prototype;
+
+// All classes share one implementation of native method 'foo'.
+T1A.prototype.foo = function() { return this.v + this.name(); };
+T1A.prototype.name = function() { return "A"; };
+T1B.prototype.name = function() { return "B"; };
+T1C.prototype.name = function() { return "C"; };
+T1D.prototype.name = function() { return "D"; };
+
+makeT1A = function(){return new T1A()};
+makeT1B = function(){return new T1B()};
+makeT1C = function(){return new T1C()};
+makeT1D = function(){return new T1D()};
+
+self.nativeConstructor(T1A);
+self.nativeConstructor(T1B);
+self.nativeConstructor(T1C);
+self.nativeConstructor(T1D);
+
+var getTagCount = 0;
+getTagCallCount = function() { return getTagCount; };
+clearTagCallCount = function() { getTagCount = 0; };
+
+function transformer1(hooks) {
+  var getTag = hooks.getTag;
+
+  function getTagNew(obj) {
+    var tag = getTag(obj);
+    // Dependency to test composition, rename T1D -> Dep -> -T1D.
+    if (tag == "T1D") return "Dep";
+    return tag;
+  }
+
+  hooks.getTag = getTagNew;
+}
+
+function transformer2(hooks) {
+  var getTag = hooks.getTag;
+
+  function getTagNew(obj) {
+    ++getTagCount;
+    var tag = getTag(obj);
+    if (tag == "T1A") return "+T1A";  // Interior cached on prototype
+    if (tag == "T1B") return "~T1B";  // Uncached
+    if (tag == "T1C") return "!T1C";  // Instance cached
+    if (tag == "Dep") return "-T1D";  // Leaf cached on prototype
+    return tag;
+  }
+
+  hooks.getTag = getTagNew;
+}
+
+dartNativeDispatchHooksTransformer = [transformer1, transformer2];
+})()''');
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var t1a = makeT1A();
+  var t1b = makeT1B();
+  var t1c = makeT1C();
+  var t1d = makeT1D();
+
+  clearTagCallCount();
+  Expect.equals("aA", confuse(t1a).foo(), 't1a is T1A');
+  Expect.equals("bB", confuse(t1b).foo(), 't1b is T1B');
+  Expect.equals("cC", confuse(t1c).foo(), 't1c is T1C');
+  Expect.equals("dD", confuse(t1d).foo(), 't1d is T1D');
+  Expect.equals(4, getTagCallCount(), '4 fresh instances / types');
+
+  clearTagCallCount();
+  Expect.equals("aA", confuse(t1a).foo(), 't1a is T1A');
+  Expect.equals("bB", confuse(t1b).foo(), 't1b is T1B');
+  Expect.equals("cC", confuse(t1c).foo(), 't1c is T1C');
+  Expect.equals("dD", confuse(t1d).foo(), 't1d is T1D');
+  Expect.equals(1, getTagCallCount(), '1 = 1 uncached + (3 cached)');
+
+  t1a = makeT1A();
+  t1b = makeT1B();
+  t1c = makeT1C();
+  t1d = makeT1D();
+
+  clearTagCallCount();
+  Expect.equals("aA", confuse(t1a).foo(), 't1a is T1A');
+  Expect.equals("bB", confuse(t1b).foo(), 't1b is T1B');
+  Expect.equals("cC", confuse(t1c).foo(), 't1c is T1C');
+  Expect.equals("dD", confuse(t1d).foo(), 't1d is T1D');
+  Expect.equals(2, getTagCallCount(),
+      '2 = 1 fresh instance + 1 uncached (+ 2 proto cached)');
+
+  clearTagCallCount();
+  Expect.equals("aA", confuse(t1a).foo(), 't1a is T1A');
+  Expect.equals("bB", confuse(t1b).foo(), 't1b is T1B');
+  Expect.equals("cC", confuse(t1c).foo(), 't1c is T1C');
+  Expect.equals("dD", confuse(t1d).foo(), 't1d is T1D');
+  Expect.equals(1, getTagCallCount(),
+      '1 = 2 proto cached + 1 instance cached + 1 uncached');
+}
diff --git a/tests/dart2js/native/catch_javascript_null_stack_trace_test.dart b/tests/dart2js/native/catch_javascript_null_stack_trace_test.dart
new file mode 100644
index 0000000..cf9f528
--- /dev/null
+++ b/tests/dart2js/native/catch_javascript_null_stack_trace_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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 'native_testing.dart';
+
+// Try throwing a javascript null, and getting a stack-trace from it.
+
+main() {
+  var savedException;
+  try {
+    try {
+      JS('', '(function () {throw null;})()');
+    } catch (e, st) {
+      savedException = st;
+      rethrow;
+    }
+  } catch (error, st) {
+    // st will be empty, but should not throw on toString().
+    Expect.equals(savedException.toString(), st.toString());
+  }
+}
diff --git a/tests/dart2js/native/compiler_test_internals.dart b/tests/dart2js/native/compiler_test_internals.dart
new file mode 100644
index 0000000..08e96d0
--- /dev/null
+++ b/tests/dart2js/native/compiler_test_internals.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, 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.
+
+library compiler_test_internals;
+
+export 'dart:_js_helper' show NoSideEffects, NoThrows, NoInline;
+
+export 'dart:_foreign_helper' show JS;
diff --git a/tests/dart2js/native/compute_this_script_test.dart b/tests/dart2js/native/compute_this_script_test.dart
new file mode 100644
index 0000000..ee5c855
--- /dev/null
+++ b/tests/dart2js/native/compute_this_script_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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 of _computeThisScript().
+
+import 'dart:_js_helper' show thisScript;
+
+main() {
+  // This is somewhat brittle and relies on an implementation detail
+  // of our test runner, but I can think of no other way to test this.
+  // -- ahe
+  if (!thisScript.endsWith('/compute_this_script_test.js')) {
+    throw 'Unexpected script: "$thisScript"';
+  }
+}
diff --git a/tests/dart2js/native/core_type_check_native_test.dart b/tests/dart2js/native/core_type_check_native_test.dart
new file mode 100644
index 0000000..6356192
--- /dev/null
+++ b/tests/dart2js/native/core_type_check_native_test.dart
@@ -0,0 +1,99 @@
+// 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.
+
+import "native_testing.dart";
+
+@Native("A")
+class A {}
+
+@Native("B")
+class B implements Comparable {
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
+
+@Native("C")
+class C implements Pattern {
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
+
+@Native("D")
+class D implements Pattern, Comparable {
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
+
+makeA() native;
+makeB() native;
+makeC() native;
+makeD() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {};
+  makeA = function() { return new A(); };
+  function B() {};
+  makeB = function() { return new B(); };
+  function C() {};
+  makeC = function() { return new C(); };
+  function D() {};
+  makeD = function() { return new D(); };
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+  self.nativeConstructor(C);
+  self.nativeConstructor(D);
+})()
+""");
+}
+
+checkTest(value, expectComparable, expectPattern) {
+  Expect.equals(expectComparable, value is Comparable);
+  Expect.equals(expectPattern, value is Pattern);
+}
+
+checkCast(value, expectComparable, expectPattern) {
+  if (expectComparable) {
+    Expect.identical(value, value as Comparable);
+  } else {
+    Expect.throws(() => value as Comparable);
+  }
+  if (expectPattern) {
+    Expect.identical(value, value as Pattern);
+  } else {
+    Expect.throws(() => value as Pattern);
+  }
+}
+
+checkAll(check) {
+  var things = [
+    [],
+    4,
+    4.2,
+    'foo',
+    new Object(),
+    makeA(),
+    makeB(),
+    makeC(),
+    makeD()
+  ];
+  value(i) => confuse(things[i]);
+
+  check(value(0), false, false); // List
+  check(value(1), true, false); // int
+  check(value(2), true, false); // num
+  check(value(3), true, true); // String
+  check(value(4), false, false); // Object
+  check(value(5), false, false); // A
+  check(value(6), true, false); // B
+  check(value(7), false, true); // C
+  check(value(8), true, true); // D
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  checkAll(checkTest);
+  checkAll(checkCast);
+}
diff --git a/tests/dart2js/native/dart2js_native.status b/tests/dart2js/native/dart2js_native.status
new file mode 100644
index 0000000..fd86b1b
--- /dev/null
+++ b/tests/dart2js/native/dart2js_native.status
@@ -0,0 +1,7 @@
+# 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.
+
+[ $browser ]
+*: Skip
+
diff --git a/tests/dart2js/native/dispatch_property_initialization_test.dart b/tests/dart2js/native/dispatch_property_initialization_test.dart
new file mode 100644
index 0000000..4e4ed95
--- /dev/null
+++ b/tests/dart2js/native/dispatch_property_initialization_test.dart
@@ -0,0 +1,44 @@
+// Copyright (c) 2016, 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 for initialization of dispatchPropertyName.
+
+import 'native_testing.dart';
+
+@Native("Foo")
+class Foo {
+  String method(String x) native;
+}
+
+makeFoo() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function Foo() {}
+  Foo.prototype.method = function(x) { return 'Foo ' + x; };
+
+  self.makeFoo = function() { return new Foo(); };
+
+  self.nativeConstructor(Foo);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  // If the dispatchPropertyName is uninitialized, it will be `undefined` or
+  // `null` instead of the secret string or Symbol. These properties on
+  // `Object.prototype` will be retrieved by the lookup instead of `undefined`
+  // for the dispatch record.
+  JS('', r'self.Object.prototype["undefined"] = {}');
+  JS('', r'self.Object.prototype["null"] = {}');
+  Expect.equals('Foo A', makeFoo().method('A'));
+
+  // Slightly different version that has malformed dispatch records.
+  JS('', r'self.Object.prototype["undefined"] = {p: false}');
+  JS('', r'self.Object.prototype["null"] = {p: false}');
+  Expect.equals('Foo B', makeFoo().method('B'));
+}
diff --git a/tests/dart2js/native/downcast_test.dart b/tests/dart2js/native/downcast_test.dart
new file mode 100644
index 0000000..ab74f5f
--- /dev/null
+++ b/tests/dart2js/native/downcast_test.dart
@@ -0,0 +1,86 @@
+// 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.
+
+// Test for downcasts on native classes.
+
+import "native_testing.dart";
+
+abstract class J {}
+
+abstract class I extends J {
+  I read();
+  write(covariant I x);
+}
+
+// Native implementation.
+
+@Native("A")
+class A implements I {
+  // The native class accepts only other native instances.
+  A read() native;
+  write(A x) native;
+}
+
+@Native("B")
+class B extends A {}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+function inherits(child, parent) {
+  if (child.prototype.__proto__) {
+    child.prototype.__proto__ = parent.prototype;
+  } else {
+    function tmp() {};
+    tmp.prototype = parent.prototype;
+    child.prototype = new tmp();
+    child.prototype.constructor = child;
+  }
+}
+function A(){}
+function B(){}
+inherits(B, A);
+A.prototype.read = function() { return this._x; };
+A.prototype.write = function(x) { this._x = x; };
+makeA = function(){return new A()};
+makeB = function(){return new B()};
+
+self.nativeConstructor(A);
+self.nativeConstructor(B);
+})()""");
+}
+
+class C {}
+
+bool _check(a, b) => identical(a, b);
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeA();
+  var b1 = makeB();
+  var ob = new Object();
+
+  Expect.throws(() => ob as J);
+  Expect.throws(() => ob as I);
+  Expect.throws(() => ob as A);
+  Expect.throws(() => ob as B);
+  Expect.throws(() => ob as C);
+
+  // Use b1 first to prevent a1 is checks patching the A prototype.
+  Expect.equals(b1, b1 as J);
+  Expect.equals(b1, b1 as I);
+  Expect.equals(b1, b1 as A);
+  Expect.equals(b1, b1 as B);
+
+  Expect.equals(a1, a1 as J);
+  Expect.equals(a1, a1 as I);
+  Expect.equals(a1, a1 as A);
+  Expect.throws(() => a1 as B);
+  Expect.throws(() => a1 as C);
+}
diff --git a/tests/dart2js/native/error_safeToString_test.dart b/tests/dart2js/native/error_safeToString_test.dart
new file mode 100644
index 0000000..115c908
--- /dev/null
+++ b/tests/dart2js/native/error_safeToString_test.dart
@@ -0,0 +1,173 @@
+// Copyright (c) 2015, 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 "native_testing.dart";
+import 'dart:_foreign_helper' show JS_INTERCEPTOR_CONSTANT;
+import 'dart:_interceptors'
+    show
+        Interceptor,
+        JavaScriptObject,
+        PlainJavaScriptObject,
+        UnknownJavaScriptObject;
+
+// Test for safe formatting of JavaScript objects by Error.safeToString.
+
+@Native('PPPP')
+class Purple {}
+
+@Native('QQQQ')
+class Q {}
+
+@Native('RRRR')
+class Rascal {
+  toString() => 'RRRRRRRR';
+}
+
+makeA() native;
+makeB() native;
+makeC() native;
+makeD() native;
+makeE() native;
+makeP() native;
+makeQ() native;
+makeR() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  makeA = function(){return {hello: 123};};
+
+  function BB(){}
+  makeB = function(){return new BB();};
+
+  function CC(){}
+  makeC = function(){
+    var x = new CC();
+    x.constructor = null;  // Foils constructor lookup.
+    return x;
+  };
+
+  function DD(){}
+  makeD = function(){
+    var x = new DD();
+    x.constructor = {name: 'DDxxx'};  // Foils constructor lookup.
+    return x;
+  };
+
+  function EE(){}
+  makeE = function(){
+    var x = new EE();
+    x.constructor = function Liar(){};  // Looks like a legitimate constructor.
+    return x;
+  };
+
+  function PPPP(){}
+  makeP = function(){return new PPPP();};
+
+  function QQQQ(){}
+  makeQ = function(){return new QQQQ();};
+
+  function RRRR(){}
+  makeR = function(){return new RRRR();};
+
+  self.nativeConstructor(PPPP);
+  self.nativeConstructor(QQQQ);
+  self.nativeConstructor(RRRR);
+})()""");
+}
+
+expectTypeName(expectedName, s) {
+  var m = new RegExp(r"Instance of '(.*)'").firstMatch(s);
+  Expect.isNotNull(m);
+  var name = m.group(1);
+  Expect.isTrue(
+      expectedName == name || name.length <= 3 || name.startsWith('minified:'),
+      "Is '$expectedName' or minified: '$name'");
+}
+
+final plainJsString =
+    Error.safeToString(JS_INTERCEPTOR_CONSTANT(PlainJavaScriptObject));
+
+final unknownJsString =
+    Error.safeToString(JS_INTERCEPTOR_CONSTANT(UnknownJavaScriptObject));
+
+final interceptorString =
+    Error.safeToString(JS_INTERCEPTOR_CONSTANT(Interceptor));
+
+testDistinctInterceptors() {
+  // Test invariants needed for the other tests.
+
+  Expect.notEquals(plainJsString, unknownJsString);
+  Expect.notEquals(plainJsString, interceptorString);
+  Expect.notEquals(unknownJsString, interceptorString);
+
+  expectTypeName('PlainJavaScriptObject', plainJsString);
+  expectTypeName('UnknownJavaScriptObject', unknownJsString);
+  expectTypeName('Interceptor', interceptorString);
+
+  // Sometimes interceptor *objects* are used instead of the prototypes. Check
+  // these work too.
+  var plain2 = Error.safeToString(const PlainJavaScriptObject());
+  Expect.equals(plainJsString, plain2);
+
+  var unk2 = Error.safeToString(const UnknownJavaScriptObject());
+  Expect.equals(unknownJsString, unk2);
+}
+
+testExternal() {
+  var x = makeA();
+  Expect.equals(plainJsString, Error.safeToString(x));
+
+  x = makeB();
+  // Gets name from constructor, regardless of minification.
+  Expect.equals("Instance of 'BB'", Error.safeToString(x));
+
+  x = makeC();
+  Expect.equals(unknownJsString, Error.safeToString(x));
+
+  x = makeD();
+  Expect.equals(unknownJsString, Error.safeToString(x));
+
+  x = makeE();
+  Expect.equals("Instance of 'Liar'", Error.safeToString(x));
+}
+
+testNative() {
+  var x = makeP();
+  Expect.isTrue(x is Purple); // This test forces Purple to be distinguished.
+  Expect.notEquals(plainJsString, Error.safeToString(x));
+  Expect.notEquals(unknownJsString, Error.safeToString(x));
+  Expect.notEquals(interceptorString, Error.safeToString(x));
+  // And not the native class constructor.
+  Expect.notEquals("Instance of 'PPPP'", Error.safeToString(x));
+  expectTypeName('Purple', Error.safeToString(x));
+
+  x = makeQ();
+  print('Q:  $x  ${Error.safeToString(x)}');
+  // We are going to get either the general interceptor or the JavaScript
+  // constructor.
+  Expect.isTrue("Instance of 'QQQQ'" == Error.safeToString(x) ||
+      interceptorString == Error.safeToString(x));
+
+  x = makeR();
+
+  // Rascal overrides 'toString'.  The toString() call causes Rascal to be
+  // distinguished.
+  x.toString();
+  Expect.notEquals(plainJsString, Error.safeToString(x));
+  Expect.notEquals(unknownJsString, Error.safeToString(x));
+  Expect.notEquals(interceptorString, Error.safeToString(x));
+  // And not the native class constructor.
+  Expect.notEquals("Instance of 'RRRR'", Error.safeToString(x));
+  expectTypeName('Rascal', Error.safeToString(x));
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testDistinctInterceptors();
+  testExternal();
+  testNative();
+}
diff --git a/tests/dart2js/native/event_loop_test.dart b/tests/dart2js/native/event_loop_test.dart
new file mode 100644
index 0000000..e69d542
--- /dev/null
+++ b/tests/dart2js/native/event_loop_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2015, 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:async_helper/async_helper.dart";
+import "native_testing.dart";
+
+typedef void Callback0();
+
+@Native("A")
+class A {
+  foo(Callback0 f) native;
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+function A() {}
+A.prototype.foo = function(f) { return f(); };
+makeA = function() { return new A(); };
+self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  // Makes sure that we don't run the event-loop when we have a reentrant
+  // call from JS to Dart code.
+  // We start by setting up a microtask that should only run after main has
+  // finished. We then pass a closure into JavaScript. That closure is
+  // immediately invoked. Dart2js had a bug, that it would start the event-loop
+  // at this moment (a JS->Dart transition), and execute the scheduled
+  // microtask.
+
+  var events = [];
+  asyncStart();
+  var a = makeA();
+  new Future.microtask(() {
+    events.add("scheduleMicrotask");
+  }).whenComplete(asyncEnd);
+
+  Expect.equals(499, a.foo(() {
+    events.add("closure to foo");
+    return 499;
+  }));
+
+  events.add("after native call");
+  Expect.listEquals(["closure to foo", "after native call"], events);
+}
diff --git a/tests/dart2js/native/fake_thing_2_test.dart b/tests/dart2js/native/fake_thing_2_test.dart
new file mode 100644
index 0000000..f630746
--- /dev/null
+++ b/tests/dart2js/native/fake_thing_2_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+// Test that native objects cannot accidentally or maliciously be mistaken for
+// Dart objects.
+// The difference between fake_thing_test and fake_thing_2_test is the
+// presence of a used declared native class.
+
+class Thing {}
+
+@Native("NT")
+class NativeThing {}
+
+make1() native;
+make2() native;
+make3() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.$isThing = true;
+  make1 = function(){return new A()};
+  make2 = function(){return {$isThing: true}};
+  function NT() {}
+  NT.prototype.$isThing = true;
+  make3 = function(){return new NT()};
+
+  self.nativeConstructor(NT);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = new Thing();
+  var b = make1();
+  var c = make2();
+  var d = make3();
+  Expect.isTrue(confuse(a) is Thing);
+  Expect.isFalse(confuse(b) is Thing);
+  Expect.isFalse(confuse(c) is Thing);
+  Expect.isFalse(confuse(d) is Thing);
+}
diff --git a/tests/dart2js/native/fake_thing_test.dart b/tests/dart2js/native/fake_thing_test.dart
new file mode 100644
index 0000000..0131821
--- /dev/null
+++ b/tests/dart2js/native/fake_thing_test.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2013, 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 "dart:_foreign_helper" show JS;
+
+// Test that native objects cannot accidentally or maliciously be mistaken for
+// Dart objects.
+
+// This test currently fails because we do not recognize the need for
+// interceptors without native *classes*.
+
+class Thing {}
+
+make1() native;
+make2() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.$isThing = true;
+  make1 = function(){return new A();};
+  make2 = function(){return {$isThing: true}};
+})()""");
+}
+
+inscrutable(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 0) {
+    return x;
+  } else {
+    return 42;
+  }
+}
+
+main() {
+  setup();
+
+  var a = new Thing();
+  var b = make1();
+  var c = make2();
+  Expect.isTrue(inscrutable(a) is Thing);
+  Expect.isFalse(inscrutable(b) is Thing);
+  Expect.isFalse(inscrutable(c) is Thing);
+}
diff --git a/tests/dart2js/native/field_type2_test.dart b/tests/dart2js/native/field_type2_test.dart
new file mode 100644
index 0000000..3bc2e10
--- /dev/null
+++ b/tests/dart2js/native/field_type2_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2013, 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 that a closure call on a native field is recognized by the
+// type inferrer.
+
+import 'native_testing.dart';
+
+@Native("Node")
+class Node {
+  final parentNode;
+}
+
+makeNode(parent) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+// This code is all inside 'setup' and so not accessible from the global scope.
+function Node(parent){ this.parentNode = parent; }
+makeNode = function(p){return new Node(p);};
+
+self.nativeConstructor(Node);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var node = makeNode(null);
+  if (node.parentNode != null) {
+    node = node.parentNode();
+  }
+}
diff --git a/tests/dart2js/native/field_type_test.dart b/tests/dart2js/native/field_type_test.dart
new file mode 100644
index 0000000..8e2e83d
--- /dev/null
+++ b/tests/dart2js/native/field_type_test.dart
@@ -0,0 +1,74 @@
+// 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.
+
+// A native class has no defined constructor.
+// This regression test verifies that compiler accounts for hidden constructor
+// when analysing field values.
+
+import "native_testing.dart";
+
+@Native("Node")
+class Node {
+  final Node parentNode;
+
+  ModelSource _modelSource; // If null, inherited from parent.
+
+  ModelSource get modelSource {
+    for (Node node = this; node != null; node = node.parentNode) {
+      ModelSource source = node._modelSource;
+      if (source != null) return source;
+    }
+    return null;
+  }
+
+  // Copy of above code renamed with suffix '2'.
+
+  ModelSource _modelSource2; // If null, inherited from parent.
+
+  ModelSource get modelSource2 {
+    for (Node node = this; node != null; node = node.parentNode) {
+      ModelSource source = node._modelSource2;
+      if (source != null) return source;
+    }
+    return null;
+  }
+}
+
+makeNode(parent) native;
+
+class ModelSource {
+  var name;
+  ModelSource(this.name);
+  toString() => 'ModelSource($name)';
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function Node(parent){ this.parentNode = parent; }
+  makeNode = function(p){return new Node(p);};
+  self.nativeConstructor(Node);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var n1 = makeNode(null);
+  var n2 = makeNode(n1);
+  var n3 = makeNode(n2);
+
+  var m1 = new ModelSource('1');
+  n2._modelSource = null; // null write.
+  n2._modelSource = m1; // Non-null write.
+  var x1 = n3.modelSource;
+  Expect.identical(m1, x1);
+
+  var m2 = new ModelSource('2');
+  n2._modelSource2 = m2; // The only write is non-null.
+  var x2 = n3.modelSource2;
+  Expect.identical(m2, x2);
+}
diff --git a/tests/dart2js/native/fixup_get_tag_test.dart b/tests/dart2js/native/fixup_get_tag_test.dart
new file mode 100644
index 0000000..e4e1ab8
--- /dev/null
+++ b/tests/dart2js/native/fixup_get_tag_test.dart
@@ -0,0 +1,61 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test for dartExperimentalFixupGetTag.
+
+@Native("A")
+class Foo {
+  // There is one native class with dispatch tag 'A'.
+  token() native;
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+
+  dartExperimentalFixupGetTag = function (originalGetTag) {
+    function fixedGetTag(obj) {
+      // Local JS 'class' B is made to be another implementation of the native
+      // class with tag 'A'.
+      if (obj instanceof B) return 'A';
+      // Other classes behave as before.
+      return originalGetTag(obj);
+    }
+    return fixedGetTag;
+  };
+
+  function A(){ }
+  A.prototype.token = function () { return 'isA'; };
+
+  function B(){ }
+  B.prototype.token = function () { return 'isB'; };
+
+  makeA = function() { return new A(); };
+  makeB = function() { return new B(); };
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+makeA() native;
+makeB() native;
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+  var b = makeB();
+
+  Expect.equals('isA', a.token());
+
+  // This call succeeds because the fixed-up 'getTag' method returns Foo's
+  // dispatch tag, and B is a faithful polyfil for Foo/A.
+  Expect.equals('isB', b.token());
+
+  Expect.isTrue(a is Foo);
+  Expect.isTrue(b is Foo);
+}
diff --git a/tests/dart2js/native/foreign_test.dart b/tests/dart2js/native/foreign_test.dart
new file mode 100644
index 0000000..31ab23b
--- /dev/null
+++ b/tests/dart2js/native/foreign_test.dart
@@ -0,0 +1,39 @@
+// 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 "native_testing.dart";
+
+foreign1(var a, var b) {
+  return JS("num", r"# + #", a, b);
+}
+
+var called = false;
+callOnce() {
+  Expect.isFalse(called);
+  called = true;
+  return 499;
+}
+
+foreign2() {
+  var t = callOnce();
+  return JS("num", r"# + #", t, t);
+}
+
+foreign11(a1, a2, a3, a4, a5, a6, a7, a8, a9, a10, a11) {
+  return JS("num|String", r"# + # + # + # + # + # + # + # + # + # + #", a1, a2,
+      a3, a4, a5, a6, a7, a8, a9, a10, a11);
+}
+
+void main() {
+  Expect.equals(9, foreign1(4, 5));
+  Expect.equals(998, foreign2());
+  Expect.equals('1234567891011',
+      foreign11('1', '2', '3', '4', '5', '6', '7', '8', '9', '10', '11'));
+  // Ensure there will be isNaN and NaN variable names.
+  var isNaN = called ? 42 : 44;
+  var NaN = called ? 52 : 54;
+  Expect.isFalse(JS('bool', 'isNaN(#)', isNaN));
+  Expect.isFalse(JS('bool', 'isNaN(#)', NaN));
+  Expect.isTrue(JS('bool', 'isNaN(#)', double.nan));
+}
diff --git a/tests/dart2js/native/hash_code_test.dart b/tests/dart2js/native/hash_code_test.dart
new file mode 100644
index 0000000..137be8f
--- /dev/null
+++ b/tests/dart2js/native/hash_code_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {}
+
+@Native("B")
+class B {
+  int get hashCode => 1234567;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  Expect.isTrue(makeA().hashCode is int);
+  Expect.equals(1234567, makeB().hashCode);
+}
diff --git a/tests/dart2js/native/internal_library_test.dart b/tests/dart2js/native/internal_library_test.dart
new file mode 100644
index 0000000..7f81f6c
--- /dev/null
+++ b/tests/dart2js/native/internal_library_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2013, 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 that a private library can be accessed from libraries in this special
+// test folder.
+
+import 'dart:_js_helper';
+
+void main() {
+  print(loadDeferredLibrary);
+}
diff --git a/tests/dart2js/native/is_check_test.dart b/tests/dart2js/native/is_check_test.dart
new file mode 100644
index 0000000..ec1d703
--- /dev/null
+++ b/tests/dart2js/native/is_check_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+@Native("A")
+class A {}
+
+main() {
+  JS('A', '(null)'); // Class 'A' appears to be created.
+  Expect.isFalse(confuse(new Object()) is A);
+}
diff --git a/tests/dart2js/native/issue9182_test.dart b/tests/dart2js/native/issue9182_test.dart
new file mode 100644
index 0000000..62a0a60
--- /dev/null
+++ b/tests/dart2js/native/issue9182_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for Issue 9182.  The generative constructor body function
+// should not have the interceptor calling convention.
+
+import "native_testing.dart";
+
+@Native("A")
+class Foo {
+  factory Foo() => makeA();
+  // Ensure the instance method 'Bar' uses interceptor convention.
+  Bar() => 123;
+}
+
+class Bar {
+  var _x, _y;
+  // Generative constructor with body, having the same name as interceptor
+  // convention instance member.
+  Bar(x, y) {
+    _x = x;
+    _y = y;
+  }
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A(){}
+  makeA = function() { return new A() };
+  self.nativeConstructor(A);
+})()""");
+}
+
+makeA() native;
+
+main() {
+  nativeTesting();
+  setup();
+
+  var foo = confuse(new Foo());
+  var bar = confuse(new Bar(30, 40));
+
+  Expect.equals(123, foo.Bar()); // Ensure that Foo.Bar is used.
+
+  Expect.equals(30, bar._x);
+  Expect.equals(40, bar._y);
+}
diff --git a/tests/dart2js/native/js_const_test.dart b/tests/dart2js/native/js_const_test.dart
new file mode 100644
index 0000000..d777e1e
--- /dev/null
+++ b/tests/dart2js/native/js_const_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, 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 'dart:_foreign_helper' show JS, JS_CONST;
+
+test1() {
+  var re = const JS_CONST(r'/-([\da-z])/ig');
+  var fToUpper =
+      const JS_CONST(r'function(_, letter){return letter.toUpperCase()}');
+  var s1 = '-hello-world';
+  var s2 = JS('String', r'#.replace(#, #)', s1, re, fToUpper);
+  Expect.equals('HelloWorld', s2);
+
+  s1 = 'hello-world';
+  s2 = JS('String', r'#.replace(#, #)', s1, re, fToUpper);
+  Expect.equals('helloWorld', s2);
+}
+
+main() {
+  test1();
+}
diff --git a/tests/dart2js/native/js_constant_test.dart b/tests/dart2js/native/js_constant_test.dart
new file mode 100644
index 0000000..40ce27c
--- /dev/null
+++ b/tests/dart2js/native/js_constant_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2015, 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 'native_testing.dart';
+
+// Negative constant numbers must be generated as negation, not just a literal
+// with a sign, i.e.
+//
+//     (-5).toString()
+//
+// not
+//
+//     -5 .toString()
+//
+// The unparethesized version is `-(5 .toString())`, which creates the string
+// `"5"`, then converts it to a number for negation, giving a number result
+// instead of a string result.
+
+@pragma('dart2js:noInline')
+checkString(r) {
+  Expect.isTrue(
+      r is String, 'Expected string, found ${r} of type ${r.runtimeType}');
+}
+
+test1() {
+  checkString(JS('', '#.toString()', -5));
+}
+
+test2() {
+  checkString(JS('', '#.toString()', -1.5));
+}
+
+test3() {
+  checkString(JS('', '#.toString()', -0.0));
+}
+
+main() {
+  test1();
+  test2();
+  test3();
+}
diff --git a/tests/dart2js/native/jsobject_test.dart b/tests/dart2js/native/jsobject_test.dart
new file mode 100644
index 0000000..dd0ec8e
--- /dev/null
+++ b/tests/dart2js/native/jsobject_test.dart
@@ -0,0 +1,106 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors'
+    show
+        JSObject, // The interface, which may be re-exported by a
+        // js-interop library.
+        JavaScriptObject, //   The interceptor abstract class.
+        PlainJavaScriptObject, //     The interceptor concrete class.
+        UnknownJavaScriptObject, //     The interceptor concrete class.
+        Interceptor;
+
+// Test for JavaScript objects from outside the Dart program.  Although we only
+// export the interface [JSObject] to user level code, this test makes sure we
+// can distinguish plain JavaScript objects from ones with a complex prototype.
+
+@Native('QQ')
+class Q {}
+
+makeA() native;
+makeB() native;
+makeQ() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+makeA = function(){return {hello: 123};};
+
+function BB(){}
+makeB = function(){return new BB();};
+
+function QQ(){}
+makeQ = function(){return new QQ();};
+
+self.nativeConstructor(QQ);
+})()""");
+}
+
+class Is<T> {
+  bool check(x) => x is T;
+}
+
+static_test() {
+  var x = makeA();
+  Expect.isTrue(x is JSObject);
+  Expect.isTrue(x is JavaScriptObject);
+  Expect.isTrue(x is PlainJavaScriptObject);
+  Expect.isTrue(x is! UnknownJavaScriptObject);
+  Expect.equals(JSObject, x.runtimeType);
+
+  x = makeB();
+  Expect.isTrue(x is JSObject);
+  Expect.isTrue(x is JavaScriptObject);
+  Expect.isTrue(x is! PlainJavaScriptObject);
+  Expect.isTrue(x is UnknownJavaScriptObject);
+  Expect.equals(JSObject, x.runtimeType);
+
+  x = makeQ();
+  Expect.isFalse(x is JSObject);
+  Expect.isFalse(x is JavaScriptObject);
+  Expect.isFalse(x is PlainJavaScriptObject);
+  Expect.isFalse(x is UnknownJavaScriptObject);
+  Expect.isFalse(x.runtimeType == JSObject);
+  Expect.isTrue(x is Q);
+}
+
+dynamic_test() {
+  var x = makeA();
+  var isJSObject = new Is<JSObject>().check;
+  var isJavaScriptObject = new Is<JavaScriptObject>().check;
+  var isPlainJavaScriptObject = new Is<PlainJavaScriptObject>().check;
+  var isUnknownJavaScriptObject = new Is<UnknownJavaScriptObject>().check;
+  var isQ = new Is<Q>().check;
+
+  Expect.isTrue(isJSObject(x));
+  Expect.isTrue(isJavaScriptObject(x));
+  Expect.isTrue(isPlainJavaScriptObject(x));
+  Expect.isTrue(!isUnknownJavaScriptObject(x));
+  Expect.equals(JSObject, x.runtimeType);
+
+  x = makeB();
+  Expect.isTrue(isJSObject(x));
+  Expect.isTrue(isJavaScriptObject(x));
+  Expect.isTrue(!isPlainJavaScriptObject(x));
+  Expect.isTrue(isUnknownJavaScriptObject(x));
+  Expect.equals(JSObject, x.runtimeType);
+
+  x = makeQ();
+  Expect.isFalse(isJSObject(x));
+  Expect.isFalse(isJavaScriptObject(x));
+  Expect.isFalse(isPlainJavaScriptObject(x));
+  Expect.isFalse(isUnknownJavaScriptObject(x));
+  Expect.isTrue(isQ(x));
+  Expect.isFalse(x.runtimeType == JSObject);
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  dynamic_test();
+  static_test();
+}
diff --git a/tests/dart2js/native/load_elim_refinement_test.dart b/tests/dart2js/native/load_elim_refinement_test.dart
new file mode 100644
index 0000000..ee9dfee
--- /dev/null
+++ b/tests/dart2js/native/load_elim_refinement_test.dart
@@ -0,0 +1,32 @@
+// 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 'native_testing.dart';
+
+class A {
+  int a;
+}
+
+class B extends A {
+  int b;
+}
+
+@pragma('dart2js:noInline')
+escape(v) {
+  g = v;
+}
+
+var g;
+
+main() {
+  g = new A();
+  var a = JS('returns:A;new:true', '(1,#)', new B());
+
+  a.a = 1;
+  if (a is B) {
+    escape(a); // Here we need to escape 'a' not the refinement of a to B.
+    g.a = 2;
+    Expect.equals(2, a.a);
+  }
+}
diff --git a/tests/dart2js/native/native_call_arity1_frog_test.dart b/tests/dart2js/native/native_call_arity1_frog_test.dart
new file mode 100644
index 0000000..f590001
--- /dev/null
+++ b/tests/dart2js/native/native_call_arity1_frog_test.dart
@@ -0,0 +1,87 @@
+// 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 "native_testing.dart";
+
+// Test that native methods with unnamed* optional arguments are called with the
+// number of arguments in the call site.  This is necessary because native
+// methods can dispatch on the number of arguments.  Passing null or undefined
+// as the last argument is not the same as passing one fewer argument.
+//
+// * Optional positional arguments are passed in the correct position, so
+// require preceding arguments to be passed.
+
+@Native("A")
+class A {
+  int foo(int x) native;
+}
+
+@Native("B")
+class B {
+  int foo([x, y, z]) native;
+}
+
+// TODO(sra): Add a case where the parameters have default values.  Wait until
+// dart:html need non-null default values.
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo = function () { return arguments.length; };
+
+  function B() {}
+  B.prototype.foo = function () { return arguments.length; };
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testDynamicContext() {
+  var a = confuse(makeA());
+  var b = confuse(makeB());
+
+  Expect.throws(() => a.foo());
+  Expect.equals(1, a.foo(10));
+  Expect.throws(() => a.foo(10, 20));
+  Expect.throws(() => a.foo(10, 20, 30));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+  Expect.equals(3, b.foo(10, 20, 30));
+
+  Expect.throws(() => b.foo(10, 20, 30, 40));
+}
+
+testStaticContext() {
+  A a = makeA();
+  B b = makeB();
+
+  Expect.throws(() => (a as dynamic).foo());
+  Expect.equals(1, a.foo(10));
+  Expect.throws(() => (a as dynamic).foo(10, 20));
+  Expect.throws(() => (a as dynamic).foo(10, 20, 30));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+  Expect.equals(3, b.foo(10, 20, 30));
+
+  Expect.throws(() => (b as dynamic).foo(10, 20, 30, 40));
+}
+
+main() {
+  nativeTesting();
+  setup();
+  testDynamicContext();
+  testStaticContext();
+}
diff --git a/tests/dart2js/native/native_call_arity2_frog_test.dart b/tests/dart2js/native/native_call_arity2_frog_test.dart
new file mode 100644
index 0000000..1646809
--- /dev/null
+++ b/tests/dart2js/native/native_call_arity2_frog_test.dart
@@ -0,0 +1,98 @@
+// 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 "native_testing.dart";
+
+// This is a similar test to NativeCallArity1FrogTest, but makes sure
+// that subclasses also get the right number of arguments.
+
+@Native("A")
+class A {
+  int foo([x, y]) native;
+}
+
+@Native("B")
+class B extends A {
+  int foo([x, y]) native;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A() {}
+  A.prototype.foo = function () { return arguments.length; };
+
+  function B() {}
+  B.prototype.foo = function () { return arguments.length; };
+  inherits(B, A);
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testDynamicContext() {
+  var a = confuse(makeA());
+  var b = confuse(makeB());
+
+  Expect.equals(0, a.foo());
+  Expect.equals(1, a.foo(10));
+  Expect.equals(2, a.foo(10, 20));
+  Expect.throws(() => a.foo(10, 20, 30));
+
+  Expect.equals(1, a.foo(10));
+  Expect.equals(2, a.foo(null, 20));
+  Expect.throws(() => a.foo(10, 20, 30));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+  Expect.throws(() => b.foo(10, 20, 30));
+
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(null, 20));
+  Expect.throws(() => b.foo(10, 20, 30));
+}
+
+testStaticContext() {
+  A a = makeA();
+  B b = makeB();
+
+  Expect.equals(0, a.foo());
+  Expect.equals(1, a.foo(10));
+  Expect.equals(2, a.foo(10, 20));
+
+  Expect.equals(1, a.foo(10));
+  Expect.equals(2, a.foo(null, 20));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(null, 20));
+}
+
+main() {
+  nativeTesting();
+  setup();
+  testDynamicContext();
+  testStaticContext();
+}
diff --git a/tests/dart2js/native/native_call_arity3_frog_test.dart b/tests/dart2js/native/native_call_arity3_frog_test.dart
new file mode 100644
index 0000000..3be4585
--- /dev/null
+++ b/tests/dart2js/native/native_call_arity3_frog_test.dart
@@ -0,0 +1,85 @@
+// 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.
+
+import "native_testing.dart";
+
+// Test similar to NativeCallArity1FrogTest, but with default values to
+// parameters set to null. These parameters should be treated as if they
+// do not have a default value for the native methods.
+
+@Native("A")
+class A {
+  int foo(int x) native;
+}
+
+@Native("B")
+class B {
+  int foo([x = null, y, z = null]) native;
+}
+
+// TODO(sra): Add a case where the parameters have default values.  Wait until
+// dart:html need non-null default values.
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo = function () { return arguments.length; };
+
+  function B() {}
+  B.prototype.foo = function () { return arguments.length; };
+
+  makeA = function(){return new A();};
+  makeB = function(){return new B();};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testDynamicContext() {
+  var a = confuse(makeA());
+  var b = confuse(makeB());
+
+  Expect.throws(() => a.foo());
+  Expect.equals(1, a.foo(10));
+  Expect.throws(() => a.foo(10, 20));
+  Expect.throws(() => a.foo(10, 20, 30));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+  Expect.equals(3, b.foo(10, 20, 30));
+
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(null, 20));
+  Expect.equals(3, b.foo(null, null, 30));
+  Expect.throws(() => b.foo(10, 20, 30, 40));
+}
+
+testStaticContext() {
+  A a = makeA();
+  B b = makeB();
+
+  Expect.equals(1, a.foo(10));
+
+  Expect.equals(0, b.foo());
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(10, 20));
+  Expect.equals(3, b.foo(10, 20, 30));
+
+  Expect.equals(1, b.foo(10));
+  Expect.equals(2, b.foo(null, 20));
+  Expect.equals(3, b.foo(null, null, 30));
+}
+
+main() {
+  nativeTesting();
+  setup();
+  testDynamicContext();
+  testStaticContext();
+}
diff --git a/tests/dart2js/native/native_checked_arguments1_frog_test.dart b/tests/dart2js/native/native_checked_arguments1_frog_test.dart
new file mode 100644
index 0000000..ddce60e
--- /dev/null
+++ b/tests/dart2js/native/native_checked_arguments1_frog_test.dart
@@ -0,0 +1,115 @@
+// 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 'native_testing.dart';
+
+// Test that type checks occur on native methods.
+
+@Native("A")
+class A {
+  int foo(int x) native;
+  int cmp(A other) native;
+}
+
+@Native("B")
+class B {
+  String foo(String x) native;
+  int cmp(B other) native;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo = function (x) { return x + 1; };
+  A.prototype.cmp = function (x) { return 0; };
+
+  function B() {}
+  B.prototype.foo = function (x) { return x + 'ha!'; };
+  B.prototype.cmp = function (x) { return 1; };
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+expectThrows(action()) {
+  bool threw = false;
+  try {
+    action();
+  } catch (e) {
+    threw = true;
+  }
+  Expect.isTrue(threw);
+}
+
+complianceModeTest() {
+  var things = <dynamic>[makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  Expect.equals(124, a.foo(123));
+  expectThrows(() => a.foo('xxx'));
+
+  Expect.equals('helloha!', b.foo('hello'));
+  expectThrows(() => b.foo(123));
+
+  Expect.equals(0, a.cmp(a));
+  expectThrows(() => a.cmp(b));
+  expectThrows(() => a.cmp(5));
+
+  Expect.equals(1, b.cmp(b));
+  expectThrows(() => b.cmp(a));
+  expectThrows(() => b.cmp(5));
+}
+
+omitImplicitChecksModeTest() {
+  var things = <dynamic>[makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  Expect.equals(124, a.foo(123));
+  Expect.equals('xxx1', a.foo('xxx'));
+
+  Expect.equals('helloha!', b.foo('hello'));
+  Expect.equals('123ha!', b.foo(123));
+
+  Expect.equals(0, a.cmp(a));
+  Expect.equals(0, a.cmp(b));
+  Expect.equals(0, a.cmp(5));
+
+  Expect.equals(1, b.cmp(b));
+  Expect.equals(1, b.cmp(a));
+  Expect.equals(1, b.cmp(5));
+}
+
+bool isComplianceMode() {
+  var stuff = <dynamic>[1, 'string'];
+  dynamic a = stuff[0];
+  // compliance-mode detection.
+  try {
+    String s = a;
+    return false;
+  } catch (e) {
+    // Ignore.
+  }
+  return true;
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  if (isComplianceMode()) {
+    complianceModeTest();
+  } else {
+    omitImplicitChecksModeTest();
+  }
+}
diff --git a/tests/dart2js/native/native_checked_fields_frog_test.dart b/tests/dart2js/native/native_checked_fields_frog_test.dart
new file mode 100644
index 0000000..f9fdece
--- /dev/null
+++ b/tests/dart2js/native/native_checked_fields_frog_test.dart
@@ -0,0 +1,99 @@
+// 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 'native_testing.dart';
+
+// Test that type checks occur on assignment to fields of native methods.
+
+@Native("A")
+class A {
+  int foo;
+}
+
+@Native("B")
+class B {
+  String foo;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+
+  function B() {}
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+expectThrows(action()) {
+  bool threw = false;
+  try {
+    action();
+  } catch (e) {
+    threw = true;
+  }
+  Expect.isTrue(threw);
+}
+
+complianceModeTest() {
+  var things = <dynamic>[makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  a.foo = 123;
+  expectThrows(() => a.foo = 'xxx');
+  Expect.equals(123, a.foo);
+
+  b.foo = 'hello';
+  expectThrows(() => b.foo = 123);
+  Expect.equals('hello', b.foo);
+}
+
+omitImplicitChecksTest() {
+  var things = <dynamic>[makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  a.foo = 123;
+  Expect.equals(123, a.foo);
+  a.foo = 'xxx';
+  Expect.equals('xxx', a.foo);
+
+  b.foo = 'hello';
+  Expect.equals('hello', b.foo);
+  b.foo = 123;
+  Expect.equals(b.foo, 123);
+}
+
+bool isComplianceMode() {
+  var stuff = [1, 'string'];
+  var a = stuff[0];
+  // Detect whether we are using --omit-implicit-checks.
+  try {
+    String s = a;
+    return false;
+  } catch (e) {
+    // Ignore.
+  }
+  return true;
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  if (isComplianceMode()) {
+    complianceModeTest();
+  } else {
+    omitImplicitChecksTest();
+  }
+}
diff --git a/tests/dart2js/native/native_class_avoids_hidden_name_frog_test.dart b/tests/dart2js/native/native_class_avoids_hidden_name_frog_test.dart
new file mode 100644
index 0000000..6e4a95c
--- /dev/null
+++ b/tests/dart2js/native/native_class_avoids_hidden_name_frog_test.dart
@@ -0,0 +1,65 @@
+// 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 "native_testing.dart";
+
+// Test that hidden native class names are not used by generated code.
+
+@Native("BB")
+class AA {
+  get name => 'AA';
+  static AA create() => makeA();
+}
+
+@Native("CC")
+class BB {
+  get name => 'BB';
+  static BB create() => makeB();
+}
+
+class CC {
+  // Ordinary class with name clashing with native class.
+  get name => 'CC';
+  static CC create() => new CC();
+}
+
+makeA() native;
+makeB() native;
+
+void setup1() {
+  JS('', r"""
+(function(){
+  // Poison hidden native names 'BB' and 'CC' to prove the compiler didn't place
+  // anything on the hidden native class.
+  BB = null;
+  CC = null;
+})()""");
+}
+
+void setup2() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function BB(){}
+  function CC(){}
+  makeA = function(){return new BB()};  // AA is native "BB"
+  makeB = function(){return new CC()};  // BB is native "CC"
+  self.nativeConstructor(BB);
+  self.nativeConstructor(CC);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup1();
+  setup2();
+
+  var a = confuse(AA.create());
+  var b = confuse(BB.create());
+  var c = confuse(CC.create());
+
+  Expect.equals('AA', a.name);
+  Expect.equals('BB', b.name);
+  Expect.equals('CC', c.name);
+}
diff --git a/tests/dart2js/native/native_class_fields_2_test.dart b/tests/dart2js/native/native_class_fields_2_test.dart
new file mode 100644
index 0000000..3b3d265
--- /dev/null
+++ b/tests/dart2js/native/native_class_fields_2_test.dart
@@ -0,0 +1,173 @@
+// 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 "native_testing.dart";
+
+// Verify that methods are not renamed to clash with native field names
+// that are known from the DOM (like x, y, z).
+@Native("A")
+class A {
+  int x;
+  int y;
+  int z;
+  int gettersCalled;
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  function getter() {
+    this.gettersCalled++;
+    return 42;
+  }
+
+  function A(){
+    var a = Object.create(
+        { constructor: A },
+        { x: { get: getter, configurable: false, writeable: false },
+          y: { get: getter, configurable: false, writeable: false },
+          z: { get: getter, configurable: false, writeable: false }
+        });
+    a.gettersCalled = 0;
+    return a;
+  }
+
+  makeA = function() { return new A(); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+A makeA() native;
+
+class B {
+  void a() {}
+  void a0() {}
+  void a1() {}
+  void a2() {}
+  void a3() {}
+  void a4() {}
+  void a5() {}
+  void a6() {}
+  void a7() {}
+  void a8() {}
+  void a9() {}
+  void a10() {}
+  void a11() {}
+  void a12() {}
+  void a13() {}
+  void a14() {}
+  void a15() {}
+  void a16() {}
+  void a17() {}
+  void a18() {}
+  void a19() {}
+  void a20() {}
+  void a21() {}
+  void a22() {}
+  void a23() {}
+  void a24() {}
+  void a25() {}
+  void a26() {}
+  int z = 0;
+}
+
+int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
+
+main() {
+  nativeTesting();
+  setup();
+  confuse(new B()).a();
+  var x = confuse(makeA());
+  // Each of these will throw, because an instance of A doesn't have any of
+  // these functions.  The important thing is that none of them have been
+  // renamed to be called 'z' by the minifier, because then the getter will be
+  // hit.
+  try {
+    x.a();
+  } catch (e) {}
+  try {
+    x.a0();
+  } catch (e) {}
+  try {
+    x.a1();
+  } catch (e) {}
+  try {
+    x.a2();
+  } catch (e) {}
+  try {
+    x.a3();
+  } catch (e) {}
+  try {
+    x.a4();
+  } catch (e) {}
+  try {
+    x.a5();
+  } catch (e) {}
+  try {
+    x.a6();
+  } catch (e) {}
+  try {
+    x.a7();
+  } catch (e) {}
+  try {
+    x.a8();
+  } catch (e) {}
+  try {
+    x.a9();
+  } catch (e) {}
+  try {
+    x.a10();
+  } catch (e) {}
+  try {
+    x.a11();
+  } catch (e) {}
+  try {
+    x.a12();
+  } catch (e) {}
+  try {
+    x.a13();
+  } catch (e) {}
+  try {
+    x.a14();
+  } catch (e) {}
+  try {
+    x.a15();
+  } catch (e) {}
+  try {
+    x.a16();
+  } catch (e) {}
+  try {
+    x.a17();
+  } catch (e) {}
+  try {
+    x.a18();
+  } catch (e) {}
+  try {
+    x.a19();
+  } catch (e) {}
+  try {
+    x.a20();
+  } catch (e) {}
+  try {
+    x.a21();
+  } catch (e) {}
+  try {
+    x.a12();
+  } catch (e) {}
+  try {
+    x.a23();
+  } catch (e) {}
+  try {
+    x.a24();
+  } catch (e) {}
+  try {
+    x.a25();
+  } catch (e) {}
+  try {
+    x.a26();
+  } catch (e) {}
+  Expect.equals(0, x.gettersCalled);
+  Expect.equals(42, x.z);
+  Expect.equals(1, x.gettersCalled);
+}
diff --git a/tests/dart2js/native/native_class_fields_3_test.dart b/tests/dart2js/native/native_class_fields_3_test.dart
new file mode 100644
index 0000000..4812292
--- /dev/null
+++ b/tests/dart2js/native/native_class_fields_3_test.dart
@@ -0,0 +1,106 @@
+// 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 "native_testing.dart";
+
+// Verify that we can have fields with names that start with g and s even
+// though those names are reserved for getters and setters in minified mode.
+
+// Note: this works because end and send are both in the list of
+// reservedNativeProperties.  In general we don't check arbitrary
+// names for clashes because it's hard - subclasses can force superclasses
+// to rename getters, and that can force unrelated classes to change their
+// getters too if they have a property that has the same name.
+@Native("A")
+class A {
+  int bar;
+  int g;
+  int s;
+  int end;
+  int gend;
+  int send;
+  int gettersCalled;
+  int settersCalled;
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  function getter() {
+    this.gettersCalled++;
+    return 42;
+  }
+
+  function setter(x) {
+    this.settersCalled++;
+    return 314;
+  }
+
+  var descriptor = {
+      get: getter,
+      set: setter,
+      configurable: false,
+      writeable: false
+  };
+
+  function A(){
+    var a = Object.create(
+        { constructor: A },
+        { bar: descriptor,
+          g: descriptor,
+          s: descriptor,
+          end: descriptor,
+          gend: descriptor,
+          send: descriptor
+        });
+    a.gettersCalled = 0;
+    a.settersCalled = 0;
+    return a;
+  }
+
+  makeA = function() { return new A(); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+A makeA() native;
+
+class B {}
+
+main() {
+  nativeTesting();
+  setup();
+  confuse(new B());
+  var a = makeA();
+
+  Expect.equals(42, confuse(a).bar);
+  Expect.equals(42, confuse(a).g);
+  Expect.equals(42, confuse(a).s);
+  Expect.equals(42, confuse(a).end);
+  Expect.equals(42, confuse(a).gend);
+  Expect.equals(42, confuse(a).send);
+  Expect.equals(271, confuse(a).bar = 271);
+  Expect.equals(271, confuse(a).g = 271);
+  Expect.equals(271, confuse(a).s = 271);
+  Expect.equals(271, confuse(a).end = 271);
+  Expect.equals(271, confuse(a).gend = 271);
+  Expect.equals(271, confuse(a).send = 271);
+  Expect.equals(6, confuse(a).gettersCalled);
+  Expect.equals(6, confuse(a).settersCalled);
+
+  Expect.equals(42, a.bar);
+  Expect.equals(42, a.g);
+  Expect.equals(42, a.s);
+  Expect.equals(42, a.end);
+  Expect.equals(42, a.gend);
+  Expect.equals(42, a.send);
+  Expect.equals(271, a.bar = 271);
+  Expect.equals(271, a.g = 271);
+  Expect.equals(271, a.s = 271);
+  Expect.equals(271, a.end = 271);
+  Expect.equals(271, a.gend = 271);
+  Expect.equals(271, a.send = 271);
+  Expect.equals(12, a.gettersCalled);
+  Expect.equals(12, a.settersCalled);
+}
diff --git a/tests/dart2js/native/native_class_fields_test.dart b/tests/dart2js/native/native_class_fields_test.dart
new file mode 100644
index 0000000..e37adbe
--- /dev/null
+++ b/tests/dart2js/native/native_class_fields_test.dart
@@ -0,0 +1,70 @@
+// 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 "native_testing.dart";
+
+// Verify that native fields on classes are not renamed by the minifier.
+@Native("A")
+class A {
+  int myLongPropertyName;
+  int getValue;
+
+  int method(int z) => myLongPropertyName;
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+function getter() {
+  return ++this.getValue;
+}
+
+function setter(x) {
+  this.getValue += 10;
+}
+
+function A(){
+  var a = Object.create(
+      { constructor: A},
+      { myLongPropertyName: { get: getter,
+                              set: setter,
+                              configurable: false,
+                              writeable: false
+                            }
+      });
+  a.getValue = 0;
+  return a;
+}
+
+makeA = function(){return new A()};
+self.nativeConstructor(A);
+})()""");
+}
+
+A makeA() native;
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  a.myLongPropertyName = 21;
+  int gotten = a.myLongPropertyName;
+  Expect.equals(11, gotten);
+
+  // Force interceptor dispatch.
+  confuse(a).myLongPropertyName = 99;
+  gotten = confuse(a).myLongPropertyName;
+  Expect.equals(22, gotten);
+
+  var a2 = makeA();
+  if (a2 is A) {
+    // Inside this 'if' the compiler knows that a2 is an A, so it is tempted
+    // to access myLongPropertyName directly, using its minified name.  But
+    // renaming of native properties can only work using getters and setters
+    // that access the original name.
+    a2.myLongPropertyName = 21;
+    int gotten = a2.myLongPropertyName;
+    Expect.equals(11, gotten);
+  }
+}
diff --git a/tests/dart2js/native/native_class_inheritance1_frog_test.dart b/tests/dart2js/native/native_class_inheritance1_frog_test.dart
new file mode 100644
index 0000000..322dcba
--- /dev/null
+++ b/tests/dart2js/native/native_class_inheritance1_frog_test.dart
@@ -0,0 +1,114 @@
+// 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 "native_testing.dart";
+
+// Test to see if resolving a hidden native class's method interferes with
+// subsequent resolving the subclass's method.  This might happen if the
+// superclass caches the method in the prototype, so shadowing the dispatcher
+// stored on Object.prototype.
+
+// Version 1: It might be possible to call foo directly.
+@Native("A1")
+class A1 {
+  foo() native;
+}
+
+@Native("B1")
+class B1 extends A1 {
+  foo() native;
+}
+
+makeA1() native;
+makeB1() native;
+
+// Version 2: foo needs some kind of trampoline.
+@Native("A2")
+class A2 {
+  foo([a = 99]) native;
+}
+
+@Native("B2")
+class B2 extends A2 {
+  foo([z = 1000]) native;
+}
+
+makeA2() native;
+makeB2() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A1(){}
+  function B1(){}
+  inherits(B1, A1);
+  A1.prototype.foo = function(){return 100;};
+  B1.prototype.foo = function(){return 200;};
+
+  makeA1 = function(){return new A1()};
+  makeB1 = function(){return new B1()};
+
+  function A2(){}
+  function B2(){}
+  inherits(B2, A2);
+  A2.prototype.foo = function(a){return a + 10000;};
+  B2.prototype.foo = function(z){return z + 20000;};
+
+  makeA2 = function(){return new A2()};
+  makeB2 = function(){return new B2()};
+
+  self.nativeConstructor(A1);
+  self.nativeConstructor(A2);
+  self.nativeConstructor(B1);
+  self.nativeConstructor(B2);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeA1();
+  var b1 = makeB1();
+  Expect.equals(100, a1.foo());
+  Expect.equals(200, b1.foo());
+
+  var a2 = makeA2();
+  var b2 = makeB2();
+  Expect.equals(10000 + 99, a2.foo());
+  Expect.equals(20000 + 1000, b2.foo());
+
+  Expect.equals(10000 + 1, a2.foo(1));
+  Expect.equals(20000 + 2, b2.foo(2));
+
+  bool caught = false;
+  try {
+    a1.foo(20);
+  } catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError);
+  }
+  Expect.isTrue(caught, 'a1.foo(20) should throw');
+
+  caught = false;
+  try {
+    dynamic x = 123;
+    x.foo(20);
+  } catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError);
+  }
+  Expect.isTrue(caught, "x.foo(20) should throw");
+}
diff --git a/tests/dart2js/native/native_class_inheritance2_frog_test.dart b/tests/dart2js/native/native_class_inheritance2_frog_test.dart
new file mode 100644
index 0000000..8fa4b67
--- /dev/null
+++ b/tests/dart2js/native/native_class_inheritance2_frog_test.dart
@@ -0,0 +1,90 @@
+// 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 "native_testing.dart";
+
+// Test to see if resolving a hidden native class's method interferes with
+// subsequent resolving the subclass's method.  This might happen if the
+// superclass caches the method in the prototype, so shadowing the dispatcher
+// stored on Object.prototype.
+
+@Native("A")
+class A {
+  foo([a = 100]) native;
+}
+
+@Native("B")
+class B extends A {}
+
+@Native("C")
+class C extends B {
+  foo([z = 300]) native;
+}
+
+@Native("D")
+class D extends C {}
+
+makeA() native;
+makeB() native;
+makeC() native;
+makeD() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+
+  function A(){}
+  function B(){}
+  inherits(B, A);
+  function C(){}
+  inherits(C, B);
+  function D(){}
+  inherits(D, C);
+
+  A.prototype.foo = function(a){return 'A.foo(' + a + ')'};
+  C.prototype.foo = function(z){return 'C.foo(' + z + ')'};
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  makeC = function(){return new C()};
+  makeD = function(){return new D()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+  self.nativeConstructor(C);
+  self.nativeConstructor(D);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+  var b = makeB();
+  var c = makeC();
+  var d = makeD();
+
+  Expect.equals('A.foo(100)', b.foo());
+  Expect.equals('C.foo(300)', d.foo());
+  // If the above line fails with C.foo(100) then the dispatch to fill in the
+  // default got the wrong one, followed by a second dispatch that resolved to
+  // the correct native method.
+
+  Expect.equals('A.foo(1)', a.foo(1));
+  Expect.equals('A.foo(2)', b.foo(2));
+  Expect.equals('C.foo(3)', c.foo(3));
+  Expect.equals('C.foo(4)', d.foo(4));
+}
diff --git a/tests/dart2js/native/native_class_inheritance3_frog_test.dart b/tests/dart2js/native/native_class_inheritance3_frog_test.dart
new file mode 100644
index 0000000..af5a8e3
--- /dev/null
+++ b/tests/dart2js/native/native_class_inheritance3_frog_test.dart
@@ -0,0 +1,106 @@
+// 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 "native_testing.dart";
+
+// Test to see if resolving a hidden native class's method to noSuchMethod
+// interferes with subsequent resolving of the method.  This might happen if the
+// noSuchMethod is cached on Object.prototype.
+
+@Native("A1")
+class A1 {}
+
+@Native("B1")
+class B1 extends A1 {}
+
+makeA1() native;
+makeB1() native;
+
+@Native("A2")
+class A2 {
+  foo([a = 99]) native;
+}
+
+@Native("B2")
+class B2 extends A2 {}
+
+makeA2() native;
+makeB2() native;
+
+makeObject() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A1(){}
+  function B1(){}
+  inherits(B1, A1);
+
+  makeA1 = function(){return new A1()};
+  makeB1 = function(){return new B1()};
+
+  function A2(){}
+  function B2(){}
+  inherits(B2, A2);
+  A2.prototype.foo = function(a){return 'A2.foo(' + a  + ')';};
+
+  makeA2 = function(){return new A2()};
+  makeB2 = function(){return new B2()};
+
+  makeObject = function(){return new Object()};
+
+  self.nativeConstructor(A1);
+  self.nativeConstructor(A2);
+  self.nativeConstructor(B1);
+  self.nativeConstructor(B2);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeA1();
+  var b1 = makeB1();
+  var ob = makeObject();
+
+  // Does calling missing methods in one tree of inheritance forest affect other
+  // trees?
+  expectNoSuchMethod(() => b1.foo(), 'b1.foo()');
+  expectNoSuchMethod(() => a1.foo(), 'a1.foo()');
+  expectNoSuchMethod(() => ob.foo(), 'ob.foo()');
+
+  var a2 = makeA2();
+  var b2 = makeB2();
+
+  Expect.equals('A2.foo(99)', a2.foo());
+  Expect.equals('A2.foo(99)', b2.foo());
+  Expect.equals('A2.foo(1)', a2.foo(1));
+  Expect.equals('A2.foo(2)', b2.foo(2));
+
+  expectNoSuchMethod(() => b1.foo(3), 'b1.foo(3)');
+  expectNoSuchMethod(() => a1.foo(4), 'a1.foo(4)');
+}
+
+expectNoSuchMethod(action, note) {
+  bool caught = false;
+  try {
+    action();
+  } catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError, note);
+  }
+  Expect.isTrue(caught, note);
+}
diff --git a/tests/dart2js/native/native_class_inheritance4_frog_test.dart b/tests/dart2js/native/native_class_inheritance4_frog_test.dart
new file mode 100644
index 0000000..25f8fcd
--- /dev/null
+++ b/tests/dart2js/native/native_class_inheritance4_frog_test.dart
@@ -0,0 +1,160 @@
+// 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 "native_testing.dart";
+
+// Additional Dart code may be 'placed on' hidden native classes.  With
+// inheritance, the superclass method must not be reached by a call on the
+// subclass.
+
+@Native("A")
+class A {
+  var _field;
+
+  int get X => _field;
+  void set X(int x) {
+    _field = x;
+  }
+
+  int method(int z) => _field + z;
+}
+
+@Native("B")
+class B extends A {
+  var _field2;
+
+  int get X => _field2;
+  void set X(int x) {
+    _field2 = x;
+  }
+
+  int method(int z) => _field2 + z;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+
+  function A(){}
+  function B(){}
+  inherits(B, A);
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testBasicA_dynamic() {
+  setup(); // Fresh constructors.
+
+  var a = [makeA()][0];
+
+  a.X = 100;
+  Expect.equals(100, a._field);
+  Expect.equals(100, a.X);
+  Expect.equals(150, a.method(50));
+}
+
+testBasicA_typed() {
+  setup(); // Fresh constructors.
+
+  A a = makeA();
+
+  a.X = 100;
+  Expect.equals(100, a._field);
+  Expect.equals(100, a.X);
+  Expect.equals(150, a.method(50));
+}
+
+testBasicB_dynamic() {
+  setup(); // Fresh constructors.
+
+  var b = [makeB()][0];
+
+  b._field = 1;
+  b.X = 123;
+  Expect.equals(1, b._field);
+  Expect.equals(123, b._field2);
+  Expect.equals(123, b.X);
+  Expect.equals(200, b.method(77));
+}
+
+testBasicB_typed() {
+  setup(); // Fresh constructors.
+
+  B b = makeB();
+
+  b._field = 1;
+  b.X = 123;
+  Expect.equals(1, b._field);
+  Expect.equals(123, b._field2);
+  Expect.equals(123, b.X);
+  Expect.equals(200, b.method(77));
+}
+
+testAB_dynamic() {
+  setup(); // Fresh constructors.
+
+  var things = <dynamic>[makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  a.X = 100;
+  Expect.equals(100, a._field);
+  Expect.equals(100, a.X);
+  Expect.equals(150, a.method(50));
+
+  b._field = 1;
+  b._field2 = 2;
+  b.X = 123;
+  Expect.equals(1, b._field);
+  Expect.equals(123, b._field2);
+  Expect.equals(123, b.X);
+  Expect.equals(200, b.method(77));
+}
+
+testAB_typed() {
+  setup(); // Fresh constructors.
+
+  A a = makeA();
+  B b = makeB();
+
+  a.X = 100;
+  Expect.equals(100, a._field);
+  Expect.equals(100, a.X);
+  Expect.equals(150, a.method(50));
+
+  b._field = 1;
+  b._field2 = 2;
+  b.X = 123;
+  Expect.equals(1, b._field);
+  Expect.equals(123, b._field2);
+  Expect.equals(123, b.X);
+  Expect.equals(200, b.method(77));
+}
+
+main() {
+  nativeTesting();
+  testBasicA_dynamic();
+  testBasicA_typed();
+  testBasicB_dynamic();
+  testBasicB_typed();
+  testAB_dynamic();
+  testAB_typed();
+}
diff --git a/tests/dart2js/native/native_class_is_check1_frog_test.dart b/tests/dart2js/native/native_class_is_check1_frog_test.dart
new file mode 100644
index 0000000..6b8bb37
--- /dev/null
+++ b/tests/dart2js/native/native_class_is_check1_frog_test.dart
@@ -0,0 +1,53 @@
+// 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 "native_testing.dart";
+
+// Test for correct simple is-checks on hidden native classes.
+
+abstract class I {
+  I read();
+  write(covariant I x);
+}
+
+// Native implementation.
+
+@Native("A")
+class A implements I {
+  // The native class accepts only other native instances.
+  A read() native;
+  write(A x) native;
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(){}
+  A.prototype.read = function() { return this._x; };
+  A.prototype.write = function(x) { this._x = x; };
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+class B {}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeA();
+  var ob = new Object();
+
+  Expect.isFalse(ob is I);
+  Expect.isFalse(ob is A);
+  Expect.isFalse(ob is B);
+
+  Expect.isTrue(a1 is I);
+  Expect.isTrue(a1 is A);
+  Expect.isTrue(a1 is! B);
+}
diff --git a/tests/dart2js/native/native_class_is_check3_frog_test.dart b/tests/dart2js/native/native_class_is_check3_frog_test.dart
new file mode 100644
index 0000000..98cbf91
--- /dev/null
+++ b/tests/dart2js/native/native_class_is_check3_frog_test.dart
@@ -0,0 +1,85 @@
+// 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 "native_testing.dart";
+
+// Test for correct simple is-checks on hidden native classes.
+
+abstract class J {}
+
+abstract class I extends J {
+  I read();
+  write(covariant I x);
+}
+
+// Native implementation.
+
+@Native("A")
+class A implements I {
+  // The native class accepts only other native instances.
+  A read() native;
+  write(A x) native;
+}
+
+@Native("B")
+class B extends A {}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A(){}
+  function B(){}
+  inherits(B, A);
+  A.prototype.read = function() { return this._x; };
+  A.prototype.write = function(x) { this._x = x; };
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+class C {}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeA();
+  var b1 = makeB();
+  var ob = new Object();
+
+  Expect.isFalse(ob is J);
+  Expect.isFalse(ob is I);
+  Expect.isFalse(ob is A);
+  Expect.isFalse(ob is B);
+  Expect.isFalse(ob is C);
+
+  // Use b1 first to prevent a1 is checks patching the A prototype.
+  Expect.isTrue(b1 is J);
+  Expect.isTrue(b1 is I);
+  Expect.isTrue(b1 is A);
+  Expect.isTrue(b1 is B);
+  Expect.isTrue(b1 is! C);
+
+  Expect.isTrue(a1 is J);
+  Expect.isTrue(a1 is I);
+  Expect.isTrue(a1 is A);
+  Expect.isTrue(a1 is! B);
+  Expect.isTrue(a1 is! C);
+}
diff --git a/tests/dart2js/native/native_class_with_dart_methods_frog_test.dart b/tests/dart2js/native/native_class_with_dart_methods_frog_test.dart
new file mode 100644
index 0000000..574e684
--- /dev/null
+++ b/tests/dart2js/native/native_class_with_dart_methods_frog_test.dart
@@ -0,0 +1,41 @@
+// 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 'native_testing.dart';
+
+// Additional Dart code may be 'placed on' hidden native classes.
+
+@Native("A")
+class A {
+  var _field;
+
+  int get X => _field;
+  void set X(int x) {
+    _field = x;
+  }
+
+  int method(int z) => _field + z;
+}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+
+  a.X = 100;
+  Expect.equals(100, a.X);
+  Expect.equals(150, a.method(50));
+}
diff --git a/tests/dart2js/native/native_closure_identity_frog_test.dart b/tests/dart2js/native/native_closure_identity_frog_test.dart
new file mode 100644
index 0000000..c5f5084
--- /dev/null
+++ b/tests/dart2js/native/native_closure_identity_frog_test.dart
@@ -0,0 +1,79 @@
+// 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.
+
+import 'native_testing.dart';
+
+typedef MyFunctionType();
+
+@Native("A")
+class A {
+  setClosure(MyFunctionType f) native;
+  check(MyFunctionType f) native;
+  invoke() native;
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.setClosure = function(f) { this.f = f; };
+  A.prototype.check = function(f) { return this.f === f; };
+  A.prototype.invoke = function() { return this.f(); };
+  makeA = function(){return new A()};
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+var staticClosure;
+staticMethod() => 42;
+
+class B {
+  var instanceClosure;
+  instanceMethod() => 43;
+}
+
+checkUntyped(a, closure) {
+  a.setClosure(closure);
+  Expect.isTrue(a.check(closure));
+  Expect.equals(closure(), a.invoke());
+}
+
+checkTyped(A a, MyFunctionType closure) {
+  a.setClosure(closure);
+  Expect.isTrue(a.check(closure));
+  Expect.equals(closure(), a.invoke());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  staticClosure = () => 44;
+  B b = new B();
+  b.instanceClosure = () => 45;
+
+  closureStatement() => 46;
+  var closureExpression = () => 47;
+
+  checkUntyped(makeA(), staticClosure);
+  checkTyped(makeA(), staticClosure);
+
+  checkUntyped(makeA(), staticMethod);
+  checkTyped(makeA(), staticMethod);
+
+  checkUntyped(makeA(), b.instanceClosure);
+  checkTyped(makeA(), b.instanceClosure);
+
+  checkUntyped(makeA(), b.instanceMethod);
+  checkTyped(makeA(), b.instanceMethod);
+
+  checkUntyped(makeA(), closureStatement);
+  checkTyped(makeA(), closureStatement);
+
+  checkUntyped(makeA(), closureExpression);
+  checkTyped(makeA(), closureExpression);
+}
diff --git a/tests/dart2js/native/native_constructor_name_test.dart b/tests/dart2js/native/native_constructor_name_test.dart
new file mode 100644
index 0000000..9d60a40
--- /dev/null
+++ b/tests/dart2js/native/native_constructor_name_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, 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 to see if a Dart class name is confused with dispatch tag.  Both class A
+// and class Z have a JavaScript constructor named "A".  The dynamic native
+// class dispatch hook on Object.prototype should avoid patching the Dart class
+// A.  This could be done by renaming the Dart constructor or by being able to
+// check that objects are Dart classes.
+
+import "native_testing.dart";
+
+class A {}
+
+@Native("A")
+class Z {
+  foo() => 100;
+}
+
+makeZ() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A(){}
+  makeZ = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  dynamic a = new A();
+  var z = makeZ();
+
+  Expect.equals(100, z.foo());
+
+  Expect.throws(() => a.foo(), (ex) => ex is NoSuchMethodError);
+}
diff --git a/tests/dart2js/native/native_equals_frog_test.dart b/tests/dart2js/native/native_equals_frog_test.dart
new file mode 100644
index 0000000..0b460b9
--- /dev/null
+++ b/tests/dart2js/native/native_equals_frog_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+@Native("A")
+class A {}
+
+int calls = 0;
+
+@Native("B")
+class B {
+  bool operator ==(other) {
+    ++calls;
+    return other is B;
+  }
+
+  int get hashCode => 1;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  Expect.isTrue(a == a);
+  Expect.isTrue(identical(a, a));
+
+  Expect.isFalse(a == makeA());
+  Expect.isFalse(identical(a, makeA()));
+
+  var b = makeB();
+  Expect.isTrue(b == b);
+  Expect.isTrue(identical(b, b));
+
+  Expect.isTrue(b == makeB());
+  Expect.isFalse(identical(b, makeB()));
+
+  Expect.equals(2, calls);
+}
diff --git a/tests/dart2js/native/native_exception2_test.dart b/tests/dart2js/native/native_exception2_test.dart
new file mode 100644
index 0000000..59cf5b0
--- /dev/null
+++ b/tests/dart2js/native/native_exception2_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2013, 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.
+
+// Similar to native_exception_test.dart but also defines a native
+// class.  This exercises a different code path in emitter.dart.
+
+library native_exception2_test;
+
+import 'native_exception_test.dart' as other;
+import 'native_testing.dart';
+
+@Native("NativeClass")
+class NativeClass {
+  foo() => 'oof';
+}
+
+makeNativeClass() native;
+
+setup() {
+  JS('', r"""
+(function(){
+  function NativeClass() {}
+  makeNativeClass = function() { return new NativeClass(); };
+  self.nativeConstructor(NativeClass);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  Expect.equals('oof', makeNativeClass().foo());
+  other.main();
+}
diff --git a/tests/dart2js/native/native_exception_test.dart b/tests/dart2js/native/native_exception_test.dart
new file mode 100644
index 0000000..e3e4a98
--- /dev/null
+++ b/tests/dart2js/native/native_exception_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, 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 that dart2js can handle unexpected exception types.
+
+library native_exception_test;
+
+import 'native_testing.dart';
+
+main() {
+  var previous;
+  check(e) {
+    print('$e');
+    Expect.equals(e, e);
+    Expect.notEquals(e, new Object());
+    Expect.notEquals(e, previous);
+    previous = e;
+    return '$e' != '[object Object]';
+  }
+
+  Expect.throws(() {
+    JS('void', 'noGlobalVariableWithThisName');
+  }, check);
+  Expect.throws(() {
+    JS('void', 'throw 3');
+  }, check);
+  Expect.throws(() {
+    JS('bool', 'Object.prototype.hasOwnProperty.call(undefined, "foo")');
+  }, check);
+  Expect.throws(() {
+    JS('void', 'throw new ReferenceError()');
+  }, check);
+  Expect.throws(() {
+    JS('void', 'throw void 0');
+  }, check);
+  Expect.throws(() {
+    JS('void', 'throw "a string"');
+  }, check);
+  Expect.throws(() {
+    JS('void', 'throw null');
+  }, check);
+}
diff --git a/tests/dart2js/native/native_exceptions1_frog_test.dart b/tests/dart2js/native/native_exceptions1_frog_test.dart
new file mode 100644
index 0000000..497a80c
--- /dev/null
+++ b/tests/dart2js/native/native_exceptions1_frog_test.dart
@@ -0,0 +1,112 @@
+// 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 'native_testing.dart';
+
+// Test that hidden native exception classes can be marked as existing.
+//
+// To infer which native hidden types exist, we need
+//   (1) return types of native methods and getters
+//   (2) argument types of callbacks
+//   (3) exceptions thrown by the operation.
+//
+// (1) and (2) can be achieved by having nicely typed native methods, but there
+// is no place in the Dart language to communicate (3).  So we use the following
+// fake body technique.
+
+// The exception type.
+@Native("E")
+class E {
+  E._used() native; // Bogus native constructor, called only from fake body.
+
+  final int code;
+}
+
+// Type with exception-throwing methods.
+@Native("A")
+class A {
+  // Exception class E is created.
+  @Creates("E")
+  @Returns('int')
+  op(int x) native;
+}
+
+// This class is here just so that a dynamic context is polymorphic.
+class B {
+  int get code => 666;
+  op(String x) => 123;
+}
+
+makeA() native;
+
+void setup1() {
+  JS('', r"""
+(function(){
+  // Ensure we are not relying on global names 'A' and 'E'.
+  A = null;
+  E = null;
+})()""");
+}
+
+void setup2() {
+  JS('', r"""
+(function(){
+// This code is all inside 'setup2' and so not accessible from the global scope.
+function E(x){ this.code = x; }
+
+function A(){}
+A.prototype.op = function (x) {
+  if (x & 1) throw new E(100);
+  return  x / 2;
+};
+makeA = function(){return new A()};
+
+self.nativeConstructor(E);
+self.nativeConstructor(A);
+})()""");
+}
+
+int inscrutable(int x) => x == 0 ? 0 : x | inscrutable(x & (x - 1));
+
+main() {
+  nativeTesting();
+  setup1();
+  setup2();
+
+  var things = [makeA(), new B()];
+  var a = things[inscrutable(0)];
+  var b = things[inscrutable(1)];
+
+  Expect.equals(25, a.op(50));
+  Expect.equals(123, b.op('hello'));
+  Expect.equals(666, b.code);
+
+  bool threw = false;
+  try {
+    var x = a.op(51);
+  } catch (e) {
+    threw = true;
+    Expect.equals(100, e.code);
+    Expect.isTrue(e is E);
+  }
+  Expect.isTrue(threw);
+
+  // Again, but with statically typed receivers.
+  A aa = a;
+  B bb = b;
+
+  Expect.equals(25, aa.op(50));
+  Expect.equals(123, bb.op('hello'));
+  Expect.equals(666, bb.code);
+
+  threw = false;
+  try {
+    var x = aa.op(51);
+  } on E catch (e) {
+    threw = true;
+    Expect.equals(100, e.code);
+    Expect.isTrue(e is E);
+  }
+  Expect.isTrue(threw);
+}
diff --git a/tests/dart2js/native/native_field_invocation2_test.dart b/tests/dart2js/native/native_field_invocation2_test.dart
new file mode 100644
index 0000000..9c150687
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation2_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+@Native("NNative")
+class NNative {
+  var status;
+
+  var f;
+
+  g(val) => "### $val ###";
+}
+
+class ClickCounter {
+  var status;
+
+  var f;
+
+  ClickCounter() {
+    f = wrap(g);
+  }
+
+  g(val) => "### $val ###";
+}
+
+wrap(cb) {
+  return (val) {
+    return cb("!!! $val !!!");
+  };
+}
+
+nativeId(x) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+nativeId = function(x) { return x; }
+})()""");
+}
+
+main() {
+  setup();
+  // Make sure the ClickCounter class goes through interceptors.
+  Expect.equals("### !!! 42 !!! ###", nativeId(new ClickCounter()).f(42));
+  // We are interested in the direct call, where the type is known.
+  Expect.equals("### !!! 499 !!! ###", new ClickCounter().f(499));
+}
diff --git a/tests/dart2js/native/native_field_invocation3_test.dart b/tests/dart2js/native/native_field_invocation3_test.dart
new file mode 100644
index 0000000..9ed3d9c
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation3_test.dart
@@ -0,0 +1,45 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+makeCC() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function CC() {}
+  makeCC = function() { return new CC() };
+  self.nativeConstructor(CC);
+})()""");
+}
+
+@Native("CC")
+class ClickCounter {
+  var status;
+
+  var foo;
+
+  init() {
+    foo = wrap(g);
+  }
+
+  g(val) => "### $val ###";
+}
+
+wrap(cb) {
+  return (val) {
+    return cb("!!! $val !!!");
+  };
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var c = makeCC();
+  c.init();
+  // `foo` contains a closure. Make sure that invoking foo through an
+  // interceptor works.
+  Expect.equals("### !!! 499 !!! ###", c.foo(499));
+}
diff --git a/tests/dart2js/native/native_field_invocation4_test.dart b/tests/dart2js/native/native_field_invocation4_test.dart
new file mode 100644
index 0000000..afce3c09
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation4_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+@Native("A")
+class A {
+  var foo;
+}
+
+class B {
+  var foo;
+}
+
+nativeId(x) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+nativeId = function(x) { return x; }
+})()""");
+}
+
+main() {
+  setup();
+  var b = new B();
+  b.foo = (x) => x + 1;
+  b = nativeId(b); // Inferrer doesn't know if A has been instantiated.
+  // At this point b could be A or B. The call to "foo" thus needs to go through
+  // an interceptor. Tests that the interceptor works for retrieving the field
+  // and invoking the closure.
+  // Use a type-check to guarantee that b is a "B".
+  if (b is B) {
+    Expect.equals(499, b.foo(498));
+  }
+}
diff --git a/tests/dart2js/native/native_field_invocation5_test.dart b/tests/dart2js/native/native_field_invocation5_test.dart
new file mode 100644
index 0000000..abd0169
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation5_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+makeCC() native;
+nativeFirst(x, y) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function CC() {}
+  makeCC = function() { return new CC() };
+  nativeFirst = function(x, y) { return x; };
+  self.nativeConstructor(CC);
+})()""");
+}
+
+class C {
+  foo(x) => x;
+}
+
+@Native("CC")
+class ClickCounter {
+  var status;
+
+  var foo;
+
+  init() {
+    foo = wrap(g);
+  }
+
+  g(val) => "### $val ###";
+}
+
+wrap(cb) {
+  return (val) {
+    return cb("!!! $val !!!");
+  };
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var c = makeCC();
+  c.init();
+  var c2 = new C();
+  c = nativeFirst(c, c2);
+  // After the `nativeFirst` invocation dart2js doesn't know if c is a
+  // ClickCounter or C. It must go through the interceptor and call the foo$1
+  // invocation.
+  Expect.equals("### !!! 499 !!! ###", c.foo(499));
+}
diff --git a/tests/dart2js/native/native_field_invocation6_test.dart b/tests/dart2js/native/native_field_invocation6_test.dart
new file mode 100644
index 0000000..17ed660
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation6_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+makeA() native;
+nativeFirst(x, y) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  nativeFirst = function(x, y) { return x; };
+
+  function A() {}
+  makeA = function() { return new A() };
+  self.nativeConstructor(A);
+})()""");
+}
+
+@Native("A")
+class A {
+  var _foo;
+
+  get foo => _foo;
+
+  init() {
+    _foo = () => 42;
+  }
+}
+
+class B {
+  var foo = 499;
+}
+
+class C {
+  foo() => 499;
+}
+
+class D {
+  var foo = () => 499;
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  a.init();
+  var b = new B();
+  var c = new C();
+  var d = new D();
+  a = nativeFirst(a, b);
+  a = nativeFirst(a, c);
+  a = nativeFirst(a, d);
+  // The variable a is still an instance of class A, but dart2js can't infer
+  // that anymore.
+  Expect.equals(42, a.foo());
+}
diff --git a/tests/dart2js/native/native_field_invocation_test.dart b/tests/dart2js/native/native_field_invocation_test.dart
new file mode 100644
index 0000000..e6f13b6
--- /dev/null
+++ b/tests/dart2js/native/native_field_invocation_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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 "native_testing.dart";
+
+@Native("A")
+class A {
+  var foo;
+}
+
+class B {
+  var foo;
+}
+
+nativeId(x) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  nativeId = function(x) { return x; }
+})()""");
+}
+
+main() {
+  setup();
+  var b = new B();
+  b.foo = (x) => x + 1;
+  b = nativeId(b); // Inferrer doesn't know if A has been instantiated.
+  // At this point b could be A or B. The call to "foo" thus needs to go through
+  // an interceptor. Tests that the interceptor works for retrieving the Dart
+  // class field and invoking the closure.
+  Expect.equals(499, b.foo(498));
+}
diff --git a/tests/dart2js/native/native_field_name_test.dart b/tests/dart2js/native/native_field_name_test.dart
new file mode 100644
index 0000000..66e25ac
--- /dev/null
+++ b/tests/dart2js/native/native_field_name_test.dart
@@ -0,0 +1,70 @@
+// 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 'native_testing.dart';
+
+// Check that native fields are not incorrectly renamed.
+
+@Native("A")
+class A {
+  int myLongPropertyName;
+  int getValue;
+
+  int method(int z) => myLongPropertyName;
+}
+
+// This code is inside the setup function, so the function names are not
+// accessible, but the makeA variable is global through the magic of JS scoping.
+// The contents of this are of course not analyzable by the compiler.
+void setup() {
+  JS('', r"""
+(function(){
+  function getter() {
+    return ++this.getValue;
+  }
+
+  function setter(x) {
+    this.getValue += 10;
+  }
+
+  function A(){
+    var a = Object.create(
+        { constructor: A },
+        { myLongPropertyName: { get: getter,
+                                set: setter,
+                                configurable: false,
+                                writeable: false
+                              }
+        });
+    a.getValue = 0;
+    return a;
+  }
+
+  makeA = function(){return new A()};
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+/*A*/ makeA() native;
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  a.myLongPropertyName = 21;
+  int gotten = a.myLongPropertyName;
+  Expect.equals(11, gotten);
+
+  var a2 = makeA();
+  if (a2 is A) {
+    // Inside this 'if' the compiler knows that a2 is an A, so it is tempted
+    // to access myLongPropertyName directly, using its minified name.  But
+    // renaming of native properties can only work using getters and setters
+    // that access the original name.
+    a2.myLongPropertyName = 21;
+    int gotten = a2.myLongPropertyName;
+    Expect.equals(11, gotten);
+  }
+}
diff --git a/tests/dart2js/native/native_field_optimization_test.dart b/tests/dart2js/native/native_field_optimization_test.dart
new file mode 100644
index 0000000..5b7e061
--- /dev/null
+++ b/tests/dart2js/native/native_field_optimization_test.dart
@@ -0,0 +1,97 @@
+// Copyright (c) 2015, 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 'native_testing.dart';
+
+// Test that compiler is cautious with optimizations on native fields.  The
+// motivation is that DOM properties are getters and setters with arbitrary
+// effects.  Setting CSSStyleDeclaration.borderLeft can canonicalize the value
+// and changes the value of CSSStyleDeclaration.border.
+
+@Native("Foo")
+class Foo {
+  var a;
+  var b;
+  var ab;
+}
+
+Foo makeFoo() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function Foo() { this.i = 0; }
+
+  Object.defineProperty(Foo.prototype, 'a', {
+    get: function () { return (this._a || '') + ++this.i; },
+    set: function (v) { this._a = v.toLowerCase(); }
+  });
+
+  Object.defineProperty(Foo.prototype, 'b', {
+    get: function () { return this._b || ''; },
+    set: function (v) { this._b = v.toLowerCase(); }
+  });
+
+  Object.defineProperty(Foo.prototype, 'ab', {
+    get: function () { return this.a + ' ' + this.b; },
+    set: function (v) {
+      var s = v.split(' ');
+      this.a = s[0];
+      this.b = s[1];
+    }
+  });
+
+  makeFoo = function() { return new Foo() };
+
+  self.nativeConstructor(Foo);
+})()""");
+}
+
+test1() {
+  var f = makeFoo();
+  f.a = 'Hi';
+  f.b = 'There';
+  Expect.equals('hi1 there', f.ab);
+}
+
+test2() {
+  // Test for CSE. dart2js currently does CSE loads. Is this the right choice?
+  var f = makeFoo();
+  var a1 = f.a;
+  var b1 = f.b;
+  var a2 = f.a;
+  Expect.equals('1', a1);
+  if (a2 == a1) {
+    // We did CSE.
+  } else {
+    Expect.equals('2', a2);
+  }
+}
+
+test3() {
+  // Must not CSE over a native field store.
+  var f = makeFoo();
+  var a1 = f.a;
+  f.ab = 'X Y';
+  var a2 = f.a;
+  Expect.equals('1', a1);
+  Expect.equals('x2', a2);
+}
+
+test4() {
+  // Must not store-forward.
+  var f = makeFoo();
+  f.a = 'A';
+  var a2 = f.a;
+  Expect.equals('a1', a2);
+}
+
+main() {
+  nativeTesting();
+  setup();
+  (test1)();
+  (test2)();
+  (test3)();
+  (test4)();
+}
diff --git a/tests/dart2js/native/native_field_rename_1_frog_test.dart b/tests/dart2js/native/native_field_rename_1_frog_test.dart
new file mode 100644
index 0000000..5fd6602
--- /dev/null
+++ b/tests/dart2js/native/native_field_rename_1_frog_test.dart
@@ -0,0 +1,89 @@
+// 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.
+
+// A native method prevents other members from having that name, including
+// fields.  However, native fields keep their name.  The implication: a getter
+// for the field must be based on the field's name, not the field's jsname.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {
+  int key; //  jsname is 'key'
+  int getKey() => key;
+}
+
+class B {
+  int key; //  jsname is not 'key'
+  B([this.key = 222]);
+  int getKey() => key;
+}
+
+@Native("X")
+class X {
+  @JSName('key')
+  int native_key_method() native;
+  // This should cause B.key to be renamed, but not A.key.
+
+  @JSName('key')
+  int key() native;
+}
+
+A makeA() native;
+X makeX() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(){ this.key = 111; }
+  A.prototype.getKey = function(){return this.key;};
+
+  function X(){}
+  X.prototype.key = function(){return 666;};
+
+  makeA = function(){return new A()};
+  makeX = function(){return new X()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(X);
+})()""");
+}
+
+testDynamic() {
+  var a = confuse(makeA());
+  var b = confuse(new B());
+  var x = confuse(makeX());
+
+  Expect.equals(111, a.key);
+  Expect.equals(222, b.key);
+  Expect.equals(111, a.getKey());
+  Expect.equals(222, b.getKey());
+
+  Expect.equals(666, x.native_key_method());
+  Expect.equals(666, x.key());
+  // The getter for the closurized member must also have the right name.
+  var fn = x.key;
+  Expect.equals(666, fn());
+}
+
+testTyped() {
+  A a = makeA();
+  B b = new B();
+  X x = makeX();
+
+  Expect.equals(666, x.native_key_method());
+  Expect.equals(111, a.key);
+  Expect.equals(222, b.key);
+  Expect.equals(111, a.getKey());
+  Expect.equals(222, b.getKey());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testTyped();
+  testDynamic();
+}
diff --git a/tests/dart2js/native/native_field_rename_2_frog_test.dart b/tests/dart2js/native/native_field_rename_2_frog_test.dart
new file mode 100644
index 0000000..2c44d54
--- /dev/null
+++ b/tests/dart2js/native/native_field_rename_2_frog_test.dart
@@ -0,0 +1,104 @@
+// 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.
+
+// A native method prevents other members from having that name, including
+// fields.  However, native fields keep their name.  The implication: a getter
+// for the field must be based on the field's name, not the field's jsname.
+
+import 'native_testing.dart';
+
+abstract class I {
+  int key;
+}
+
+@Native("A")
+class A implements I {
+  int key; //  jsname is 'key'
+  int getKey() => key;
+}
+
+class B implements I {
+  int key; //  jsname is not 'key'
+  B([this.key = 222]);
+  int getKey() => key;
+}
+
+@Native("X")
+class X {
+  @JSName('key')
+  int native_key_method() native;
+  // This should cause B.key to be renamed, but not A.key.
+  @JSName('key')
+  int key() native;
+}
+
+A makeA() native;
+X makeX() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(){ this.key = 111; }
+  A.prototype.getKey = function(){return this.key;};
+
+  function X(){}
+  X.prototype.key = function(){return 666;};
+
+  makeA = function(){return new A()};
+  makeX = function(){return new X()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(X);
+})()""");
+}
+
+testDynamic() {
+  var a = confuse(makeA());
+  var b = confuse(new B());
+  var x = confuse(makeX());
+
+  Expect.equals(111, a.key);
+  Expect.equals(222, b.key);
+  Expect.equals(111, a.getKey());
+  Expect.equals(222, b.getKey());
+
+  Expect.equals(666, x.native_key_method());
+  Expect.equals(666, x.key());
+  var fn = x.key;
+  Expect.equals(666, fn());
+}
+
+testPartial() {
+  var things = [makeA(), new B(), makeX()];
+  I a = things[0];
+  I b = things[1];
+
+  // All subtypes of I have a field 'key'. The compiler might be tempted to
+  // generate a direct property access, but that will fail since one of the
+  // fields is renamed.  A getter call is required here.
+  Expect.equals(111, a.key);
+  Expect.equals(222, b.key);
+}
+
+testTyped() {
+  A a = makeA();
+  B b = new B();
+  X x = makeX();
+
+  Expect.equals(666, x.native_key_method());
+  Expect.equals(111, a.key);
+  Expect.equals(222, b.key);
+  Expect.equals(111, a.getKey());
+  Expect.equals(222, b.getKey());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testTyped();
+  testPartial();
+  testDynamic();
+}
diff --git a/tests/dart2js/native/native_library_same_name_used_frog_test.dart b/tests/dart2js/native/native_library_same_name_used_frog_test.dart
new file mode 100644
index 0000000..4909b7f
--- /dev/null
+++ b/tests/dart2js/native/native_library_same_name_used_frog_test.dart
@@ -0,0 +1,59 @@
+// 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.
+
+// Test for correct hidden native class when abstract class has same name.
+
+library main;
+
+import 'native_testing.dart';
+import 'native_library_same_name_used_lib1.dart';
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is all inside 'setup' and so not accessible from the global
+  // scope.
+  function I(){}
+  I.prototype.read = function() { return this._x; };
+  I.prototype.write = function(x) { this._x = x; };
+  makeI = function(){return new I()};
+  self.nativeConstructor(I);
+})()""");
+}
+
+// A pure Dart implementation of I.
+
+class ProxyI implements I {
+  ProxyI b;
+  ProxyI read() {
+    return b;
+  }
+
+  write(ProxyI x) {
+    b = x;
+  }
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = makeI();
+  var a2 = makeI();
+  var b1 = new ProxyI();
+  var b2 = new ProxyI();
+  var ob = new Object();
+
+  Expect.isFalse(ob is I, 'ob is I');
+  Expect.isFalse(ob is ProxyI, 'ob is ProxyI');
+
+  Expect.isTrue(b1 is I, 'b1 is I');
+  Expect.isTrue(b1 is ProxyI, 'b1 is ProxyI');
+
+  Expect.isTrue(a1 is I, 'a1 is I');
+  Expect.isFalse(a1 is ProxyI, 'a1 is ProxyI');
+
+  Expect.isTrue(confuse(a1) is I, 'a1 is I');
+  Expect.isFalse(confuse(a1) is ProxyI, 'a1 is ProxyI');
+}
diff --git a/tests/dart2js/native/native_library_same_name_used_lib1.dart b/tests/dart2js/native/native_library_same_name_used_lib1.dart
new file mode 100644
index 0000000..5046ff7
--- /dev/null
+++ b/tests/dart2js/native/native_library_same_name_used_lib1.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// 'I' is the name of an abstract class and the name of the native class.
+
+library native_library_same_name_used_lib1;
+
+import 'native_library_same_name_used_lib2.dart';
+import 'dart:_foreign_helper' show JS;
+
+abstract class I {
+  I read();
+  write(I x);
+}
+
+makeI() => JS('creates:Impl; returns:I;', 'makeI()');
diff --git a/tests/dart2js/native/native_library_same_name_used_lib2.dart b/tests/dart2js/native/native_library_same_name_used_lib2.dart
new file mode 100644
index 0000000..feec6bb
--- /dev/null
+++ b/tests/dart2js/native/native_library_same_name_used_lib2.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Native implementation.
+
+library lib2;
+
+import 'native_library_same_name_used_lib1.dart'; // To get abstract class I.
+import 'dart:_js_helper';
+
+// Native impl has same name as abstract class.
+@Native("I")
+class Impl implements I {
+  Impl read() native;
+  write(Impl x) native;
+}
diff --git a/tests/dart2js/native/native_method_inlining_test.dart b/tests/dart2js/native/native_method_inlining_test.dart
new file mode 100644
index 0000000..ba0ee3b
--- /dev/null
+++ b/tests/dart2js/native/native_method_inlining_test.dart
@@ -0,0 +1,145 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+// Test that native methods with unnamed optional arguments are called with the
+// number of arguments in the call site AND the call site is inlined.
+
+import 'native_testing.dart';
+
+typedef int Int2Int(int x);
+
+@Native("A")
+class A {
+  int foo([x, y, z]) native;
+
+  // Calls can be inlined provided they don't pass an argument.
+  int callFun([Int2Int fn]) native;
+}
+
+class B {
+  @pragma('dart2js:noElision')
+  static var g;
+
+  @pragma('dart2js:noInline')
+  method1(a) {
+    g = '(Method1Tag)'; // Tag to identify compiled JavaScript method.
+    A x = makeA();
+    // Call sites that are searched for in compiled JavaScript.
+    x.foo();
+    x.foo(1);
+    x.foo(2, 10);
+    return x.foo(3, 10, 30);
+  }
+
+  @pragma('dart2js:noInline')
+  method2() {
+    g = '(Method2Tag)';
+    A x = makeA();
+    var r1 = x.callFun(); // Can be inlined.
+    var r2 = x.callFun();
+    return r1 + r2;
+  }
+
+  @pragma('dart2js:noInline')
+  method3() {
+    g = '(Method3Tag)';
+    A x = makeA();
+    var r1 = x.callFun((x) => x * 2); // Can't be inlined due to conversion.
+    var r2 = x.callFun((x) => x * 0);
+    return r1 + r2;
+  }
+}
+
+A makeA() native;
+
+String findMethodTextContaining(instance, string) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo = function () { return arguments.length; };
+  A.prototype.callFun = function (fn) { return fn ? fn(123) : 1; };
+
+  makeA = function(){return new A()};
+
+  findMethodTextContaining = function (instance, string) {
+    var proto = Object.getPrototypeOf(instance);
+    var keys = Object.keys(proto);
+    for (var i = 0; i < keys.length; i++) {
+      var name = keys[i];
+      var member = proto[name];
+      var s = String(member);
+      if (s.indexOf(string)>0) return s;
+    }
+  };
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+void match(String s, String pattern1) {
+  var pattern2 = pattern1.replaceAll(' ', '');
+  Expect.isTrue(s.contains(pattern1) || s.contains(pattern2),
+      "expected $pattern1 or $pattern2 in '$s'");
+}
+
+void nomatch(String s, String pattern1) {
+  var pattern2 = pattern1.replaceAll(' ', '');
+  Expect.isFalse(s.contains(pattern1) || s.contains(pattern2),
+      "should not have $pattern1 or $pattern2 in '$s'");
+}
+
+test1() {
+  String method1 = findMethodTextContaining(new B(), '(Method1Tag)');
+  Expect.isNotNull(method1, 'No method found containing "(Method1Tag)"');
+
+  // Direct (inlined) calls don't have $3 or minified names.
+  match(method1, r'.foo()');
+  match(method1, r'.foo(1)');
+  match(method1, r'.foo(2, 10)');
+  match(method1, r'.foo(3, 10, 30)');
+
+  // Ensure the methods are compiled by calling them.
+  var a = makeA();
+
+  Expect.equals(0, a.foo());
+  Expect.equals(1, a.foo(10));
+  Expect.equals(2, a.foo(10, 20));
+  Expect.equals(3, a.foo(10, 20, 30));
+
+  var b = new B();
+  var r = b.method1(a);
+  Expect.equals(3, r);
+}
+
+test2() {
+  String method2 = findMethodTextContaining(new B(), '(Method2Tag)');
+  Expect.isNotNull(method2, 'No method found containing "(Method2Tag)"');
+  // Can always inline the zero-arg call.
+  match(method2, r'.callFun()');
+
+  String method3 = findMethodTextContaining(new B(), '(Method3Tag)');
+  Expect.isNotNull(method3, 'No method found containing "(Method3Tag)"');
+  // Don't inline native method with a function argument - should call a stub
+  // containing the conversion.
+  nomatch(method3, r'.callFun(');
+
+  // Ensure the methods are compiled by calling them.
+  var a = makeA();
+  Expect.equals(369, a.callFun((i) => 3 * i));
+
+  var b = new B();
+  Expect.equals(2, b.method2());
+  Expect.equals(246, b.method3());
+}
+
+main() {
+  nativeTesting();
+  setup();
+  test1();
+  test2();
+}
diff --git a/tests/dart2js/native/native_method_rename1_frog_test.dart b/tests/dart2js/native/native_method_rename1_frog_test.dart
new file mode 100644
index 0000000..5d05694
--- /dev/null
+++ b/tests/dart2js/native/native_method_rename1_frog_test.dart
@@ -0,0 +1,82 @@
+// 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.
+
+// Test the feature where the native string declares the native method's name.
+
+import 'native_testing.dart';
+import 'dart:_js_helper' show Native, JSName;
+
+@Native("A")
+class A {
+  @JSName('fooA')
+  int foo() native;
+
+  @JSName('barA')
+  int bar() native;
+
+  @JSName('bazA')
+  int baz() native;
+}
+
+A makeA() native;
+
+class B {
+  int bar([x]) => 800;
+  int baz() => 900;
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(){}
+  A.prototype.fooA = function(){return 100;};
+  A.prototype.barA = function(){return 200;};
+  A.prototype.bazA = function(){return 300;};
+
+  makeA = function(){return new A()};
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+testDynamic() {
+  var a = confuse(makeA());
+  var b = confuse(new B());
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, a.bar());
+  Expect.equals(300, a.baz());
+  Expect.equals(800, b.bar());
+  Expect.equals(900, b.baz());
+}
+
+testTyped() {
+  A a = makeA();
+  B b = new B();
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, a.bar());
+  Expect.equals(300, a.baz());
+  Expect.equals(800, b.bar());
+  Expect.equals(900, b.baz());
+}
+
+main() {
+  nativeTesting();
+  setup();
+  testDynamic();
+  testTyped();
+}
+
+expectNoSuchMethod(action, note) {
+  bool caught = false;
+  try {
+    action();
+  } catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError, note);
+  }
+  Expect.isTrue(caught, note);
+}
diff --git a/tests/dart2js/native/native_method_rename2_frog_test.dart b/tests/dart2js/native/native_method_rename2_frog_test.dart
new file mode 100644
index 0000000..35713a2
--- /dev/null
+++ b/tests/dart2js/native/native_method_rename2_frog_test.dart
@@ -0,0 +1,100 @@
+// 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.
+
+// Test the feature where the native string declares the native method's name.
+
+import "native_testing.dart";
+
+@Native("A")
+class A {
+  @JSName('fooA')
+  int foo() native;
+}
+
+@Native("B")
+class B extends A {
+  @JSName('fooB')
+  int foo() native;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A(){}
+  A.prototype.fooA = function(){return 100;};
+  function B(){}
+  inherits(B, A);
+  B.prototype.fooB = function(){return 200;};
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testDynamic() {
+  var things = [makeA(), makeB()];
+  var a = things[0];
+  var b = things[1];
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, b.foo());
+
+  expectNoSuchMethod(() {
+    a.fooA();
+  }, 'fooA should be invisible on A');
+  expectNoSuchMethod(() {
+    b.fooA();
+  }, 'fooA should be invisible on B');
+
+  expectNoSuchMethod(() {
+    a.fooB();
+  }, 'fooB should be absent on A');
+  expectNoSuchMethod(() {
+    b.fooB();
+  }, 'fooA should be invisible on B');
+}
+
+testTyped() {
+  A a = makeA();
+  B b = makeB();
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, b.foo());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testDynamic();
+  testTyped();
+}
+
+expectNoSuchMethod(action, note) {
+  bool caught = false;
+  try {
+    action();
+  } catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError, note);
+  }
+  Expect.isTrue(caught, note);
+}
diff --git a/tests/dart2js/native/native_method_rename3_frog_test.dart b/tests/dart2js/native/native_method_rename3_frog_test.dart
new file mode 100644
index 0000000..c5759b2
--- /dev/null
+++ b/tests/dart2js/native/native_method_rename3_frog_test.dart
@@ -0,0 +1,110 @@
+// 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.
+
+// Test the feature where the native string declares the native method's name.
+// #3. The name does not get
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {
+  @JSName('fooA')
+  int foo() native;
+}
+
+@Native("B")
+class B extends A {
+  @JSName('fooB')
+  int foo() native;
+  int fooA() => 333;
+}
+
+class Decoy {
+  int fooA() => 666;
+  int fooB() => 999;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function A(){}
+  A.prototype.fooA = function(){return 100;};
+  function B(){}
+  inherits(B, A);
+  B.prototype.fooB = function(){return 200;};
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testDynamic() {
+  var a = confuse(makeA());
+  var b = confuse(makeB());
+  var d = confuse(new Decoy());
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, b.foo());
+  Expect.equals(666, d.fooA());
+  Expect.equals(999, d.fooB());
+
+  expectNoSuchMethod(() {
+    a.fooA();
+  }, 'fooA should be invisible on A');
+  Expect.equals(333, b.fooA());
+
+  expectNoSuchMethod(() {
+    a.fooB();
+  }, 'fooB should be absent on A');
+  expectNoSuchMethod(() {
+    b.fooB();
+  }, 'fooA should be invisible on B');
+}
+
+testTyped() {
+  A a = makeA();
+  B b = makeB();
+  Decoy d = new Decoy();
+
+  Expect.equals(100, a.foo());
+  Expect.equals(200, b.foo());
+  Expect.equals(666, d.fooA());
+  Expect.equals(999, d.fooB());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testDynamic();
+  testTyped();
+}
+
+expectNoSuchMethod(action, note) {
+  bool caught = false;
+  try {
+    action();
+  } on NoSuchMethodError catch (ex) {
+    caught = true;
+    Expect.isTrue(ex is NoSuchMethodError, note);
+  }
+  Expect.isTrue(caught, note);
+}
diff --git a/tests/dart2js/native/native_method_with_keyword_name_test.dart b/tests/dart2js/native/native_method_with_keyword_name_test.dart
new file mode 100644
index 0000000..c535d90
--- /dev/null
+++ b/tests/dart2js/native/native_method_with_keyword_name_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+import 'native_testing.dart';
+
+// Make sure we can have a native with a name that is a JavaScript keyword.
+
+@Native("A")
+class A {
+  int delete() native;
+}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+function A() {}
+A.prototype.delete = function() { return 87; };
+
+makeA = function(){return new A()};
+self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a1 = confuse(makeA());
+  Expect.equals(87, a1.delete());
+  A a2 = makeA();
+  Expect.equals(87, a2.delete());
+}
diff --git a/tests/dart2js/native/native_missing_method1_frog_test.dart b/tests/dart2js/native/native_missing_method1_frog_test.dart
new file mode 100644
index 0000000..d0595f6
--- /dev/null
+++ b/tests/dart2js/native/native_missing_method1_frog_test.dart
@@ -0,0 +1,55 @@
+// 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.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {};
+  A.prototype.foo = function() { return  99; };
+  makeA = function() { return new A(); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+class B {
+  // We need to define a foo method so that dart2js sees it. Because the
+  // only occurences of 'foo' is on B, a Dart class, no interceptor is used.  It
+  // thinks all calls will either go to this method, or throw a
+  // NoSuchMethodError. It is possible that the native class will shadow a
+  // method, but it will not shadow 'foo' because the name is either 'mangled'
+  // with the arity, or minified.
+  foo() {
+    return 42;
+  }
+}
+
+typedContext() {
+  confuse(new B()).foo();
+  dynamic a = makeA();
+  Expect.throws(() => a.foo(), (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo = 4, (e) => e is NoSuchMethodError);
+}
+
+untypedContext() {
+  confuse(new B()).foo();
+  var a = confuse(makeA());
+  Expect.throws(() => a.foo(), (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo = 4, (e) => e is NoSuchMethodError);
+}
+
+main() {
+  nativeTesting();
+  setup();
+  typedContext();
+  untypedContext();
+}
diff --git a/tests/dart2js/native/native_missing_method2_frog_test.dart b/tests/dart2js/native/native_missing_method2_frog_test.dart
new file mode 100644
index 0000000..ae5799f
--- /dev/null
+++ b/tests/dart2js/native/native_missing_method2_frog_test.dart
@@ -0,0 +1,57 @@
+// 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.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {};
+  A.prototype.foo = function() { return  42; };
+  makeA = function() { return new A() };
+  self.nativeConstructor(A);
+})()""");
+}
+
+class B {
+  foo() {
+    return 42;
+  }
+}
+
+class C {
+  // By having two 'foo' defined in the application, Frog will mangle
+  // all calls to 'foo', which makes this test pass.
+  foo(x) {
+    return 43;
+  }
+}
+
+inferredContext() {
+  dynamic a = makeA();
+  Expect.throws(() => a.foo(), (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo = 4, (e) => e is NoSuchMethodError);
+}
+
+untypedContext() {
+  var a = confuse(makeA());
+  Expect.throws(() => a.foo(), (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => a.foo = 4, (e) => e is NoSuchMethodError);
+}
+
+main() {
+  nativeTesting();
+  setup();
+  confuse(new B()).foo();
+  confuse(new C()).foo(1);
+  inferredContext();
+  untypedContext();
+}
diff --git a/tests/dart2js/native/native_mixin_field2_test.dart b/tests/dart2js/native/native_mixin_field2_test.dart
new file mode 100644
index 0000000..4612391
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_field2_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes can use ordinary Dart classes with fields
+// as mixins.
+
+@Native("A")
+class A {
+  var foo;
+}
+
+class A1 {
+  get foo => 42;
+  set foo(value) {}
+}
+
+@Native("B")
+class B extends A with M1, M2 {
+  var bar;
+}
+
+class B1 extends A1 with M1, M2 {
+  get bar => 42;
+  set bar(value) {}
+}
+
+class M1 {
+  var baz; // This field is not a native field, even when mixed in.
+}
+
+class M2 {
+  var bar;
+  var buz;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {this.foo='A-foo';}
+  function B() {A.call(this);this.bar='B-bar';this.baz='M1-baz';}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+main() {
+  nativeTesting();
+  setup();
+  dynamic a = makeA();
+  a ??= new A1();
+  Expect.equals("A-foo", confuse(a).foo);
+  Expect.throws(() => confuse(a).bar, (e) => e is NoSuchMethodError);
+  Expect.throws(() => confuse(a).baz, (e) => e is NoSuchMethodError);
+  Expect.throws(() => confuse(a).buz, (e) => e is NoSuchMethodError);
+
+  dynamic b = makeB();
+  b ??= new B1();
+  Expect.equals("A-foo", confuse(b).foo);
+  Expect.equals("B-bar", confuse(b).bar);
+  // Expect.equals("M1-baz", b.baz);  // not true, see M1.
+  Expect.isNull(confuse(b).baz); // native b.baz is not the same as dart b.baz.
+  Expect.isNull(confuse(b).buz);
+
+  M1 m1 = new M1();
+  Expect.throws(() => confuse(m1).foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => confuse(m1).bar, (e) => e is NoSuchMethodError);
+  Expect.isNull(m1.baz);
+  Expect.throws(() => confuse(m1).buz, (e) => e is NoSuchMethodError);
+
+  M2 m2 = new M2();
+  Expect.throws(() => confuse(m2).foo, (e) => e is NoSuchMethodError);
+  Expect.isNull(confuse(m2).bar);
+  Expect.throws(() => confuse(m2).baz, (e) => e is NoSuchMethodError);
+  Expect.isNull(confuse(m2).buz);
+}
diff --git a/tests/dart2js/native/native_mixin_field_test.dart b/tests/dart2js/native/native_mixin_field_test.dart
new file mode 100644
index 0000000..7f1aebb
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_field_test.dart
@@ -0,0 +1,72 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes can use ordinary Dart classes with fields
+// as mixins.
+
+@Native("A")
+class A {
+  var foo;
+}
+
+@Native("B")
+class B extends A with M1, M2 {
+  var bar;
+}
+
+class M1 {
+  var baz; // This field is not a native field, even when mixed in.
+}
+
+class M2 {
+  var bar;
+  var buz;
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {this.foo='A-foo';}
+  function B() {A.call(this);this.bar='B-bar';this.baz='M1-baz';}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  A a = makeA();
+  Expect.equals("A-foo", a.foo);
+  Expect.throws(() => (a as dynamic).bar, (e) => e is NoSuchMethodError);
+  Expect.throws(() => (a as dynamic).baz, (e) => e is NoSuchMethodError);
+  Expect.throws(() => (a as dynamic).buz, (e) => e is NoSuchMethodError);
+
+  B b = makeB();
+  Expect.equals("A-foo", b.foo);
+  Expect.equals("B-bar", b.bar);
+  // Expect.equals("M1-baz", b.baz);  // not true, see M1.
+  Expect.isNull(b.baz); // native b.baz is not the same as dart b.baz.
+  Expect.isNull(b.buz);
+
+  M1 m1 = new M1();
+  Expect.throws(() => (m1 as dynamic).foo, (e) => e is NoSuchMethodError);
+  Expect.throws(() => (m1 as dynamic).bar, (e) => e is NoSuchMethodError);
+  Expect.isNull(m1.baz);
+  Expect.throws(() => (m1 as dynamic).buz, (e) => e is NoSuchMethodError);
+
+  M2 m2 = new M2();
+  Expect.throws(() => (m2 as dynamic).foo, (e) => e is NoSuchMethodError);
+  Expect.isNull(m2.bar);
+  Expect.throws(() => (m2 as dynamic).baz, (e) => e is NoSuchMethodError);
+  Expect.isNull(m2.buz);
+}
diff --git a/tests/dart2js/native/native_mixin_multiple2_test.dart b/tests/dart2js/native/native_mixin_multiple2_test.dart
new file mode 100644
index 0000000..0747e6b
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_multiple2_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes can access methods defined only by mixins.
+
+@Native("A")
+class A {
+  foo(x, [y]) => '$x;$y';
+}
+
+@Native("B")
+class B extends A with M1, M2, M3 {}
+
+class M1 {}
+
+class M2 {
+  // These methods are only defined in this non-first, non-last mixin.
+  plain(x) => 'P $x';
+  bar(x, [y]) => '$y,$x';
+}
+
+class M3 {}
+
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() {}
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  B b = makeB();
+  Expect.equals('1;2', b.foo(1, 2));
+  Expect.equals('2;null', b.foo(2));
+  Expect.equals('P 3', b.plain(3));
+  Expect.equals('100,4', b.bar(4, 100));
+  Expect.equals('null,5', b.bar(5));
+}
diff --git a/tests/dart2js/native/native_mixin_multiple3_test.dart b/tests/dart2js/native/native_mixin_multiple3_test.dart
new file mode 100644
index 0000000..1963186
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_multiple3_test.dart
@@ -0,0 +1,94 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes and plain classes can access methods defined only by
+// the same mixin.
+
+class D extends Object with M1, M2, M3 {}
+
+class E extends D {
+  foo() => 'E.foo';
+}
+
+class M1 {}
+
+class M2 {
+  foo() => 'M2.foo';
+}
+
+class M3 {}
+
+@Native("A")
+class A {
+  foo() => 'A.foo';
+}
+
+@Native("B")
+class B extends A with M1, M2, M3 {}
+
+@Native("C")
+class C extends B {
+  foo() => 'C.foo';
+}
+
+makeA() native;
+makeB() native;
+makeC() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  function C() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  makeC = function(){return new C()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+  self.nativeConstructor(C);
+})()""");
+}
+
+var g;
+
+callFoo(x) {
+  // Dominating getInterceptor call should be shared.
+  g = x.toString();
+  // These call sites are partitioned into pure-dart and native subsets,
+  // allowing differences in getInterceptors.
+  if (x is D) return x.foo();
+  if (x is A) return x.foo();
+}
+
+makeAll() => [makeA(), makeB(), makeC(), new D(), new E()];
+
+main() {
+  nativeTesting();
+  setup();
+  /*
+  var a = makeA();
+  var b = makeB();
+  var c = makeC();
+  var d = new D();
+  var e = new E();
+  */
+  var x = makeAll();
+  var a = x[0];
+  var b = x[1];
+  var c = x[2];
+  var d = x[3];
+  var e = x[4];
+
+  var f = callFoo;
+
+  Expect.equals('A.foo', f(a));
+  Expect.equals('M2.foo', f(b));
+  Expect.equals('C.foo', f(c));
+  Expect.equals('M2.foo', f(d));
+  Expect.equals('E.foo', f(e));
+}
diff --git a/tests/dart2js/native/native_mixin_multiple_test.dart b/tests/dart2js/native/native_mixin_multiple_test.dart
new file mode 100644
index 0000000..310d75b
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_multiple_test.dart
@@ -0,0 +1,87 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes can use ordinary Dart classes as mixins.
+
+@Native("A")
+class A {
+  foo() => "A-foo";
+  baz() => "A-baz";
+}
+
+@Native("B")
+class B extends A with M1, M2 {
+  bar() => baz();
+}
+
+class M1 {
+  foo() => "M1-foo";
+  baz() => "M1-baz";
+}
+
+class M2 {
+  foo() => "M2-foo";
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  A a = makeA();
+  Expect.equals("A-foo", a.foo());
+  Expect.throws(
+      () => (a as dynamic).bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("A-baz", a.baz());
+  Expect.isTrue(a is A);
+  Expect.isFalse(a is B);
+  Expect.isFalse(a is M1);
+  Expect.isFalse(a is M2);
+
+  B b = makeB();
+  Expect.equals("M2-foo", b.foo());
+  Expect.equals("M1-baz", b.bar());
+  Expect.equals("M1-baz", b.baz());
+  Expect.isTrue(b is A);
+  Expect.isTrue(b is B);
+  Expect.isTrue(b is M1);
+  Expect.isTrue(b is M2);
+
+  M1 m1 = new M1();
+  Expect.equals("M1-foo", m1.foo());
+  Expect.throws(
+      () => (m1 as dynamic).bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("M1-baz", m1.baz());
+  Expect.isFalse(m1 is A);
+  Expect.isFalse(m1 is B);
+  Expect.isTrue(m1 is M1);
+  Expect.isFalse(m1 is M2);
+
+  M2 m2 = new M2();
+  Expect.equals("M2-foo", m2.foo());
+  Expect.throws(
+      () => (m2 as dynamic).bar(), (error) => error is NoSuchMethodError);
+  Expect.throws(
+      () => (m2 as dynamic).baz(), (error) => error is NoSuchMethodError);
+  Expect.isFalse(m2 is A);
+  Expect.isFalse(m2 is B);
+  Expect.isFalse(m2 is M1);
+  Expect.isTrue(m2 is M2);
+}
diff --git a/tests/dart2js/native/native_mixin_test.dart b/tests/dart2js/native/native_mixin_test.dart
new file mode 100644
index 0000000..64bd3e4
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes can use ordinary Dart classes as mixins.
+
+@Native("A")
+class A {
+  foo() => "A-foo";
+  baz() => "A-baz";
+}
+
+@Native("B")
+class B extends A with M {
+  bar() => baz();
+}
+
+class M {
+  foo() => "M-foo";
+  bar() => "M-bar";
+}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  A a = makeA();
+  Expect.equals("A-foo", a.foo());
+  Expect.throws(
+      () => (a as dynamic).bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("A-baz", a.baz());
+  Expect.isTrue(a is A);
+  Expect.isFalse(a is B);
+  Expect.isFalse(a is M);
+
+  B b = makeB();
+  Expect.equals("M-foo", b.foo());
+  Expect.equals("A-baz", b.bar());
+  Expect.equals("A-baz", b.baz());
+  Expect.isTrue(b is A);
+  Expect.isTrue(b is B);
+  Expect.isTrue(b is M);
+
+  M m = new M();
+  Expect.equals("M-foo", m.foo());
+  Expect.equals("M-bar", m.bar());
+  Expect.throws(
+      () => (m as dynamic).baz(), (error) => error is NoSuchMethodError);
+  Expect.isFalse(m is A);
+  Expect.isFalse(m is B);
+  Expect.isTrue(m is M);
+}
diff --git a/tests/dart2js/native/native_mixin_with_plain_test.dart b/tests/dart2js/native/native_mixin_with_plain_test.dart
new file mode 100644
index 0000000..aea5e67
--- /dev/null
+++ b/tests/dart2js/native/native_mixin_with_plain_test.dart
@@ -0,0 +1,112 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes and ordinary Dart classes can both use the same
+// ordinary Dart classes as a mixin.
+
+@Native("A")
+class A {
+  final String aa;
+  foo() => "A-foo $aa";
+  baz() => "A-baz $aa";
+}
+
+@Native("B")
+class B extends A with M {
+  bar() => 'B-bar -> ${baz()}';
+  get mm => 'B.mm($aa)';
+}
+
+class M {
+  foo() => "M-foo ${this.mm}";
+  bar() => "M-bar ${this.mm}";
+  get mm => 'M.mm';
+}
+
+class C {
+  final String cc = 'cc';
+  foo() => 'C-foo $cc';
+  baz() => 'C-baz $cc';
+}
+
+class D extends C with M {
+  bar() => 'D-bar -> ${baz()}';
+  get mm => 'D.mm($cc)';
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {this.aa = 'aa'}
+  function B() {this.aa = 'bb'}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var things = [makeA, makeB, () => new C(), () => new D(), () => new M()]
+      .map((f) => f())
+      .toList();
+  var a = things[0];
+  var b = things[1];
+  var c = things[2];
+  var d = things[3];
+  var m = things[4];
+
+  Expect.equals("M-foo M.mm", m.foo());
+  Expect.equals("M-bar M.mm", m.bar());
+  Expect.throws(() => m.baz(), (error) => error is NoSuchMethodError);
+  Expect.isFalse(m is A);
+  Expect.isFalse(m is B);
+  Expect.isFalse(m is C);
+  Expect.isFalse(m is D);
+  Expect.isTrue(m is M);
+
+  Expect.equals("A-foo aa", a.foo());
+  Expect.throws(() => a.bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("A-baz aa", a.baz());
+  Expect.isTrue(a is A);
+  Expect.isFalse(a is B);
+  Expect.isFalse(a is C);
+  Expect.isFalse(a is D);
+  Expect.isFalse(a is M);
+
+  Expect.equals("M-foo B.mm(bb)", b.foo());
+  Expect.equals("B-bar -> A-baz bb", b.bar());
+  Expect.equals("A-baz bb", b.baz());
+  Expect.isTrue(b is A);
+  Expect.isTrue(b is B);
+  Expect.isFalse(b is C);
+  Expect.isFalse(b is D);
+  Expect.isTrue(b is M);
+
+  Expect.equals("C-foo cc", c.foo());
+  Expect.throws(() => c.bar(), (error) => error is NoSuchMethodError);
+  Expect.equals("C-baz cc", c.baz());
+  Expect.isFalse(c is A);
+  Expect.isFalse(c is B);
+  Expect.isTrue(c is C);
+  Expect.isFalse(c is D);
+  Expect.isFalse(c is M);
+
+  Expect.equals("M-foo D.mm(cc)", d.foo());
+  Expect.equals("D-bar -> C-baz cc", d.bar());
+  Expect.equals("C-baz cc", d.baz());
+  Expect.isFalse(d is A);
+  Expect.isFalse(d is B);
+  Expect.isTrue(d is C);
+  Expect.isTrue(d is D);
+  Expect.isTrue(d is M);
+}
diff --git a/tests/dart2js/native/native_named_constructors2_frog_test.dart b/tests/dart2js/native/native_named_constructors2_frog_test.dart
new file mode 100644
index 0000000..b200628
--- /dev/null
+++ b/tests/dart2js/native/native_named_constructors2_frog_test.dart
@@ -0,0 +1,49 @@
+// 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 "native_testing.dart";
+
+// Native class with named constructors and static methods.
+
+@Native("A")
+class A {
+  factory A(int len) => _construct(len);
+
+  factory A.fromString(String s) => _construct(s.length);
+
+  factory A.nativeConstructor() {
+    return JS('A|Null', 'makeA(102)');
+  }
+
+  static A _construct(v) {
+    return makeA(v);
+  }
+
+  foo() native;
+}
+
+makeA(v) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(arg) { this._x = arg; }
+  A.prototype.foo = function() { return this._x; };
+  makeA = function(arg) { return new A(arg); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a1 = new A(100);
+  var a2 = new A.fromString('Hello');
+  var a3 = new A.nativeConstructor();
+
+  Expect.equals(100, a1.foo());
+  Expect.equals(5, a2.foo());
+  Expect.equals(102, a3.foo());
+}
diff --git a/tests/dart2js/native/native_named_constructors3_frog_test.dart b/tests/dart2js/native/native_named_constructors3_frog_test.dart
new file mode 100644
index 0000000..949a405
--- /dev/null
+++ b/tests/dart2js/native/native_named_constructors3_frog_test.dart
@@ -0,0 +1,48 @@
+// 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 "native_testing.dart";
+
+// Hidden native class with factory constructors and NO static methods.
+// Regression test.
+
+@Native("A")
+class A {
+  // No static methods in this class.
+
+  factory A(int len) => makeA(len);
+
+  factory A.fromString(String s) => makeA(s.length);
+
+  factory A.nativeConstructor() {
+    return JS('A|Null', 'makeA(102)');
+  }
+
+  foo() native;
+}
+
+makeA(v) native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(arg) { this._x = arg; }
+  A.prototype.foo = function(){ return this._x; };
+  makeA = function(arg) { return new A(arg); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a1 = new A(100);
+  var a2 = new A.fromString('Hello');
+  var a3 = new A.nativeConstructor();
+
+  Expect.equals(100, a1.foo());
+  Expect.equals(5, a2.foo());
+  Expect.equals(102, a3.foo());
+}
diff --git a/tests/dart2js/native/native_no_such_method_exception2_frog_test.dart b/tests/dart2js/native/native_no_such_method_exception2_frog_test.dart
new file mode 100644
index 0000000..5df3c12
--- /dev/null
+++ b/tests/dart2js/native/native_no_such_method_exception2_frog_test.dart
@@ -0,0 +1,57 @@
+// 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.
+
+import "native_testing.dart";
+
+@Native("A")
+class A {}
+
+@Native("B")
+class B extends A {
+  foo() native;
+}
+
+makeA() native;
+makeB() native;
+
+setup() {
+  JS('', r"""
+(function(){
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+    function A() {}
+    function B() {}
+    inherits(B, A);
+    makeA = function() { return new A() };
+    makeB = function() { return new B() };
+    B.prototype.foo = function() { return 42; };
+
+    self.nativeConstructor(A);
+    self.nativeConstructor(B);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  var exception;
+  try {
+    a.foo();
+  } on NoSuchMethodError catch (e) {
+    exception = e;
+  }
+  Expect.isNotNull(exception);
+
+  var b = makeB();
+  Expect.equals(42, b.foo());
+}
diff --git a/tests/dart2js/native/native_no_such_method_exception_frog_test.dart b/tests/dart2js/native/native_no_such_method_exception_frog_test.dart
new file mode 100644
index 0000000..c4a7951
--- /dev/null
+++ b/tests/dart2js/native/native_no_such_method_exception_frog_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+import "native_testing.dart";
+
+@Native("A")
+class A {
+  bar() => 42;
+}
+
+@Native("B")
+class B {
+  foo() => 42;
+}
+
+makeA() native;
+
+setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  makeA = function() { return new A(); };
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  a.bar();
+  var exception;
+  try {
+    a.foo();
+  } on NoSuchMethodError catch (e) {
+    exception = e;
+  }
+  Expect.isNotNull(exception);
+}
diff --git a/tests/dart2js/native/native_novel_html_test.dart b/tests/dart2js/native/native_novel_html_test.dart
new file mode 100644
index 0000000..3738ff0
--- /dev/null
+++ b/tests/dart2js/native/native_novel_html_test.dart
@@ -0,0 +1,52 @@
+// 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 'native_testing.dart';
+
+// Test to see if novel HTML tags are interpreted as HTMLElement.
+
+@Native("HTMLElement")
+class Element {
+  String dartMethod(int x) => 'dartMethod(${nativeMethod(x + 1)})';
+  String nativeMethod(int x) native;
+}
+
+makeE() native;
+makeF() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // A novel HTML element.
+  function HTMLGoofyElement(){}
+  HTMLGoofyElement.prototype.nativeMethod = function(a) {
+    return 'Goofy.nativeMethod(' + a  + ')';
+  };
+  makeE = function(){return new HTMLGoofyElement()};
+
+  // A non-HTML element with a misleading name.
+  function HTMLFakeyElement(){}
+  HTMLFakeyElement.prototype.nativeMethod = function(a) {
+    return 'Fakey.nativeMethod(' + a  + ')';
+  };
+  makeF = function(){return new HTMLFakeyElement()};
+
+  self.nativeConstructor(HTMLGoofyElement);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var e = makeE();
+  Expect.equals('Goofy.nativeMethod(10)', e.nativeMethod(10));
+  Expect.equals('dartMethod(Goofy.nativeMethod(11))', e.dartMethod(10));
+
+  var f = makeF();
+  Expect.throws(() => f.nativeMethod(20), (e) => e is NoSuchMethodError,
+      'fake HTML Element must not run Dart method on native class');
+  Expect.throws(() => f.dartMethod(20), (e) => e is NoSuchMethodError,
+      'fake HTML Element must not run native method on native class');
+}
diff --git a/tests/dart2js/native/native_null_closure_frog_test.dart b/tests/dart2js/native/native_null_closure_frog_test.dart
new file mode 100644
index 0000000..1768cac
--- /dev/null
+++ b/tests/dart2js/native/native_null_closure_frog_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+// Test that exception unwrapping handle cases like ({foo:null}).foo().
+
+import "native_testing.dart";
+
+typedef void MyFunctionType();
+
+@Native("A")
+class A {
+  setClosure(MyFunctionType f) native;
+  check(MyFunctionType f) native;
+  invoke() native;
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+function A() {}
+  A.prototype.setClosure = function(f) { this.f = f; };
+  A.prototype.check = function(f) { return this.f === f; };
+  A.prototype.invoke = function() { return this.f(); };
+  makeA = function(){return new A()};
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  A a = makeA();
+  a.setClosure(null);
+  Expect.isTrue(a.check(null));
+  bool caughtException = false;
+  try {
+    a.invoke();
+  } on NoSuchMethodError catch (e) {
+    print(e);
+    caughtException = true;
+  }
+  Expect.isTrue(caughtException);
+}
diff --git a/tests/dart2js/native/native_null_frog_test.dart b/tests/dart2js/native/native_null_frog_test.dart
new file mode 100644
index 0000000..0abdd35
--- /dev/null
+++ b/tests/dart2js/native/native_null_frog_test.dart
@@ -0,0 +1,65 @@
+// 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 "native_testing.dart";
+
+// Test for values of some basic types.
+
+@Native("A")
+class A {
+  returnNull() native;
+  returnUndefined() native;
+  returnEmptyString() native;
+  returnZero() native;
+}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.returnNull = function() { return null; };
+  A.prototype.returnUndefined = function() { return void 0; };
+  A.prototype.returnEmptyString = function() { return ""; };
+  A.prototype.returnZero = function() { return 0; };
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+@pragma('dart2js:noInline')
+staticTests() {
+  A a = makeA();
+  Expect.equals(null, a.returnNull());
+  Expect.equals(null, a.returnUndefined());
+
+  Expect.equals('', a.returnEmptyString());
+  Expect.isTrue(a.returnEmptyString().isEmpty);
+  Expect.isTrue(a.returnEmptyString() is String);
+
+  Expect.isTrue(a.returnZero() is int);
+  Expect.equals(0, a.returnZero());
+}
+
+@pragma('dart2js:noInline')
+dynamicTests() {
+  A a = makeA();
+  Expect.equals(null, confuse(a).returnNull());
+  Expect.equals(null, confuse(a).returnUndefined());
+
+  Expect.equals('', confuse(a).returnEmptyString());
+  Expect.isTrue(confuse(a).returnEmptyString().isEmpty);
+  Expect.isTrue(confuse(a).returnEmptyString() is String);
+
+  Expect.isTrue(confuse(a).returnZero() is int);
+  Expect.equals(0, confuse(a).returnZero());
+}
+
+main() {
+  nativeTesting();
+  setup();
+  staticTests();
+  dynamicTests();
+}
diff --git a/tests/dart2js/native/native_property_frog_test.dart b/tests/dart2js/native/native_property_frog_test.dart
new file mode 100644
index 0000000..0c4d3ef
--- /dev/null
+++ b/tests/dart2js/native/native_property_frog_test.dart
@@ -0,0 +1,70 @@
+// 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.
+
+// Properties on hidden native classes.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {
+  // Setters and getters should be similar to these methods:
+  int getX() => JS('int', '#._x', this);
+  void setX(int value) {
+    JS('void', '#._x = #', this, value);
+  }
+
+  int get X native;
+  set X(int value) native;
+
+  int get Y native;
+  set Y(int value) native;
+
+  int get Z => JS('int', '#._z', this);
+  set Z(int value) {
+    JS('void', '#._z = #', this, value);
+  }
+}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+
+  Object.defineProperty(A.prototype, "X", {
+    get: function () { return this._x; },
+    set: function (v) { this._x = v; }
+  });
+
+  makeA = function(){return new A()};
+
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+
+  a.setX(5);
+  Expect.equals(5, a.getX());
+
+  a.X = 10;
+  a.Y = 20;
+  a.Z = 30;
+
+  Expect.equals(10, a.X);
+  Expect.equals(20, a.Y);
+  Expect.equals(30, a.Z);
+
+  confuse(a).setX(6);
+  Expect.equals(6, confuse(a).getX());
+
+  Expect.equals(6, confuse(a).X);
+  Expect.equals(20, confuse(a).Y);
+  Expect.equals(30, confuse(a).Z);
+}
diff --git a/tests/dart2js/native/native_test.dart b/tests/dart2js/native/native_test.dart
new file mode 100644
index 0000000..0eb52d6
--- /dev/null
+++ b/tests/dart2js/native/native_test.dart
@@ -0,0 +1,211 @@
+// 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.
+
+// Test for positive and negative uses of named declarations. This file is
+// also used in tests/compiler/dart2js/model/native_test.dart.
+
+import 'dart:_js_helper';
+
+var topLevelField;
+
+get topLevelGetter => null;
+
+set topLevelSetter(_) {}
+
+topLevelFunction() {}
+
+// NON_NATIVE_EXTERNAL               //# 01: compile-time error
+external get externalTopLevelGetter; //# 01: continued
+
+// NON_NATIVE_EXTERNAL                  //# 02: compile-time error
+external set externalTopLevelSetter(_); //# 02: continued
+
+// NON_NATIVE_EXTERNAL               //# 03: compile-time error
+external externalTopLevelFunction(); //# 03: continued
+
+get nativeTopLevelGetter native;
+
+set nativeTopLevelSetter(_) native;
+
+nativeTopLevelFunction() native;
+
+class Class {
+  Class.generative();
+  factory Class.fact() => null;
+
+  // NON_NATIVE_EXTERNAL               //# 08: compile-time error
+  external Class.externalGenerative(); //# 08: continued
+
+  // NON_NATIVE_EXTERNAL                 //# 09: compile-time error
+  external factory Class.externalFact(); //# 09: continued
+
+  // NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS //# 10: compile-time error
+  Class.nativeGenerative() native; //# 10: continued
+
+  // NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS //# 11: compile-time error
+  factory Class.nativeFact() native; //# 11: continued
+
+  var instanceField;
+  get instanceGetter => null;
+  set instanceSetter(_) {}
+  instanceMethod() {}
+
+  static var staticField;
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
+
+  // NON_NATIVE_EXTERNAL               //# 22: compile-time error
+  external get externalInstanceGetter; //# 22: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 23: compile-time error
+  external set externalInstanceSetter(_); //# 23: continued
+
+  // NON_NATIVE_EXTERNAL             //# 24: compile-time error
+  external externalInstanceMethod(); //# 24: continued
+
+  // NON_NATIVE_EXTERNAL                    //# 25: compile-time error
+  external static get externalStaticGetter; //# 25: continued
+
+  // NON_NATIVE_EXTERNAL                       //# 26: compile-time error
+  external static set externalStaticSetter(_); //# 26: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 27: compile-time error
+  external static externalStaticMethod(); //# 27: continued
+
+  get nativeInstanceGetter native;
+  set nativeInstanceSetter(_) native;
+  nativeInstanceMethod() native;
+
+  // NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS //# 28: compile-time error
+  static get nativeStaticGetter native; //# 28: continued
+
+  // NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS //# 29: compile-time error
+  static set nativeStaticSetter(_) native; //# 29: continued
+
+  // NATIVE_NON_INSTANCE_IN_NON_NATIVE_CLASS //# 30: compile-time error
+  static nativeStaticMethod() native; //# 30: continued
+}
+
+@Native('d')
+class NativeClass {
+  NativeClass.generative();
+
+  factory NativeClass.fact() => null;
+
+  // NON_NATIVE_EXTERNAL                     //# 31: compile-time error
+  external NativeClass.externalGenerative(); //# 31: continued
+  // NON_NATIVE_EXTERNAL                       //# 32: compile-time error
+  external factory NativeClass.externalFact(); //# 32: continued
+
+  NativeClass.nativeGenerative() native;
+  factory NativeClass.nativeFact() native;
+
+  var instanceField;
+  get instanceGetter => null;
+  set instanceSetter(_) {}
+  instanceMethod() {}
+
+  static var staticField;
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
+
+  var instanceNamedField;
+
+  // NON_NATIVE_EXTERNAL               //# 36: compile-time error
+  external get externalInstanceGetter; //# 36: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 37: compile-time error
+  external set externalInstanceSetter(_); //# 37: continued
+
+  // NON_NATIVE_EXTERNAL             //# 38: compile-time error
+  external externalInstanceMethod(); //# 38: continued
+
+  // NON_NATIVE_EXTERNAL                    //# 39: compile-time error
+  external static get externalStaticGetter; //# 39: continued
+
+  // NON_NATIVE_EXTERNAL                       //# 40: compile-time error
+  external static set externalStaticSetter(_); //# 40: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 41: compile-time error
+  external static externalStaticMethod(); //# 41: continued
+
+  get nativeInstanceGetter native;
+  set nativeInstanceSetter(_) native;
+  nativeInstanceMethod() native;
+
+  static get nativeStaticGetter native;
+  static set nativeStaticSetter(_) native;
+  static nativeStaticMethod() native;
+}
+
+main() {
+  if (true) return;
+
+  topLevelField;
+  topLevelGetter;
+  topLevelSetter = null;
+  topLevelFunction();
+  externalTopLevelGetter; //# 01: continued
+  externalTopLevelSetter = null; //# 02: continued
+  externalTopLevelFunction(); //# 03: continued
+  nativeTopLevelGetter;
+  nativeTopLevelSetter = null;
+  nativeTopLevelFunction();
+
+  var c1 = new Class.generative();
+  new Class.fact();
+  new Class.externalGenerative(); //# 08: continued
+  new Class.externalFact(); //# 09: continued
+  new Class.nativeGenerative(); //# 10: continued
+  new Class.nativeFact(); //# 11: continued
+  c1.instanceField;
+  c1.instanceGetter;
+  c1.instanceSetter = null;
+  c1.instanceMethod();
+  Class.staticField;
+  Class.staticGetter;
+  Class.staticSetter = null;
+  Class.staticMethod();
+  c1.externalInstanceGetter; //# 22: continued
+  c1.externalInstanceSetter = null; //# 23: continued
+  c1.externalInstanceMethod(); //# 24: continued
+  Class.externalStaticGetter; //# 25: continued
+  Class.externalStaticSetter = null; //# 26: continued
+  Class.externalStaticMethod(); //# 27: continued
+  c1.nativeInstanceGetter;
+  c1.nativeInstanceSetter = null;
+  c1.nativeInstanceMethod();
+  Class.nativeStaticGetter; //# 28: continued
+  Class.nativeStaticSetter = null; //# 29: continued
+  Class.nativeStaticMethod(); //# 30: continued
+
+  var c2 = new NativeClass.generative();
+  new NativeClass.fact();
+  new NativeClass.externalGenerative(); //# 31: continued
+  new NativeClass.externalFact(); //# 32: continued
+  new NativeClass.nativeGenerative();
+  new NativeClass.nativeFact();
+  c2.instanceField;
+  c2.instanceGetter;
+  c2.instanceSetter = null;
+  c2.instanceMethod();
+  NativeClass.staticField;
+  NativeClass.staticGetter;
+  NativeClass.staticSetter = null;
+  NativeClass.staticMethod();
+  c2.externalInstanceGetter; //# 36: continued
+  c2.externalInstanceSetter = null; //# 37: continued
+  c2.externalInstanceMethod(); //# 38: continued
+  NativeClass.externalStaticGetter; //# 39: continued
+  NativeClass.externalStaticSetter = null; //# 40: continued
+  NativeClass.externalStaticMethod(); //# 41: continued
+  c2.nativeInstanceGetter;
+  c2.nativeInstanceSetter = null;
+  c2.nativeInstanceMethod();
+  NativeClass.nativeStaticGetter;
+  NativeClass.nativeStaticSetter = null;
+  NativeClass.nativeStaticMethod();
+}
diff --git a/tests/dart2js/native/native_testing.dart b/tests/dart2js/native/native_testing.dart
new file mode 100644
index 0000000..5dcaa24
--- /dev/null
+++ b/tests/dart2js/native/native_testing.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2016, 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.
+
+// Native testing library. Provides support for mock @Native classes and
+// collects common imports.
+
+import "package:expect/expect.dart";
+import 'dart:_js_helper' show Native;
+import 'dart:_foreign_helper' show JS;
+
+export "package:expect/expect.dart";
+export 'dart:_js_helper' show Creates, Native, JSName, Returns;
+export 'dart:_foreign_helper' show JS;
+
+void nativeTesting() {
+  JS('', r'''
+((function() {
+  var toStringResultProperty = "_toStringResult";
+  var objectToStringMethod = Object.prototype.toString;
+
+  Object.prototype.toString = function() {
+    if (this != null) {
+      var constructor = this.constructor;
+      if (constructor != null) {
+        var result = constructor[toStringResultProperty];
+        if (typeof result == "string") return result;
+      }
+    }
+    return objectToStringMethod.call(this);
+  };
+
+  // To mock a @Native class with JavaScript constructor `Foo`, add
+  //
+  //     self.nativeConstructor(Foo);
+  //
+  // to the JavaScript code.
+  self.nativeConstructor = function(constructor, opt_name) {
+    var toStringResult = "[object " + (opt_name || constructor.name) + "]";
+    constructor[toStringResultProperty] = toStringResult;
+  };
+})())
+''');
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
diff --git a/tests/dart2js/native/native_to_string_frog_test.dart b/tests/dart2js/native/native_to_string_frog_test.dart
new file mode 100644
index 0000000..6fdca6f
--- /dev/null
+++ b/tests/dart2js/native/native_to_string_frog_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+import 'native_testing.dart';
+
+@Native("A")
+class A {
+  toString() => 'AAA';
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  Expect.isTrue(makeA().toString() is String);
+  Expect.equals('AAA', makeA().toString());
+
+  Expect.isTrue(confuse(makeA()).toString() is String);
+  Expect.equals('AAA', confuse(makeA()).toString());
+}
diff --git a/tests/dart2js/native/native_use_native_name_in_table_frog_test.dart b/tests/dart2js/native/native_use_native_name_in_table_frog_test.dart
new file mode 100644
index 0000000..0bd930a
--- /dev/null
+++ b/tests/dart2js/native/native_use_native_name_in_table_frog_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+import 'native_testing.dart';
+
+// Test that we put native names and not Dart names into the dynamic
+// dispatch table.
+
+@Native("NativeA")
+class A {
+  foo() native;
+}
+
+@Native("NativeB")
+class B extends A {}
+
+A makeA() native;
+B makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+  function NativeA() {}
+  function NativeB() {}
+  inherits(NativeB, NativeA);
+  NativeA.prototype.foo = function() { return 42; };
+
+  makeA = function(){return new NativeA()};
+  makeB = function(){return new NativeB()};
+
+  self.nativeConstructor(NativeA);
+  self.nativeConstructor(NativeB);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  Expect.equals(42, makeA().foo());
+  Expect.equals(42, confuse(makeA()).foo());
+
+  Expect.equals(42, makeB().foo());
+  Expect.equals(42, confuse(makeB()).foo());
+}
diff --git a/tests/dart2js/native/native_window1_frog_test.dart b/tests/dart2js/native/native_window1_frog_test.dart
new file mode 100644
index 0000000..f47b66d
--- /dev/null
+++ b/tests/dart2js/native/native_window1_frog_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import "native_testing.dart";
+
+abstract class Window {
+  final int document;
+}
+
+// Defining this global object makes Frog eager on optimizing
+// call sites where the receiver is typed 'Window'.
+@Native("@*DOMWindow")
+class _DOMWindowJs implements Window {
+  final int document;
+}
+
+class Win implements Window {
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
+
+main() {
+  nativeTesting();
+  // By typing this variable to 'Window', Frog will optimize calls on
+  // it.
+  Window win = new Win();
+  Expect.throws(() => win.document, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/dart2js/native/native_window2_frog_test.dart b/tests/dart2js/native/native_window2_frog_test.dart
new file mode 100644
index 0000000..143c1e6
--- /dev/null
+++ b/tests/dart2js/native/native_window2_frog_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import "native_testing.dart";
+
+abstract class Window {
+  final int document;
+}
+
+// Defining this global object makes Frog eager on optimizing
+// call sites where the receiver is typed 'Window'.
+@Native("@*DOMWindow")
+class _DOMWindowJs implements Window {
+  final int document;
+}
+
+class Win implements Window {
+  noSuchMethod(m) => super.noSuchMethod(m);
+}
+
+main() {
+  nativeTesting();
+  // By not typing the variable, Frog does not try to optimize calls
+  // on it.
+  dynamic win = new Win();
+  Expect.throws(() => win.document, (e) => e is NoSuchMethodError);
+}
diff --git a/tests/dart2js/native/native_wrapping_function3_frog_test.dart b/tests/dart2js/native/native_wrapping_function3_frog_test.dart
new file mode 100644
index 0000000..111e2f5
--- /dev/null
+++ b/tests/dart2js/native/native_wrapping_function3_frog_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+import "native_testing.dart";
+
+typedef void Callback0();
+typedef void Callback1(arg1);
+typedef void Callback2(arg1, arg2);
+
+@Native("A")
+class A {
+  foo1(Callback1 closure, [arg1 = 0]) native;
+  foo2(Callback2 closure, [arg1 = 0, arg2 = 1]) native;
+}
+
+A makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo1 = function(closure, arg1) { return closure(arg1); };
+  A.prototype.foo2 = function(closure, arg1, arg2) {
+    return closure(arg1, arg2);
+  };
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  // Statically known receiver type calls.
+  Expect.equals(43, a.foo1((arg1) => arg1, 43));
+  Expect.equals(0, a.foo1((arg1) => arg1));
+
+  Expect.equals(44, a.foo2((arg1, arg2) => arg1 + arg2, 21, 23));
+  Expect.equals(22, a.foo2((arg1, arg2) => arg1 + arg2, 21));
+
+  // Dynamic calls.
+  Expect.equals(43, confuse(a).foo1((arg1) => arg1, 43));
+  Expect.equals(0, confuse(a).foo1((arg1) => arg1));
+
+  Expect.equals(44, confuse(a).foo2((arg1, arg2) => arg1 + arg2, 21, 23));
+  Expect.equals(22, confuse(a).foo2((arg1, arg2) => arg1 + arg2, 21));
+}
diff --git a/tests/dart2js/native/native_wrapping_function_frog_test.dart b/tests/dart2js/native/native_wrapping_function_frog_test.dart
new file mode 100644
index 0000000..53473b8
--- /dev/null
+++ b/tests/dart2js/native/native_wrapping_function_frog_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+import "native_testing.dart";
+
+typedef void Callback0();
+typedef void Callback1(arg1);
+typedef void Callback2(arg1, arg2);
+
+@Native("A")
+class A {
+  foo0(Callback0 closure) native;
+  foo1(Callback1 closure, arg1) native;
+  foo2(Callback2 closure, arg1, arg2) native;
+}
+
+makeA() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  A.prototype.foo0 = function(closure) { return closure(); };
+  A.prototype.foo1 = function(closure, arg1) { return closure(arg1); };
+  A.prototype.foo2 = function(closure, arg1, arg2) {
+    return closure(arg1, arg2);
+  };
+  makeA = function(){return new A()};
+  self.nativeConstructor(A);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var a = makeA();
+  Expect.equals(42, a.foo0(() => 42));
+  Expect.equals(43, a.foo1((arg1) => arg1, 43));
+  Expect.equals(44, a.foo2((arg1, arg2) => arg1 + arg2, 21, 23));
+
+  A aa = a;
+  Expect.equals(42, aa.foo0(() => 42));
+  Expect.equals(43, aa.foo1((arg1) => arg1, 43));
+  Expect.equals(44, aa.foo2((arg1, arg2) => arg1 + arg2, 21, 23));
+}
diff --git a/tests/dart2js/native/oddly_named_fields_test.dart b/tests/dart2js/native/oddly_named_fields_test.dart
new file mode 100644
index 0000000..54d9bd4
--- /dev/null
+++ b/tests/dart2js/native/oddly_named_fields_test.dart
@@ -0,0 +1,1402 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+// JavaScript reserved words:
+//
+// break
+// case
+// catch
+// class
+// const
+// continue
+// debugger
+// default
+// delete
+// do
+// else
+// enum
+// export
+// extends
+// false
+// finally
+// for
+// function
+// if
+// implements
+// import
+// in
+// instanceof
+// interface
+// let
+// new
+// null
+// package
+// private
+// protected
+// public
+// return
+// static
+// super
+// switch
+// this
+// throw
+// true
+// try
+// typeof
+// var
+// void
+// while
+// with
+// yield
+//
+// Funny thing in JavaScript: there are two syntactic categories:
+// "Identifier" and "IdentifierName".  The latter includes reserved
+// words.  This is legal JavaScript according to ECMA-262.5:
+//
+//    this.default
+//
+// See section 11.2 "Left-Hand-Side Expressions" which states that a
+// "MemberExpression" includes: "MemberExpression . IdentifierName".
+
+@Native("NativeClassWithOddNames")
+class NativeClassWithOddNames {
+  @JSName('break')
+  bool breakValue;
+  @JSName('case')
+  bool caseValue;
+  @JSName('catch')
+  bool catchValue;
+  @JSName('class')
+  bool classValue;
+  @JSName('const')
+  bool constValue;
+  @JSName('continue')
+  bool continueValue;
+  @JSName('debugger')
+  bool debuggerValue;
+  @JSName('default')
+  bool defaultValue;
+  @JSName('delete')
+  bool deleteValue;
+  @JSName('do')
+  bool doValue;
+  @JSName('else')
+  bool elseValue;
+  @JSName('enum')
+  bool enumValue;
+  @JSName('export')
+  bool exportValue;
+  @JSName('extends')
+  bool extendsValue;
+  @JSName('false')
+  bool falseValue;
+  @JSName('finally')
+  bool finallyValue;
+  @JSName('for')
+  bool forValue;
+  @JSName('function')
+  bool functionValue;
+  @JSName('if')
+  bool ifValue;
+  @JSName('implements')
+  bool implementsValue;
+  @JSName('import')
+  bool importValue;
+  @JSName('in')
+  bool inValue;
+  @JSName('instanceof')
+  bool instanceofValue;
+  @JSName('interface')
+  bool interfaceValue;
+  @JSName('let')
+  bool letValue;
+  @JSName('new')
+  bool newValue;
+  @JSName('null')
+  bool nullValue;
+  @JSName('package')
+  bool packageValue;
+  @JSName('private')
+  bool privateValue;
+  @JSName('protected')
+  bool protectedValue;
+  @JSName('public')
+  bool publicValue;
+  @JSName('return')
+  bool returnValue;
+  @JSName('static')
+  bool staticValue;
+  @JSName('super')
+  bool superValue;
+  @JSName('switch')
+  bool switchValue;
+  @JSName('this')
+  bool thisValue;
+  @JSName('throw')
+  bool throwValue;
+  @JSName('true')
+  bool trueValue;
+  @JSName('try')
+  bool tryValue;
+  @JSName('typeof')
+  bool typeofValue;
+  @JSName('var')
+  bool varValue;
+  @JSName('void')
+  bool voidValue;
+  @JSName('while')
+  bool whileValue;
+  @JSName('with')
+  bool withValue;
+  @JSName('yield')
+  bool yieldValue;
+
+  void testMyFields() {
+    if (breakValue != null) throw 'incorrect initialization of "breakValue"';
+    breakValue = true;
+    if (!breakValue) throw 'incorrect value in "breakValue"';
+    breakValue = false;
+    if (breakValue) throw 'incorrect value in "breakValue"';
+
+    if (caseValue != null) throw 'incorrect initialization of "caseValue"';
+    caseValue = true;
+    if (!caseValue) throw 'incorrect value in "caseValue"';
+    caseValue = false;
+    if (caseValue) throw 'incorrect value in "caseValue"';
+
+    if (catchValue != null) throw 'incorrect initialization of "catchValue"';
+    catchValue = true;
+    if (!catchValue) throw 'incorrect value in "catchValue"';
+    catchValue = false;
+    if (catchValue) throw 'incorrect value in "catchValue"';
+
+    if (classValue != null) throw 'incorrect initialization of "classValue"';
+    classValue = true;
+    if (!classValue) throw 'incorrect value in "classValue"';
+    classValue = false;
+    if (classValue) throw 'incorrect value in "classValue"';
+
+    if (constValue != null) throw 'incorrect initialization of "constValue"';
+    constValue = true;
+    if (!constValue) throw 'incorrect value in "constValue"';
+    constValue = false;
+    if (constValue) throw 'incorrect value in "constValue"';
+
+    if (continueValue != null)
+      throw 'incorrect initialization of "continueValue"';
+    continueValue = true;
+    if (!continueValue) throw 'incorrect value in "continueValue"';
+    continueValue = false;
+    if (continueValue) throw 'incorrect value in "continueValue"';
+
+    if (debuggerValue != null)
+      throw 'incorrect initialization of "debuggerValue"';
+    debuggerValue = true;
+    if (!debuggerValue) throw 'incorrect value in "debuggerValue"';
+    debuggerValue = false;
+    if (debuggerValue) throw 'incorrect value in "debuggerValue"';
+
+    if (defaultValue != null)
+      throw 'incorrect initialization of "defaultValue"';
+    defaultValue = true;
+    if (!defaultValue) throw 'incorrect value in "defaultValue"';
+    defaultValue = false;
+    if (defaultValue) throw 'incorrect value in "defaultValue"';
+
+    if (deleteValue != null) throw 'incorrect initialization of "deleteValue"';
+    deleteValue = true;
+    if (!deleteValue) throw 'incorrect value in "deleteValue"';
+    deleteValue = false;
+    if (deleteValue) throw 'incorrect value in "deleteValue"';
+
+    if (doValue != null) throw 'incorrect initialization of "doValue"';
+    doValue = true;
+    if (!doValue) throw 'incorrect value in "doValue"';
+    doValue = false;
+    if (doValue) throw 'incorrect value in "doValue"';
+
+    if (elseValue != null) throw 'incorrect initialization of "elseValue"';
+    elseValue = true;
+    if (!elseValue) throw 'incorrect value in "elseValue"';
+    elseValue = false;
+    if (elseValue) throw 'incorrect value in "elseValue"';
+
+    if (enumValue != null) throw 'incorrect initialization of "enumValue"';
+    enumValue = true;
+    if (!enumValue) throw 'incorrect value in "enumValue"';
+    enumValue = false;
+    if (enumValue) throw 'incorrect value in "enumValue"';
+
+    if (exportValue != null) throw 'incorrect initialization of "exportValue"';
+    exportValue = true;
+    if (!exportValue) throw 'incorrect value in "exportValue"';
+    exportValue = false;
+    if (exportValue) throw 'incorrect value in "exportValue"';
+
+    if (extendsValue != null)
+      throw 'incorrect initialization of "extendsValue"';
+    extendsValue = true;
+    if (!extendsValue) throw 'incorrect value in "extendsValue"';
+    extendsValue = false;
+    if (extendsValue) throw 'incorrect value in "extendsValue"';
+
+    if (falseValue != null) throw 'incorrect initialization of "falseValue"';
+    falseValue = true;
+    if (!falseValue) throw 'incorrect value in "falseValue"';
+    falseValue = false;
+    if (falseValue) throw 'incorrect value in "falseValue"';
+
+    if (finallyValue != null)
+      throw 'incorrect initialization of "finallyValue"';
+    finallyValue = true;
+    if (!finallyValue) throw 'incorrect value in "finallyValue"';
+    finallyValue = false;
+    if (finallyValue) throw 'incorrect value in "finallyValue"';
+
+    if (forValue != null) throw 'incorrect initialization of "forValue"';
+    forValue = true;
+    if (!forValue) throw 'incorrect value in "forValue"';
+    forValue = false;
+    if (forValue) throw 'incorrect value in "forValue"';
+
+    if (functionValue != null)
+      throw 'incorrect initialization of "functionValue"';
+    functionValue = true;
+    if (!functionValue) throw 'incorrect value in "functionValue"';
+    functionValue = false;
+    if (functionValue) throw 'incorrect value in "functionValue"';
+
+    if (ifValue != null) throw 'incorrect initialization of "ifValue"';
+    ifValue = true;
+    if (!ifValue) throw 'incorrect value in "ifValue"';
+    ifValue = false;
+    if (ifValue) throw 'incorrect value in "ifValue"';
+
+    if (implementsValue != null)
+      throw 'incorrect initialization of "implementsValue"';
+    implementsValue = true;
+    if (!implementsValue) throw 'incorrect value in "implementsValue"';
+    implementsValue = false;
+    if (implementsValue) throw 'incorrect value in "implementsValue"';
+
+    if (importValue != null) throw 'incorrect initialization of "importValue"';
+    importValue = true;
+    if (!importValue) throw 'incorrect value in "importValue"';
+    importValue = false;
+    if (importValue) throw 'incorrect value in "importValue"';
+
+    if (inValue != null) throw 'incorrect initialization of "inValue"';
+    inValue = true;
+    if (!inValue) throw 'incorrect value in "inValue"';
+    inValue = false;
+    if (inValue) throw 'incorrect value in "inValue"';
+
+    if (instanceofValue != null)
+      throw 'incorrect initialization of "instanceofValue"';
+    instanceofValue = true;
+    if (!instanceofValue) throw 'incorrect value in "instanceofValue"';
+    instanceofValue = false;
+    if (instanceofValue) throw 'incorrect value in "instanceofValue"';
+
+    if (interfaceValue != null)
+      throw 'incorrect initialization of "interfaceValue"';
+    interfaceValue = true;
+    if (!interfaceValue) throw 'incorrect value in "interfaceValue"';
+    interfaceValue = false;
+    if (interfaceValue) throw 'incorrect value in "interfaceValue"';
+
+    if (letValue != null) throw 'incorrect initialization of "letValue"';
+    letValue = true;
+    if (!letValue) throw 'incorrect value in "letValue"';
+    letValue = false;
+    if (letValue) throw 'incorrect value in "letValue"';
+
+    if (newValue != null) throw 'incorrect initialization of "newValue"';
+    newValue = true;
+    if (!newValue) throw 'incorrect value in "newValue"';
+    newValue = false;
+    if (newValue) throw 'incorrect value in "newValue"';
+
+    if (nullValue != null) throw 'incorrect initialization of "nullValue"';
+    nullValue = true;
+    if (!nullValue) throw 'incorrect value in "nullValue"';
+    nullValue = false;
+    if (nullValue) throw 'incorrect value in "nullValue"';
+
+    if (packageValue != null)
+      throw 'incorrect initialization of "packageValue"';
+    packageValue = true;
+    if (!packageValue) throw 'incorrect value in "packageValue"';
+    packageValue = false;
+    if (packageValue) throw 'incorrect value in "packageValue"';
+
+    if (privateValue != null)
+      throw 'incorrect initialization of "privateValue"';
+    privateValue = true;
+    if (!privateValue) throw 'incorrect value in "privateValue"';
+    privateValue = false;
+    if (privateValue) throw 'incorrect value in "privateValue"';
+
+    if (protectedValue != null)
+      throw 'incorrect initialization of "protectedValue"';
+    protectedValue = true;
+    if (!protectedValue) throw 'incorrect value in "protectedValue"';
+    protectedValue = false;
+    if (protectedValue) throw 'incorrect value in "protectedValue"';
+
+    if (publicValue != null) throw 'incorrect initialization of "publicValue"';
+    publicValue = true;
+    if (!publicValue) throw 'incorrect value in "publicValue"';
+    publicValue = false;
+    if (publicValue) throw 'incorrect value in "publicValue"';
+
+    if (returnValue != null) throw 'incorrect initialization of "returnValue"';
+    returnValue = true;
+    if (!returnValue) throw 'incorrect value in "returnValue"';
+    returnValue = false;
+    if (returnValue) throw 'incorrect value in "returnValue"';
+
+    if (staticValue != null) throw 'incorrect initialization of "staticValue"';
+    staticValue = true;
+    if (!staticValue) throw 'incorrect value in "staticValue"';
+    staticValue = false;
+    if (staticValue) throw 'incorrect value in "staticValue"';
+
+    if (superValue != null) throw 'incorrect initialization of "superValue"';
+    superValue = true;
+    if (!superValue) throw 'incorrect value in "superValue"';
+    superValue = false;
+    if (superValue) throw 'incorrect value in "superValue"';
+
+    if (switchValue != null) throw 'incorrect initialization of "switchValue"';
+    switchValue = true;
+    if (!switchValue) throw 'incorrect value in "switchValue"';
+    switchValue = false;
+    if (switchValue) throw 'incorrect value in "switchValue"';
+
+    if (thisValue != null) throw 'incorrect initialization of "thisValue"';
+    thisValue = true;
+    if (!thisValue) throw 'incorrect value in "thisValue"';
+    thisValue = false;
+    if (thisValue) throw 'incorrect value in "thisValue"';
+
+    if (throwValue != null) throw 'incorrect initialization of "throwValue"';
+    throwValue = true;
+    if (!throwValue) throw 'incorrect value in "throwValue"';
+    throwValue = false;
+    if (throwValue) throw 'incorrect value in "throwValue"';
+
+    if (trueValue != null) throw 'incorrect initialization of "trueValue"';
+    trueValue = true;
+    if (!trueValue) throw 'incorrect value in "trueValue"';
+    trueValue = false;
+    if (trueValue) throw 'incorrect value in "trueValue"';
+
+    if (tryValue != null) throw 'incorrect initialization of "tryValue"';
+    tryValue = true;
+    if (!tryValue) throw 'incorrect value in "tryValue"';
+    tryValue = false;
+    if (tryValue) throw 'incorrect value in "tryValue"';
+
+    if (typeofValue != null) throw 'incorrect initialization of "typeofValue"';
+    typeofValue = true;
+    if (!typeofValue) throw 'incorrect value in "typeofValue"';
+    typeofValue = false;
+    if (typeofValue) throw 'incorrect value in "typeofValue"';
+
+    if (varValue != null) throw 'incorrect initialization of "varValue"';
+    varValue = true;
+    if (!varValue) throw 'incorrect value in "varValue"';
+    varValue = false;
+    if (varValue) throw 'incorrect value in "varValue"';
+
+    if (voidValue != null) throw 'incorrect initialization of "voidValue"';
+    voidValue = true;
+    if (!voidValue) throw 'incorrect value in "voidValue"';
+    voidValue = false;
+    if (voidValue) throw 'incorrect value in "voidValue"';
+
+    if (whileValue != null) throw 'incorrect initialization of "whileValue"';
+    whileValue = true;
+    if (!whileValue) throw 'incorrect value in "whileValue"';
+    whileValue = false;
+    if (whileValue) throw 'incorrect value in "whileValue"';
+
+    if (withValue != null) throw 'incorrect initialization of "withValue"';
+    withValue = true;
+    if (!withValue) throw 'incorrect value in "withValue"';
+    withValue = false;
+    if (withValue) throw 'incorrect value in "withValue"';
+
+    if (yieldValue != null) throw 'incorrect initialization of "yieldValue"';
+    yieldValue = true;
+    if (!yieldValue) throw 'incorrect value in "yieldValue"';
+    yieldValue = false;
+    if (yieldValue) throw 'incorrect value in "yieldValue"';
+  }
+}
+
+class ClassWithOddNames {
+  bool breakValue;
+  bool caseValue;
+  bool catchValue;
+  bool classValue;
+  bool constValue;
+  bool continueValue;
+  bool debuggerValue;
+  bool defaultValue;
+  bool deleteValue;
+  bool doValue;
+  bool elseValue;
+  bool enumValue;
+  bool exportValue;
+  bool extendsValue;
+  bool falseValue;
+  bool finallyValue;
+  bool forValue;
+  bool functionValue;
+  bool ifValue;
+  bool implementsValue;
+  bool importValue;
+  bool inValue;
+  bool instanceofValue;
+  bool interfaceValue;
+  bool letValue;
+  bool newValue;
+  bool nullValue;
+  bool packageValue;
+  bool privateValue;
+  bool protectedValue;
+  bool publicValue;
+  bool returnValue;
+  bool staticValue;
+  bool superValue;
+  bool switchValue;
+  bool thisValue;
+  bool throwValue;
+  bool trueValue;
+  bool tryValue;
+  bool typeofValue;
+  bool varValue;
+  bool voidValue;
+  bool whileValue;
+  bool withValue;
+  bool yieldValue;
+
+  void testMyFields() {
+    if (breakValue != null) throw 'incorrect initialization of "breakValue"';
+    breakValue = true;
+    if (!breakValue) throw 'incorrect value in "breakValue"';
+    breakValue = false;
+    if (breakValue) throw 'incorrect value in "breakValue"';
+
+    if (caseValue != null) throw 'incorrect initialization of "caseValue"';
+    caseValue = true;
+    if (!caseValue) throw 'incorrect value in "caseValue"';
+    caseValue = false;
+    if (caseValue) throw 'incorrect value in "caseValue"';
+
+    if (catchValue != null) throw 'incorrect initialization of "catchValue"';
+    catchValue = true;
+    if (!catchValue) throw 'incorrect value in "catchValue"';
+    catchValue = false;
+    if (catchValue) throw 'incorrect value in "catchValue"';
+
+    if (classValue != null) throw 'incorrect initialization of "classValue"';
+    classValue = true;
+    if (!classValue) throw 'incorrect value in "classValue"';
+    classValue = false;
+    if (classValue) throw 'incorrect value in "classValue"';
+
+    if (constValue != null) throw 'incorrect initialization of "constValue"';
+    constValue = true;
+    if (!constValue) throw 'incorrect value in "constValue"';
+    constValue = false;
+    if (constValue) throw 'incorrect value in "constValue"';
+
+    if (continueValue != null)
+      throw 'incorrect initialization of "continueValue"';
+    continueValue = true;
+    if (!continueValue) throw 'incorrect value in "continueValue"';
+    continueValue = false;
+    if (continueValue) throw 'incorrect value in "continueValue"';
+
+    if (debuggerValue != null)
+      throw 'incorrect initialization of "debuggerValue"';
+    debuggerValue = true;
+    if (!debuggerValue) throw 'incorrect value in "debuggerValue"';
+    debuggerValue = false;
+    if (debuggerValue) throw 'incorrect value in "debuggerValue"';
+
+    if (defaultValue != null)
+      throw 'incorrect initialization of "defaultValue"';
+    defaultValue = true;
+    if (!defaultValue) throw 'incorrect value in "defaultValue"';
+    defaultValue = false;
+    if (defaultValue) throw 'incorrect value in "defaultValue"';
+
+    if (deleteValue != null) throw 'incorrect initialization of "deleteValue"';
+    deleteValue = true;
+    if (!deleteValue) throw 'incorrect value in "deleteValue"';
+    deleteValue = false;
+    if (deleteValue) throw 'incorrect value in "deleteValue"';
+
+    if (doValue != null) throw 'incorrect initialization of "doValue"';
+    doValue = true;
+    if (!doValue) throw 'incorrect value in "doValue"';
+    doValue = false;
+    if (doValue) throw 'incorrect value in "doValue"';
+
+    if (elseValue != null) throw 'incorrect initialization of "elseValue"';
+    elseValue = true;
+    if (!elseValue) throw 'incorrect value in "elseValue"';
+    elseValue = false;
+    if (elseValue) throw 'incorrect value in "elseValue"';
+
+    if (enumValue != null) throw 'incorrect initialization of "enumValue"';
+    enumValue = true;
+    if (!enumValue) throw 'incorrect value in "enumValue"';
+    enumValue = false;
+    if (enumValue) throw 'incorrect value in "enumValue"';
+
+    if (exportValue != null) throw 'incorrect initialization of "exportValue"';
+    exportValue = true;
+    if (!exportValue) throw 'incorrect value in "exportValue"';
+    exportValue = false;
+    if (exportValue) throw 'incorrect value in "exportValue"';
+
+    if (extendsValue != null)
+      throw 'incorrect initialization of "extendsValue"';
+    extendsValue = true;
+    if (!extendsValue) throw 'incorrect value in "extendsValue"';
+    extendsValue = false;
+    if (extendsValue) throw 'incorrect value in "extendsValue"';
+
+    if (falseValue != null) throw 'incorrect initialization of "falseValue"';
+    falseValue = true;
+    if (!falseValue) throw 'incorrect value in "falseValue"';
+    falseValue = false;
+    if (falseValue) throw 'incorrect value in "falseValue"';
+
+    if (finallyValue != null)
+      throw 'incorrect initialization of "finallyValue"';
+    finallyValue = true;
+    if (!finallyValue) throw 'incorrect value in "finallyValue"';
+    finallyValue = false;
+    if (finallyValue) throw 'incorrect value in "finallyValue"';
+
+    if (forValue != null) throw 'incorrect initialization of "forValue"';
+    forValue = true;
+    if (!forValue) throw 'incorrect value in "forValue"';
+    forValue = false;
+    if (forValue) throw 'incorrect value in "forValue"';
+
+    if (functionValue != null)
+      throw 'incorrect initialization of "functionValue"';
+    functionValue = true;
+    if (!functionValue) throw 'incorrect value in "functionValue"';
+    functionValue = false;
+    if (functionValue) throw 'incorrect value in "functionValue"';
+
+    if (ifValue != null) throw 'incorrect initialization of "ifValue"';
+    ifValue = true;
+    if (!ifValue) throw 'incorrect value in "ifValue"';
+    ifValue = false;
+    if (ifValue) throw 'incorrect value in "ifValue"';
+
+    if (implementsValue != null)
+      throw 'incorrect initialization of "implementsValue"';
+    implementsValue = true;
+    if (!implementsValue) throw 'incorrect value in "implementsValue"';
+    implementsValue = false;
+    if (implementsValue) throw 'incorrect value in "implementsValue"';
+
+    if (importValue != null) throw 'incorrect initialization of "importValue"';
+    importValue = true;
+    if (!importValue) throw 'incorrect value in "importValue"';
+    importValue = false;
+    if (importValue) throw 'incorrect value in "importValue"';
+
+    if (inValue != null) throw 'incorrect initialization of "inValue"';
+    inValue = true;
+    if (!inValue) throw 'incorrect value in "inValue"';
+    inValue = false;
+    if (inValue) throw 'incorrect value in "inValue"';
+
+    if (instanceofValue != null)
+      throw 'incorrect initialization of "instanceofValue"';
+    instanceofValue = true;
+    if (!instanceofValue) throw 'incorrect value in "instanceofValue"';
+    instanceofValue = false;
+    if (instanceofValue) throw 'incorrect value in "instanceofValue"';
+
+    if (interfaceValue != null)
+      throw 'incorrect initialization of "interfaceValue"';
+    interfaceValue = true;
+    if (!interfaceValue) throw 'incorrect value in "interfaceValue"';
+    interfaceValue = false;
+    if (interfaceValue) throw 'incorrect value in "interfaceValue"';
+
+    if (letValue != null) throw 'incorrect initialization of "letValue"';
+    letValue = true;
+    if (!letValue) throw 'incorrect value in "letValue"';
+    letValue = false;
+    if (letValue) throw 'incorrect value in "letValue"';
+
+    if (newValue != null) throw 'incorrect initialization of "newValue"';
+    newValue = true;
+    if (!newValue) throw 'incorrect value in "newValue"';
+    newValue = false;
+    if (newValue) throw 'incorrect value in "newValue"';
+
+    if (nullValue != null) throw 'incorrect initialization of "nullValue"';
+    nullValue = true;
+    if (!nullValue) throw 'incorrect value in "nullValue"';
+    nullValue = false;
+    if (nullValue) throw 'incorrect value in "nullValue"';
+
+    if (packageValue != null)
+      throw 'incorrect initialization of "packageValue"';
+    packageValue = true;
+    if (!packageValue) throw 'incorrect value in "packageValue"';
+    packageValue = false;
+    if (packageValue) throw 'incorrect value in "packageValue"';
+
+    if (privateValue != null)
+      throw 'incorrect initialization of "privateValue"';
+    privateValue = true;
+    if (!privateValue) throw 'incorrect value in "privateValue"';
+    privateValue = false;
+    if (privateValue) throw 'incorrect value in "privateValue"';
+
+    if (protectedValue != null)
+      throw 'incorrect initialization of "protectedValue"';
+    protectedValue = true;
+    if (!protectedValue) throw 'incorrect value in "protectedValue"';
+    protectedValue = false;
+    if (protectedValue) throw 'incorrect value in "protectedValue"';
+
+    if (publicValue != null) throw 'incorrect initialization of "publicValue"';
+    publicValue = true;
+    if (!publicValue) throw 'incorrect value in "publicValue"';
+    publicValue = false;
+    if (publicValue) throw 'incorrect value in "publicValue"';
+
+    if (returnValue != null) throw 'incorrect initialization of "returnValue"';
+    returnValue = true;
+    if (!returnValue) throw 'incorrect value in "returnValue"';
+    returnValue = false;
+    if (returnValue) throw 'incorrect value in "returnValue"';
+
+    if (staticValue != null) throw 'incorrect initialization of "staticValue"';
+    staticValue = true;
+    if (!staticValue) throw 'incorrect value in "staticValue"';
+    staticValue = false;
+    if (staticValue) throw 'incorrect value in "staticValue"';
+
+    if (superValue != null) throw 'incorrect initialization of "superValue"';
+    superValue = true;
+    if (!superValue) throw 'incorrect value in "superValue"';
+    superValue = false;
+    if (superValue) throw 'incorrect value in "superValue"';
+
+    if (switchValue != null) throw 'incorrect initialization of "switchValue"';
+    switchValue = true;
+    if (!switchValue) throw 'incorrect value in "switchValue"';
+    switchValue = false;
+    if (switchValue) throw 'incorrect value in "switchValue"';
+
+    if (thisValue != null) throw 'incorrect initialization of "thisValue"';
+    thisValue = true;
+    if (!thisValue) throw 'incorrect value in "thisValue"';
+    thisValue = false;
+    if (thisValue) throw 'incorrect value in "thisValue"';
+
+    if (throwValue != null) throw 'incorrect initialization of "throwValue"';
+    throwValue = true;
+    if (!throwValue) throw 'incorrect value in "throwValue"';
+    throwValue = false;
+    if (throwValue) throw 'incorrect value in "throwValue"';
+
+    if (trueValue != null) throw 'incorrect initialization of "trueValue"';
+    trueValue = true;
+    if (!trueValue) throw 'incorrect value in "trueValue"';
+    trueValue = false;
+    if (trueValue) throw 'incorrect value in "trueValue"';
+
+    if (tryValue != null) throw 'incorrect initialization of "tryValue"';
+    tryValue = true;
+    if (!tryValue) throw 'incorrect value in "tryValue"';
+    tryValue = false;
+    if (tryValue) throw 'incorrect value in "tryValue"';
+
+    if (typeofValue != null) throw 'incorrect initialization of "typeofValue"';
+    typeofValue = true;
+    if (!typeofValue) throw 'incorrect value in "typeofValue"';
+    typeofValue = false;
+    if (typeofValue) throw 'incorrect value in "typeofValue"';
+
+    if (varValue != null) throw 'incorrect initialization of "varValue"';
+    varValue = true;
+    if (!varValue) throw 'incorrect value in "varValue"';
+    varValue = false;
+    if (varValue) throw 'incorrect value in "varValue"';
+
+    if (voidValue != null) throw 'incorrect initialization of "voidValue"';
+    voidValue = true;
+    if (!voidValue) throw 'incorrect value in "voidValue"';
+    voidValue = false;
+    if (voidValue) throw 'incorrect value in "voidValue"';
+
+    if (whileValue != null) throw 'incorrect initialization of "whileValue"';
+    whileValue = true;
+    if (!whileValue) throw 'incorrect value in "whileValue"';
+    whileValue = false;
+    if (whileValue) throw 'incorrect value in "whileValue"';
+
+    if (withValue != null) throw 'incorrect initialization of "withValue"';
+    withValue = true;
+    if (!withValue) throw 'incorrect value in "withValue"';
+    withValue = false;
+    if (withValue) throw 'incorrect value in "withValue"';
+
+    if (yieldValue != null) throw 'incorrect initialization of "yieldValue"';
+    yieldValue = true;
+    if (!yieldValue) throw 'incorrect value in "yieldValue"';
+    yieldValue = false;
+    if (yieldValue) throw 'incorrect value in "yieldValue"';
+  }
+}
+
+/// Called once with an instance of NativeClassWithOddNames making it easy
+/// to inline accessors.
+testObjectStronglyTyped(object) {
+  if (object.breakValue == null)
+    throw 'incorrect initialization of "breakValue"';
+  object.breakValue = true;
+  if (!object.breakValue) throw 'incorrect value in "breakValue"';
+  object.breakValue = false;
+  if (object.breakValue) throw 'incorrect value in "breakValue"';
+
+  if (object.caseValue == null) throw 'incorrect initialization of "caseValue"';
+  object.caseValue = true;
+  if (!object.caseValue) throw 'incorrect value in "caseValue"';
+  object.caseValue = false;
+  if (object.caseValue) throw 'incorrect value in "caseValue"';
+
+  if (object.catchValue == null)
+    throw 'incorrect initialization of "catchValue"';
+  object.catchValue = true;
+  if (!object.catchValue) throw 'incorrect value in "catchValue"';
+  object.catchValue = false;
+  if (object.catchValue) throw 'incorrect value in "catchValue"';
+
+  if (object.classValue == null)
+    throw 'incorrect initialization of "classValue"';
+  object.classValue = true;
+  if (!object.classValue) throw 'incorrect value in "classValue"';
+  object.classValue = false;
+  if (object.classValue) throw 'incorrect value in "classValue"';
+
+  if (object.constValue == null)
+    throw 'incorrect initialization of "constValue"';
+  object.constValue = true;
+  if (!object.constValue) throw 'incorrect value in "constValue"';
+  object.constValue = false;
+  if (object.constValue) throw 'incorrect value in "constValue"';
+
+  if (object.continueValue == null)
+    throw 'incorrect initialization of "continueValue"';
+  object.continueValue = true;
+  if (!object.continueValue) throw 'incorrect value in "continueValue"';
+  object.continueValue = false;
+  if (object.continueValue) throw 'incorrect value in "continueValue"';
+
+  if (object.debuggerValue == null)
+    throw 'incorrect initialization of "debuggerValue"';
+  object.debuggerValue = true;
+  if (!object.debuggerValue) throw 'incorrect value in "debuggerValue"';
+  object.debuggerValue = false;
+  if (object.debuggerValue) throw 'incorrect value in "debuggerValue"';
+
+  if (object.defaultValue == null)
+    throw 'incorrect initialization of "defaultValue"';
+  object.defaultValue = true;
+  if (!object.defaultValue) throw 'incorrect value in "defaultValue"';
+  object.defaultValue = false;
+  if (object.defaultValue) throw 'incorrect value in "defaultValue"';
+
+  if (object.deleteValue == null)
+    throw 'incorrect initialization of "deleteValue"';
+  object.deleteValue = true;
+  if (!object.deleteValue) throw 'incorrect value in "deleteValue"';
+  object.deleteValue = false;
+  if (object.deleteValue) throw 'incorrect value in "deleteValue"';
+
+  if (object.doValue == null) throw 'incorrect initialization of "doValue"';
+  object.doValue = true;
+  if (!object.doValue) throw 'incorrect value in "doValue"';
+  object.doValue = false;
+  if (object.doValue) throw 'incorrect value in "doValue"';
+
+  if (object.elseValue == null) throw 'incorrect initialization of "elseValue"';
+  object.elseValue = true;
+  if (!object.elseValue) throw 'incorrect value in "elseValue"';
+  object.elseValue = false;
+  if (object.elseValue) throw 'incorrect value in "elseValue"';
+
+  if (object.enumValue == null) throw 'incorrect initialization of "enumValue"';
+  object.enumValue = true;
+  if (!object.enumValue) throw 'incorrect value in "enumValue"';
+  object.enumValue = false;
+  if (object.enumValue) throw 'incorrect value in "enumValue"';
+
+  if (object.exportValue == null)
+    throw 'incorrect initialization of "exportValue"';
+  object.exportValue = true;
+  if (!object.exportValue) throw 'incorrect value in "exportValue"';
+  object.exportValue = false;
+  if (object.exportValue) throw 'incorrect value in "exportValue"';
+
+  if (object.extendsValue == null)
+    throw 'incorrect initialization of "extendsValue"';
+  object.extendsValue = true;
+  if (!object.extendsValue) throw 'incorrect value in "extendsValue"';
+  object.extendsValue = false;
+  if (object.extendsValue) throw 'incorrect value in "extendsValue"';
+
+  if (object.falseValue == null)
+    throw 'incorrect initialization of "falseValue"';
+  object.falseValue = true;
+  if (!object.falseValue) throw 'incorrect value in "falseValue"';
+  object.falseValue = false;
+  if (object.falseValue) throw 'incorrect value in "falseValue"';
+
+  if (object.finallyValue == null)
+    throw 'incorrect initialization of "finallyValue"';
+  object.finallyValue = true;
+  if (!object.finallyValue) throw 'incorrect value in "finallyValue"';
+  object.finallyValue = false;
+  if (object.finallyValue) throw 'incorrect value in "finallyValue"';
+
+  if (object.forValue == null) throw 'incorrect initialization of "forValue"';
+  object.forValue = true;
+  if (!object.forValue) throw 'incorrect value in "forValue"';
+  object.forValue = false;
+  if (object.forValue) throw 'incorrect value in "forValue"';
+
+  if (object.functionValue == null)
+    throw 'incorrect initialization of "functionValue"';
+  object.functionValue = true;
+  if (!object.functionValue) throw 'incorrect value in "functionValue"';
+  object.functionValue = false;
+  if (object.functionValue) throw 'incorrect value in "functionValue"';
+
+  if (object.ifValue == null) throw 'incorrect initialization of "ifValue"';
+  object.ifValue = true;
+  if (!object.ifValue) throw 'incorrect value in "ifValue"';
+  object.ifValue = false;
+  if (object.ifValue) throw 'incorrect value in "ifValue"';
+
+  if (object.implementsValue == null)
+    throw 'incorrect initialization of "implementsValue"';
+  object.implementsValue = true;
+  if (!object.implementsValue) throw 'incorrect value in "implementsValue"';
+  object.implementsValue = false;
+  if (object.implementsValue) throw 'incorrect value in "implementsValue"';
+
+  if (object.importValue == null)
+    throw 'incorrect initialization of "importValue"';
+  object.importValue = true;
+  if (!object.importValue) throw 'incorrect value in "importValue"';
+  object.importValue = false;
+  if (object.importValue) throw 'incorrect value in "importValue"';
+
+  if (object.inValue == null) throw 'incorrect initialization of "inValue"';
+  object.inValue = true;
+  if (!object.inValue) throw 'incorrect value in "inValue"';
+  object.inValue = false;
+  if (object.inValue) throw 'incorrect value in "inValue"';
+
+  if (object.instanceofValue == null)
+    throw 'incorrect initialization of "instanceofValue"';
+  object.instanceofValue = true;
+  if (!object.instanceofValue) throw 'incorrect value in "instanceofValue"';
+  object.instanceofValue = false;
+  if (object.instanceofValue) throw 'incorrect value in "instanceofValue"';
+
+  if (object.interfaceValue == null)
+    throw 'incorrect initialization of "interfaceValue"';
+  object.interfaceValue = true;
+  if (!object.interfaceValue) throw 'incorrect value in "interfaceValue"';
+  object.interfaceValue = false;
+  if (object.interfaceValue) throw 'incorrect value in "interfaceValue"';
+
+  if (object.letValue == null) throw 'incorrect initialization of "letValue"';
+  object.letValue = true;
+  if (!object.letValue) throw 'incorrect value in "letValue"';
+  object.letValue = false;
+  if (object.letValue) throw 'incorrect value in "letValue"';
+
+  if (object.newValue == null) throw 'incorrect initialization of "newValue"';
+  object.newValue = true;
+  if (!object.newValue) throw 'incorrect value in "newValue"';
+  object.newValue = false;
+  if (object.newValue) throw 'incorrect value in "newValue"';
+
+  if (object.nullValue == null) throw 'incorrect initialization of "nullValue"';
+  object.nullValue = true;
+  if (!object.nullValue) throw 'incorrect value in "nullValue"';
+  object.nullValue = false;
+  if (object.nullValue) throw 'incorrect value in "nullValue"';
+
+  if (object.packageValue == null)
+    throw 'incorrect initialization of "packageValue"';
+  object.packageValue = true;
+  if (!object.packageValue) throw 'incorrect value in "packageValue"';
+  object.packageValue = false;
+  if (object.packageValue) throw 'incorrect value in "packageValue"';
+
+  if (object.privateValue == null)
+    throw 'incorrect initialization of "privateValue"';
+  object.privateValue = true;
+  if (!object.privateValue) throw 'incorrect value in "privateValue"';
+  object.privateValue = false;
+  if (object.privateValue) throw 'incorrect value in "privateValue"';
+
+  if (object.protectedValue == null)
+    throw 'incorrect initialization of "protectedValue"';
+  object.protectedValue = true;
+  if (!object.protectedValue) throw 'incorrect value in "protectedValue"';
+  object.protectedValue = false;
+  if (object.protectedValue) throw 'incorrect value in "protectedValue"';
+
+  if (object.publicValue == null)
+    throw 'incorrect initialization of "publicValue"';
+  object.publicValue = true;
+  if (!object.publicValue) throw 'incorrect value in "publicValue"';
+  object.publicValue = false;
+  if (object.publicValue) throw 'incorrect value in "publicValue"';
+
+  if (object.returnValue == null)
+    throw 'incorrect initialization of "returnValue"';
+  object.returnValue = true;
+  if (!object.returnValue) throw 'incorrect value in "returnValue"';
+  object.returnValue = false;
+  if (object.returnValue) throw 'incorrect value in "returnValue"';
+
+  if (object.staticValue == null)
+    throw 'incorrect initialization of "staticValue"';
+  object.staticValue = true;
+  if (!object.staticValue) throw 'incorrect value in "staticValue"';
+  object.staticValue = false;
+  if (object.staticValue) throw 'incorrect value in "staticValue"';
+
+  if (object.superValue == null)
+    throw 'incorrect initialization of "superValue"';
+  object.superValue = true;
+  if (!object.superValue) throw 'incorrect value in "superValue"';
+  object.superValue = false;
+  if (object.superValue) throw 'incorrect value in "superValue"';
+
+  if (object.switchValue == null)
+    throw 'incorrect initialization of "switchValue"';
+  object.switchValue = true;
+  if (!object.switchValue) throw 'incorrect value in "switchValue"';
+  object.switchValue = false;
+  if (object.switchValue) throw 'incorrect value in "switchValue"';
+
+  if (object.thisValue == null) throw 'incorrect initialization of "thisValue"';
+  object.thisValue = true;
+  if (!object.thisValue) throw 'incorrect value in "thisValue"';
+  object.thisValue = false;
+  if (object.thisValue) throw 'incorrect value in "thisValue"';
+
+  if (object.throwValue == null)
+    throw 'incorrect initialization of "throwValue"';
+  object.throwValue = true;
+  if (!object.throwValue) throw 'incorrect value in "throwValue"';
+  object.throwValue = false;
+  if (object.throwValue) throw 'incorrect value in "throwValue"';
+
+  if (object.trueValue == null) throw 'incorrect initialization of "trueValue"';
+  object.trueValue = true;
+  if (!object.trueValue) throw 'incorrect value in "trueValue"';
+  object.trueValue = false;
+  if (object.trueValue) throw 'incorrect value in "trueValue"';
+
+  if (object.tryValue == null) throw 'incorrect initialization of "tryValue"';
+  object.tryValue = true;
+  if (!object.tryValue) throw 'incorrect value in "tryValue"';
+  object.tryValue = false;
+  if (object.tryValue) throw 'incorrect value in "tryValue"';
+
+  if (object.typeofValue == null)
+    throw 'incorrect initialization of "typeofValue"';
+  object.typeofValue = true;
+  if (!object.typeofValue) throw 'incorrect value in "typeofValue"';
+  object.typeofValue = false;
+  if (object.typeofValue) throw 'incorrect value in "typeofValue"';
+
+  if (object.varValue == null) throw 'incorrect initialization of "varValue"';
+  object.varValue = true;
+  if (!object.varValue) throw 'incorrect value in "varValue"';
+  object.varValue = false;
+  if (object.varValue) throw 'incorrect value in "varValue"';
+
+  if (object.voidValue == null) throw 'incorrect initialization of "voidValue"';
+  object.voidValue = true;
+  if (!object.voidValue) throw 'incorrect value in "voidValue"';
+  object.voidValue = false;
+  if (object.voidValue) throw 'incorrect value in "voidValue"';
+
+  if (object.whileValue == null)
+    throw 'incorrect initialization of "whileValue"';
+  object.whileValue = true;
+  if (!object.whileValue) throw 'incorrect value in "whileValue"';
+  object.whileValue = false;
+  if (object.whileValue) throw 'incorrect value in "whileValue"';
+
+  if (object.withValue == null) throw 'incorrect initialization of "withValue"';
+  object.withValue = true;
+  if (!object.withValue) throw 'incorrect value in "withValue"';
+  object.withValue = false;
+  if (object.withValue) throw 'incorrect value in "withValue"';
+
+  if (object.yieldValue == null)
+    throw 'incorrect initialization of "yieldValue"';
+  object.yieldValue = true;
+  if (!object.yieldValue) throw 'incorrect value in "yieldValue"';
+  object.yieldValue = false;
+  if (object.yieldValue) throw 'incorrect value in "yieldValue"';
+}
+
+/// Called multiple times with arguments that are hard to track in type
+/// inference making it hard to inline accessors.
+testObjectWeaklyTyped(object) {
+  object = object[0];
+  if (object == 'fisk') return;
+  if (object.breakValue == null)
+    throw 'incorrect initialization of "breakValue"';
+  object.breakValue = true;
+  if (!object.breakValue) throw 'incorrect value in "breakValue"';
+  object.breakValue = false;
+  if (object.breakValue) throw 'incorrect value in "breakValue"';
+
+  if (object.caseValue == null) throw 'incorrect initialization of "caseValue"';
+  object.caseValue = true;
+  if (!object.caseValue) throw 'incorrect value in "caseValue"';
+  object.caseValue = false;
+  if (object.caseValue) throw 'incorrect value in "caseValue"';
+
+  if (object.catchValue == null)
+    throw 'incorrect initialization of "catchValue"';
+  object.catchValue = true;
+  if (!object.catchValue) throw 'incorrect value in "catchValue"';
+  object.catchValue = false;
+  if (object.catchValue) throw 'incorrect value in "catchValue"';
+
+  if (object.classValue == null)
+    throw 'incorrect initialization of "classValue"';
+  object.classValue = true;
+  if (!object.classValue) throw 'incorrect value in "classValue"';
+  object.classValue = false;
+  if (object.classValue) throw 'incorrect value in "classValue"';
+
+  if (object.constValue == null)
+    throw 'incorrect initialization of "constValue"';
+  object.constValue = true;
+  if (!object.constValue) throw 'incorrect value in "constValue"';
+  object.constValue = false;
+  if (object.constValue) throw 'incorrect value in "constValue"';
+
+  if (object.continueValue == null)
+    throw 'incorrect initialization of "continueValue"';
+  object.continueValue = true;
+  if (!object.continueValue) throw 'incorrect value in "continueValue"';
+  object.continueValue = false;
+  if (object.continueValue) throw 'incorrect value in "continueValue"';
+
+  if (object.debuggerValue == null)
+    throw 'incorrect initialization of "debuggerValue"';
+  object.debuggerValue = true;
+  if (!object.debuggerValue) throw 'incorrect value in "debuggerValue"';
+  object.debuggerValue = false;
+  if (object.debuggerValue) throw 'incorrect value in "debuggerValue"';
+
+  if (object.defaultValue == null)
+    throw 'incorrect initialization of "defaultValue"';
+  object.defaultValue = true;
+  if (!object.defaultValue) throw 'incorrect value in "defaultValue"';
+  object.defaultValue = false;
+  if (object.defaultValue) throw 'incorrect value in "defaultValue"';
+
+  if (object.deleteValue == null)
+    throw 'incorrect initialization of "deleteValue"';
+  object.deleteValue = true;
+  if (!object.deleteValue) throw 'incorrect value in "deleteValue"';
+  object.deleteValue = false;
+  if (object.deleteValue) throw 'incorrect value in "deleteValue"';
+
+  if (object.doValue == null) throw 'incorrect initialization of "doValue"';
+  object.doValue = true;
+  if (!object.doValue) throw 'incorrect value in "doValue"';
+  object.doValue = false;
+  if (object.doValue) throw 'incorrect value in "doValue"';
+
+  if (object.elseValue == null) throw 'incorrect initialization of "elseValue"';
+  object.elseValue = true;
+  if (!object.elseValue) throw 'incorrect value in "elseValue"';
+  object.elseValue = false;
+  if (object.elseValue) throw 'incorrect value in "elseValue"';
+
+  if (object.enumValue == null) throw 'incorrect initialization of "enumValue"';
+  object.enumValue = true;
+  if (!object.enumValue) throw 'incorrect value in "enumValue"';
+  object.enumValue = false;
+  if (object.enumValue) throw 'incorrect value in "enumValue"';
+
+  if (object.exportValue == null)
+    throw 'incorrect initialization of "exportValue"';
+  object.exportValue = true;
+  if (!object.exportValue) throw 'incorrect value in "exportValue"';
+  object.exportValue = false;
+  if (object.exportValue) throw 'incorrect value in "exportValue"';
+
+  if (object.extendsValue == null)
+    throw 'incorrect initialization of "extendsValue"';
+  object.extendsValue = true;
+  if (!object.extendsValue) throw 'incorrect value in "extendsValue"';
+  object.extendsValue = false;
+  if (object.extendsValue) throw 'incorrect value in "extendsValue"';
+
+  if (object.falseValue == null)
+    throw 'incorrect initialization of "falseValue"';
+  object.falseValue = true;
+  if (!object.falseValue) throw 'incorrect value in "falseValue"';
+  object.falseValue = false;
+  if (object.falseValue) throw 'incorrect value in "falseValue"';
+
+  if (object.finallyValue == null)
+    throw 'incorrect initialization of "finallyValue"';
+  object.finallyValue = true;
+  if (!object.finallyValue) throw 'incorrect value in "finallyValue"';
+  object.finallyValue = false;
+  if (object.finallyValue) throw 'incorrect value in "finallyValue"';
+
+  if (object.forValue == null) throw 'incorrect initialization of "forValue"';
+  object.forValue = true;
+  if (!object.forValue) throw 'incorrect value in "forValue"';
+  object.forValue = false;
+  if (object.forValue) throw 'incorrect value in "forValue"';
+
+  if (object.functionValue == null)
+    throw 'incorrect initialization of "functionValue"';
+  object.functionValue = true;
+  if (!object.functionValue) throw 'incorrect value in "functionValue"';
+  object.functionValue = false;
+  if (object.functionValue) throw 'incorrect value in "functionValue"';
+
+  if (object.ifValue == null) throw 'incorrect initialization of "ifValue"';
+  object.ifValue = true;
+  if (!object.ifValue) throw 'incorrect value in "ifValue"';
+  object.ifValue = false;
+  if (object.ifValue) throw 'incorrect value in "ifValue"';
+
+  if (object.implementsValue == null)
+    throw 'incorrect initialization of "implementsValue"';
+  object.implementsValue = true;
+  if (!object.implementsValue) throw 'incorrect value in "implementsValue"';
+  object.implementsValue = false;
+  if (object.implementsValue) throw 'incorrect value in "implementsValue"';
+
+  if (object.importValue == null)
+    throw 'incorrect initialization of "importValue"';
+  object.importValue = true;
+  if (!object.importValue) throw 'incorrect value in "importValue"';
+  object.importValue = false;
+  if (object.importValue) throw 'incorrect value in "importValue"';
+
+  if (object.inValue == null) throw 'incorrect initialization of "inValue"';
+  object.inValue = true;
+  if (!object.inValue) throw 'incorrect value in "inValue"';
+  object.inValue = false;
+  if (object.inValue) throw 'incorrect value in "inValue"';
+
+  if (object.instanceofValue == null)
+    throw 'incorrect initialization of "instanceofValue"';
+  object.instanceofValue = true;
+  if (!object.instanceofValue) throw 'incorrect value in "instanceofValue"';
+  object.instanceofValue = false;
+  if (object.instanceofValue) throw 'incorrect value in "instanceofValue"';
+
+  if (object.interfaceValue == null)
+    throw 'incorrect initialization of "interfaceValue"';
+  object.interfaceValue = true;
+  if (!object.interfaceValue) throw 'incorrect value in "interfaceValue"';
+  object.interfaceValue = false;
+  if (object.interfaceValue) throw 'incorrect value in "interfaceValue"';
+
+  if (object.letValue == null) throw 'incorrect initialization of "letValue"';
+  object.letValue = true;
+  if (!object.letValue) throw 'incorrect value in "letValue"';
+  object.letValue = false;
+  if (object.letValue) throw 'incorrect value in "letValue"';
+
+  if (object.newValue == null) throw 'incorrect initialization of "newValue"';
+  object.newValue = true;
+  if (!object.newValue) throw 'incorrect value in "newValue"';
+  object.newValue = false;
+  if (object.newValue) throw 'incorrect value in "newValue"';
+
+  if (object.nullValue == null) throw 'incorrect initialization of "nullValue"';
+  object.nullValue = true;
+  if (!object.nullValue) throw 'incorrect value in "nullValue"';
+  object.nullValue = false;
+  if (object.nullValue) throw 'incorrect value in "nullValue"';
+
+  if (object.packageValue == null)
+    throw 'incorrect initialization of "packageValue"';
+  object.packageValue = true;
+  if (!object.packageValue) throw 'incorrect value in "packageValue"';
+  object.packageValue = false;
+  if (object.packageValue) throw 'incorrect value in "packageValue"';
+
+  if (object.privateValue == null)
+    throw 'incorrect initialization of "privateValue"';
+  object.privateValue = true;
+  if (!object.privateValue) throw 'incorrect value in "privateValue"';
+  object.privateValue = false;
+  if (object.privateValue) throw 'incorrect value in "privateValue"';
+
+  if (object.protectedValue == null)
+    throw 'incorrect initialization of "protectedValue"';
+  object.protectedValue = true;
+  if (!object.protectedValue) throw 'incorrect value in "protectedValue"';
+  object.protectedValue = false;
+  if (object.protectedValue) throw 'incorrect value in "protectedValue"';
+
+  if (object.publicValue == null)
+    throw 'incorrect initialization of "publicValue"';
+  object.publicValue = true;
+  if (!object.publicValue) throw 'incorrect value in "publicValue"';
+  object.publicValue = false;
+  if (object.publicValue) throw 'incorrect value in "publicValue"';
+
+  if (object.returnValue == null)
+    throw 'incorrect initialization of "returnValue"';
+  object.returnValue = true;
+  if (!object.returnValue) throw 'incorrect value in "returnValue"';
+  object.returnValue = false;
+  if (object.returnValue) throw 'incorrect value in "returnValue"';
+
+  if (object.staticValue == null)
+    throw 'incorrect initialization of "staticValue"';
+  object.staticValue = true;
+  if (!object.staticValue) throw 'incorrect value in "staticValue"';
+  object.staticValue = false;
+  if (object.staticValue) throw 'incorrect value in "staticValue"';
+
+  if (object.superValue == null)
+    throw 'incorrect initialization of "superValue"';
+  object.superValue = true;
+  if (!object.superValue) throw 'incorrect value in "superValue"';
+  object.superValue = false;
+  if (object.superValue) throw 'incorrect value in "superValue"';
+
+  if (object.switchValue == null)
+    throw 'incorrect initialization of "switchValue"';
+  object.switchValue = true;
+  if (!object.switchValue) throw 'incorrect value in "switchValue"';
+  object.switchValue = false;
+  if (object.switchValue) throw 'incorrect value in "switchValue"';
+
+  if (object.thisValue == null) throw 'incorrect initialization of "thisValue"';
+  object.thisValue = true;
+  if (!object.thisValue) throw 'incorrect value in "thisValue"';
+  object.thisValue = false;
+  if (object.thisValue) throw 'incorrect value in "thisValue"';
+
+  if (object.throwValue == null)
+    throw 'incorrect initialization of "throwValue"';
+  object.throwValue = true;
+  if (!object.throwValue) throw 'incorrect value in "throwValue"';
+  object.throwValue = false;
+  if (object.throwValue) throw 'incorrect value in "throwValue"';
+
+  if (object.trueValue == null) throw 'incorrect initialization of "trueValue"';
+  object.trueValue = true;
+  if (!object.trueValue) throw 'incorrect value in "trueValue"';
+  object.trueValue = false;
+  if (object.trueValue) throw 'incorrect value in "trueValue"';
+
+  if (object.tryValue == null) throw 'incorrect initialization of "tryValue"';
+  object.tryValue = true;
+  if (!object.tryValue) throw 'incorrect value in "tryValue"';
+  object.tryValue = false;
+  if (object.tryValue) throw 'incorrect value in "tryValue"';
+
+  if (object.typeofValue == null)
+    throw 'incorrect initialization of "typeofValue"';
+  object.typeofValue = true;
+  if (!object.typeofValue) throw 'incorrect value in "typeofValue"';
+  object.typeofValue = false;
+  if (object.typeofValue) throw 'incorrect value in "typeofValue"';
+
+  if (object.varValue == null) throw 'incorrect initialization of "varValue"';
+  object.varValue = true;
+  if (!object.varValue) throw 'incorrect value in "varValue"';
+  object.varValue = false;
+  if (object.varValue) throw 'incorrect value in "varValue"';
+
+  if (object.voidValue == null) throw 'incorrect initialization of "voidValue"';
+  object.voidValue = true;
+  if (!object.voidValue) throw 'incorrect value in "voidValue"';
+  object.voidValue = false;
+  if (object.voidValue) throw 'incorrect value in "voidValue"';
+
+  if (object.whileValue == null)
+    throw 'incorrect initialization of "whileValue"';
+  object.whileValue = true;
+  if (!object.whileValue) throw 'incorrect value in "whileValue"';
+  object.whileValue = false;
+  if (object.whileValue) throw 'incorrect value in "whileValue"';
+
+  if (object.withValue == null) throw 'incorrect initialization of "withValue"';
+  object.withValue = true;
+  if (!object.withValue) throw 'incorrect value in "withValue"';
+  object.withValue = false;
+  if (object.withValue) throw 'incorrect value in "withValue"';
+
+  if (object.yieldValue == null)
+    throw 'incorrect initialization of "yieldValue"';
+  object.yieldValue = true;
+  if (!object.yieldValue) throw 'incorrect value in "yieldValue"';
+  object.yieldValue = false;
+  if (object.yieldValue) throw 'incorrect value in "yieldValue"';
+}
+
+NativeClassWithOddNames makeNativeClassWithOddNames() native;
+
+setup() {
+  JS('', r"""
+(function(){
+  function NativeClassWithOddNames() {}
+  makeNativeClassWithOddNames = function() {return new NativeClassWithOddNames()};
+  self.nativeConstructor(NativeClassWithOddNames);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var object = makeNativeClassWithOddNames();
+  object.testMyFields();
+  testObjectStronglyTyped(object);
+  testObjectWeaklyTyped([object]);
+  testObjectWeaklyTyped(['fisk']);
+  testObjectWeaklyTyped([new ClassWithOddNames()..testMyFields()]);
+}
diff --git a/tests/dart2js/native/optimization_hints_test.dart b/tests/dart2js/native/optimization_hints_test.dart
new file mode 100644
index 0000000..45ee3ad
--- /dev/null
+++ b/tests/dart2js/native/optimization_hints_test.dart
@@ -0,0 +1,221 @@
+// Copyright (c) 2013, 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:_foreign_helper' show JS;
+
+import 'package:expect/expect.dart';
+
+var x;
+
+foo(c) {
+  x = "in foo function";
+  c.c_field = x;
+}
+
+@pragma('dart2js:noSideEffects')
+@pragma('dart2js:noInline')
+bar(d) {
+  x = "in bar function";
+  d.d_field = x;
+}
+
+class C {
+  var c_field;
+  m() => c_field;
+}
+
+class D {
+  var d_field;
+  m() => d_field;
+}
+
+@pragma('dart2js:noSideEffects')
+@pragma('dart2js:noInline')
+@pragma('dart2js:noThrows')
+baz() {
+  throw 'in baz function';
+}
+
+@pragma('dart2js:noInline')
+geeNoInline() {
+  // Use `gee` several times, so `gee` isn't used only once (and thus inlinable
+  // independently of its size).
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+  gee();
+}
+
+@pragma('dart2js:tryInline')
+// Big function that would normally not be inlinable.
+gee([c]) {
+  if (c != null) {
+    x = "in gee function";
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+    geeNoInline();
+  }
+}
+
+main() {
+  JS('', 'String("in main function")');
+  var c;
+  if (new DateTime.now().millisecondsSinceEpoch != 42) {
+    c = new C();
+    print(c.m());
+    foo(c);
+    print(c.m());
+  } else {
+    var d = new D();
+    print(d.m());
+    bar(d);
+    print(d.m());
+  }
+  print(c.m());
+  simple();
+  noinline();
+  baz(); // This call should be eliminated by the optimizer.
+  gee(new C());
+  print(x);
+  check(JS('', 'arguments.callee'));
+}
+
+@pragma('dart2js:noInline')
+check(func) {
+  JS('', 'String("in check function")');
+  var source = JS('String', 'String(#)', func);
+  print(source);
+  Expect.isTrue(source.contains('"in main function"'), "should contain 'main'");
+  Expect.isTrue(
+      source.contains('"in simple function"'), "should inline 'simple'");
+  Expect.isTrue(source.contains('"in foo function"'), "should inline 'foo'");
+  Expect.isFalse(
+      source.contains('"in bar function"'), "should not inline 'bar'");
+  Expect.isFalse(
+      source.contains('"in check function"'), "should not inline 'check'");
+  Expect.isFalse(source.contains('"in noinline function"'),
+      "should not inline 'noinline'");
+  Expect.equals(2, new RegExp(r'\.c_field').allMatches(source).length,
+      "should contain r'\.c_field' exactly twice");
+  Expect.isFalse(
+      source.contains('.d_field'), "should not contain r'\.d_field'");
+  Expect.isTrue(source.contains('"in gee function"'), "must inline 'gee'");
+}
+
+simple() {
+  JS('', 'String("in simple function")');
+}
+
+@pragma('dart2js:noInline')
+noinline() {
+  JS('', 'String("in noinline function")');
+}
diff --git a/tests/dart2js/native/rti_only_native_test.dart b/tests/dart2js/native/rti_only_native_test.dart
new file mode 100644
index 0000000..ec2fa525
--- /dev/null
+++ b/tests/dart2js/native/rti_only_native_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for a bug that was caused by uninstantiated classes being
+// added to emitted classes by runtime-type system.
+// See my explanation in https://codereview.chromium.org/14018036/.
+//   -- ahe
+
+import "dart:_js_helper";
+
+@Native("A")
+class A {
+  // Just making sure the field name is unique.
+  var rti_only_native_test_field;
+}
+
+typedef fisk();
+
+main() {
+  void foo(A x) {}
+  var map = <String, dynamic>{'a': 0, 'b': main};
+  try {
+    map.values.forEach((x) => x.rti_only_native_test_field);
+  } finally {
+    print(main is fisk);
+    return;
+  }
+}
diff --git a/tests/dart2js/native/runtimetype_test.dart b/tests/dart2js/native/runtimetype_test.dart
new file mode 100644
index 0000000..558f7ee
--- /dev/null
+++ b/tests/dart2js/native/runtimetype_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+
+// Test to see runtimeType works on native classes and does not use the native
+// constructor name.
+
+@Native("TAGX")
+class A {}
+
+@Native("TAGY")
+class B extends A {}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    function tmp() {};
+    tmp.prototype = parent.prototype;
+    child.prototype = new tmp();
+    child.prototype.constructor = child;
+  }
+
+  function TAGX(){}
+  function TAGY(){}
+  inherits(TAGY, TAGX);
+
+  makeA = function(){return new TAGX()};
+  makeB = function(){return new TAGY()};
+
+  self.nativeConstructor(TAGX);
+  self.nativeConstructor(TAGY);
+})()""");
+}
+
+testDynamicContext() {
+  var a = makeA();
+  var b = makeB();
+
+  var aT = a.runtimeType;
+  var bT = b.runtimeType;
+
+  Expect.notEquals('TAGX', '$aT');
+  Expect.notEquals('TAGY', '$bT');
+}
+
+testStaticContext() {
+  var a = JS('A', '#', makeA()); // Force compiler to know type.
+  var b = JS('B', '#', makeB());
+
+  var aT = a.runtimeType;
+  var bT = b.runtimeType;
+
+  Expect.notEquals('TAGX', '$aT');
+  Expect.notEquals('TAGY', '$bT');
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  testDynamicContext();
+  testStaticContext();
+}
diff --git a/tests/dart2js/native/static_methods_test.dart b/tests/dart2js/native/static_methods_test.dart
new file mode 100644
index 0000000..d356c25
--- /dev/null
+++ b/tests/dart2js/native/static_methods_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2015, 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.
+
+// Accessing static native methods names:
+//   plain declaration ->  use @Native tag as 'scope' for declared name.
+//   identifier @JSName -> use @Native tag as 'scope' for @JSName.
+//   other @JSName -> use @JSName as an expression.
+
+import 'native_testing.dart';
+import 'dart:_js_helper' show convertDartClosureToJS;
+
+typedef int Callback(String s);
+
+@Native("CC") // Tag can be different to class name.
+class AA {
+  // This name is not an identifier, so completely defines how to access method.
+  @JSName('CC.foo')
+  static int foo(String s) native;
+
+  // This name is not an identifier, so completely defines how to access method.
+  @JSName('CC.bar')
+  static int bar(Callback c) native;
+  static int baz(Callback c) {
+    return bar(c);
+  }
+
+  // Compiler should automatically use the tag and the declared name, i.e. call
+  // `CC.lepton`.
+  static int lepton(Callback c) native;
+  static int electron(c) => lepton(c);
+
+  // Compiler should automatically use the tag and JSName, i.e. call
+  // `CC.baryon`.
+  @JSName('baryon')
+  static int _baryon(Callback c) native;
+  static int proton(c) => _baryon(c);
+}
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+
+  function CC(){}
+
+  CC.foo = function(s) { return s.length; };
+  CC.bar = function(f) { return f("Bye"); };
+  CC.lepton = function(f) { return f("Lepton"); };
+  CC.baryon = function(f) { return f("three quarks"); };
+
+  self.CC = CC;
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  Expect.equals(5, AA.foo("Hello"));
+
+  Expect.equals(3, AA.bar((String s) => s.length));
+  Expect.equals(3, AA.baz((String s) => s.length));
+
+  Expect.equals(6, AA.lepton((String s) => s.length));
+  Expect.equals(6, AA.electron((String s) => s.length));
+
+  Expect.equals(12, AA._baryon((String s) => s.length));
+  Expect.equals(12, AA.proton((String s) => s.length));
+}
diff --git a/tests/dart2js/native/subclassing_1_test.dart b/tests/dart2js/native/subclassing_1_test.dart
new file mode 100644
index 0000000..77a636f
--- /dev/null
+++ b/tests/dart2js/native/subclassing_1_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show findInterceptorForType;
+
+// Test that subclasses of native classes can be defined by setting the dispatch
+// record.
+
+@Native("A")
+class A {
+  foo(x) => '$x,${this.oof()}';
+  oof() => 'A';
+}
+
+class B extends A {
+  oof() => 'B';
+}
+
+B makeB1() native;
+B makeB2() native;
+B makeC() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+@Creates('=Object')
+getCPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  function C() {}
+  makeA = function(){return new A()};
+  makeB1 = function(){return new B()};
+  makeB2 = function(){return new B()};
+  makeC = function(){return new C()};
+
+  getBPrototype = function(){return B.prototype;};
+  getCPrototype = function(){return C.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+  setNativeSubclassDispatchRecord(getCPrototype(), findInterceptorForType(B));
+
+  B b1 = makeB1();
+  Expect.equals('1,B', b1.foo(1));
+
+  B b2 = makeB2();
+  Expect.equals('2,B', b2.foo(2));
+
+  B b3 = makeC();
+  Expect.equals('3,B', b3.foo(3));
+}
diff --git a/tests/dart2js/native/subclassing_2_test.dart b/tests/dart2js/native/subclassing_2_test.dart
new file mode 100644
index 0000000..66c8d68
--- /dev/null
+++ b/tests/dart2js/native/subclassing_2_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show findInterceptorForType;
+
+// Test calling convention of methods introduced on subclasses of native
+// classes.
+
+doFoo(r, x) => '$x,${r.oof()}';
+
+@Native("A")
+class A {
+  foo(x) => (doFoo)(this, x);
+}
+
+class B extends A {
+  // [oof] is introduced only on this subclass of a native class.  It should
+  // have interceptor calling convention.
+  oof() => 'B';
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function A() {}
+  function B() {}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+  Expect.equals('1,B', b.foo(1));
+}
diff --git a/tests/dart2js/native/subclassing_3_test.dart b/tests/dart2js/native/subclassing_3_test.dart
new file mode 100644
index 0000000..5a2c3d9
--- /dev/null
+++ b/tests/dart2js/native/subclassing_3_test.dart
@@ -0,0 +1,55 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show Interceptor, findInterceptorForType;
+
+// Test calling convention of methods introduced on subclasses of native
+// class of mixin.
+
+doFoo(r, x) => '$x,${r.oof()},${r.miz()}';
+
+class M {
+  miz() => 'M';
+}
+
+@Native("N")
+class N {
+  foo(x) => (doFoo)(this, x);
+}
+
+class A extends N {}
+
+class B extends A with M {
+  // [oof] is introduced only on this subclass of a native class.  It should
+  // have interceptor calling convention.
+  oof() => 'B';
+  // [miz] is introduced only on the mixin-application A+M.
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() {}
+  makeB = function(){return new B();};
+
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+  Expect.equals('1,B,M', b.foo(1));
+}
diff --git a/tests/dart2js/native/subclassing_4_test.dart b/tests/dart2js/native/subclassing_4_test.dart
new file mode 100644
index 0000000..07a2d4c
--- /dev/null
+++ b/tests/dart2js/native/subclassing_4_test.dart
@@ -0,0 +1,52 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show Interceptor, findInterceptorForType;
+
+// Test calling convention on subclasses of native classes.
+
+class M {
+  miz() => 'M';
+}
+
+@Native("N")
+class N {}
+
+class A extends N {}
+
+class B extends A with M {
+  // The call to [miz] has a know type [B].  The call is in an intercepted
+  // method and to an intercepted method, so the ambient interceptor can be
+  // used.  For correct optimization of the interceptor, the compiler needs to
+  // (1) correctly determine that B is an intercepted type (because it extends a
+  // native class) and (2) realize that the intersection of [B] and subclasses
+  // of mixin applications of [M] is non-empty.
+  callMiz() => this.miz();
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() {}
+  makeB = function(){return new B()};
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+  Expect.equals('M', b.callMiz());
+}
diff --git a/tests/dart2js/native/subclassing_5_test.dart b/tests/dart2js/native/subclassing_5_test.dart
new file mode 100644
index 0000000..220563b
--- /dev/null
+++ b/tests/dart2js/native/subclassing_5_test.dart
@@ -0,0 +1,172 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show Interceptor, findInterceptorForType;
+
+// Test type checks.
+
+class I {}
+
+class M implements I {
+  miz() => 'M';
+}
+
+@Native("N")
+class N {}
+
+class A extends N {}
+
+class B extends A with M {}
+
+class Checks<T> {
+  bool isCheck(x) => x is T;
+  void assignCheck(x) {
+    T z = x;
+    Expect.identical(x, z);
+  }
+
+  void castCheck(x) {
+    var z = x as T;
+    Expect.identical(x, z);
+  }
+}
+
+makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() {}
+  makeB = function(){return new B()};
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+bool isCheckedMode() {
+  var isChecked = false;
+  assert(isChecked = true);
+  return isChecked;
+}
+
+testIsI(x) {
+  Expect.isTrue(x is I);
+}
+
+testIsM(x) {
+  Expect.isTrue(x is M);
+}
+
+testIsN(x) {
+  Expect.isTrue(x is N);
+}
+
+testIsA(x) {
+  Expect.isTrue(x is A);
+}
+
+testIsB(x) {
+  Expect.isTrue(x is B);
+}
+
+testAssignI(x) {
+  I z = x;
+  Expect.identical(x, z);
+}
+
+testAssignM(x) {
+  M z = x;
+  Expect.identical(x, z);
+}
+
+testAssignN(x) {
+  N z = x;
+  Expect.identical(x, z);
+}
+
+testAssignA(x) {
+  A z = x;
+  Expect.identical(x, z);
+}
+
+testAssignB(x) {
+  B z = x;
+  Expect.identical(x, z);
+}
+
+testCastI(x) {
+  var z = x as I;
+  Expect.identical(x, z);
+}
+
+testCastM(x) {
+  var z = x as M;
+  Expect.identical(x, z);
+}
+
+testCastN(x) {
+  var z = x as N;
+  Expect.identical(x, z);
+}
+
+testCastA(x) {
+  var z = x as A;
+  Expect.identical(x, z);
+}
+
+testCastB(x) {
+  var z = x as B;
+  Expect.identical(x, z);
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  var b = confuse(makeB());
+
+  confuse(testIsB)(b);
+  confuse(testIsA)(b);
+  confuse(testIsN)(b);
+  confuse(testIsM)(b);
+  confuse(testIsI)(b);
+
+  confuse(new Checks<B>().isCheck)(b);
+  confuse(new Checks<A>().isCheck)(b);
+  confuse(new Checks<N>().isCheck)(b);
+  confuse(new Checks<M>().isCheck)(b);
+  confuse(new Checks<I>().isCheck)(b);
+
+  if (isCheckedMode()) {
+    confuse(testAssignB)(b);
+    confuse(testAssignA)(b);
+    confuse(testAssignN)(b);
+    confuse(testAssignM)(b);
+    confuse(testAssignI)(b);
+
+    confuse(testCastB)(b);
+    confuse(testCastA)(b);
+    confuse(testCastN)(b);
+    confuse(testCastM)(b);
+    confuse(testCastI)(b);
+
+    confuse(new Checks<B>().assignCheck)(b);
+    confuse(new Checks<A>().assignCheck)(b);
+    confuse(new Checks<N>().assignCheck)(b);
+    confuse(new Checks<M>().assignCheck)(b);
+    confuse(new Checks<I>().assignCheck)(b);
+
+    confuse(new Checks<B>().castCheck)(b);
+    confuse(new Checks<A>().castCheck)(b);
+    confuse(new Checks<N>().castCheck)(b);
+    confuse(new Checks<M>().castCheck)(b);
+    confuse(new Checks<I>().castCheck)(b);
+  }
+}
diff --git a/tests/dart2js/native/subclassing_constructor_1_test.dart b/tests/dart2js/native/subclassing_constructor_1_test.dart
new file mode 100644
index 0000000..bf989a7
--- /dev/null
+++ b/tests/dart2js/native/subclassing_constructor_1_test.dart
@@ -0,0 +1,177 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors'
+    show findInterceptorForType, findConstructorForNativeSubclassType;
+
+// Test that subclasses of native classes can be initialized by calling the
+// 'upgrade' constructor.
+
+var trace = [];
+
+var log;
+
+@Native("A")
+class A {
+  final a1 = log(101); // Only initialized IF named constructor called.
+  final a2; // Initialized by native constructor.
+  final a3; // Initialized only by A.two.
+  var a4 = log(104);
+
+  A.one();
+
+  A.two() : a3 = log(103) {
+    log('body(A.two)');
+    log(a4 += increment);
+  }
+
+  A.three(x, this.a4) {
+    log('body(A.three)');
+    log(a4 = '($a4, $x)');
+  }
+
+  get increment => 10;
+}
+
+class B extends A {
+  final b1;
+  final b2 = log(202);
+  var b3;
+
+  B.one() : super.one();
+
+  B.two()
+      : b1 = log(201),
+        b3 = log(203),
+        super.two() {
+    log('body(B.two)');
+  }
+
+  B.three([x]) : super.three(205, x);
+
+  get increment => 20;
+}
+
+makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() { this.a2 = 102; }
+
+  makeB = function(){return new B()};
+
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+test_one() {
+  trace = [];
+  var constructor = findConstructorForNativeSubclassType(B, 'one');
+  Expect.isNotNull(constructor);
+  Expect.isNull(findConstructorForNativeSubclassType(B, 'Missing'));
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  var b2 = JS('', '#(#)', constructor, b);
+  Expect.identical(b, b2);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(null, b.a3);
+  Expect.equals(104, b.a4);
+  Expect.equals(null, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(null, b.b3);
+
+  Expect.equals('[202, 101, 104]', '$trace');
+}
+
+test_two() {
+  trace = [];
+  var constructor = findConstructorForNativeSubclassType(B, 'two');
+  Expect.isNotNull(constructor);
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  JS('', '#(#)', constructor, b);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(103, b.a3);
+  Expect.equals(124, b.a4);
+  Expect.equals(201, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(203, b.b3);
+
+  Expect.equals('[202, 201, 101, 104, 103, 203, body(A.two), 124, body(B.two)]',
+      '$trace');
+}
+
+test_three() {
+  trace = [];
+  var constructor = findConstructorForNativeSubclassType(B, 'three');
+  Expect.isNotNull(constructor);
+
+  var b = makeB();
+  Expect.isTrue(b is B);
+  // Call constructor to initialize native object.
+  //
+  // Since the constructor takes some optional arguments that are not passed, it
+  // is as though the web components runtime explicitly passed `null` for all
+  // parameters.
+  //
+  // TODO(sra): The constructor returned by findConstructorForNativeSubclassType
+  // should be a function that fills in the default values.
+  JS('', '#(#)', constructor, b);
+  Expect.isTrue(b is B);
+
+  Expect.equals(101, b.a1);
+  Expect.equals(102, b.a2);
+  Expect.equals(null, b.a3);
+  Expect.equals('(null, 205)', b.a4);
+  Expect.equals(null, b.b1);
+  Expect.equals(202, b.b2);
+  Expect.equals(null, b.b3);
+  print(trace);
+  Expect.equals('[202, 101, 104, body(A.three), (null, 205)]', '$trace');
+}
+
+test_new() {
+  trace = [];
+  checkThrows(action, description) {
+    Expect.throws(action, (e) => true, "'$description must fail'");
+  }
+
+  checkThrows(() => new B.one(), 'new B.one()');
+  checkThrows(() => new B.two(), 'new B.two()');
+  checkThrows(() => new B.three(), 'new B.three()');
+  checkThrows(() => new B.three(1), 'new B.three(1)');
+  checkThrows(() => new B.three([]), 'new B.three([])');
+}
+
+main() {
+  nativeTesting();
+  setup();
+  log = (message) {
+    trace.add('$message');
+    return message;
+  };
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  test_one();
+  test_two();
+  test_three();
+  test_new();
+}
diff --git a/tests/dart2js/native/subclassing_constructor_2_test.dart b/tests/dart2js/native/subclassing_constructor_2_test.dart
new file mode 100644
index 0000000..f1c8dd1
--- /dev/null
+++ b/tests/dart2js/native/subclassing_constructor_2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Test that native classes and subclasses of native classes cannot be directly
+// created via a generative constructor.
+
+@Native("A")
+class A {
+  A.one();
+}
+
+class B extends A {
+  B.one() : super.one();
+}
+
+main() {
+  Expect.throws(() => new A.one());
+  Expect.throws(() => new B.one());
+}
diff --git a/tests/dart2js/native/subclassing_super_call_test.dart b/tests/dart2js/native/subclassing_super_call_test.dart
new file mode 100644
index 0000000..61e3fc1
--- /dev/null
+++ b/tests/dart2js/native/subclassing_super_call_test.dart
@@ -0,0 +1,134 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors'
+    show findInterceptorForType, findConstructorForNativeSubclassType;
+
+// Test for super access from classes that extend native classes.
+
+@Native("N1")
+class N1 {}
+
+@Native("N2")
+class N2 extends N1 {
+  N2.init();
+  String text;
+  foo() native;
+}
+
+class AA extends N2 {
+  AA.init() : super.init();
+  String afield;
+  afun() => 'afun:$afield';
+}
+
+class BB extends AA {
+  BB.init() : super.init();
+
+  get text => super.text;
+  set text(value) => super.text = value;
+  foo() => super.foo();
+
+  get afield => super.afield;
+  set afield(value) => super.afield = value;
+  afun() => super.afun();
+}
+
+BB makeBB() native;
+
+@Creates('=Object')
+getBBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function N2() {}
+  N2.prototype.foo = function() { return "foo:" + this.text; };
+  function BB() {}
+  BB.prototype.__proto__ = N2.prototype;
+  makeBB = function(){return new BB()};
+
+  getBBPrototype = function(){return BB.prototype;};
+})()""");
+}
+
+testSuperOnNative() {
+  BB b1 = makeBB();
+  BB b2 = makeBB();
+
+  var constructor = findConstructorForNativeSubclassType(BB, 'init');
+  Expect.isNotNull(constructor);
+  JS('', '#(#)', constructor, b1);
+  JS('', '#(#)', constructor, b2);
+
+  b1.text = confuse('one');
+  b2.text = confuse('two');
+
+  print('b1.text ${confuse(b1).text}');
+  print('b2.text ${confuse(b2).text}');
+
+  print('b1.foo() ${confuse(b1).foo()}');
+  print('b2.foo() ${confuse(b2).foo()}');
+
+  Expect.equals('one', b1.text);
+  Expect.equals('two', b2.text);
+
+  Expect.equals('foo:one', b1.foo());
+  Expect.equals('foo:two', b2.foo());
+
+  confuse(b1).text = confuse('three');
+  confuse(b2).text = confuse('four');
+
+  Expect.equals('three', confuse(b1).text);
+  Expect.equals('four', confuse(b2).text);
+
+  Expect.equals('foo:three', confuse(b1).foo());
+  Expect.equals('foo:four', confuse(b2).foo());
+}
+
+testSuperOnSubclassOfNative() {
+  BB b1 = makeBB();
+  BB b2 = makeBB();
+
+  var constructor = findConstructorForNativeSubclassType(BB, 'init');
+  Expect.isNotNull(constructor);
+  JS('', '#(#)', constructor, b1);
+  JS('', '#(#)', constructor, b2);
+
+  b1.afield = confuse('one');
+  b2.afield = confuse('two');
+
+  print('b1.afield ${confuse(b1).afield}');
+  print('b2.afield ${confuse(b2).afield}');
+
+  print('b1.afun() ${confuse(b1).afun()}');
+  print('b2.afun() ${confuse(b2).afun()}');
+
+  Expect.equals('one', b1.afield);
+  Expect.equals('two', b2.afield);
+
+  Expect.equals('afun:one', b1.afun());
+  Expect.equals('afun:two', b2.afun());
+
+  confuse(b1).afield = confuse('three');
+  confuse(b2).afield = confuse('four');
+
+  Expect.equals('three', confuse(b1).afield);
+  Expect.equals('four', confuse(b2).afield);
+
+  Expect.equals('afun:three', confuse(b1).afun());
+  Expect.equals('afun:four', confuse(b2).afun());
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBBPrototype(), findInterceptorForType(BB));
+
+  testSuperOnNative();
+  testSuperOnSubclassOfNative();
+}
diff --git a/tests/dart2js/native/subclassing_super_field_1_test.dart b/tests/dart2js/native/subclassing_super_field_1_test.dart
new file mode 100644
index 0000000..827cb358
--- /dev/null
+++ b/tests/dart2js/native/subclassing_super_field_1_test.dart
@@ -0,0 +1,64 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors'
+    show findInterceptorForType, findConstructorForNativeSubclassType;
+
+// Test for shadowed fields in classes that extend native classes.
+
+@Native("N")
+class N {
+  N.init();
+}
+
+class A extends N {
+  var foo = 111;
+  A.init() : super.init();
+}
+
+class B extends A {
+  var foo = 222;
+  B.init() : super.init();
+
+  Afoo() => super.foo;
+  Bfoo() => foo;
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+function B() { }
+makeB = function(){return new B()};
+
+getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+
+  var constructor = findConstructorForNativeSubclassType(B, 'init');
+  Expect.isNotNull(constructor);
+  JS('', '#(#)', constructor, b);
+
+  print(b);
+
+  Expect.equals(222, confuse(b).Bfoo());
+  Expect.equals(111, confuse(b).Afoo());
+
+  Expect.equals(222, b.Bfoo());
+  Expect.equals(111, b.Afoo());
+}
diff --git a/tests/dart2js/native/subclassing_super_field_2_test.dart b/tests/dart2js/native/subclassing_super_field_2_test.dart
new file mode 100644
index 0000000..837568a
--- /dev/null
+++ b/tests/dart2js/native/subclassing_super_field_2_test.dart
@@ -0,0 +1,70 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors'
+    show findInterceptorForType, findConstructorForNativeSubclassType;
+
+// Test for fields with same name as native fields.  We expect N.foo to have the
+// property name 'foo' and A.foo and B.foo to have non-conflicting names.
+
+@Native("N")
+class N {
+  var foo;
+  N.init();
+}
+
+class A extends N {
+  var foo = 222;
+  A.init() : super.init();
+  Nfoo() => super.foo; // TODO(sra): Fix compiler assert.
+}
+
+class B extends A {
+  var foo = 333;
+  B.init() : super.init();
+  Afoo() => super.foo;
+  Bfoo() => foo;
+
+  toString() => '[N.foo = ${Nfoo()}, A.foo = ${Afoo()}, B.foo = ${Bfoo()}]';
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() { this.foo = 111; }  // N.foo
+  makeB = function(){return new B()};
+
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+
+  var constructor = findConstructorForNativeSubclassType(B, 'init');
+  Expect.isNotNull(constructor);
+  JS('', '#(#)', constructor, b);
+
+  print(b);
+
+  Expect.equals(333, confuse(b).Bfoo());
+  Expect.equals(222, confuse(b).Afoo());
+  Expect.equals(111, confuse(b).Nfoo());
+
+  Expect.equals(333, b.Bfoo());
+  Expect.equals(222, b.Afoo());
+  Expect.equals(111, b.Nfoo());
+}
diff --git a/tests/dart2js/native/subclassing_type_test.dart b/tests/dart2js/native/subclassing_type_test.dart
new file mode 100644
index 0000000..b99872e
--- /dev/null
+++ b/tests/dart2js/native/subclassing_type_test.dart
@@ -0,0 +1,156 @@
+// Copyright (c) 2013, 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 'native_testing.dart';
+import 'dart:_js_helper' show setNativeSubclassDispatchRecord;
+import 'dart:_interceptors' show Interceptor, findInterceptorForType;
+
+// Test that type checks and casts work for subclasses of native classes and
+// mixins on native classes.
+
+class M {}
+
+@Native("N")
+class N {}
+
+class A extends N {}
+
+class B extends A with M {
+  // native mixin application.
+}
+
+class C extends Object with M {
+  // non-native mixin application.
+}
+
+B makeB() native;
+
+@Creates('=Object')
+getBPrototype() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  function B() {}
+  makeB = function(){return new B()};
+
+  getBPrototype = function(){return B.prototype;};
+})()""");
+}
+
+A gA;
+B gB;
+C gC;
+M gM;
+
+isA(x) => x is A;
+asA(x) => x as A;
+setA(x) => gA = x;
+
+isB(x) => x is B;
+asB(x) => x as B;
+setB(x) => gB = x;
+
+isC(x) => x is C;
+asC(x) => x as C;
+setC(x) => gC = x;
+
+isM(x) => x is M;
+asM(x) => x as M;
+setM(x) => gM = x;
+
+checkTrue(f) => (x) {
+      Expect.isTrue(f(x));
+    };
+checkFalse(f) => (x) {
+      Expect.isFalse(f(x));
+    };
+checkId(f) => (x) {
+      Expect.identical(x, f(x));
+    };
+checkThrows(f) => (x) {
+      Expect.throws(() => f(x));
+    };
+
+bool get checkedMode {
+  try {
+    setA(1);
+    gA = null;
+    return false;
+  } catch (e) {
+    return true;
+  }
+}
+
+main() {
+  setup();
+
+  setNativeSubclassDispatchRecord(getBPrototype(), findInterceptorForType(B));
+
+  B b = makeB();
+  C c = new C();
+
+  checkFalse(isA)(1);
+  checkFalse(isB)(1);
+  checkFalse(isC)(1);
+  checkFalse(isM)(1);
+
+  checkTrue(isA)(b);
+  checkTrue(isB)(b);
+  checkTrue(isM)(b);
+  checkFalse(isC)(b);
+
+  checkTrue(isC)(c);
+  checkTrue(isM)(c);
+  checkFalse(isA)(c);
+  checkFalse(isB)(c);
+
+  checkThrows(asA)(1);
+  checkThrows(asB)(1);
+  checkThrows(asC)(1);
+  checkThrows(asM)(1);
+
+  checkId(asA)(b);
+  checkId(asB)(b);
+  checkId(asM)(b);
+  checkThrows(asC)(b);
+
+  checkId(asC)(c);
+  checkId(asM)(c);
+  checkThrows(asA)(c);
+  checkThrows(asB)(c);
+
+  if (checkedMode) {
+    checkThrows(setA)(1);
+    checkThrows(setB)(1);
+    checkThrows(setC)(1);
+    checkThrows(setM)(1);
+
+    checkId(setA)(b);
+    checkId(setB)(b);
+    checkId(setM)(b);
+    checkThrows(setC)(b);
+
+    checkId(setC)(c);
+    checkId(setM)(c);
+    checkThrows(setA)(c);
+    checkThrows(setB)(c);
+
+    // One of the above assignments had a value of the correct type.
+    Expect.isNotNull(gA);
+    Expect.isNotNull(gB);
+    Expect.isNotNull(gC);
+    Expect.isNotNull(gM);
+
+    checkId(setA)(null);
+    checkId(setB)(null);
+    checkId(setC)(null);
+    checkId(setM)(null);
+
+    Expect.isNull(gA);
+    Expect.isNull(gB);
+    Expect.isNull(gC);
+    Expect.isNull(gM);
+  }
+}
diff --git a/tests/dart2js/native/super_call_test.dart b/tests/dart2js/native/super_call_test.dart
new file mode 100644
index 0000000..5238bb5
--- /dev/null
+++ b/tests/dart2js/native/super_call_test.dart
@@ -0,0 +1,87 @@
+// 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 "native_testing.dart";
+
+// Test to see if resolving a hidden native class's method interferes with
+// subsequent resolving the subclass's method.  This might happen if the
+// superclass caches the method in the prototype, so shadowing the dispatcher
+// stored on Object.prototype.
+
+@Native("A")
+class A {
+  foo() => 'A.foo ${bar()}';
+  bar() => 'A.bar';
+}
+
+@Native("B")
+class B extends A {
+  bar() => 'B.bar';
+}
+
+@Native("C")
+class C extends B {
+  foo() => 'C.foo; super.foo = ${super.foo()}';
+  bar() => 'C.bar';
+}
+
+@Native("D")
+class D extends C {
+  bar() => 'D.bar';
+}
+
+makeA() native;
+makeB() native;
+makeC() native;
+makeD() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function inherits(child, parent) {
+    if (child.prototype.__proto__) {
+      child.prototype.__proto__ = parent.prototype;
+    } else {
+      function tmp() {};
+      tmp.prototype = parent.prototype;
+      child.prototype = new tmp();
+      child.prototype.constructor = child;
+    }
+  }
+
+  function A(){}
+  function B(){}
+  inherits(B, A);
+  function C(){}
+  inherits(C, B);
+  function D(){}
+  inherits(D, C);
+
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  makeC = function(){return new C()};
+  makeD = function(){return new D()};
+
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+  self.nativeConstructor(C);
+  self.nativeConstructor(D);
+})()""");
+}
+
+main() {
+  nativeTesting();
+  setup();
+
+  var a = makeA();
+  var b = makeB();
+  var c = makeC();
+  var d = makeD();
+
+  Expect.equals('A.foo A.bar', a.foo());
+  Expect.equals('A.foo B.bar', b.foo());
+  Expect.equals('C.foo; super.foo = A.foo C.bar', c.foo());
+  Expect.equals('C.foo; super.foo = A.foo D.bar', d.foo());
+}
diff --git a/tests/dart2js/native/super_property_test.dart b/tests/dart2js/native/super_property_test.dart
new file mode 100644
index 0000000..68e815a
--- /dev/null
+++ b/tests/dart2js/native/super_property_test.dart
@@ -0,0 +1,75 @@
+// Copyright (c) 2013, 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 "native_testing.dart";
+
+// Tests super setter where the HInvokeSuper is using interceptor aka
+// explicit-receiver calling convention.
+
+@Native("A")
+class A {
+  var foo;
+  get_foo() => foo;
+  set bar(value) => foo = value;
+}
+
+@Native("B")
+class B extends A {
+  set foo(value) {
+    super.foo = value;
+  }
+
+  get foo => super.foo;
+}
+
+class C {
+  var foo;
+  get_foo() => foo;
+  set bar(value) => foo = value;
+}
+
+class D extends C {
+  set foo(value) {
+    super.foo = value;
+  }
+
+  get foo => super.foo;
+}
+
+makeA() native;
+makeB() native;
+
+void setup() {
+  JS('', r"""
+(function(){
+  // This code is inside 'setup' and so not accessible from the global scope.
+  function A(){}
+  function B(){}
+  makeA = function(){return new A()};
+  makeB = function(){return new B()};
+  self.nativeConstructor(A);
+  self.nativeConstructor(B);
+})()""");
+}
+
+testThing(a) {
+  a.foo = 123;
+  Expect.equals(123, a.foo);
+  Expect.equals(123, a.get_foo());
+
+  a.bar = 234;
+  Expect.equals(234, a.foo);
+  Expect.equals(234, a.get_foo());
+}
+
+main() {
+  nativeTesting();
+  setup();
+  var things = [makeA(), makeB(), new C(), new D()];
+  var test = testThing;
+  test(things[0]);
+  test(things[1]);
+  test(things[2]);
+  test(things[3]);
+}
diff --git a/tests/dart2js/native/type_error_decode_test.dart b/tests/dart2js/native/type_error_decode_test.dart
new file mode 100644
index 0000000..ba97210
--- /dev/null
+++ b/tests/dart2js/native/type_error_decode_test.dart
@@ -0,0 +1,58 @@
+// Copyright (c) 2013, 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.
+
+library test.type_error_decode_test;
+
+import 'native_testing.dart';
+import 'dart:_js_helper' show NullError, JsNoSuchMethodError;
+
+class Foo {
+  var field;
+}
+
+isNullError(e, trace) {
+  print('$e\nTrace: $trace');
+  return e is NullError;
+}
+
+isJsNoSuchMethodError(e, trace) {
+  print('$e\nTrace: $trace');
+  return e is JsNoSuchMethodError;
+}
+
+expectThrows(f, check) {
+  try {
+    f();
+  } catch (e, trace) {
+    if (check(e, trace)) {
+      return;
+    }
+    throw 'Unexpected exception: $e\n$trace';
+  }
+  throw 'No exception thrown';
+}
+
+main() {
+  dynamic x = null;
+  dynamic z = new Object();
+  dynamic v = new List(1)[0];
+  dynamic s = "Cannot call method 'foo' of null";
+  dynamic nul = null;
+  dynamic f = new Foo();
+
+  expectThrows(() => x.fisk(), isNullError);
+  expectThrows(() => v.fisk(), isNullError);
+  expectThrows(() => z.fisk(), isJsNoSuchMethodError);
+  expectThrows(() => s.fisk(), isJsNoSuchMethodError);
+  expectThrows(() => (null as dynamic)(), isNullError);
+  expectThrows(() => f.field(), isNullError);
+
+  expectThrows(() => confuse(x).fisk(), isNullError);
+  expectThrows(() => confuse(v).fisk(), isNullError);
+  expectThrows(() => confuse(z).fisk(), isJsNoSuchMethodError);
+  expectThrows(() => confuse(s).fisk(), isJsNoSuchMethodError);
+  expectThrows(() => confuse(null)(), isNullError);
+  expectThrows(() => confuse(f).field(), isNullError);
+  expectThrows(() => confuse(f.field)(), isNullError);
+}
diff --git a/tests/dart2js/native/undefined_bailout_test.dart b/tests/dart2js/native/undefined_bailout_test.dart
new file mode 100644
index 0000000..feff806
--- /dev/null
+++ b/tests/dart2js/native/undefined_bailout_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, 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.
+
+// dart2js regression test where the SSA backend would use the wrong
+// type for an instruction: when doing a speculative type propagation,
+// if an instruction gets analyzed multiple times, we used to save the
+// last inferred type, which could be speculative, instead of the
+// first inferred type, which is the actual, non-speculative, type.
+//
+// Because we are doing speculative type propagation at the very end,
+// before emitting the bailout version, the only place where we might
+// do wrong optimizations is during the codegen. It turns out that the
+// codegen optimizes '==' comparisons on null to '===' in case it knows
+// the receiver cannot be null. So in the following example, the
+// [:e == null:] comparison in [foo] got wrongly generated to a
+// JavaScript identity check (that is, using '==='). But this
+// comparison does not work for undefined, which the DOM sometimes
+// returns.
+
+import "native_testing.dart";
+
+var a = 42;
+var b = 0;
+
+foo(e) {
+  // Loop to force a bailout.
+  for (int i = 0; i < b; i++) {
+    a = e[i]; // Will desire a readable primitive.
+  }
+  // Our heuristics for '==' on an indexable primitive is that it's
+  // more common to do it on string, so we'll want e to be a string.
+  return a == e || e == null;
+}
+
+main() {
+  Expect.isTrue(foo(JS('', 'void 0')));
+}
diff --git a/tests/dart2js/native/uninstantiated_type_parameter_test.dart b/tests/dart2js/native/uninstantiated_type_parameter_test.dart
new file mode 100644
index 0000000..158063c
--- /dev/null
+++ b/tests/dart2js/native/uninstantiated_type_parameter_test.dart
@@ -0,0 +1,22 @@
+// 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 "native_testing.dart";
+
+// Test for uninstantiated native classes as type parameters.
+
+class UA {}
+
+@Native("B")
+class UB {}
+
+class C<T> {}
+
+main() {
+  var a = new C<UA>();
+  var b = new C<UB>();
+
+  Expect.isTrue(a is! C<int>);
+  Expect.isTrue(a is! C<C>);
+}
diff --git a/tests/dart2js/new_from_env_test.dart b/tests/dart2js/new_from_env_test.dart
new file mode 100644
index 0000000..13988e8
--- /dev/null
+++ b/tests/dart2js/new_from_env_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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';
+
+/// Dart2js only supports the const constructor for `?.fromEnvironment`. The
+/// current behavior is to throw at runtime if they call this constructor with
+/// `new` instead of `const`.
+main() {
+  Expect.isFalse(const bool.fromEnvironment('X'));
+  Expect.equals('', const String.fromEnvironment('X', defaultValue: ''));
+  Expect.equals(const int.fromEnvironment('X', defaultValue: 0), 0);
+
+  Expect.throws(() => new bool.fromEnvironment('X'));
+  Expect.throws(() => new String.fromEnvironment('X'));
+  Expect.throws(() => new int.fromEnvironment('X', defaultValue: 0));
+}
diff --git a/tests/dart2js/no_such_method_strong10_test.dart b/tests/dart2js/no_such_method_strong10_test.dart
new file mode 100644
index 0000000..c09441f
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong10_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m(x);
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    print("nsm call: ${i.memberName}");
+    if (i.isGetter) {
+      throw (" - tearoff");
+    }
+    if (i.isMethod) {
+      print(" - method invocation");
+      return 42;
+    }
+    return 123;
+  }
+}
+
+void main() {
+  A x = new B();
+  var tearoff = x.m;
+  Expect.equals(42, tearoff(3));
+}
diff --git a/tests/dart2js/no_such_method_strong11_lib.dart b/tests/dart2js/no_such_method_strong11_lib.dart
new file mode 100644
index 0000000..a1f1e15
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong11_lib.dart
@@ -0,0 +1,11 @@
+// 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.
+
+abstract class I {
+  // ignore: unused_element
+  int _m1();
+
+  // ignore: unused_element
+  int _m2();
+}
diff --git a/tests/dart2js/no_such_method_strong11_test.dart b/tests/dart2js/no_such_method_strong11_test.dart
new file mode 100644
index 0000000..d16c31c
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong11_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+// Regression test checking that nsm-forwarders do not get installed for private
+// members of other libraries. See http://dartbug.com/33665
+
+import 'package:expect/expect.dart';
+import 'no_such_method_strong11_lib.dart';
+
+abstract class J {
+  int _m3();
+  int _m4();
+}
+
+class A implements I, J {
+  int _m1() => 1;
+  int _m3() => 3;
+  noSuchMethod(Invocation m) => -1;
+}
+
+main() {
+  dynamic a = confuse(new A());
+  Expect.equals(1, a._m1());
+  Expect.equals(3, a._m3());
+  Expect.equals(1, (a._m1)());
+  Expect.equals(3, (a._m3)());
+
+  Expect.equals(-1, a._m2());
+  Expect.equals(-1, a._m4());
+  Expect.isFalse(a._m2 is Function);
+  Expect.equals(-1, a._m2);
+  Expect.isTrue(a._m4 is Function);
+  Expect.equals(-1, (a._m4)());
+}
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
diff --git a/tests/dart2js/no_such_method_strong12_test.dart b/tests/dart2js/no_such_method_strong12_test.dart
new file mode 100644
index 0000000..b097966
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong12_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m({a: 1, c: 3, b: 2});
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return '${i.namedArguments[#a]},${i.namedArguments[#b]},${i.namedArguments[#c]}';
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals('1,2,3', x.m());
+  Expect.equals('1,2,3', x.m(a: 1));
+  Expect.equals('1,2,3', x.m(c: 3));
+  Expect.equals('1,2,3', x.m(b: 2));
+  Expect.equals('1,2,3', x.m(a: 1, b: 2));
+  Expect.equals('1,2,3', x.m(a: 1, b: 2, c: 3));
+}
diff --git a/tests/dart2js/no_such_method_strong1_test.dart b/tests/dart2js/no_such_method_strong1_test.dart
new file mode 100644
index 0000000..62b6c60
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong1_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m(x);
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    print("nsm call: ${i.memberName}");
+    if (i.isGetter) {
+      throw (" - tearoff");
+    }
+    if (i.isMethod) {
+      print(" - method invocation");
+      return 42;
+    }
+    return 123;
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals(42, x.m(3));
+}
diff --git a/tests/dart2js/no_such_method_strong2_test.dart b/tests/dart2js/no_such_method_strong2_test.dart
new file mode 100644
index 0000000..e42f388
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong2_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m(x);
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return i.memberName;
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals(#m, x.m(3));
+}
diff --git a/tests/dart2js/no_such_method_strong3_test.dart b/tests/dart2js/no_such_method_strong3_test.dart
new file mode 100644
index 0000000..5353d7b
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong3_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m(x, y);
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return '${i.positionalArguments[0]},${i.positionalArguments[1]}';
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals('3,4', x.m(3, 4));
+}
diff --git a/tests/dart2js/no_such_method_strong4_test.dart b/tests/dart2js/no_such_method_strong4_test.dart
new file mode 100644
index 0000000..1ec9499
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong4_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m({a, b});
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return '${i.namedArguments[#a]},${i.namedArguments[#b]}';
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals('3,4', x.m(a: 3, b: 4));
+  Expect.equals('3,4', x.m(b: 4, a: 3));
+}
diff --git a/tests/dart2js/no_such_method_strong5_test.dart b/tests/dart2js/no_such_method_strong5_test.dart
new file mode 100644
index 0000000..94f1531
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong5_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m<X, Y>();
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return [i.typeArguments[0], i.typeArguments[1]];
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.listEquals([int, String], x.m<int, String>());
+}
diff --git a/tests/dart2js/no_such_method_strong6_test.dart b/tests/dart2js/no_such_method_strong6_test.dart
new file mode 100644
index 0000000..0018b85
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong6_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m();
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return 42;
+  }
+}
+
+class C extends B {
+  noSuchMethod(Invocation i) => 87;
+
+  method() => super.m();
+}
+
+void main() {
+  C x = new C();
+  Expect.equals(87, x.method());
+}
diff --git a/tests/dart2js/no_such_method_strong7_test.dart b/tests/dart2js/no_such_method_strong7_test.dart
new file mode 100644
index 0000000..7f3925f
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong7_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  get m;
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return i.isGetter ? 42 : 87;
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals(42, x.m);
+}
diff --git a/tests/dart2js/no_such_method_strong8_test.dart b/tests/dart2js/no_such_method_strong8_test.dart
new file mode 100644
index 0000000..a98447b
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong8_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  set m(_);
+}
+
+class B implements A {
+  noSuchMethod(Invocation i) {
+    return i.isSetter ? i.positionalArguments[0] : 87;
+  }
+}
+
+void main() {
+  A x = new B();
+  Expect.equals(42, x.m = 42);
+}
diff --git a/tests/dart2js/no_such_method_strong9_test.dart b/tests/dart2js/no_such_method_strong9_test.dart
new file mode 100644
index 0000000..25ccc7e
--- /dev/null
+++ b/tests/dart2js/no_such_method_strong9_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+abstract class A {
+  m();
+}
+
+abstract class B implements A {
+  noSuchMethod(Invocation i) {
+    return 42;
+  }
+}
+
+class C extends B {}
+
+class D extends C {
+  noSuchMethod(Invocation i) => 87;
+
+  method() => super.m();
+}
+
+void main() {
+  D x = new D();
+  Expect.equals(87, x.method());
+}
diff --git a/tests/dart2js/no_such_method_test.dart b/tests/dart2js/no_such_method_test.dart
new file mode 100644
index 0000000..38375d3
--- /dev/null
+++ b/tests/dart2js/no_such_method_test.dart
@@ -0,0 +1,56 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class NoSuchMethodInfo {
+  Object receiver;
+  String name;
+  List args;
+  NoSuchMethodInfo(Object r, String m, List a)
+      : receiver = r,
+        name = m,
+        args = a;
+}
+
+class A {
+  noSuchMethod(Invocation invocation) {
+    topLevelInfo = new NoSuchMethodInfo(
+        this, invocation.memberName, invocation.positionalArguments);
+    return topLevelInfo;
+  }
+
+  foo(a, b, c) {
+    Expect.fail('Should never enter here');
+  }
+}
+
+// Used for the setter case.
+NoSuchMethodInfo topLevelInfo;
+
+main() {
+  A a = new A();
+  var info = a.foo();
+  Expect.equals('foo', info.name);
+  Expect.isTrue(info.args.isEmpty);
+  Expect.isTrue(identical(info.receiver, a));
+
+  info = a.foo(2);
+  Expect.equals('foo', info.name);
+  Expect.isTrue(info.args.length == 1);
+  Expect.isTrue(info.args[0] == 2);
+  Expect.isTrue(identical(info.receiver, a));
+
+  info = a.bar;
+  Expect.equals('bar', info.name);
+  Expect.isTrue(info.args.length == 0);
+  Expect.isTrue(identical(info.receiver, a));
+
+  a.bar = 2;
+  info = topLevelInfo;
+  Expect.equals('bar', info.name);
+  Expect.isTrue(info.args.length == 1);
+  Expect.isTrue(info.args[0] == 2);
+  Expect.isTrue(identical(info.receiver, a));
+}
diff --git a/tests/dart2js/non_jsinterop_test.dart b/tests/dart2js/non_jsinterop_test.dart
new file mode 100644
index 0000000..e66c5d5
--- /dev/null
+++ b/tests/dart2js/non_jsinterop_test.dart
@@ -0,0 +1,270 @@
+// 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.
+
+// TODO(johnniwinther): Share this test with ddc.
+
+// Test for positive and negative uses of js-interop declarations in a library
+// _without_ a @JS() anntaotion. This file is also used in
+// tests/compiler/dart2js/model/native_test.dart.
+
+library lib;
+
+import 'package:js/js.dart';
+
+var topLevelField;
+
+get topLevelGetter => null;
+
+set topLevelSetter(_) {}
+
+topLevelFunction() {}
+
+@JS('a') // JS_INTEROP_FIELD_NOT_SUPPORTED       //# 01: compile-time error
+var topLevelJsInteropField; //# 01: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 02: compile-time error
+get topLevelJsInteropGetter => null; //# 02: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 03: compile-time error
+set topLevelJsInteropSetter(_) {} //# 03: continued
+
+@JS('a') // JS_INTEROP_NON_EXTERNAL_MEMBER       //# 04: compile-time error
+topLevelJsInteropFunction() {} //# 04: continued
+
+// NON_NATIVE_EXTERNAL               //# 05: compile-time error
+external get externalTopLevelGetter; //# 05: continued
+
+// NON_NATIVE_EXTERNAL                  //# 06: compile-time error
+external set externalTopLevelSetter(_); //# 06: continued
+
+// NON_NATIVE_EXTERNAL               //# 07: compile-time error
+external externalTopLevelFunction(); //# 07: continued
+
+@JS('a')
+external get externalTopLevelJsInteropGetter;
+
+@JS('b')
+external set externalTopLevelJsInteropSetter(_);
+
+@JS('c')
+external externalTopLevelJsInteropFunction();
+
+class Class {
+  Class.generative();
+  factory Class.fact() => null;
+
+  // NON_NATIVE_EXTERNAL               //# 08: compile-time error
+  external Class.externalGenerative(); //# 08: continued
+
+  // NON_NATIVE_EXTERNAL                 //# 09: compile-time error
+  external factory Class.externalFact(); //# 09: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 10: compile-time error
+  Class.jsInteropGenerative(); //# 10: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 11: compile-time error
+  factory Class.jsInteropFact() => null; //# 11: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 12: compile-time error
+  external Class.externalJsInteropGenerative(); //# 12: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 13: compile-time error
+  external factory Class.externalJsInteropFact(); //# 13: continued
+
+  var instanceField;
+  get instanceGetter => null;
+  set instanceSetter(_) {}
+  instanceMethod() {}
+
+  static var staticField;
+  static get staticGetter => null;
+  static set staticSetter(_) {}
+  static staticMethod() {}
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 14: compile-time error
+  var instanceJsInteropField; //# 14: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 15: compile-time error
+  get instanceJsInteropGetter => null; //# 15: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 16: compile-time error
+  set instanceJsInteropSetter(_) {} //# 16: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 17: compile-time error
+  instanceJsInteropMethod() {} //# 17: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 18: compile-time error
+  static var staticJsInteropField; //# 18: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 19: compile-time error
+  static get staticJsInteropGetter => null; //# 19: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 20: compile-time error
+  static set staticJsInteropSetter(_) {} //# 20: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 21: compile-time error
+  static staticJsInteropMethod() {} //# 21: continued
+
+  // NON_NATIVE_EXTERNAL               //# 22: compile-time error
+  external get externalInstanceGetter; //# 22: continued
+
+  // NON_NATIVE_EXTERNAL                  //# 23: compile-time error
+  external set externalInstanceSetter(_); //# 23: continued
+
+  // NON_NATIVE_EXTERNAL             //# 24: compile-time error
+  external externalInstanceMethod(); //# 24: continued
+
+  // NON_NATIVE_EXTERNAL             //# 25: compile-time error
+  external static get externalStaticGetter; //# 25: continued
+
+  // NON_NATIVE_EXTERNAL                //# 26: compile-time error
+  external static set externalStaticSetter(_); //# 26: continued
+
+  // NON_NATIVE_EXTERNAL           //# 27: compile-time error
+  external static externalStaticMethod(); //# 27: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 28: compile-time error
+  external get externalInstanceJsInteropGetter; //# 28: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 29: compile-time error
+  external set externalInstanceJsInteropSetter(_); //# 29: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 30: compile-time error
+  external externalInstanceJsInteropMethod(); //# 30: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 31: compile-time error
+  external static get externalStaticJsInteropGetter; //# 31: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 32: compile-time error
+  external static set externalStaticJsInteropSetter(_); //# 32: continued
+
+  @JS('a') // JS_INTEROP_MEMBER_IN_NON_JS_INTEROP_CLASS  //# 33: compile-time error
+  external static externalStaticJsInteropMethod(); //# 33: continued
+}
+
+@JS('d')
+class JsInteropClass {
+  // GENERIC //# 34: compile-time error
+  JsInteropClass.generative(); //# 34: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 35: compile-time error
+  factory JsInteropClass.fact() => null; //# 35: continued
+
+  external JsInteropClass.externalGenerative();
+  external factory JsInteropClass.externalFact();
+
+  @JS('a') // GENERIC //# 36: compile-time error
+  JsInteropClass.jsInteropGenerative(); //# 36: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_CONSTRUCTOR //# 37: compile-time error
+  factory JsInteropClass.jsInteropFact() => null; //# 37: continued
+
+  @JS('a')
+  external JsInteropClass.externalJsInteropGenerative();
+
+  @JS('a')
+  external factory JsInteropClass.externalJsInteropFact();
+
+  // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 38: compile-time error
+  var instanceField; //# 38: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 39: compile-time error
+  get instanceGetter => null; //# 39: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 40: compile-time error
+  set instanceSetter(_) {} //# 40: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 41: compile-time error
+  instanceMethod() {} //# 41: continued
+
+  // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 42: compile-time error
+  static var staticField; //# 42: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 43: compile-time error
+  static get staticGetter => null; //# 43: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 44: compile-time error
+  static set staticSetter(_) {} //# 44: continued
+
+  // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 45: compile-time error
+  static staticMethod() {} //# 45: continued
+
+  @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 46: compile-time error
+  var instanceJsInteropField; //# 46: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 48: compile-time error
+  get instanceJsInteropGetter => null; //# 48: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 49: compile-time error
+  set instanceJsInteropSetter(_) {} //# 49: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 50: compile-time error
+  instanceJsInteropMethod() {} //# 50: continued
+
+  @JS('a') // IMPLICIT_JS_INTEROP_FIELD_NOT_SUPPORTED //# 51: compile-time error
+  static var staticJsInteropField; //# 51: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 52: compile-time error
+  static get staticJsInteropGetter => null; //# 52: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 53: compile-time error
+  static set staticJsInteropSetter(_) {} //# 53: continued
+
+  @JS('a') // JS_INTEROP_CLASS_NON_EXTERNAL_MEMBER //# 54: compile-time error
+  static staticJsInteropMethod() {} //# 54: continued
+
+  external get externalInstanceGetter;
+  external set externalInstanceSetter(_);
+  external externalInstanceMethod();
+
+  external static get externalStaticGetter;
+  external static set externalStaticSetter(_);
+  external static externalStaticMethod();
+
+  @JS('a')
+  external get externalInstanceJsInteropGetter;
+
+  @JS('a')
+  external set externalInstanceJsInteropSetter(_);
+
+  @JS('a')
+  external externalInstanceJsInteropMethod();
+
+  @JS('a')
+  external static get externalStaticJsInteropGetter;
+
+  @JS('a')
+  external static set externalStaticJsInteropSetter(_);
+
+  @JS('a')
+  external static externalStaticJsInteropMethod();
+}
+
+main() {
+  if (false) {
+    topLevelSetter = topLevelField = topLevelGetter;
+    topLevelFunction();
+    externalTopLevelJsInteropSetter = externalTopLevelJsInteropGetter;
+    externalTopLevelJsInteropFunction();
+    Class c1 = new Class.generative();
+    new Class.fact();
+    c1.instanceSetter = c1.instanceField = c1.instanceGetter;
+    c1.instanceMethod();
+    Class.staticSetter = Class.staticField = Class.staticGetter;
+    Class.staticMethod();
+    JsInteropClass c2 = new JsInteropClass.externalGenerative();
+    new JsInteropClass.externalFact();
+    new JsInteropClass.externalJsInteropGenerative();
+    new JsInteropClass.externalJsInteropFact();
+    c2.externalInstanceSetter = c2.externalInstanceGetter;
+    c2.externalInstanceMethod();
+    c2.externalInstanceJsInteropSetter = c2.externalInstanceJsInteropGetter;
+    c2.externalInstanceJsInteropMethod();
+    JsInteropClass.externalStaticSetter = JsInteropClass.externalStaticGetter;
+    JsInteropClass.externalStaticMethod();
+    JsInteropClass.externalStaticJsInteropSetter =
+        JsInteropClass.externalStaticJsInteropGetter;
+    JsInteropClass.externalStaticJsInteropMethod();
+  }
+}
diff --git a/tests/dart2js/non_trivial_substitution_test.dart b/tests/dart2js/non_trivial_substitution_test.dart
new file mode 100644
index 0000000..2a4ebf00
--- /dev/null
+++ b/tests/dart2js/non_trivial_substitution_test.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";
+
+class A {}
+
+class B {}
+
+class C extends A implements B {}
+
+class Base<T> {}
+
+class Sub implements Base<C> {}
+
+void main() {
+  Expect.subtype<Sub, Base<A>>();
+  Expect.subtype<Sub, Base<B>>();
+}
diff --git a/tests/dart2js/not_equals_test.dart b/tests/dart2js/not_equals_test.dart
new file mode 100644
index 0000000..58003d6
--- /dev/null
+++ b/tests/dart2js/not_equals_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+void main() {
+  var x = 3;
+  if (x != x) {
+    throw "x != x with x == 3";
+  } else {
+    print('good');
+  }
+  var y = x;
+  if (x != y) throw "3 != 3";
+
+  var z = 4;
+  if (x != z) {
+    print('good');
+  } else {
+    throw 'x == z';
+  }
+}
diff --git a/tests/dart2js/not_test.dart b/tests/dart2js/not_test.dart
new file mode 100644
index 0000000..e75f2ca
--- /dev/null
+++ b/tests/dart2js/not_test.dart
@@ -0,0 +1,36 @@
+// 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 "package:expect/expect.dart";
+
+void not1() {
+  var x = !true;
+  Expect.equals(false, x);
+}
+
+void not2() {
+  var x = true;
+  var y = !x;
+  Expect.equals(false, y);
+}
+
+void not3() {
+  var x = true;
+  var y = !x;
+  var z = !y;
+  Expect.equals(true, z);
+}
+
+void not4() {
+  var x = true;
+  if (!x) Expect.fail('unreachable');
+  Expect.equals(true, x);
+}
+
+void main() {
+  not1();
+  not2();
+  not3();
+  not4();
+}
diff --git a/tests/dart2js/null_stacktrace_test.dart b/tests/dart2js/null_stacktrace_test.dart
new file mode 100644
index 0000000..1be361b
--- /dev/null
+++ b/tests/dart2js/null_stacktrace_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+/// Regression test: stack trace could be null when using async-await.
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+
+main() async {
+  C value = await test();
+  Expect.identical(StackTrace.empty, value._s);
+}
+
+Future<C> test() async {
+  try {
+    await throwInFuture();
+    return C(StackTrace.fromString("no-throw"));
+  } on MyException catch (e, s) {
+    return C(s); // Note: s is *no longer* null
+  }
+}
+
+Future<int> throwInFuture() {
+  var completer = new Completer<int>();
+  var future = completer.future;
+  new Future(() {}).then((_) {
+    StackTrace.fromString("hi");
+    completer.completeError(new MyException());
+  });
+  return future;
+}
+
+class MyException {}
+
+class C {
+  final StackTrace _s; // Global inference used to infer this field as non-null
+  C(this._s);
+
+  @override
+  String toString() => '[[$_s]]';
+}
diff --git a/tests/dart2js/null_test.dart b/tests/dart2js/null_test.dart
new file mode 100644
index 0000000..2378a91
--- /dev/null
+++ b/tests/dart2js/null_test.dart
@@ -0,0 +1,24 @@
+// 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 "package:expect/expect.dart";
+
+null1() {
+  return; // implicit null;
+}
+
+null2() {
+  // Implicit null return.
+}
+
+null3() {
+  var x; // Implicit null value.
+  return x;
+}
+
+void main() {
+  Expect.equals(null, null1());
+  Expect.equals(null, null2());
+  Expect.equals(null, null3());
+}
diff --git a/tests/dart2js/operator2_test.dart b/tests/dart2js/operator2_test.dart
new file mode 100644
index 0000000..7d43fb0
--- /dev/null
+++ b/tests/dart2js/operator2_test.dart
@@ -0,0 +1,187 @@
+// 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 "package:expect/expect.dart";
+
+int zero() {
+  return 0;
+}
+
+int one() {
+  return 1;
+}
+
+int minus1() {
+  return 0 - 1;
+}
+
+int two() {
+  return 2;
+}
+
+int three() {
+  return 3;
+}
+
+int five() {
+  return 5;
+}
+
+int minus5() {
+  return 0 - 5;
+}
+
+int ninetyNine() {
+  return 99;
+}
+
+int four99() {
+  return 499;
+}
+
+int four99times99() {
+  return 499 * 99;
+}
+
+int four99times99plus1() {
+  return 499 * 99 + 1;
+}
+
+void addTest() {
+  var m1 = 0 - 1;
+  var x = 0;
+  x += 0;
+  Expect.equals(0, x);
+  x += one();
+  Expect.equals(1, x);
+  x += m1;
+  Expect.equals(0, x);
+  x += 499;
+  Expect.equals(499, x);
+}
+
+void subTest() {
+  var m1 = 0 - 1;
+  var x = 0;
+  x -= 0;
+  Expect.equals(0, x);
+  x -= one();
+  Expect.equals(m1, x);
+  x -= m1;
+  Expect.equals(0, x);
+  x = 499;
+  x -= one();
+  x -= 98;
+  Expect.equals(400, x);
+}
+
+void mulTest() {
+  var m1 = 0 - 1;
+  var x = 0;
+  x *= 0;
+  Expect.equals(0, x);
+  x = one();
+  x *= 1;
+  Expect.equals(1, x);
+  x *= four99();
+  Expect.equals(499, x);
+  x *= m1;
+  Expect.equals(0 - 499, x);
+}
+
+void divTest() {
+  var m1 = 0.0 - 1.0;
+  var m2 = 0 - 2;
+  num x = two();
+  x /= 2;
+  Expect.equals(1.0, x);
+  x /= 2;
+  Expect.equals(0.5, x);
+  x = four99times99();
+  x /= 99;
+  Expect.equals(499.0, x);
+}
+
+void tdivTest() {
+  var x = 3;
+  x ~/= two();
+  Expect.equals(1, x);
+  x = 49402;
+  x ~/= ninetyNine();
+  Expect.equals(499, x);
+}
+
+void modTest() {
+  var x = five();
+  x %= 3;
+  Expect.equals(2, x);
+  x = 49402;
+  x %= ninetyNine();
+  Expect.equals(1, x);
+}
+
+void shlTest() {
+  var x = five();
+  x <<= 2;
+  Expect.equals(20, x);
+  x <<= 1;
+  Expect.equals(40, x);
+}
+
+void shrTest() {
+  var x = four99();
+  x >>= 1;
+  Expect.equals(249, x);
+  x >>= 2;
+  Expect.equals(62, x);
+}
+
+void andTest() {
+  var x = five();
+  x &= 3;
+  Expect.equals(1, x);
+  x &= 10;
+  Expect.equals(0, x);
+  x = four99();
+  x &= 63;
+  Expect.equals(51, x);
+}
+
+void orTest() {
+  var x = five();
+  x |= 2;
+  Expect.equals(7, x);
+  x |= 7;
+  Expect.equals(7, x);
+  x |= 10;
+  Expect.equals(15, x);
+  x |= 499;
+  Expect.equals(511, x);
+}
+
+void xorTest() {
+  var x = five();
+  x ^= 2;
+  Expect.equals(7, x);
+  x ^= 7;
+  Expect.equals(0, x);
+  x ^= 10;
+  Expect.equals(10, x);
+  x ^= 499;
+  Expect.equals(505, x);
+}
+
+void main() {
+  addTest();
+  subTest();
+  mulTest();
+  divTest();
+  tdivTest();
+  modTest();
+  shlTest();
+  shrTest();
+  andTest();
+  orTest();
+  xorTest();
+}
diff --git a/tests/dart2js/operator3_test.dart b/tests/dart2js/operator3_test.dart
new file mode 100644
index 0000000..04ceec8
--- /dev/null
+++ b/tests/dart2js/operator3_test.dart
@@ -0,0 +1,92 @@
+// 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 "package:expect/expect.dart";
+
+int zero() {
+  return 0;
+}
+
+int one() {
+  return 1;
+}
+
+int minus1() {
+  return 0 - 1;
+}
+
+int two() {
+  return 2;
+}
+
+int three() {
+  return 3;
+}
+
+int five() {
+  return 5;
+}
+
+int minus5() {
+  return 0 - 5;
+}
+
+int ninetyNine() {
+  return 99;
+}
+
+int four99() {
+  return 499;
+}
+
+int four99times99() {
+  return 499 * 99;
+}
+
+int four99times99plus1() {
+  return 499 * 99 + 1;
+}
+
+void postPlusPlusTest() {
+  var x = zero();
+  var y = x++;
+  Expect.equals(0, y);
+  Expect.equals(1, x);
+  Expect.equals(1, x++);
+  Expect.equals(2, x);
+}
+
+void prePlusPlusTest() {
+  var x = zero();
+  var y = ++x;
+  Expect.equals(1, x);
+  Expect.equals(1, y);
+  Expect.equals(2, ++x);
+  Expect.equals(2, ++y);
+}
+
+void postMinusMinusTest() {
+  var x = four99();
+  var y = x--;
+  Expect.equals(499, y);
+  Expect.equals(498, x);
+  Expect.equals(498, x--);
+  Expect.equals(497, x);
+}
+
+void preMinusMinusTest() {
+  var x = four99();
+  var y = --x;
+  Expect.equals(498, y);
+  Expect.equals(498, x);
+  Expect.equals(497, --x);
+  Expect.equals(497, x);
+}
+
+void main() {
+  postPlusPlusTest();
+  prePlusPlusTest();
+  postMinusMinusTest();
+  preMinusMinusTest();
+}
diff --git a/tests/dart2js/operator_equals_test.dart b/tests/dart2js/operator_equals_test.dart
new file mode 100644
index 0000000..6d73309
--- /dev/null
+++ b/tests/dart2js/operator_equals_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class AlwaysTrue {
+  operator ==(a) => true;
+}
+
+class AlwaysFalse {
+  operator ==(b) => false;
+}
+
+main() {
+  dynamic a = new AlwaysTrue();
+  Expect.isTrue(a == 2);
+  Expect.isFalse(a == null);
+  Expect.isFalse(a != 2);
+  Expect.isTrue(a != null);
+
+  a = new AlwaysFalse();
+  Expect.isFalse(a == 2);
+  Expect.isFalse(a == null);
+  Expect.isTrue(a != 2);
+  Expect.isTrue(a != null);
+}
diff --git a/tests/dart2js/operator_test.dart b/tests/dart2js/operator_test.dart
new file mode 100644
index 0000000..65edd95
--- /dev/null
+++ b/tests/dart2js/operator_test.dart
@@ -0,0 +1,564 @@
+// 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 "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+@pragma('dart2js:noInline')
+asNum(x) {
+  var result = confuse(x);
+  if (result is num) return result;
+  throw new ArgumentError.value(x);
+}
+
+@pragma('dart2js:noInline')
+uint31(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0x7fffffff & x; // inferred uint31 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint31: $x');
+}
+
+@pragma('dart2js:noInline')
+uint32(x) {
+  var result = confuse(x);
+  if (x is int) {
+    var masked = 0xffffffff & x; // inferred uint32 type.
+    if (masked == x) return masked;
+  }
+  throw new ArgumentError('Not uint32: $x');
+}
+
+@pragma('dart2js:noInline')
+int zero() {
+  return 0;
+}
+
+@pragma('dart2js:noInline')
+int one() {
+  return 1;
+}
+
+@pragma('dart2js:noInline')
+int minus1() {
+  return 0 - 1;
+}
+
+@pragma('dart2js:noInline')
+int minus2() {
+  return 0 - 2;
+}
+
+@pragma('dart2js:noInline')
+int two() {
+  return 2;
+}
+
+@pragma('dart2js:noInline')
+int three() {
+  return 3;
+}
+
+@pragma('dart2js:noInline')
+int five() {
+  return 5;
+}
+
+@pragma('dart2js:noInline')
+int minus5() {
+  return 0 - 5;
+}
+
+@pragma('dart2js:noInline')
+int ninetyNine() {
+  return 99;
+}
+
+@pragma('dart2js:noInline')
+int four99() {
+  return 499;
+}
+
+@pragma('dart2js:noInline')
+int four99times99() {
+  return 499 * 99;
+}
+
+@pragma('dart2js:noInline')
+int four99times99plus1() {
+  return 499 * 99 + 1;
+}
+
+@pragma('dart2js:noInline')
+void addTest() {
+  var m1 = 0 - 1;
+  Expect.equals(0, 0 + 0);
+  Expect.equals(0, confuse(0) + 0);
+  Expect.equals(0, asNum(0) + 0);
+  Expect.equals(0, uint31(0) + 0);
+
+  Expect.equals(m1, m1 + 0);
+  Expect.equals(0, m1 + 1);
+  Expect.equals(499, 400 + 99);
+  Expect.equals(1, 0 + one());
+  Expect.equals(1, one() + 0);
+  Expect.equals(2, one() + one());
+}
+
+@pragma('dart2js:noInline')
+void subTest() {
+  var m1 = 0 - 1;
+  Expect.equals(0, 0 - 0);
+  Expect.equals(m1, 0 - 1);
+  Expect.equals(0, 1 - 1);
+  Expect.equals(400, 499 - 99);
+  Expect.equals(m1, 0 - one());
+  Expect.equals(1, one() - 0);
+  Expect.equals(0, one() - one());
+}
+
+@pragma('dart2js:noInline')
+void mulTest() {
+  var m1 = 0 - 1;
+  Expect.equals(0, 0 * 0);
+  Expect.equals(m1, m1 * 1);
+  Expect.equals(1, 1 * 1);
+  Expect.equals(49401, 499 * 99);
+  Expect.equals(499, 499 * one());
+  Expect.equals(499, one() * 499);
+  Expect.equals(49401, four99() * 99);
+}
+
+@pragma('dart2js:noInline')
+void divTest() {
+  var m1 = 0.0 - 1.0;
+  var m2 = 0 - 2;
+  Expect.equals(1.0, 2 / 2);
+  Expect.equals(m1, m2 / 2);
+  Expect.equals(m1, minus2() / 2);
+  Expect.equals(0.5, 1 / 2);
+  Expect.equals(499.0, 49401 / 99);
+
+  Expect.equals(1.0, two() / 2);
+  Expect.equals(1.0, 2 / two());
+  Expect.equals(m1, m2 / two());
+  Expect.equals(m1, minus2() / two());
+  Expect.equals(m1, two() / m2);
+  Expect.equals(m1, two() / minus2());
+  Expect.equals(0.5, 1 / two());
+  Expect.equals(0.5, one() / 2);
+  Expect.equals(499.0, four99times99() / 99);
+
+  Expect.equals(1.5, confuse(150) / confuse(100));
+}
+
+@pragma('dart2js:noInline')
+void tdivTest() {
+  var m1 = 0 - 1;
+  var m2 = 0 - 2;
+  Expect.equals(1, 2 ~/ 2);
+  Expect.equals(m1, m2 ~/ 2);
+  Expect.equals(0, 1 ~/ 2);
+  Expect.equals(0, m1 ~/ 2);
+  Expect.equals(499, 49401 ~/ 99);
+  Expect.equals(499, 49402 ~/ 99);
+
+  Expect.equals(1, two() ~/ 2);
+  Expect.equals(1, 2 ~/ two());
+  Expect.equals(m1, m2 ~/ two());
+  Expect.equals(m1, two() ~/ m2);
+  Expect.equals(0, 1 ~/ two());
+  Expect.equals(0, one() ~/ 2);
+  Expect.equals(499, four99times99() ~/ 99);
+  Expect.equals(499, four99times99plus1() ~/ 99);
+
+  Expect.equals(-33, -100 ~/ 3);
+  Expect.equals(-33, asNum(-100) ~/ 3);
+  Expect.equals(33, -100 ~/ -3);
+  Expect.equals(33, asNum(-100) ~/ -3);
+
+  // Signed int32 boundary is involved in optimizations.
+
+  Expect.equals(-0x80000000, -0x80000000 ~/ 1.0);
+  Expect.equals(-0x80000000, -0x80000000 ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff, -0x80000000 ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000, asNum(-0x80000000) ~/ 1.0);
+  Expect.equals(-0x80000000, asNum(-0x80000000) ~/ 1.0000000000000001);
+  Expect.equals(-0x7fffffff, asNum(-0x80000000) ~/ 1.0000000000000002);
+
+  Expect.equals(-0x80000000, asNum(0x80000000) ~/ -1.0);
+  Expect.equals(-0x80000000, asNum(0x80000000) ~/ -1.0000000000000001);
+  Expect.equals(-0x7fffffff, asNum(0x80000000) ~/ -1.0000000000000002);
+
+  Expect.equals(0x7fffffff, 0x10000000 ~/ .12500000000000002);
+  Expect.equals(0x80000000, 0x10000000 ~/ .125);
+  Expect.equals(-0x7fffffff, 0x10000000 ~/ -.12500000000000002);
+  Expect.equals(-0x80000000, 0x10000000 ~/ -.125);
+
+  Expect.equals(0x7fffffff, uint31(0x10000000) ~/ .12500000000000002);
+  Expect.equals(0x80000000, uint31(0x10000000) ~/ .125);
+  Expect.equals(-0x7fffffff, uint31(0x10000000) ~/ -.12500000000000002);
+  Expect.equals(-0x80000000, uint31(0x10000000) ~/ -.125);
+
+  // These can be compiled to `(a / 2) | 0`.
+  Expect.equals(100, uint31(200) ~/ 2);
+  Expect.equals(100, uint32(200) ~/ 2);
+
+  Expect.equals(100, asNum(200) ~/ 2);
+  Expect.equals(100, confuse(200) ~/ 2);
+  Expect.equals(-100, uint31(200) ~/ -2);
+  Expect.equals(-100, uint32(200) ~/ -2);
+  Expect.equals(-100, asNum(200) ~/ -2);
+  Expect.equals(-100, confuse(200) ~/ -2);
+
+  // These can be compiled to `((a + b) / 2) | 0`.
+  Expect.equals(100, (uint31(100) + uint31(100)) ~/ 2);
+  Expect.equals(0x7fffffff, (uint31(0x7fffffff) + uint31(0x7fffffff)) ~/ 2);
+
+  // NaN and Infinity results are errors.
+  Expect.throws(() => -1 ~/ 0);
+  Expect.throws(() => 1.5 ~/ 0);
+  Expect.throws(() => 1e200 ~/ 1e-200);
+  Expect.throws(() => -1e200 ~/ 1e-200);
+  Expect.throws(() => 1e200 ~/ -1e-200);
+  Expect.throws(() => -1e200 ~/ -1e-200);
+  Expect.throws(() => double.nan ~/ 2);
+}
+
+@pragma('dart2js:noInline')
+void modTest() {
+  var m5 = 0 - 5;
+  var m3 = 0 - 3;
+  Expect.equals(2, 5 % 3);
+  Expect.equals(0, 49401 % 99);
+  Expect.equals(1, 49402 % 99);
+  Expect.equals(1, m5 % 3);
+  Expect.equals(2, 5 % m3);
+
+  Expect.equals(2, five() % 3);
+  Expect.equals(2, 5 % three());
+  Expect.equals(0, four99times99() % 99);
+  Expect.equals(1, four99times99plus1() % 99);
+  Expect.equals(1, minus5() % 3);
+  Expect.equals(2, five() % m3);
+}
+
+@pragma('dart2js:noInline')
+void remainderTest() {
+  var m5 = 0 - 5;
+  Expect.equals(2, confuse(5).remainder(3));
+  Expect.equals(0, confuse(49401).remainder(99));
+  Expect.equals(1, confuse(49402).remainder(99));
+  Expect.equals(-2, confuse(m5).remainder(3));
+  Expect.equals(2, confuse(5).remainder(-3));
+
+  Expect.equals(2, uint32(5).remainder(3));
+  Expect.equals(0, uint32(49401).remainder(99));
+  Expect.equals(1, uint32(49402).remainder(99));
+  Expect.equals(-2, (-5).remainder(uint32(3)));
+  Expect.equals(2, uint32(5).remainder(-3));
+
+  Expect.equals(2, 5.remainder(3));
+  Expect.equals(0, 49401.remainder(99));
+  Expect.equals(1, 49402.remainder(99));
+  Expect.equals(-2, (-5).remainder(3));
+  Expect.equals(2, 5.remainder(-3));
+
+  Expect.equals(2, five().remainder(3));
+  Expect.equals(2, 5.remainder(three()));
+  Expect.equals(0, four99times99().remainder(99));
+  Expect.equals(1, four99times99plus1().remainder(99));
+  Expect.equals(-2, minus5().remainder(3));
+  Expect.equals(2, five().remainder(-3));
+}
+
+@pragma('dart2js:noInline')
+void shlTest() {
+  Expect.equals(2, 1 << 1);
+  Expect.equals(8, 1 << 3);
+  Expect.equals(6, 3 << 1);
+
+  Expect.equals(10, five() << 1);
+  Expect.equals(24, 3 << three());
+
+  Expect.equals(10, confuse(5) << 1);
+  Expect.equals(24, 3 << confuse(3));
+
+  Expect.equals(10, uint31(5) << 1);
+  Expect.equals(24, 3 << uint31(3));
+
+  Expect.equals(10, asNum(5) << 1);
+  Expect.equals(24, 3 << asNum(3));
+}
+
+@pragma('dart2js:noInline')
+void shrTest() {
+  Expect.equals(1, 2 >> 1);
+  Expect.equals(1, 8 >> 3);
+  Expect.equals(3, 6 >> 1);
+
+  Expect.equals(6, ninetyNine() >> 4);
+  Expect.equals(6, confuse(99) >> 4);
+  Expect.equals(6, asNum(99) >> 4);
+  Expect.equals(6, uint31(99) >> 4);
+
+  Expect.equals(6, 99 >> 4);
+  Expect.equals(6, 99 >> confuse(4));
+  Expect.equals(6, 99 >> asNum(4));
+  Expect.equals(6, 99 >> uint31(4));
+
+  Expect.equals(0, uint31(1) >> 31);
+  Expect.equals(0, asNum(0xffffffff) >> 32);
+}
+
+@pragma('dart2js:noInline')
+void andTest() {
+  Expect.equals(2, 10 & 3);
+  Expect.equals(7, 15 & 7);
+  Expect.equals(10, 10 & 10);
+
+  Expect.equals(99, ninetyNine() & ninetyNine());
+  Expect.equals(34, four99() & 42);
+  Expect.equals(3, minus5() & 7);
+
+  Expect.equals(0, uint31(0x7ffffffe) & uint31(1));
+  Expect.equals(0, asNum(0x7ffffffe) & asNum(1));
+}
+
+@pragma('dart2js:noInline')
+void orTest() {
+  Expect.equals(11, 10 | 3);
+  Expect.equals(15, 15 | 7);
+  Expect.equals(10, 10 | 10);
+
+  Expect.equals(99, ninetyNine() | ninetyNine());
+  Expect.equals(507, four99() | 42);
+
+  Expect.equals(11, asNum(10) | 3);
+  Expect.equals(15, asNum(15) | 7);
+  Expect.equals(10, asNum(10) | 10);
+}
+
+@pragma('dart2js:noInline')
+void xorTest() {
+  Expect.equals(9, 10 ^ 3);
+  Expect.equals(8, 15 ^ 7);
+  Expect.equals(0, 10 ^ 10);
+
+  Expect.equals(0, ninetyNine() ^ ninetyNine());
+  Expect.equals(473, four99() ^ 42);
+  Expect.equals(0, minus5() ^ -5);
+  Expect.equals(6, minus5() ^ -3);
+}
+
+@pragma('dart2js:noInline')
+void notTest() {
+  Expect.equals(4, ~minus5());
+}
+
+@pragma('dart2js:noInline')
+void negateTest() {
+  Expect.equals(minus5(), -5);
+  Expect.equals(-5, -five());
+  Expect.equals(5, -minus5());
+
+  Expect.equals(-3, -confuse(3));
+  Expect.equals(-3, -asNum(3));
+  Expect.equals(-3, -uint31(3));
+
+  Expect.equals(3, -confuse(-3));
+  Expect.equals(3, -asNum(-3));
+}
+
+@pragma('dart2js:noInline')
+void equalsTest() {
+  // Equality of normal numbers is already well tested with "Expect.equals".
+  Expect.equals(true, true == true);
+  Expect.equals(true, false == false);
+  Expect.equals(true, 0 == 0);
+  Expect.equals(true, null == null);
+
+  Expect.equals(false, 1 == 2);
+  Expect.equals(false, 1 == "foo");
+  Expect.equals(false, 1 == true);
+  Expect.equals(false, 1 == false);
+  Expect.equals(false, false == "");
+  Expect.equals(false, false == 0);
+  Expect.equals(false, false == null);
+  Expect.equals(false, "" == false);
+  Expect.equals(false, 0 == false);
+  Expect.equals(false, null == false);
+
+  var falseValue = false;
+  var trueValue = true;
+  var nullValue = null;
+  if (one() == 2) {
+    falseValue = true;
+    trueValue = false;
+    nullValue = 5;
+  }
+
+  Expect.equals(true, true == trueValue);
+  Expect.equals(true, false == falseValue);
+  Expect.equals(true, 1 == one());
+  Expect.equals(true, null == nullValue);
+  Expect.equals(false, one() == 2);
+  Expect.equals(false, one() == "foo");
+  Expect.equals(false, one() == true);
+  Expect.equals(false, one() == false);
+  Expect.equals(false, falseValue == "");
+  Expect.equals(false, falseValue == 0);
+  Expect.equals(false, falseValue == null);
+  Expect.equals(false, "" == falseValue);
+  Expect.equals(false, 0 == falseValue);
+  Expect.equals(false, null == falseValue);
+}
+
+@pragma('dart2js:noInline')
+void lessTest() {
+  var m1 = minus1();
+  Expect.equals(true, 1 < 2);
+  Expect.equals(false, 2 < 1);
+  Expect.equals(false, 1 < 1);
+
+  Expect.equals(true, 0 < 1);
+  Expect.equals(false, 1 < 0);
+  Expect.equals(false, 0 < 0);
+
+  Expect.equals(true, one() < 2);
+  Expect.equals(false, 2 < one());
+  Expect.equals(false, 1 < one());
+
+  Expect.equals(true, 0 < one());
+  Expect.equals(false, one() < 0);
+  Expect.equals(false, 0 < 0);
+
+  Expect.equals(true, m1 < 0);
+  Expect.equals(false, 0 < m1);
+  Expect.equals(false, m1 < m1);
+
+  Expect.equals(true, minus1() < 0);
+  Expect.equals(false, 0 < minus1());
+  Expect.equals(false, minus1() < minus1());
+}
+
+@pragma('dart2js:noInline')
+void lessEqualTest() {
+  var m1 = minus1();
+  Expect.equals(true, 1 <= 2);
+  Expect.equals(false, 2 <= 1);
+  Expect.equals(true, 1 <= 1);
+
+  Expect.equals(true, 0 <= 1);
+  Expect.equals(false, 1 <= 0);
+  Expect.equals(true, 0 <= 0);
+
+  Expect.equals(true, confuse(1) <= 2);
+  Expect.equals(false, confuse(2) <= 1);
+  Expect.equals(true, confuse(1) <= 1);
+
+  Expect.equals(true, confuse(0) <= 1);
+  Expect.equals(false, confuse(1) <= 0);
+  Expect.equals(true, confuse(0) <= 0);
+
+  Expect.equals(true, one() <= 2);
+  Expect.equals(false, 2 <= one());
+  Expect.equals(true, 1 <= one());
+
+  Expect.equals(true, 0 <= one());
+  Expect.equals(false, one() <= 0);
+  Expect.equals(true, 0 <= 0);
+
+  Expect.equals(true, m1 <= 0);
+  Expect.equals(false, 0 <= m1);
+  Expect.equals(true, m1 <= m1);
+
+  Expect.equals(true, minus1() <= 0);
+  Expect.equals(false, 0 <= minus1());
+  Expect.equals(true, minus1() <= minus1());
+}
+
+@pragma('dart2js:noInline')
+void greaterTest() {
+  var m1 = minus1();
+  Expect.equals(false, 1 > 2);
+  Expect.equals(true, 2 > 1);
+  Expect.equals(false, 1 > 1);
+
+  Expect.equals(false, 0 > 1);
+  Expect.equals(true, 1 > 0);
+  Expect.equals(false, 0 > 0);
+
+  Expect.equals(false, one() > 2);
+  Expect.equals(true, 2 > one());
+  Expect.equals(false, 1 > one());
+
+  Expect.equals(false, 0 > one());
+  Expect.equals(true, one() > 0);
+  Expect.equals(false, 0 > 0);
+
+  Expect.equals(false, m1 > 0);
+  Expect.equals(true, 0 > m1);
+  Expect.equals(false, m1 > m1);
+
+  Expect.equals(false, minus1() > 0);
+  Expect.equals(true, 0 > minus1());
+  Expect.equals(false, minus1() > minus1());
+}
+
+@pragma('dart2js:noInline')
+void greaterEqualTest() {
+  var m1 = minus1();
+  Expect.equals(false, 1 >= 2);
+  Expect.equals(true, 2 >= 1);
+  Expect.equals(true, 1 >= 1);
+
+  Expect.equals(false, 0 >= 1);
+  Expect.equals(true, 1 >= 0);
+  Expect.equals(true, 0 >= 0);
+
+  Expect.equals(false, one() >= 2);
+  Expect.equals(true, 2 >= one());
+  Expect.equals(true, 1 >= one());
+
+  Expect.equals(false, 0 >= one());
+  Expect.equals(true, one() >= 0);
+  Expect.equals(true, 0 >= 0);
+
+  Expect.equals(false, m1 >= 0);
+  Expect.equals(true, 0 >= m1);
+  Expect.equals(true, m1 >= m1);
+
+  Expect.equals(false, minus1() >= 0);
+  Expect.equals(true, 0 >= minus1());
+  Expect.equals(true, minus1() >= minus1());
+}
+
+void main() {
+  addTest();
+  subTest();
+  mulTest();
+  divTest();
+  tdivTest();
+  modTest();
+  remainderTest();
+  shlTest();
+  shrTest();
+  andTest();
+  orTest();
+  xorTest();
+  notTest();
+  negateTest();
+  equalsTest();
+  lessTest();
+  lessEqualTest();
+  greaterTest();
+  greaterEqualTest();
+}
diff --git a/tests/dart2js/optional_parameter_test.dart b/tests/dart2js/optional_parameter_test.dart
new file mode 100644
index 0000000..48418fb
--- /dev/null
+++ b/tests/dart2js/optional_parameter_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo([a]) {
+    return a;
+  }
+
+  bar(a, [b]) {
+    return b;
+  }
+
+  noSuchMethod(mirror) {
+    return 0;
+  }
+}
+
+main() {
+  A a = new A();
+  Expect.equals(42, a.foo(42));
+  Expect.equals(null, a.foo());
+  Expect.equals(null, a.bar(42));
+  Expect.equals(42, a.bar(null, 42));
+  Expect.equals(0, (a as dynamic).foo(1, 2));
+  Expect.equals(0, (a as dynamic).bar());
+  Expect.equals(0, (a as dynamic).bar(1, 2, 3));
+}
diff --git a/tests/dart2js/panda_lib.dart b/tests/dart2js/panda_lib.dart
new file mode 100644
index 0000000..1d20b03
--- /dev/null
+++ b/tests/dart2js/panda_lib.dart
@@ -0,0 +1,9 @@
+// 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.
+
+library panda_lib;
+
+class Panda {
+  Panda() {}
+}
diff --git a/tests/dart2js/panda_test.dart b/tests/dart2js/panda_test.dart
new file mode 100644
index 0000000..2afaee6
--- /dev/null
+++ b/tests/dart2js/panda_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+library panda_test;
+
+import "package:expect/expect.dart";
+import 'panda_lib.dart' as p;
+
+void main() {
+  p.Panda x = new p.Panda();
+  Expect.isTrue(x is p.Panda);
+  x = null;
+  Expect.isFalse(x is p.Panda);
+}
diff --git a/tests/dart2js/phi_elimination_test.dart b/tests/dart2js/phi_elimination_test.dart
new file mode 100644
index 0000000..fe3f33f
--- /dev/null
+++ b/tests/dart2js/phi_elimination_test.dart
@@ -0,0 +1,58 @@
+// 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 "package:expect/expect.dart";
+
+void bar() {
+  var a = 0;
+  var c = 0;
+
+  if (a == 0)
+    c = a++;
+  else
+    c = a--;
+
+  Expect.equals(1, a);
+  Expect.equals(0, c);
+
+  if (a == 0)
+    c = a++;
+  else
+    c = a--;
+
+  Expect.equals(0, a);
+  Expect.equals(1, c);
+}
+
+void foo() {
+  var a = 0;
+  var c = 0;
+
+  if (a == 0) {
+    c = a;
+    a = a + 1;
+  } else {
+    c = a;
+    a = a - 1;
+  }
+
+  Expect.equals(1, a);
+  Expect.equals(0, c);
+
+  if (a == 0) {
+    c = a;
+    a = a + 1;
+  } else {
+    c = a;
+    a = a - 1;
+  }
+
+  Expect.equals(0, a);
+  Expect.equals(1, c);
+}
+
+main() {
+  foo();
+  bar();
+}
diff --git a/tests/dart2js/phi_gvn_test.dart b/tests/dart2js/phi_gvn_test.dart
new file mode 100644
index 0000000..558ce8b
--- /dev/null
+++ b/tests/dart2js/phi_gvn_test.dart
@@ -0,0 +1,14 @@
+// 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 "package:expect/expect.dart";
+
+foo(x) {}
+
+main() {
+  for (var i = 0; i < 1; i++) {
+    foo(i + 1);
+    Expect.equals(0, i);
+  }
+}
diff --git a/tests/dart2js/phi_test.dart b/tests/dart2js/phi_test.dart
new file mode 100644
index 0000000..14ca2be
--- /dev/null
+++ b/tests/dart2js/phi_test.dart
@@ -0,0 +1,170 @@
+// 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 "package:expect/expect.dart";
+
+void phi1() {
+  var x = 42;
+  if (true) {
+    Expect.equals(42, x);
+    print(x);
+  }
+  Expect.equals(42, x);
+  print(x);
+}
+
+void phi2() {
+  var x = 499;
+  if (true) {
+    Expect.equals(499, x);
+    x = 42;
+  }
+  Expect.equals(42, x);
+  print(x);
+}
+
+void phi3() {
+  var x = 499;
+  if (true) {
+    Expect.equals(499, x);
+    x = 42;
+  } else {
+    Expect.fail('unreachable');
+    print(x);
+  }
+  Expect.equals(42, x);
+  print(x);
+}
+
+void phi4() {
+  var x = 499;
+  if (true) {
+    Expect.equals(499, x);
+    print(x);
+  } else {
+    Expect.fail('unreachable');
+    x = 42;
+  }
+  Expect.equals(499, x);
+  print(x);
+}
+
+void phi5() {
+  var x = 499;
+  if (true) {
+    if (true) {
+      Expect.equals(499, x);
+      x = 42;
+    }
+  }
+  Expect.equals(42, x);
+  print(x);
+}
+
+void phi6() {
+  var x = 499;
+  if (true) {
+    if (true) {
+      Expect.equals(499, x);
+      print(x);
+    } else {
+      x = 42;
+      Expect.fail('unreachable');
+    }
+  }
+  Expect.equals(499, x);
+  print(x);
+}
+
+void phi7() {
+  var x = 499;
+  if (true) {
+    x = 42;
+    if (true) {
+      Expect.equals(42, x);
+      x = 99;
+    } else {
+      x = 111;
+      Expect.fail('unreachable');
+    }
+  } else {
+    Expect.fail('unreachable');
+    if (false) {
+      x = 341;
+    } else {
+      x = 1024;
+    }
+  }
+  Expect.equals(99, x);
+  print(x);
+}
+
+void phi8() {
+  var x = 499;
+  if (true) {
+    x = 42;
+    if (true) {
+      Expect.equals(42, x);
+      x = 99;
+    } else {
+      Expect.fail('unreachable');
+      x = 111;
+    }
+  } else {
+    Expect.fail('unreachable');
+    if (false) {
+      x = 341;
+    } else {
+      x = 1024;
+    }
+  }
+  if (true) {
+    Expect.equals(99, x);
+    x = 12342;
+    if (true) {
+      x = 12399;
+    } else {
+      Expect.fail('unreachable');
+      x = 123111;
+    }
+  } else {
+    Expect.fail('unreachable');
+    if (false) {
+      x = 123341;
+    } else {
+      x = 1231024;
+    }
+  }
+  Expect.equals(12399, x);
+  print(x);
+}
+
+void phi9() {
+  var x = 499;
+  if (true) {
+    var y = 42;
+    if (true) {
+      y = 99;
+    } else {
+      Expect.fail('unreachable');
+      x = 111;
+    }
+    Expect.equals(99, y);
+    print(y);
+  }
+  Expect.equals(499, x);
+  print(x);
+}
+
+void main() {
+  phi1();
+  phi2();
+  phi3();
+  phi4();
+  phi5();
+  phi6();
+  phi7();
+  phi8();
+  phi9();
+}
diff --git a/tests/dart2js/private_symbol_literal_test.dart b/tests/dart2js/private_symbol_literal_test.dart
new file mode 100644
index 0000000..1f12b06
--- /dev/null
+++ b/tests/dart2js/private_symbol_literal_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, 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 symbol literals with underscores.
+// These are currently unsupported by dart2js.
+
+library symbol_literal_test;
+
+main() {
+  print(#a);
+  print(#_a); //# 01: compile-time error
+
+  print(#a.b);
+  print(#_a.b); //# 02: compile-time error
+  print(#a._b); //# 03: compile-time error
+
+  print(#a.b.c);
+  print(#_a.b.c); //# 04: compile-time error
+  print(#a._b.c); //# 05: compile-time error
+  print(#a.b._c); //# 06: compile-time error
+}
diff --git a/tests/dart2js/recursive_metadata_test.dart b/tests/dart2js/recursive_metadata_test.dart
new file mode 100644
index 0000000..1c46209
--- /dev/null
+++ b/tests/dart2js/recursive_metadata_test.dart
@@ -0,0 +1,38 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+// Tests that the compiler doesn't crash resolving annotations that refer
+// to other annotated types.
+
+class Annotation {
+  final String value;
+  const Annotation({this.value});
+}
+
+enum Enum {
+  a,
+  b,
+}
+
+class SubAnno extends Annotation {
+  final Enum e;
+  final Type type;
+  const SubAnno({String value, this.e, this.type}) : super(value: value);
+}
+
+@SubAnno(value: 'super')
+class A {}
+
+@SubAnno(value: 'sub')
+class B extends A {}
+
+@SubAnno(type: B)
+class C {}
+
+main() {
+  var c = new C();
+  Expect.isTrue(c != null);
+}
diff --git a/tests/dart2js/regress/41781_test.dart b/tests/dart2js/regress/41781_test.dart
new file mode 100644
index 0000000..f4f6ac8
--- /dev/null
+++ b/tests/dart2js/regress/41781_test.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.
+
+@pragma('dart2js:noInline')
+test(List a, List b) {
+  return [
+    throw 123,
+    {...a, ...b}
+  ];
+}
+
+void main() {
+  try {
+    print(test([1], [2, 3]));
+    print(test([1, 2], [3]));
+  } catch (e) {}
+}
diff --git a/tests/dart2js/regress/4434_lib.dart b/tests/dart2js/regress/4434_lib.dart
new file mode 100644
index 0000000..a2ac7c4
--- /dev/null
+++ b/tests/dart2js/regress/4434_lib.dart
@@ -0,0 +1,10 @@
+// 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.
+
+library lib_a;
+
+class A {
+  x(A a) => a._x;
+  get _x => null;
+}
diff --git a/tests/dart2js/regress/4434_test.dart b/tests/dart2js/regress/4434_test.dart
new file mode 100644
index 0000000..72582f7
--- /dev/null
+++ b/tests/dart2js/regress/4434_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+library lib_b;
+
+import '4434_lib.dart';
+
+class B extends A {}
+
+main() {
+  B b = new B();
+  b.x(b);
+}
diff --git a/tests/dart2js/regress/4492_test.dart b/tests/dart2js/regress/4492_test.dart
new file mode 100644
index 0000000..2b3d6c8
--- /dev/null
+++ b/tests/dart2js/regress/4492_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  x(p1, p2) {
+    print(p1 * p2);
+    if (p1 * p2 == 12) return;
+    x("3", "4");
+  }
+}
+
+main() {
+  Expect.throws(() => new A().x(1, 2));
+}
diff --git a/tests/dart2js/regress/4515_1_test.dart b/tests/dart2js/regress/4515_1_test.dart
new file mode 100644
index 0000000..8c758b0
--- /dev/null
+++ b/tests/dart2js/regress/4515_1_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  a(x) => x + 1;
+}
+
+f(p) => p("A");
+
+main() {
+  A a = new A();
+  a.a(1);
+  Expect.throws(() => print(f(a.a)));
+}
diff --git a/tests/dart2js/regress/4515_2_test.dart b/tests/dart2js/regress/4515_2_test.dart
new file mode 100644
index 0000000..3411648
--- /dev/null
+++ b/tests/dart2js/regress/4515_2_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  a(x) => x + 1;
+}
+
+f(p) => p("A");
+
+main() {
+  A a = new A();
+  a.a(1);
+  Expect.throws(() => print(f((x) => (a.a(x)))));
+}
diff --git a/tests/dart2js/regress/4515_3_test.dart b/tests/dart2js/regress/4515_3_test.dart
new file mode 100644
index 0000000..23438ad
--- /dev/null
+++ b/tests/dart2js/regress/4515_3_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, 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";
+
+class A {
+  a(x) => x + 1;
+}
+
+f(p) => p("A");
+
+main() {
+  A a = new A();
+  a.a(1);
+  var v = null;
+  try {
+    v = f(a.a);
+  } catch (e) {}
+
+  Expect.equals(null, v);
+}
diff --git a/tests/dart2js/regress/4562_test.dart b/tests/dart2js/regress/4562_test.dart
new file mode 100644
index 0000000..61ba859
--- /dev/null
+++ b/tests/dart2js/regress/4562_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+void main() {
+  var foo = new Foo();
+  var bar = new Bar(); //# 01: compile-time error
+}
+
+class Foo {
+  factory Foo() => null;
+}
+
+class Bar extends Foo {
+  Bar(); //# 01: continued
+}
diff --git a/tests/dart2js/regress/4639_test.dart b/tests/dart2js/regress/4639_test.dart
new file mode 100644
index 0000000..2aa9308
--- /dev/null
+++ b/tests/dart2js/regress/4639_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  bool contains(x, y) => true;
+}
+
+class B {
+  A makeA() => new A();
+  bool test() => makeA().contains(1, 2);
+}
+
+main() {
+  Expect.isTrue(new B().test());
+  Expect.isTrue("x".contains("x"));
+}
diff --git a/tests/dart2js/regress/regression_type_variables_is_test.dart b/tests/dart2js/regress/regression_type_variables_is_test.dart
new file mode 100644
index 0000000..9826cf4
--- /dev/null
+++ b/tests/dart2js/regress/regression_type_variables_is_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, 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";
+
+class Bar<X> implements Baz {}
+
+class Baz {}
+
+var g;
+
+abstract class Foo<A extends Baz> {
+  final bool thing = g is A;
+}
+
+class Qux extends Foo<Baz> {}
+
+main() {
+  g = new Baz();
+  var f = new Qux();
+  Expect.isTrue(f.thing);
+  g = 'ello';
+  var f2 = new Qux();
+  Expect.isFalse(f2.thing);
+}
diff --git a/tests/dart2js/regress/unused_generator_type_parameter_test.dart b/tests/dart2js/regress/unused_generator_type_parameter_test.dart
new file mode 100644
index 0000000..93ce458
--- /dev/null
+++ b/tests/dart2js/regress/unused_generator_type_parameter_test.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.
+
+import "package:expect/expect.dart";
+
+class Foo<X> {
+  // T is unused, so can be erased, but that should not break anything.  The
+  // generator should still have a header and a body since it needs to compute
+  // the return type.
+  Iterable<Set<X>> bar<T>() sync* {}
+}
+
+main() {
+  var f = Foo<String>();
+  var c = f.bar<int>();
+  Expect.isFalse(c.iterator is Iterator<Set<int>>);
+  Expect.isTrue(c.iterator is Iterator<Set<String>>);
+}
diff --git a/tests/dart2js/regress_32069_test.dart b/tests/dart2js/regress_32069_test.dart
new file mode 100644
index 0000000..23a0aff
--- /dev/null
+++ b/tests/dart2js/regress_32069_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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';
+
+main() {
+  var m1 = {
+    'hello': <String>['hi', 'howdy'],
+    'bye': <String>[]
+  };
+  var m = new Map<String, List<String>>.unmodifiable(m1);
+  print(m);
+  Expect.isTrue(m is Map<String, List<String>>);
+  Expect.isFalse(m is Map<List<String>, String>);
+}
diff --git a/tests/dart2js/regress_36222_test.dart b/tests/dart2js/regress_36222_test.dart
new file mode 100644
index 0000000..f030833
--- /dev/null
+++ b/tests/dart2js/regress_36222_test.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.
+
+typedef int BinaryFunc(int x, int y);
+
+class A {
+  const A({this.foo = A.defaultFoo});
+
+  static int defaultFoo(int x, int y) {
+    return x + y;
+  }
+
+  final BinaryFunc foo;
+}
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+test(dynamic a) => a.foo(1, 2);
+
+main() {
+  test(new A());
+}
diff --git a/tests/dart2js/regress_40349_test.dart b/tests/dart2js/regress_40349_test.dart
new file mode 100644
index 0000000..796688d
--- /dev/null
+++ b/tests/dart2js/regress_40349_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+/// Regression test for Issue #40349:
+///
+/// Before the fix, this code was accidentally generating a type check twice.
+/// In between the two checks, code to update `_foo` was overriding a temporary
+/// variable used by the check subexpression, which made the code for the
+/// second check invalid.
+///
+/// The second check should not have been generated, but it was emitted due to
+/// a broken invariant of the SSA generate-at-use logic.
+
+void main() {
+  // `x` which is used multiple times after inilining, so a temporary is used.
+  x.method(40);
+}
+
+dynamic x = Wrapper<int>();
+
+class A<E> {
+  int _foo = 0;
+  List<E> list = [null];
+
+  @pragma('dart2js:tryInline')
+  void internalMethod(E value) {
+    // The update and use of `_foo` requires a separate temporary which reuses
+    // the same variable given to `x` (technically `x` is no longer live).
+    _foo = (_foo + 1) & 0;
+
+    // This use of `value` accidentally contains the second check, which
+    // still refers to the temporary assuming it was `x` and not `_foo`.
+    list[_foo] = value;
+  }
+}
+
+class Wrapper<T> {
+  A<T> a = A<T>();
+
+  @pragma('dart2js:tryInline')
+  method(T t) => a.internalMethod(t);
+}
diff --git a/tests/dart2js/regress_42281_test.dart b/tests/dart2js/regress_42281_test.dart
new file mode 100644
index 0000000..67dc401
--- /dev/null
+++ b/tests/dart2js/regress_42281_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.
+
+class ComponentFactory<T> {
+  @pragma('dart2js:noInline')
+  Type get componentType => T;
+}
+
+var mm = {'String': String, 'int': int};
+var gf1 = ComponentFactory<int>();
+var gf2 = ComponentFactory<dynamic>();
+Map<String, ComponentFactory?> mf = {'RegExp': ComponentFactory<RegExp>()};
+
+ComponentFactory? test(String s, [Map<String, ComponentFactory>? mf2]) {
+  var f = mf[s];
+  if (f == null) {
+    var t = mm[s];
+    if (mf2 != null) f = mf2[s];
+    if (t != null && t != f?.componentType) {
+      print('not match $t');
+      f = gf2;
+    }
+  }
+  return f;
+}
+
+main() {
+  Map<String, ComponentFactory> mf2 = {'int': ComponentFactory<num>()};
+
+  test('String');
+  test('String', mf2);
+  test('int');
+  test('int', mf2);
+  test('RegExp');
+  test('RegExp', mf2);
+}
diff --git a/tests/dart2js/regress_null_aware_test.dart b/tests/dart2js/regress_null_aware_test.dart
new file mode 100644
index 0000000..4ef8dc3
--- /dev/null
+++ b/tests/dart2js/regress_null_aware_test.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.md file.
+
+// Regression test for failure on CFE null-aware encoding.
+
+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) {
+  if (args != null && args.isNotEmpty) new Class().method('', <String>{});
+}
diff --git a/tests/dart2js/regression_2913_test.dart b/tests/dart2js/regression_2913_test.dart
new file mode 100644
index 0000000..85b0916
--- /dev/null
+++ b/tests/dart2js/regression_2913_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+main() {
+  var a = 10;
+  var b = 11;
+
+  for (var i = 0; i < 1; i++) {
+    print('--------');
+    print('a $a');
+    print('b $b');
+    var t = 1;
+    if (i < 20) {
+      t = 2;
+    }
+
+    b = a;
+    a = t;
+  }
+  Expect.equals(2, a);
+  Expect.equals(10, b);
+}
diff --git a/tests/dart2js/replaced_type_variable_test.dart b/tests/dart2js/replaced_type_variable_test.dart
new file mode 100644
index 0000000..e95ea81
--- /dev/null
+++ b/tests/dart2js/replaced_type_variable_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+// This class is inlined away.
+class Class<T> {
+  const Class();
+
+  Type get type => T;
+}
+
+class A {}
+
+@pragma('dart2js:noInline')
+test(o) => Expect.notEquals('dynamic', '$o');
+
+main() {
+  test(const Class<A>().type);
+}
diff --git a/tests/dart2js/return_setter_test.dart b/tests/dart2js/return_setter_test.dart
new file mode 100644
index 0000000..a938b71
--- /dev/null
+++ b/tests/dart2js/return_setter_test.dart
@@ -0,0 +1,27 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  int foo;
+
+  static int invocations;
+
+  static bar() {
+    Expect.equals(0, invocations);
+    invocations++;
+    return 2;
+  }
+}
+
+main() {
+  A.invocations = 0;
+
+  int a = (new A().foo = 2);
+  Expect.equals(2, a);
+
+  a = (new A().foo = A.bar());
+  Expect.equals(2, a);
+}
diff --git a/tests/dart2js/round_constant_folding_test.dart b/tests/dart2js/round_constant_folding_test.dart
new file mode 100644
index 0000000..2c786dd
--- /dev/null
+++ b/tests/dart2js/round_constant_folding_test.dart
@@ -0,0 +1,180 @@
+// Copyright (c) 2016, 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 double PD1 = 0.0;
+const double PD2 = double.minPositive;
+const double PD3 = 2.0 * double.minPositive;
+const double PD4 = 1.18e-38;
+const double PD5 = 1.18e-38 * 2;
+const double PD6 = 0.49999999999999994;
+const double PD7 = 0.5;
+const double PD8 = 0.9999999999999999;
+const double PD9 = 1.0;
+const double PD10 = 1.000000000000001;
+const double PD11 = double.maxFinite;
+
+const double ND1 = -PD1;
+const double ND2 = -PD2;
+const double ND3 = -PD3;
+const double ND4 = -PD4;
+const double ND5 = -PD5;
+const double ND6 = -PD6;
+const double ND7 = -PD7;
+const double ND8 = -PD8;
+const double ND9 = -PD9;
+const double ND10 = -PD10;
+const double ND11 = -PD11;
+
+const X1 = double.infinity;
+const X2 = double.negativeInfinity;
+const X3 = double.nan;
+
+// The following numbers are on the border of 52 bits.
+// For example: 4503599627370499 + 0.5 => 4503599627370500.
+const PQ1 = 4503599627370496.0;
+const PQ2 = 4503599627370497.0;
+const PQ3 = 4503599627370498.0;
+const PQ4 = 4503599627370499.0;
+const PQ5 = 9007199254740991.0;
+const PQ6 = 9007199254740992.0;
+
+const NQ1 = -PQ1;
+const NQ2 = -PQ2;
+const NQ3 = -PQ3;
+const NQ4 = -PQ4;
+const NQ5 = -PQ5;
+const NQ6 = -PQ6;
+
+const int PI1 = 0;
+const int PI2 = 1;
+const int PI3 = 0x1234;
+const int PI4 = 0x12345678;
+const int PI5 = 0x123456789AB;
+const int PI6 = 0x123456789ABCD00 + 0xEF;
+const int PI7 = 0x123456789ABCD * 0x1234567 * 0x1234567 * 0x1234567;
+//const int PI7 = 0x123456789ABCDEF0123456789ABCDEF0123456789ABCDEF;
+
+const int NI1 = 0 - PI1;
+const int NI2 = -PI2;
+const int NI3 = -PI3;
+const int NI4 = -PI4;
+const int NI5 = -PI5;
+const int NI6 = -PI6;
+const int NI7 = -PI7;
+
+/// Ensures that the behaviour of `action()` is the same as `value.round()`.
+@pragma(
+    'dart2js:noInline') // To ensure 'value.round()' has a non-constant receiver.
+check(value, action) {
+  var result1, result2;
+  try {
+    result1 = value.round();
+  } catch (e) {
+    result1 = e;
+  }
+
+  try {
+    result2 = action();
+  } catch (e) {
+    result2 = e;
+  }
+
+  Expect.equals(result1.runtimeType, result2.runtimeType);
+  if (result1 is num) {
+    Expect.equals(result1, result2);
+    Expect.equals(result1 is int, result2 is int);
+  } else {
+    Expect.equals(result1.runtimeType, result2.runtimeType);
+    Expect.isTrue(result1 is Error);
+  }
+}
+
+@pragma('dart2js:noInline')
+void unusedCall(num x) {
+  x.round(); // This call should not be removed since it might throw.
+}
+
+main() {
+  check(PD1, () => PD1.round());
+  check(PD2, () => PD2.round());
+  check(PD3, () => PD3.round());
+  check(PD4, () => PD4.round());
+  check(PD5, () => PD5.round());
+  check(PD6, () => PD6.round());
+  check(PD7, () => PD7.round());
+  check(PD8, () => PD8.round());
+  check(PD9, () => PD9.round());
+  check(PD10, () => PD10.round());
+  check(PD11, () => PD11.round());
+
+  check(ND1, () => ND1.round());
+  check(ND2, () => ND2.round());
+  check(ND3, () => ND3.round());
+  check(ND4, () => ND4.round());
+  check(ND5, () => ND5.round());
+  check(ND6, () => ND6.round());
+  check(ND7, () => ND7.round());
+  check(ND8, () => ND8.round());
+  check(ND9, () => ND9.round());
+  check(ND10, () => ND10.round());
+  check(ND11, () => ND11.round());
+
+  check(X1, () => X1.round());
+  check(X2, () => X2.round());
+  check(X3, () => X3.round());
+
+  check(PQ1, () => PQ1.round());
+  check(PQ2, () => PQ2.round());
+  check(PQ3, () => PQ3.round());
+  check(PQ4, () => PQ4.round());
+  check(PQ5, () => PQ5.round());
+  check(PQ6, () => PQ6.round());
+
+  check(NQ1, () => NQ1.round());
+  check(NQ2, () => NQ2.round());
+  check(NQ3, () => NQ3.round());
+  check(NQ4, () => NQ4.round());
+  check(NQ5, () => NQ5.round());
+  check(NQ6, () => NQ6.round());
+
+  check(PI1, () => PI1.round());
+  check(PI2, () => PI2.round());
+  check(PI3, () => PI3.round());
+  check(PI4, () => PI4.round());
+  check(PI5, () => PI5.round());
+  check(PI6, () => PI6.round());
+  check(PI7, () => PI7.round());
+
+  check(NI1, () => NI1.round());
+  check(NI2, () => NI2.round());
+  check(NI3, () => NI3.round());
+  check(NI4, () => NI4.round());
+  check(NI5, () => NI5.round());
+  check(NI6, () => NI6.round());
+  check(NI7, () => NI7.round());
+
+  // Check that the operation is not removed if it can throw, even if the result
+  // is unused.
+  Expect.throws(() {
+    X1.round();
+  });
+  Expect.throws(() {
+    X2.round();
+  });
+  Expect.throws(() {
+    X3.round();
+  });
+  unusedCall(0);
+  Expect.throws(() {
+    unusedCall(X1);
+  });
+  Expect.throws(() {
+    unusedCall(X2);
+  });
+  Expect.throws(() {
+    unusedCall(X3);
+  });
+}
diff --git a/tests/dart2js/rti_need_for_closure_signature_test.dart b/tests/dart2js/rti_need_for_closure_signature_test.dart
new file mode 100644
index 0000000..61fda79
--- /dev/null
+++ b/tests/dart2js/rti_need_for_closure_signature_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+/// User-facing regression test: ensure we correctly record when a closure needs
+/// runtime type information for a type parameter that may be used or
+/// .runtimeType.
+
+// This test should be run in strong mode to ensure we have not regressed on
+// this failure.
+class Bar<Q> {
+  Q aVar;
+
+  Bar(this.aVar);
+
+  baz(onThing(Q value)) {
+    onThing(aVar);
+  }
+}
+
+foo<T>(Bar<T> bar) {
+  bar.baz((T value) {
+    print('hi');
+  });
+}
+
+main() {
+  foo<int>(new Bar<int>(3));
+}
diff --git a/tests/dart2js/rti_need_for_runtime_type_test.dart b/tests/dart2js/rti_need_for_runtime_type_test.dart
new file mode 100644
index 0000000..48c20e4
--- /dev/null
+++ b/tests/dart2js/rti_need_for_runtime_type_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+/// User-facing regression test: ensure we correctly record when a closure needs
+/// runtime type information for a type parameter that may be used or
+/// .runtimeType.
+class A<T> {
+  final f;
+  A() : f = (() => new C<T>());
+}
+
+class C<T> {}
+
+main() => print(new A<int>().f().runtimeType);
diff --git a/tests/dart2js/runtime_type_closure_equals1_test.dart b/tests/dart2js/runtime_type_closure_equals1_test.dart
new file mode 100644
index 0000000..5defc5e
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals1_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  local1a() {}
+
+  local1b() {}
+
+  local2(int i, String s) => i;
+
+  Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+  Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+  new Class();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals2_test.dart b/tests/dart2js/runtime_type_closure_equals2_test.dart
new file mode 100644
index 0000000..86fe4b2
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals2_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  T local1a<T>() => null;
+
+  T local1b<T>() => null;
+
+  T local2<T>(T t, String s) => t;
+
+  Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+  Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+  new Class();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals3_test.dart b/tests/dart2js/runtime_type_closure_equals3_test.dart
new file mode 100644
index 0000000..ffcd03f
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals3_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+String method() => null;
+
+class Class1<T> {
+  Class1();
+
+  method() {
+    T local1a() => null;
+
+    T local1b() => null;
+
+    T local2(T t, String s) => t;
+
+    Expect.isTrue(local1a.runtimeType == local1b.runtimeType);
+    Expect.isFalse(local1a.runtimeType == local2.runtimeType);
+    Expect.isFalse(local1a.runtimeType == method.runtimeType);
+  }
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  new Class1<int>().method();
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals4_test.dart b/tests/dart2js/runtime_type_closure_equals4_test.dart
new file mode 100644
index 0000000..967b5f6
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals4_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1<T> {
+  Class1();
+
+  method1a() => null;
+
+  method1b() => null;
+
+  method2(t, s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals5_test.dart b/tests/dart2js/runtime_type_closure_equals5_test.dart
new file mode 100644
index 0000000..1b19f8d
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals5_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1<T> {
+  Class1();
+
+  T method1a() => null;
+
+  T method1b() => null;
+
+  T method2(T t, String s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals6_test.dart b/tests/dart2js/runtime_type_closure_equals6_test.dart
new file mode 100644
index 0000000..5090f04
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals6_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+method1a() => null;
+
+method1b() => null;
+
+method2(t, s) => t;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
+  Expect.isFalse(method1a.runtimeType == method2.runtimeType);
+  new Class<int>();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals7_test.dart b/tests/dart2js/runtime_type_closure_equals7_test.dart
new file mode 100644
index 0000000..73348c9
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals7_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+T method1a<T>() => null;
+
+T method1b<T>() => null;
+
+T method2<T>(T t, String s) => t;
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  Expect.isTrue(method1a.runtimeType == method1b.runtimeType);
+  Expect.isFalse(method1a.runtimeType == method2.runtimeType);
+  new Class<int>();
+}
diff --git a/tests/dart2js/runtime_type_closure_equals8_test.dart b/tests/dart2js/runtime_type_closure_equals8_test.dart
new file mode 100644
index 0000000..5f03539
--- /dev/null
+++ b/tests/dart2js/runtime_type_closure_equals8_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1<S> {
+  Class1();
+
+  T method1a<T>() => null;
+
+  T method1b<T>() => null;
+
+  T method2<T>(T t, String s) => t;
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  var c = new Class1<int>();
+
+  Expect.isTrue(c.method1a.runtimeType == c.method1b.runtimeType);
+  Expect.isFalse(c.method1a.runtimeType == c.method2.runtimeType);
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_equals1_test.dart b/tests/dart2js/runtime_type_equals1_test.dart
new file mode 100644
index 0000000..f625055
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals1_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return runtimeType == other.runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/runtime_type_equals2_test.dart b/tests/dart2js/runtime_type_equals2_test.dart
new file mode 100644
index 0000000..ce93178
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals2_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return other.runtimeType == runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/runtime_type_equals3_test.dart b/tests/dart2js/runtime_type_equals3_test.dart
new file mode 100644
index 0000000..f412f86
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals3_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return runtimeType == other?.runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/runtime_type_equals4_test.dart b/tests/dart2js/runtime_type_equals4_test.dart
new file mode 100644
index 0000000..4a1c8d9
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals4_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+
+  bool operator ==(other) {
+    if (identical(this, other)) return true;
+    return other?.runtimeType == runtimeType;
+  }
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> implements Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+main() {
+  Class1a<int> cls1a = new Class1a<int>();
+  Class1a<int> cls1b1 = new Class1b<int>();
+  Class1a<int> cls1b2 = new Class1b<int>();
+  Class1c<int> cls1c = new Class1c<int>();
+  Class2<int> cls2 = new Class2<int>();
+  Expect.isFalse(cls1a == cls1b1);
+  Expect.isTrue(cls1b1 == cls1b2);
+  Expect.isFalse(cls1a == cls1c);
+  Expect.isFalse(cls1a == cls2);
+}
diff --git a/tests/dart2js/runtime_type_equals5_test.dart b/tests/dart2js/runtime_type_equals5_test.dart
new file mode 100644
index 0000000..cd6926e
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals5_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class Class1 {
+  Class1();
+}
+
+class Class2<T> implements Class1 {
+  Class2();
+}
+
+main() {
+  Class1 cls1 = new Class1();
+  Class1 cls2a = new Class2<int>();
+  Class1 cls2b = new Class2<int>();
+  Class1 cls2c = new Class2<String>();
+  var r1 = cls1.runtimeType;
+  var r2a = cls2a.runtimeType;
+  var r2b = cls2b.runtimeType;
+  var r2c = cls2c.runtimeType;
+  Expect.equals(r1, r1);
+  Expect.notEquals(r1, r2a);
+  Expect.notEquals(r1, r2b);
+  Expect.notEquals(r1, r2c);
+  Expect.equals(r2a, r2a);
+  Expect.equals(r2a, r2b);
+  Expect.notEquals(r2a, r2c);
+  Expect.equals(r2b, r2b);
+  Expect.notEquals(r2b, r2c);
+  Expect.equals(r2c, r2c);
+}
diff --git a/tests/dart2js/runtime_type_equals6_test.dart b/tests/dart2js/runtime_type_equals6_test.dart
new file mode 100644
index 0000000..af98ea6
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals6_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a {
+  Class1a();
+}
+
+class Class1b<T> extends Class1a {
+  Class1b();
+}
+
+class Class1c<T> extends Class1a {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+test(Class1a c, Type type) {
+  return c.runtimeType == type;
+}
+
+main() {
+  Expect.isTrue(test(new Class1a(), Class1a));
+  Expect.isFalse(test(new Class1b<int>(), Class1a));
+  Expect.isFalse(test(new Class1c<int>(), Class1a));
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_equals7_test.dart b/tests/dart2js/runtime_type_equals7_test.dart
new file mode 100644
index 0000000..0d2727b
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals7_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a<T> {
+  Class1a();
+}
+
+class Class1b<T> extends Class1a<T> {
+  Class1b();
+}
+
+class Class1c<T> extends Class1a<T> {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+test(Class1a c, Type type) {
+  return c.runtimeType == type;
+}
+
+main() {
+  Expect.isTrue(test(new Class1a(), Class1a));
+  Expect.isFalse(test(new Class1b<int>(), Class1a));
+  Expect.isFalse(test(new Class1c<int>(), Class1a));
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_equals8_test.dart b/tests/dart2js/runtime_type_equals8_test.dart
new file mode 100644
index 0000000..145ceae
--- /dev/null
+++ b/tests/dart2js/runtime_type_equals8_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1a {
+  Class1a();
+}
+
+class Class1b<T> extends Class1a {
+  Class1b();
+}
+
+class Class1c<T> extends Class1a {
+  Class1c();
+}
+
+class Class2<T> {
+  Class2();
+}
+
+class Class3<T> {
+  final Class1a field;
+
+  Class3(this.field);
+}
+
+test(Class3 c, Type type) {
+  return c.field.runtimeType == type;
+}
+
+main() {
+  Expect.isTrue(test(new Class3<int>(new Class1a()), Class1a));
+  Expect.isFalse(test(new Class3<int>(new Class1b<int>()), Class1a));
+  Expect.isFalse(test(new Class3<int>(new Class1c<int>()), Class1a));
+  new Class2<int>();
+}
diff --git a/tests/dart2js/runtime_type_int_test.dart b/tests/dart2js/runtime_type_int_test.dart
new file mode 100644
index 0000000..d98484a
--- /dev/null
+++ b/tests/dart2js/runtime_type_int_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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 that in dart2js, the constant system matches the runtime
+// handling of numbers.
+
+import "package:expect/expect.dart";
+
+main() {
+  var x = 10000000000000000;
+  var y = [x][0];
+  var a = x.runtimeType;
+  var b = y.runtimeType;
+
+  Expect.equals(x, y);
+  Expect.isTrue(x is int);
+  Expect.isTrue(y is int);
+  Expect.equals(x.runtimeType, int);
+  Expect.equals(y.runtimeType, int);
+}
diff --git a/tests/dart2js/runtime_type_test.dart b/tests/dart2js/runtime_type_test.dart
new file mode 100644
index 0000000..f127dbe
--- /dev/null
+++ b/tests/dart2js/runtime_type_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2013, 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.
+
+// dart2jsOptions=--strong
+
+// Test that Type.toString returns nice strings for native classes with
+// reserved names and for raw types.
+
+import "package:expect/expect.dart";
+
+class C<T> {}
+
+class D<X, Y, Z> {}
+
+class Class$With$Dollar {}
+
+void main() {
+  Expect.equals('C<dynamic>', new C().runtimeType.toString());
+  Expect.equals('C<int>', new C<int>().runtimeType.toString());
+  Expect.equals('C<double>', new C<double>().runtimeType.toString());
+  Expect.equals('C<num>', new C<num>().runtimeType.toString());
+  Expect.equals('C<bool>', new C<bool>().runtimeType.toString());
+  Expect.equals('D<dynamic, dynamic, dynamic>', new D().runtimeType.toString());
+  Expect.equals('D<dynamic, int, dynamic>',
+      new D<dynamic, int, dynamic>().runtimeType.toString());
+  D d = new D<dynamic, D, D<dynamic, dynamic, int>>();
+  Expect.equals(
+      'D<dynamic, D<dynamic, dynamic, dynamic>, D<dynamic, dynamic, int>>',
+      d.runtimeType.toString());
+  Expect.equals(r'C<Class$With$Dollar>',
+      new C<Class$With$Dollar>().runtimeType.toString());
+}
diff --git a/tests/dart2js/runtime_type_to_string1_test.dart b/tests/dart2js/runtime_type_to_string1_test.dart
new file mode 100644
index 0000000..d61335f
--- /dev/null
+++ b/tests/dart2js/runtime_type_to_string1_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// dart2jsOptions=--strong --omit-implicit-checks --lax-runtime-type-to-string --experiment-new-rti
+
+import 'package:expect/expect.dart';
+
+class Class<T> {
+  Class();
+}
+
+main() {
+  // Since the type argument of `Class` is only needed for
+  // `.runtimeType.toString()`, it is not reified, and the toString is therefore
+  // 'Class<erased>'.
+  String className = (Class).toString();
+  className = className.substring(0, className.indexOf('<'));
+  String erasedName = '$className<erased>';
+  Expect.equals(erasedName, new Class().runtimeType.toString());
+  Expect.equals(erasedName, new Class<int>().runtimeType.toString());
+}
diff --git a/tests/dart2js/send_test.dart b/tests/dart2js/send_test.dart
new file mode 100644
index 0000000..3c98c51
--- /dev/null
+++ b/tests/dart2js/send_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+class A {
+  int foo() {
+    return 42;
+  }
+}
+
+void main() {
+  int i = new A().foo();
+  print(i);
+  if (i == 42) {
+    print('pass');
+  } else {
+    throw "error";
+  }
+}
diff --git a/tests/dart2js/simple_string_constant_test.dart b/tests/dart2js/simple_string_constant_test.dart
new file mode 100644
index 0000000..746e4d2
--- /dev/null
+++ b/tests/dart2js/simple_string_constant_test.dart
@@ -0,0 +1,11 @@
+// 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 "package:expect/expect.dart";
+
+const String m = "\u{21}";
+
+main() {
+  Expect.equals('!', m);
+}
diff --git a/tests/dart2js/source_mapping_crash_source.dart b/tests/dart2js/source_mapping_crash_source.dart
new file mode 100644
index 0000000..78f15e3
--- /dev/null
+++ b/tests/dart2js/source_mapping_crash_source.dart
@@ -0,0 +1,56 @@
+// 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.
+
+part of source_mapping_crash_test;
+
+/*******************************************************************************
+ * Long comment to make positions in this file exceed those in
+ * 'source_mapping_crash_test.dart'.
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ *******************************************************************************
+ */
+class Super {
+  final sb = new StringBuffer();
+  Super(var y);
+}
diff --git a/tests/dart2js/source_mapping_crash_test.dart b/tests/dart2js/source_mapping_crash_test.dart
new file mode 100644
index 0000000..38ca4c6
--- /dev/null
+++ b/tests/dart2js/source_mapping_crash_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+library source_mapping_crash_test;
+
+part 'source_mapping_crash_source.dart';
+
+class Sub extends Super {
+  Sub(var x) : super(x.y);
+}
+
+class X {
+  var y;
+}
+
+main() {
+  new Sub(new X());
+}
diff --git a/tests/dart2js/statements_test.dart b/tests/dart2js/statements_test.dart
new file mode 100644
index 0000000..7e45397
--- /dev/null
+++ b/tests/dart2js/statements_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+void main() {
+  print(3);
+  print(4);
+  if (true) {
+    print('hest');
+  }
+  if (false) {
+    print('hest');
+  } else {
+    print('fisk');
+  }
+  int foo() {}
+  int i = 0;
+
+  for (int j = 0; j < 10; j += 1) {
+    print('kat');
+  }
+
+  if (false) throw;
+
+  if (false) throw 'dwarf';
+}
diff --git a/tests/dart2js/static_field2_test.dart b/tests/dart2js/static_field2_test.dart
new file mode 100644
index 0000000..d2f5cc7
--- /dev/null
+++ b/tests/dart2js/static_field2_test.dart
@@ -0,0 +1,14 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static int b;
+}
+
+main() {
+  A.b = 42;
+  Expect.equals(42, A.b);
+}
diff --git a/tests/dart2js/static_field_test.dart b/tests/dart2js/static_field_test.dart
new file mode 100644
index 0000000..63c96af
--- /dev/null
+++ b/tests/dart2js/static_field_test.dart
@@ -0,0 +1,28 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static int b;
+
+  setA(val) {
+    b = val;
+  }
+
+  bar() {
+    return b;
+  }
+
+  bar2() {
+    return A.b;
+  }
+}
+
+main() {
+  A a = new A();
+  a.setA(42);
+  Expect.equals(42, a.bar());
+  Expect.equals(42, a.bar2());
+}
diff --git a/tests/dart2js/static_method2_test.dart b/tests/dart2js/static_method2_test.dart
new file mode 100644
index 0000000..ab6517f
--- /dev/null
+++ b/tests/dart2js/static_method2_test.dart
@@ -0,0 +1,15 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static foo(res) {
+    return res;
+  }
+}
+
+main() {
+  Expect.equals(42, A.foo(42));
+}
diff --git a/tests/dart2js/static_method_test.dart b/tests/dart2js/static_method_test.dart
new file mode 100644
index 0000000..a65e0b6
--- /dev/null
+++ b/tests/dart2js/static_method_test.dart
@@ -0,0 +1,25 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  static foo(res) {
+    return res;
+  }
+
+  bar(res) {
+    return foo(res);
+  }
+
+  bar2(res) {
+    return A.foo(res);
+  }
+}
+
+main() {
+  A a = new A();
+  Expect.equals(42, a.bar(42));
+  Expect.equals(43, a.bar2(43));
+}
diff --git a/tests/dart2js/static_var_no_initializer_test.dart b/tests/dart2js/static_var_no_initializer_test.dart
new file mode 100644
index 0000000..e6cb720
--- /dev/null
+++ b/tests/dart2js/static_var_no_initializer_test.dart
@@ -0,0 +1,35 @@
+// 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 "package:expect/expect.dart";
+
+int one;
+int x;
+
+void testOne() {
+  Expect.equals(1, one);
+}
+
+void testX(var expected) {
+  Expect.equals(expected, x);
+}
+
+void increaseX() {
+  x = x + 1;
+}
+
+void main() {
+  one = 1;
+  x = 5;
+  Expect.equals(1, one);
+  testOne();
+  Expect.equals(5, x);
+  testX(5);
+  x = x + 1;
+  Expect.equals(6, x);
+  testX(6);
+  increaseX();
+  Expect.equals(7, x);
+  testX(7);
+}
diff --git a/tests/dart2js/static_var_test.dart b/tests/dart2js/static_var_test.dart
new file mode 100644
index 0000000..1b3a9fc
--- /dev/null
+++ b/tests/dart2js/static_var_test.dart
@@ -0,0 +1,33 @@
+// 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 "package:expect/expect.dart";
+
+int one = 1;
+int x = 5;
+
+void testOne() {
+  Expect.equals(1, one);
+}
+
+void testX(var expected) {
+  Expect.equals(expected, x);
+}
+
+void increaseX() {
+  x = x + 1;
+}
+
+void main() {
+  Expect.equals(1, one);
+  testOne();
+  Expect.equals(5, x);
+  testX(5);
+  x = x + 1;
+  Expect.equals(6, x);
+  testX(6);
+  increaseX();
+  Expect.equals(7, x);
+  testX(7);
+}
diff --git a/tests/dart2js/string_escape_test.dart b/tests/dart2js/string_escape_test.dart
new file mode 100644
index 0000000..3bd1b99
--- /dev/null
+++ b/tests/dart2js/string_escape_test.dart
@@ -0,0 +1,148 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test that string escapes work correctly.
+
+testSingleCharacterEscapes() {
+  List/*<String>*/ examples = [
+    "\b\f\n\r\t\v",
+    '\b\f\n\r\t\v',
+    """\b\f\n\r\t\v""",
+    '''\b\f\n\r\t\v''',
+  ];
+  List values = [8, 12, 10, 13, 9, 11];
+  for (String s in examples) {
+    Expect.equals(6, s.length);
+    for (int i = 0; i < 6; i++) {
+      Expect.equals(values[i], s.codeUnitAt(i));
+    }
+  }
+
+  // An escaped quote isn't part of a multiline end quote.
+  Expect.equals(r'"', """\"""");
+  Expect.equals(r"'", '''\'''');
+  Expect.equals(r'" "', """" \"""");
+  Expect.equals(r"' '", '''' \'''');
+  Expect.equals(r'"" ', """"" """);
+  Expect.equals(r"'' ", ''''' ''');
+}
+
+testXEscapes() {
+  var allBytes =
+      "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+      "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
+      "\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
+      "\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
+      "\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
+      "\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
+      "\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
+      "\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
+      "\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
+      "\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
+      "\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
+      "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
+      "\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
+      "\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
+      "\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
+      "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff";
+  Expect.equals(256, allBytes.length);
+  for (int i = 0; i < 256; i++) {
+    Expect.equals(i, allBytes.codeUnitAt(i));
+  }
+}
+
+testUEscapes() {
+  List /*String*/ examples = [
+    "\u0000\u0001\u0022\u0027\u005c\u007f\u0080\u00ff"
+        "\u0100\u1000\ud7ff\ue000\uffff",
+    '\u0000\u0001\u0022\u0027\u005c\u007f\u0080\u00ff'
+        '\u0100\u1000\ud7ff\ue000\uffff',
+    """\u0000\u0001\u0022\u0027\u005c\u007f\u0080\u00ff"""
+        """\u0100\u1000\ud7ff\ue000\uffff""",
+    '''\u0000\u0001\u0022\u0027\u005c\u007f\u0080\u00ff'''
+        '''\u0100\u1000\ud7ff\ue000\uffff'''
+  ];
+  List/*<int>*/ values = [
+    0,
+    1,
+    0x22,
+    0x27,
+    0x5c,
+    0x7f,
+    0x80,
+    0xff,
+    0x100,
+    0x1000,
+    0xd7ff,
+    0xe000,
+    0xffff
+  ];
+  for (String s in examples) {
+    Expect.equals(values.length, s.length);
+    for (int i = 0; i < values.length; i++) {
+      Expect.equals(values[i], s.codeUnitAt(i));
+    }
+  }
+  // No characters above 0xffff until Leg supports that.
+  var long = "\u{0}\u{00}\u{000}\u{0000}\u{00000}\u{000000}"
+      "\u{1}\u{01}\u{001}\u{00001}"
+      "\u{ffff}\u{0ffff}\u{00ffff}";
+  var longValues = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0xffff, 0xffff, 0xffff];
+  Expect.equals(longValues.length, long.length);
+  for (int i = 0; i < longValues.length; i++) {
+    Expect.equals(longValues[i], long.codeUnitAt(i));
+  }
+}
+
+testIdentityEscapes() {
+  // All non-control ASCII characters escaped, except those with special
+  // meaning: b, f, n, r, t, u, v, and x (replaced by \x00).
+  var asciiLiterals =
+      "\ \!\"\#\$\%\&\'\(\)\*\+\,\-\.\/\0\1\2\3\4\5\6\7\8\9\:\;\<\=\>"
+      "\?\@\A\B\C\D\E\F\G\H\I\J\K\L\M\N\O\P\Q\R\S\T\U\V\W\X\Y\Z\[\\\]"
+      "\^\_\`\a\x00\c\d\e\x00\g\h\i\j\k\l\m\x00\o\p\q\x00\s\x00\x00\x00"
+      "\w\x00\y\z\{\|\}\~\";
+
+  Expect.equals(128 - 32, asciiLiterals.length);
+  for (int i = 32; i < 128; i++) {
+    int code = asciiLiterals.codeUnitAt(i - 32);
+    if (code != 0) {
+      Expect.equals(i, code);
+    }
+  }
+}
+
+testQuotes() {
+  // The string [ "' ].
+  String bothQuotes = ' "' "' ";
+  Expect.equals(bothQuotes, " \"' ");
+  Expect.equals(bothQuotes, ' "\' ');
+  Expect.equals(bothQuotes, """ "' """);
+  Expect.equals(bothQuotes, ''' "' ''');
+  Expect.equals(bothQuotes, r""" "' """);
+  Expect.equals(bothQuotes, r''' "' ''');
+}
+
+testRawStrings() {
+  String raw1 = r'\x00';
+  Expect.equals(4, raw1.length);
+  Expect.equals(0x5c, raw1.codeUnitAt(0));
+}
+
+main() {
+  // Test \x??.
+  testXEscapes();
+  // Test \u???? and \u{?+}.
+  testUEscapes();
+  // Test \b, \f, \n, \r, \t, \v.
+  testSingleCharacterEscapes();
+  // Test all other single character (identity) escaeps.
+  testIdentityEscapes();
+  // Test that quotes are handled correctly.
+  testQuotes();
+  // Test that raw strings are raw.
+  testRawStrings();
+}
diff --git a/tests/dart2js/string_interpolation_dynamic_test.dart b/tests/dart2js/string_interpolation_dynamic_test.dart
new file mode 100644
index 0000000..115f070
--- /dev/null
+++ b/tests/dart2js/string_interpolation_dynamic_test.dart
Binary files differ
diff --git a/tests/dart2js/string_interpolation_opt1_test.dart b/tests/dart2js/string_interpolation_opt1_test.dart
new file mode 100644
index 0000000..60e92d4
--- /dev/null
+++ b/tests/dart2js/string_interpolation_opt1_test.dart
@@ -0,0 +1,56 @@
+// Copyright (c) 2014, 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 'dart:math';
+
+// Test that String interpolation works in some optimized cases.
+
+bool get inscrutableFalse => new Random().nextDouble() > 2;
+
+returnsNullOrString(x) {
+  if (inscrutableFalse) return 'hi';
+  if (inscrutableFalse) return null;
+  return x;
+}
+
+returnsNullOrInt(x) {
+  if (inscrutableFalse) return 123;
+  if (inscrutableFalse) return null;
+  return x;
+}
+
+spoil(a) {
+  a[3] = 123;
+  a[4] = 'ddd';
+}
+
+void testString() {
+  var a = new List(100); // 'null' values in here are JavaScript undefined.
+  spoil(a);
+  var s = returnsNullOrString('hi');
+  var x = a[2];
+  if (x == null) {
+    s = returnsNullOrString(x);
+  }
+
+  Expect.equals('s: null', 's: $s');
+}
+
+void testInt() {
+  var a = new List(100); // 'null' values in here are JavaScript undefined.
+  spoil(a);
+  var s = returnsNullOrInt(123);
+  var x = a[2];
+  if (x == null) {
+    s = returnsNullOrInt(x);
+  }
+
+  Expect.equals('s: null', 's: $s');
+}
+
+void main() {
+  testInt();
+  testString();
+}
diff --git a/tests/dart2js/string_interpolation_test.dart b/tests/dart2js/string_interpolation_test.dart
new file mode 100644
index 0000000..027128a
--- /dev/null
+++ b/tests/dart2js/string_interpolation_test.dart
Binary files differ
diff --git a/tests/dart2js/super_call_test.dart b/tests/dart2js/super_call_test.dart
new file mode 100644
index 0000000..c9f777f
--- /dev/null
+++ b/tests/dart2js/super_call_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, 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";
+
+class A {
+  foo() => "A.foo${baz()}";
+  baz() => "A.baz";
+  hest(String s, int i) => "$s$i";
+}
+
+class B extends A {
+  foo() => "B.foo${super.foo()}";
+  baz() => "B.baz";
+  hest(s, i) => "B.hest${super.hest(s, i)}";
+}
+
+main() {
+  B b = new B();
+  Expect.equals("B.fooA.fooB.baz", b.foo());
+  Expect.equals("B.hestfisk42", b.hest('fisk', 42));
+}
diff --git a/tests/dart2js/super_constructor1_test.dart b/tests/dart2js/super_constructor1_test.dart
new file mode 100644
index 0000000..a0aaf86
--- /dev/null
+++ b/tests/dart2js/super_constructor1_test.dart
@@ -0,0 +1,41 @@
+// 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 "package:expect/expect.dart";
+
+String message;
+
+class A {
+  int x;
+  A(i) : x = i {
+    message = '${message}A($i)';
+  }
+}
+
+class B extends A {
+  int y;
+  B(i)
+      : y = i++,
+        super(i + 5) {
+    message = '${message}B($i)';
+  }
+}
+
+class C extends B {
+  var z;
+  C(i)
+      : z = i,
+        super(i * 3) {
+    message = '${message}C($i)';
+  }
+}
+
+main() {
+  message = '';
+  var c = new C(7);
+  Expect.equals(27, c.x);
+  Expect.equals(21, c.y);
+  Expect.equals(7, c.z);
+  Expect.equals('A(27)B(22)C(7)', message);
+}
diff --git a/tests/dart2js/super_constructor2_test.dart b/tests/dart2js/super_constructor2_test.dart
new file mode 100644
index 0000000..73ac20a
--- /dev/null
+++ b/tests/dart2js/super_constructor2_test.dart
@@ -0,0 +1,23 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  int x;
+  A() : x = 27;
+}
+
+class B extends A {
+  B();
+}
+
+class C extends A {}
+
+main() {
+  A a = new B();
+  Expect.equals(27, a.x);
+  a = new C();
+  Expect.equals(27, a.x);
+}
diff --git a/tests/dart2js/supermixin/supermixin10_test.dart b/tests/dart2js/supermixin/supermixin10_test.dart
new file mode 100644
index 0000000..361e98b
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin10_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method1(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method1(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method1(a) => super.method1('M$a');
+  method2(a) => 'M$a';
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method1('C'));
+  Expect.equals("MC", c.method2('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin11_test.dart b/tests/dart2js/supermixin/supermixin11_test.dart
new file mode 100644
index 0000000..efd86c0
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin11_test.dart
@@ -0,0 +1,39 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA1 {
+  method1(a) => 'A1.m1$a';
+}
+
+class SuperA2 {
+  method2(a) => 'A2.m2$a';
+}
+
+class SuperA {
+  method1(a) => 'A.m1$a';
+  method2(a) => 'A.m2$a';
+}
+
+class SuperB1 extends SuperA implements SuperA1 {
+  method1(a) => 'B1.m1$a';
+}
+
+class SuperB2 extends SuperB1 implements SuperA2 {
+  method2(a) => 'B2.m2$a';
+}
+
+mixin Mixin on SuperA1, SuperA2 {
+  method1(a) => super.method1('M$a');
+  method2(a) => super.method2('M$a');
+}
+
+class Class extends SuperB2 with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("B1.m1MC", c.method1('C'));
+  Expect.equals("B2.m2MC", c.method2('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin12_test.dart b/tests/dart2js/supermixin/supermixin12_test.dart
new file mode 100644
index 0000000..81fa7f29
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin12_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a, [b = 'foo']) => 'A$a$b';
+}
+
+class SuperB extends SuperA {
+  method(a, [b = 'foo']) => 'B$a$b';
+}
+
+mixin Mixin on SuperA {
+  method2(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMCfoo", c.method2('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin13_test.dart b/tests/dart2js/supermixin/supermixin13_test.dart
new file mode 100644
index 0000000..142e893
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin13_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a, [b = 'foo']) => 'B$a$b';
+}
+
+mixin Mixin on SuperA {
+  method2(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMCfoo", c.method2('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin14_test.dart b/tests/dart2js/supermixin/supermixin14_test.dart
new file mode 100644
index 0000000..224baa4
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin14_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB implements SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+} 
\ No newline at end of file
diff --git a/tests/dart2js/supermixin/supermixin15_test.dart b/tests/dart2js/supermixin/supermixin15_test.dart
new file mode 100644
index 0000000..a2df040
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin15_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+} 
\ No newline at end of file
diff --git a/tests/dart2js/supermixin/supermixin16_test.dart b/tests/dart2js/supermixin/supermixin16_test.dart
new file mode 100644
index 0000000..09e0267
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin16_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA1 {}
+
+class SuperA2 {}
+
+class InterfaceA {}
+
+mixin MixinA on SuperA1, SuperA2 implements InterfaceA {}
+
+class SuperB1<T> {}
+
+class SuperB2<T> {}
+
+class SuperB3<T> {}
+
+class InterfaceB<T> {}
+
+mixin MixinB<T> on SuperB1<List<T>>, SuperB2<int>, SuperB3<T>
+    implements InterfaceB<Map<int, T>> {}
+
+class C extends SuperA1 with SuperA2 {}
+
+main() {
+  var listA = <MixinA>[];
+  Expect.isTrue(listA is List<MixinA>);
+  Expect.isTrue(listA is List<SuperA1>);
+  Expect.isTrue(listA is List<SuperA2>);
+  Expect.isTrue(listA is List<InterfaceA>);
+
+  var listB = <MixinB<String>>[];
+  Expect.isTrue(listB is List<MixinB<String>>);
+  Expect.isTrue(listB is List<SuperB1<List<String>>>);
+  Expect.isTrue(listB is List<SuperB2<int>>);
+  Expect.isTrue(listB is List<SuperB3<String>>);
+  Expect.isTrue(listB is List<InterfaceB<Map<int, String>>>);
+
+} 
\ No newline at end of file
diff --git a/tests/dart2js/supermixin/supermixin17_test.dart b/tests/dart2js/supermixin/supermixin17_test.dart
new file mode 100644
index 0000000..14aa9e3
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin17_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class S {}
+
+class M {}
+
+class SuperC = S with M;
+
+class SuperA {}
+
+class SuperB extends SuperA implements SuperC {}
+
+mixin Mixin on SuperC, SuperA {}
+
+class Class extends SuperB with Mixin {}
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+test(c) {
+  Expect.isTrue(c is Mixin, "Unexpected result for $c is Mixin");
+  Expect.isTrue(c is SuperC, "Unexpected result for $c is SuperC");
+  Expect.isTrue(c is SuperA, "Unexpected result for $c is SuperA");
+  Expect.isTrue(c is S, "Unexpected result for $c is S");
+  Expect.isTrue(c is M, "Unexpected result for $c is M");
+}
+
+main() {
+  new SuperC();
+  test(new Class());
+}
diff --git a/tests/dart2js/supermixin/supermixin18_test.dart b/tests/dart2js/supermixin/supermixin18_test.dart
new file mode 100644
index 0000000..d29409c
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin18_test.dart
@@ -0,0 +1,34 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class S {}
+
+class M {}
+
+class SuperC = S with M;
+
+class SuperA {}
+
+class SuperB extends SuperA implements SuperC {}
+
+mixin Mixin on SuperA, SuperC {}
+
+class Class extends SuperB with Mixin {}
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+test(c) {
+  Expect.isTrue(c is Mixin, "Unexpected result for $c is Mixin");
+  Expect.isTrue(c is SuperC, "Unexpected result for $c is SuperC");
+  Expect.isTrue(c is SuperA, "Unexpected result for $c is SuperA");
+  Expect.isTrue(c is S, "Unexpected result for $c is S");
+  Expect.isTrue(c is M, "Unexpected result for $c is M");
+}
+
+main() {
+  new SuperC();
+  test(new Class());
+}
diff --git a/tests/dart2js/supermixin/supermixin1_test.dart b/tests/dart2js/supermixin/supermixin1_test.dart
new file mode 100644
index 0000000..6f6d16a
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin1_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin2_test.dart b/tests/dart2js/supermixin/supermixin2_test.dart
new file mode 100644
index 0000000..846fe88
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin2_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  method(a) => 'A$a';
+}
+
+class SuperB extends SuperA {
+  method(a) => 'B$a';
+}
+
+mixin Mixin on SuperA {
+  method(a) => super.method('M$a');
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  Expect.equals("BMC", c.method('C'));
+}
diff --git a/tests/dart2js/supermixin/supermixin3_test.dart b/tests/dart2js/supermixin/supermixin3_test.dart
new file mode 100644
index 0000000..c5bfca0
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin3_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  get getter => 'A';
+}
+
+class SuperB extends SuperA {
+  get getter => 'B';
+}
+
+mixin Mixin on SuperA {
+  get getter => super.getter;
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  Expect.equals("B", c.getter);
+}
diff --git a/tests/dart2js/supermixin/supermixin4_test.dart b/tests/dart2js/supermixin/supermixin4_test.dart
new file mode 100644
index 0000000..a450c76
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin4_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  get getter => 'A';
+}
+
+class SuperB extends SuperA {
+  get getter => 'B';
+}
+
+mixin Mixin on SuperA {
+  get getter => super.getter;
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  Expect.equals("B", c.getter);
+}
diff --git a/tests/dart2js/supermixin/supermixin5_test.dart b/tests/dart2js/supermixin/supermixin5_test.dart
new file mode 100644
index 0000000..41ea90c
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin5_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  int field = 0;
+
+  set setter(int a) => field = a;
+}
+
+class SuperB extends SuperA {
+  set setter(int a) => field = a + 1;
+}
+
+mixin Mixin on SuperA {
+  set setter(int a) => super.setter = a;
+}
+
+class Class extends SuperB with Mixin {}
+
+main() {
+  var c = new Class();
+  c.setter = 41;
+  Expect.equals(42, c.field);
+}
diff --git a/tests/dart2js/supermixin/supermixin6_test.dart b/tests/dart2js/supermixin/supermixin6_test.dart
new file mode 100644
index 0000000..86a998f
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin6_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA {
+  int field = 0;
+
+  set setter(int a) => field = a;
+}
+
+class SuperB extends SuperA {
+  set setter(int a) => field = a + 1;
+}
+
+mixin Mixin on SuperA {
+  set setter(int a) => super.setter = a;
+}
+
+class Class = SuperB with Mixin;
+
+main() {
+  var c = new Class();
+  c.setter = 41;
+  Expect.equals(42, c.field);
+}
diff --git a/tests/dart2js/supermixin/supermixin7_test.dart b/tests/dart2js/supermixin/supermixin7_test.dart
new file mode 100644
index 0000000..80e0a17
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin7_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T> {
+  method() => null;
+}
+
+class SuperB<T> extends SuperA<T> {
+  method() => T;
+}
+
+mixin Mixin<T> on SuperA<T> {
+  method() => super.method();
+}
+
+class Class<T> extends SuperB<T> with Mixin<T> {}
+
+main() {
+  var c1 = new Class<String>();
+  var c2 = new Class<int>();
+  Expect.equals(String, c1.method());
+  Expect.equals(int, c2.method());
+}
diff --git a/tests/dart2js/supermixin/supermixin8_test.dart b/tests/dart2js/supermixin/supermixin8_test.dart
new file mode 100644
index 0000000..42af785
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin8_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T, S> {
+  method() => T;
+}
+
+class SuperB<T, S> extends SuperA<T, S> {
+  method() => S;
+}
+
+mixin Mixin<T, S> on SuperA<T, S> {
+  method() => super.method();
+}
+
+class Class<T, S> extends SuperB<T, S> with Mixin<T, S> {}
+
+main() {
+  var c1 = new Class<int, String>();
+  var c2 = new Class<String, int>();
+  Expect.equals(String, c1.method());
+  Expect.equals(int, c2.method());
+}
diff --git a/tests/dart2js/supermixin/supermixin9_test.dart b/tests/dart2js/supermixin/supermixin9_test.dart
new file mode 100644
index 0000000..41a688f
--- /dev/null
+++ b/tests/dart2js/supermixin/supermixin9_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class SuperA<T> {
+  method() => T;
+}
+
+class SuperB extends SuperA<int> {
+  method() => String;
+}
+
+mixin Mixin<T> on SuperA<T> {
+  method() => super.method();
+}
+
+class Class extends SuperB with Mixin<int> {}
+
+main() {
+  var c = new Class();
+  Expect.equals(String, c.method());
+}
diff --git a/tests/dart2js/switch_equals_test.dart b/tests/dart2js/switch_equals_test.dart
new file mode 100644
index 0000000..cdf6607
--- /dev/null
+++ b/tests/dart2js/switch_equals_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+class SuperClass {
+  const SuperClass();
+
+  bool operator ==(Object other);
+}
+
+class Class extends SuperClass {
+  const Class();
+
+  bool operator ==(Object other);
+}
+
+class SubClass extends Class {
+  const SubClass();
+
+  bool operator ==(Object other) => false;
+}
+
+main() {
+  // This test verifies that when overriding `==` it is a compile time error to
+  // use that class as a key in a switch, but only if the override provides a
+  // body. However, with NNBD, all of these switches became compile time errors
+  // so now we cast `null` as `dynamic` to get these first two switches past
+  // the compiler.
+  switch (null as dynamic) {
+    case const SuperClass():
+      break;
+    default:
+  }
+  switch (null as dynamic) {
+    case const Class():
+      break;
+    default:
+  }
+  switch (null as dynamic) {
+    case const SubClass(): //# 01: compile-time error
+      break; //# 01: continued
+    default:
+  }
+  switch (null) {
+    case null:
+      break;
+    default:
+  }
+}
diff --git a/tests/dart2js/switch_test.dart b/tests/dart2js/switch_test.dart
new file mode 100644
index 0000000..9e5eef1
--- /dev/null
+++ b/tests/dart2js/switch_test.dart
@@ -0,0 +1,143 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+switcher(val) {
+  var x = 0;
+  switch (val) {
+    case 1:
+      x = 100;
+      break;
+    case 2:
+      x = 200;
+      break;
+    case 3:
+      x = 300;
+      break;
+    default:
+      return 400;
+      break; // Intentional dead code (regression test for crash).
+  }
+  return x;
+}
+
+// Check unambiguated grammar allowing multiple labels per case/default.
+switcher2(val) {
+  var x = 0;
+  switch (val) {
+    foo:
+    bar:
+    case 1:
+    baz:
+    case 2:
+      fez:
+      {
+        x = 100;
+        break fez;
+      }
+      break;
+    hest:
+    fisk:
+    case 3:
+    case 4:
+    svin:
+    default:
+      barber:
+      {
+        if (val > 2) {
+          x = 200;
+          break;
+        } else {
+          // Enable when continue to switch-case is implemented.
+          continue hest;
+        }
+      }
+  }
+  return x;
+}
+
+var x = 0;
+
+@pragma('dart2js:noInline')
+switcher3(val) {
+  switch (val) {
+    case 1:
+    default:
+      incrementX();
+  }
+}
+
+// Tests that switch cases work when there is a case that calls a function
+// that always throws, and there is no break in the switch statement.
+switcher4(val) {
+  switch (val) {
+    case 1:
+      return 100;
+    case 2: _throw(); //# 00: compile-time error
+    case 3:
+      _throw();
+      break;
+    default:
+      return 300;
+  }
+}
+
+_throw() {
+  throw 'exception';
+}
+
+// Tests that we generate a break after the last case if it isn't default.
+switcher5(val) {
+  var x = 0;
+  switch(val) {
+    case 1:
+      return 100;
+    case 2:
+      return 200;
+    case 3:
+      x = 300;
+  }
+  return x;
+}
+
+incrementX() {
+  x++;
+}
+
+badswitches(val) {
+  // Test some badly formed switch bodies.
+  // 01 - a label/statement without a following case/default.
+  // 02 - a label without a following case/default or statement.
+  switch (val) {
+    foo: break; //    //# 01: compile-time error
+    case 2: //        //# 02: compile-time error
+    foo: //           //# 02: continued
+  }
+}
+
+main() {
+  Expect.equals(100, switcher(1));
+  Expect.equals(200, switcher(2));
+  Expect.equals(300, switcher(3));
+  Expect.equals(400, switcher(4));
+
+  Expect.equals(100, switcher2(1));
+  Expect.equals(100, switcher2(2));
+  Expect.equals(200, switcher2(3));
+  Expect.equals(200, switcher2(4));
+  Expect.equals(200, switcher2(5));
+
+
+  switcher3(1);
+  Expect.equals(1, x);
+
+  Expect.equals(100, switcher4(1));
+
+  Expect.equals(100, switcher5(1));
+  Expect.equals(200, switcher5(2));
+  Expect.equals(300, switcher5(3));
+
+  badswitches(42);
+}
diff --git a/tests/dart2js/tear_off_types_test.dart b/tests/dart2js/tear_off_types_test.dart
new file mode 100644
index 0000000..d7f6c41
--- /dev/null
+++ b/tests/dart2js/tear_off_types_test.dart
@@ -0,0 +1,143 @@
+// 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.
+
+// dart2jsOptions=--omit-implicit-checks
+
+import 'package:expect/expect.dart';
+
+main() {
+  test1();
+  test2();
+  test3();
+  test4();
+  test5();
+  test6();
+  test7();
+}
+
+class A1<T> {}
+
+class B1 extends A1<int> {}
+
+@pragma('dart2js:noInline')
+test1() {
+  Expect.isTrue(_test1(method1a));
+  Expect.isTrue(_test1(method1b));
+  Expect.isFalse(_test1(method1c));
+}
+
+B1 method1a() => null;
+A1<int> method1b() => null;
+A1<String> method1c() => null;
+
+@pragma('dart2js:noInline')
+bool _test1(f) => f is A1<int> Function();
+
+class A2<T> {}
+
+class B2 extends A2<int> {}
+
+@pragma('dart2js:noInline')
+test2() {
+  Expect.isFalse(_test2(method2a));
+  Expect.isTrue(_test2(method2b));
+  Expect.isFalse(_test2(method2c));
+}
+
+void method2a(B2 b) {}
+void method2b(A2<int> a) {}
+void method2c(A2<String> a) {}
+
+@pragma('dart2js:noInline')
+bool _test2(f) => f is void Function(A2<int>);
+
+class A3<T> {}
+
+class B3 extends A3<int> {}
+
+@pragma('dart3js:noInline')
+test3() {
+  Expect.isTrue(_test3(method3a));
+  Expect.isTrue(_test3(method3b));
+  Expect.isFalse(_test3(method3c));
+}
+
+void method3a(B3 b) {}
+void method3b(A3<int> a) {}
+void method3c(A3<String> a) {}
+
+@pragma('dart3js:noInline')
+_test3(f) => f is void Function(B3);
+
+class A4<T> {}
+
+class B4 extends A4<int> {}
+
+@pragma('dart4js:noInline')
+test4() {
+  Expect.isTrue(_test4(method4a));
+  Expect.isFalse(_test4(method4b));
+  Expect.isFalse(_test4(method4c));
+}
+
+B4 method4a() => null;
+A4<int> method4b() => null;
+A4<String> method4c() => null;
+
+@pragma('dart4js:noInline')
+_test4(f) => f is B4 Function();
+
+class A5<T> {}
+
+class B5 extends A5<int> {}
+
+@pragma('dart2js:noInline')
+test5() {
+  Expect.isTrue(_test5(method5a));
+  Expect.isTrue(_test5(method5b));
+  Expect.isFalse(_test5(method5c));
+}
+
+void method5a(void Function(B5) f) => null;
+void method5b(void Function(A5<int>) f) => null;
+void method5c(void Function(A5<String>) f) => null;
+
+@pragma('dart2js:noInline')
+bool _test5(f) => f is void Function(void Function(A5<int>));
+
+class A6<T> {}
+
+class B6 extends A6<int> {}
+
+@pragma('dart6js:noInline')
+test6() {
+  Expect.isTrue(_test6(method6a));
+  Expect.isTrue(_test6(method6b));
+  Expect.isFalse(_test6(method6c));
+}
+
+void Function(B6) method6a() => null;
+void Function(A6<int>) method6b() => null;
+void Function(A6<String>) method6c() => null;
+
+@pragma('dart6js:noInline')
+_test6(f) => f is void Function(B6) Function();
+
+class A7<T> {}
+
+class B7 extends A7<int> {}
+
+@pragma('dart7js:noInline')
+test7() {
+  Expect.isTrue(_test7(method7a));
+  Expect.isFalse(_test7(method7b));
+  Expect.isFalse(_test7(method7c));
+}
+
+void method7a(void Function(B7) f) => null;
+void method7b(void Function(A7<int>) f) => null;
+void method7c(void Function(A7<String>) f) => null;
+
+@pragma('dart7js:noInline')
+_test7(f) => f is void Function(void Function(B7));
diff --git a/tests/dart2js/this_phi_elimination_test.dart b/tests/dart2js/this_phi_elimination_test.dart
new file mode 100644
index 0000000..80f7bb0
--- /dev/null
+++ b/tests/dart2js/this_phi_elimination_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo(a) {
+    while (false) {
+      // This call will make the builder want to put [this] as a phi.
+      foo(0);
+    }
+    // This computation makes sure there will be a bailout version.
+    return a + 42;
+  }
+}
+
+main() {
+  Expect.equals(42, new A().foo(0));
+  Expect.throws(() => new A().foo(""));
+}
diff --git a/tests/dart2js/this_redirecting_constructor_test.dart b/tests/dart2js/this_redirecting_constructor_test.dart
new file mode 100644
index 0000000..feeedd4
--- /dev/null
+++ b/tests/dart2js/this_redirecting_constructor_test.dart
@@ -0,0 +1,25 @@
+// 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 "package:expect/expect.dart";
+
+// Confirm that redirecting named constructors are properly resolved.
+//
+// Note that this test may become invalid due to http://dartbug.com/5940.
+
+class C {
+  var x;
+  C() {
+    x = 1;
+  }
+  C.C() {
+    x = 2;
+  }
+  C.redirecting() : this.C();
+}
+
+main() {
+  var c = new C.redirecting();
+  Expect.equals(c.x, 2);
+}
diff --git a/tests/dart2js/this_test.dart b/tests/dart2js/this_test.dart
new file mode 100644
index 0000000..e0804e7
--- /dev/null
+++ b/tests/dart2js/this_test.dart
@@ -0,0 +1,19 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  int x;
+  getX() => this.x;
+  setX(val) {
+    this.x = val;
+  }
+}
+
+main() {
+  A a = new A();
+  a.setX(42);
+  Expect.equals(42, a.getX());
+}
diff --git a/tests/dart2js/throw1_test.dart b/tests/dart2js/throw1_test.dart
new file mode 100644
index 0000000..b91485c
--- /dev/null
+++ b/tests/dart2js/throw1_test.dart
@@ -0,0 +1,7 @@
+// 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.
+
+void main() {
+  throw "foo"; // //# 01: runtime error
+}
diff --git a/tests/dart2js/throw2_test.dart b/tests/dart2js/throw2_test.dart
new file mode 100644
index 0000000..350ec72
--- /dev/null
+++ b/tests/dart2js/throw2_test.dart
@@ -0,0 +1,39 @@
+// 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.
+
+void throw1() {
+  throw "foo";
+}
+
+void throw2() {
+  if (true) throw "foo";
+}
+
+void throw3() {
+  if (false) {
+    print("argh");
+  } else {
+    throw "foo";
+  }
+}
+
+void throw4() {
+  if (true) {
+    throw "foo";
+  } else {
+    throw "bar";
+  }
+}
+
+void nonThrow5() {
+  if (false) throw "foo";
+}
+
+void main() {
+  throw1(); // //# 01: runtime error
+  throw2(); // //# 02: runtime error
+  throw3(); // //# 03: runtime error
+  throw4(); // //# 04: runtime error
+  nonThrow5();
+}
diff --git a/tests/dart2js/timer_test.dart b/tests/dart2js/timer_test.dart
new file mode 100644
index 0000000..818a6ae
--- /dev/null
+++ b/tests/dart2js/timer_test.dart
@@ -0,0 +1,26 @@
+// 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.
+
+import 'dart:async';
+import 'dart:isolate';
+
+import 'async_helper.dart';
+
+void test(void onDone(bool success)) {
+  Duration ms = const Duration(milliseconds: 1);
+  int expected = 4;
+
+  void timerCallback() {
+    if (--expected == 0) onDone(true);
+  }
+
+  new Timer(ms * 0, timerCallback);
+  new Timer(ms * 10, timerCallback);
+  new Timer(ms * 100, timerCallback);
+  new Timer(ms * 1000, timerCallback);
+}
+
+main() {
+  asyncTest(test);
+}
diff --git a/tests/dart2js/to_string_test.dart b/tests/dart2js/to_string_test.dart
new file mode 100644
index 0000000..7157548
--- /dev/null
+++ b/tests/dart2js/to_string_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A extends Object {}
+
+class Concater {
+  final x;
+  final y;
+  Concater(x, y)
+      : this.x = x,
+        this.y = y;
+  add() => x + y.toString();
+}
+
+test(expected, x) {
+  Expect.equals(expected, x.toString());
+  Expect.equals(expected, new Concater("", x).add());
+}
+
+main() {
+  test("Instance of 'Object'", new Object());
+  test("Instance of 'A'", new A());
+  test("[]", []);
+  test("1", 1);
+}
diff --git a/tests/dart2js/truncation_errors_test.dart b/tests/dart2js/truncation_errors_test.dart
new file mode 100644
index 0000000..92532f2
--- /dev/null
+++ b/tests/dart2js/truncation_errors_test.dart
@@ -0,0 +1,92 @@
+// Copyright (c) 2015, 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.
+
+// Check that exception messages for truncating operations contains the
+// operands.
+
+import 'package:expect/expect.dart';
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+void find1(expected, thunk) {
+  if (thunk == null) return;
+  var returned, exceptionText;
+  try {
+    returned = thunk();
+  } catch (e) {
+    exceptionText = '$e';
+  }
+  if (exceptionText == null) {
+    Expect.fail(
+        'Expected exception containing "$expected", returned: $returned');
+  }
+  Expect.isTrue(exceptionText.contains(expected),
+      'Expected "$expected" in "$exceptionText"');
+}
+
+void find(expected, [thunk1, thunk2, thunk3, thunk4]) {
+  find1(expected, thunk1);
+  find1(expected, thunk2);
+  find1(expected, thunk3);
+  find1(expected, thunk4);
+}
+
+main() {
+  var NaN = double.nan;
+  var Infinity = double.infinity;
+
+  find(' Infinity: 123 ~/ 0', () => confuse(123) ~/ confuse(0),
+      () => confuse(123) ~/ 0, () => 123 ~/ confuse(0), () => 123 ~/ 0);
+
+  find(
+      '-Infinity: 123 ~/ -0.0',
+      () => confuse(123) ~/ confuse(-0.0),
+      () => confuse(123) ~/ -0.0,
+      () => 123 ~/ confuse(-0.0),
+      () => 123 ~/ -0.0);
+
+  find(' NaN: NaN ~/ 123', () => confuse(NaN) ~/ confuse(123),
+      () => confuse(NaN) ~/ 123, () => NaN ~/ confuse(123), () => NaN ~/ 123);
+
+  find(
+      ' Infinity: 1e+200 ~/ 1e-200',
+      () => confuse(1e200) ~/ confuse(1e-200),
+      () => confuse(1e200) ~/ 1e-200,
+      () => 1e200 ~/ confuse(1e-200),
+      () => 1e200 ~/ 1e-200);
+
+  find('NaN.toInt()', () => confuse(NaN).toInt(), () => NaN.toInt());
+  find(' Infinity.toInt()', () => confuse(Infinity).toInt(),
+      () => Infinity.toInt());
+  find('-Infinity.toInt()', () => confuse(-Infinity).toInt(),
+      () => (-Infinity).toInt());
+
+  find('NaN.ceil()', () => confuse(NaN).ceil(), () => NaN.ceil());
+  find(' Infinity.ceil()', () => confuse(Infinity).ceil(),
+      () => Infinity.ceil());
+  find('-Infinity.ceil()', () => confuse(-Infinity).ceil(),
+      () => (-Infinity).ceil());
+
+  find('NaN.floor()', () => confuse(NaN).floor(), () => NaN.floor());
+  find(' Infinity.floor()', () => confuse(Infinity).floor(),
+      () => Infinity.floor());
+  find('-Infinity.floor()', () => confuse(-Infinity).floor(),
+      () => (-Infinity).floor());
+
+  find('NaN.round()', () => confuse(NaN).round(), () => NaN.round());
+  find(' Infinity.round()', () => confuse(Infinity).round(),
+      () => Infinity.round());
+  find('-Infinity.round()', () => confuse(-Infinity).round(),
+      () => (-Infinity).round());
+
+  // `truncate()` is the same as `toInt()`.
+  // We could change the runtime so that `truncate` is reported.
+  find('NaN.toInt()', () => confuse(NaN).truncate(), () => NaN.truncate());
+  find(' Infinity.toInt()', () => confuse(Infinity).truncate(),
+      () => Infinity.truncate());
+  find('-Infinity.toInt()', () => confuse(-Infinity).truncate(),
+      () => (-Infinity).truncate());
+}
diff --git a/tests/dart2js/type_argument_factory_crash_test.dart b/tests/dart2js/type_argument_factory_crash_test.dart
new file mode 100644
index 0000000..36dd8eb
--- /dev/null
+++ b/tests/dart2js/type_argument_factory_crash_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// A regression test for a dart2js crash.
+library type.argument.factory.crash.test;
+
+import "package:expect/expect.dart";
+import 'dart:collection' show LinkedHashMap;
+
+void main() {
+  // This constructor call causes a crash in dart2js.
+  var o = new LinkedHashMap<int, int>();
+
+  // Comment out this line, the compiler doesn't crash.
+  Expect.isFalse(o is List<int>);
+
+  // Enable these two lines, the compiler doesn't crash.
+  // Expect.isTrue(o.keys is Iterable<int>);
+  // Expect.isFalse(o.keys is Iterable<String>);
+}
diff --git a/tests/dart2js/type_argument_factory_nocrash_test.dart b/tests/dart2js/type_argument_factory_nocrash_test.dart
new file mode 100644
index 0000000..1708b04
--- /dev/null
+++ b/tests/dart2js/type_argument_factory_nocrash_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+// A regression test for a dart2js crash.
+library type.argument.factory.nocrash.test;
+
+import "package:expect/expect.dart";
+import 'dart:collection' show LinkedHashMap;
+
+void main() {
+  // This constructor call causes a crash in dart2js.
+  var o = new LinkedHashMap<int, int>();
+
+  // Comment out this line, the compiler doesn't crash.
+  Expect.isFalse(o is List<int>);
+
+  // Enable these two lines, the compiler doesn't crash.
+  Expect.isTrue(o.keys is Iterable<int>);
+  Expect.isFalse(o.keys is Iterable<String>);
+}
diff --git a/tests/dart2js/type_argument_optimization_test.dart b/tests/dart2js/type_argument_optimization_test.dart
new file mode 100644
index 0000000..21b41c5
--- /dev/null
+++ b/tests/dart2js/type_argument_optimization_test.dart
@@ -0,0 +1,121 @@
+// 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.
+
+// Regression test for issue 37267.
+
+typedef UpdateShouldNotify<T> = bool Function(T previous, T current);
+
+typedef ValueWidgetBuilder<T> = Widget Function(
+    BuildContext context, T value, Widget child);
+
+class BuildContext {}
+
+class Widget {}
+
+abstract class ProxyWidget extends Widget {
+  final Widget child;
+
+  ProxyWidget({this.child});
+}
+
+abstract class InheritedWidget extends ProxyWidget {
+  InheritedWidget({Widget child}) : super(child: child);
+}
+
+class InheritedProvider<T> extends InheritedWidget {
+  final T _value;
+  final UpdateShouldNotify<T> _updateShouldNotify;
+
+  InheritedProvider(
+      {T value, UpdateShouldNotify<T> updateShouldNotify, Widget child})
+      : _value = value,
+        _updateShouldNotify = updateShouldNotify,
+        super(child: child);
+}
+
+class StateDelegate {}
+
+abstract class ValueStateDelegate<T> extends StateDelegate {
+  T get value;
+}
+
+class ValueStateDelegateImpl<T> implements ValueStateDelegate<T> {
+  final T value;
+
+  ValueStateDelegateImpl(this.value);
+}
+
+class DelegateWidget {
+  final StateDelegate delegate;
+
+  DelegateWidget(this.delegate);
+}
+
+abstract class Listenable {}
+
+abstract class ValueListenable<T> extends Listenable {
+  T get value;
+}
+
+class ValueListenableImpl<T> implements ValueListenable<T> {
+  final T value;
+
+  ValueListenableImpl(this.value);
+}
+
+class ValueDelegateWidget<T> extends DelegateWidget {
+  ValueDelegateWidget(ValueStateDelegate<T> delegate) : super(delegate);
+
+  @pragma('dart2js:tryInline')
+  ValueStateDelegate<T> get delegate => super.delegate as ValueStateDelegate<T>;
+}
+
+class ValueListenableProvider<T>
+    extends ValueDelegateWidget<ValueListenable<T>> {
+  final Widget child;
+
+  final UpdateShouldNotify<T> updateShouldNotify;
+
+  ValueListenableProvider(ValueStateDelegate<ValueListenable<T>> delegate,
+      this.updateShouldNotify, this.child)
+      : super(delegate);
+
+  Widget build() {
+    return ValueListenableBuilder<T>(
+      valueListenable: delegate.value,
+      builder: (_, value, child) {
+        return InheritedProvider<T>(
+          value: value,
+          updateShouldNotify: updateShouldNotify,
+          child: child,
+        );
+      },
+      child: child,
+    );
+  }
+}
+
+class ValueListenableBuilder<T> extends Widget {
+  final ValueListenable<T> valueListenable;
+  final ValueWidgetBuilder<T> builder;
+  final Widget child;
+
+  ValueListenableBuilder({this.valueListenable, this.builder, this.child});
+}
+
+void main() {
+  print(create(42).valueListenable.value);
+  print(create('foo').valueListenable.value);
+}
+
+ValueListenableBuilder<T> create<T>(T value) {
+  ValueListenableImpl<T> valueListenable = new ValueListenableImpl<T>(value);
+  ValueStateDelegateImpl<ValueListenable<T>> valueStateDelegate =
+      new ValueStateDelegateImpl<ValueListenable<T>>(valueListenable);
+  ValueListenableProvider<T> valueListenableProvider =
+      new ValueListenableProvider<T>(valueStateDelegate, null, null);
+  Widget widget = valueListenableProvider.build();
+  print(value);
+  return widget;
+}
diff --git a/tests/dart2js/type_constant_switch_test.dart b/tests/dart2js/type_constant_switch_test.dart
new file mode 100644
index 0000000..875c9d8
--- /dev/null
+++ b/tests/dart2js/type_constant_switch_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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 that switching on type literals leads to a compile time error in
+// dart2js since its implementation of [Type] implements 'operator =='.
+
+class C {}
+
+var v;
+
+main() {
+  switch (v) {
+    case C: break; // //# 01: compile-time error
+  }
+}
diff --git a/tests/dart2js/type_error_message_test.dart b/tests/dart2js/type_error_message_test.dart
new file mode 100644
index 0000000..6f34931
--- /dev/null
+++ b/tests/dart2js/type_error_message_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2013, 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 that the error message for a failing subtype test includes type
+// arguments.
+
+import 'package:expect/expect.dart';
+
+class C<T, S> {}
+
+bool inComplianceMode() {
+  try {
+    int i = ('hest' as dynamic);
+  } catch (e) {
+    return true;
+  }
+  return false;
+}
+
+main() {
+  if (inComplianceMode()) {
+    bool caught = false;
+    try {
+      C<String, String> x = (new C<C<int, String>, String>()) as dynamic;
+    } catch (e) {
+      String nameOfC = (C).toString();
+      if (nameOfC.contains('<')) {
+        nameOfC = nameOfC.substring(0, nameOfC.indexOf('<'));
+      }
+      String nameOfInt = (int).toString();
+      String nameOfString = (String).toString();
+      String expected =
+          "'$nameOfC<$nameOfC<$nameOfInt, $nameOfString>, $nameOfString>'";
+      Expect.isTrue(e.toString().contains(expected),
+          'Expected "$expected" in the message: $e');
+      print(e);
+      caught = true;
+    }
+    Expect.isTrue(caught);
+  }
+}
diff --git a/tests/dart2js/type_literal2_test.dart b/tests/dart2js/type_literal2_test.dart
new file mode 100644
index 0000000..53d06a3
--- /dev/null
+++ b/tests/dart2js/type_literal2_test.dart
@@ -0,0 +1,27 @@
+// 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 'dart:async';
+import 'package:expect/expect.dart';
+
+typedef Typedef();
+typedef GenericTypedef<T> = void Function(T);
+typedef GenericFunctionTypedef = void Function<T>(T);
+typedef TypedefWithFutureOr = void Function<T>(FutureOr<T>);
+
+const typedef = Typedef;
+const genericTypedef = GenericTypedef;
+const genericFunctionTypedef = GenericFunctionTypedef;
+const typedefWithFutureOr = TypedefWithFutureOr;
+const futureOr = FutureOr;
+const null_ = Null;
+
+main() {
+  Expect.isTrue(identical(typedef, Typedef));
+  Expect.isTrue(identical(genericTypedef, GenericTypedef));
+  Expect.isTrue(identical(genericFunctionTypedef, GenericFunctionTypedef));
+  Expect.isTrue(identical(typedefWithFutureOr, TypedefWithFutureOr));
+  Expect.isTrue(identical(futureOr, FutureOr));
+  Expect.isTrue(identical(null_, Null));
+}
diff --git a/tests/dart2js/type_literal_test.dart b/tests/dart2js/type_literal_test.dart
new file mode 100644
index 0000000..4426847
--- /dev/null
+++ b/tests/dart2js/type_literal_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// dart2jsOptions=--strong
+
+import 'package:expect/expect.dart';
+
+class Class1 {}
+
+class Class2<X> {}
+
+void main() {
+  String name1 = '${Class1}';
+  String name2 = '${Class2}';
+  Expect.equals('Class1', name1);
+  Expect.equals('Class2<dynamic>', name2);
+}
diff --git a/tests/dart2js/typevariable_factory_test.dart b/tests/dart2js/typevariable_factory_test.dart
new file mode 100644
index 0000000..2f977cf
--- /dev/null
+++ b/tests/dart2js/typevariable_factory_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, 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.
+
+// Regression test to ensure that we can use type variable in factories.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  factory A.foo(o) {
+    Expect.isTrue(o is A<T>);
+    return new A();
+  }
+  A();
+}
+
+main() => new A<int>.foo(new A<int>());
diff --git a/tests/dart2js/typevariable_substitution_test.dart b/tests/dart2js/typevariable_substitution_test.dart
new file mode 100644
index 0000000..dd5e75f
--- /dev/null
+++ b/tests/dart2js/typevariable_substitution_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, 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.
+
+// Regression test to ensure that we substitute type variables in is-tests.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  A.foo(o) {
+    Expect.isTrue(o is A<T>);
+  }
+  A();
+}
+
+class B extends A<int> {
+  B.foo(o) : super.foo(o);
+}
+
+main() => new B.foo(new A<int>());
diff --git a/tests/dart2js/typevariable_typedef_test.dart b/tests/dart2js/typevariable_typedef_test.dart
new file mode 100644
index 0000000..5dc6d2b
--- /dev/null
+++ b/tests/dart2js/typevariable_typedef_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+typedef T Func<T>(T x);
+
+class A<T> {
+  final Box<T> box;
+  A._(this.box);
+  A.foo(Func<T> func) : this._(new Box<T>(func));
+}
+
+class Box<T> {
+  final Func<T> func;
+  Box(this.func);
+}
+
+class B extends A {
+  B() : super.foo((x) => x);
+}
+
+main() {
+  var x = new B();
+  Expect.equals(x.runtimeType.toString(), 'B');
+}
diff --git a/tests/dart2js/unconditional_dartio_import_test.dart b/tests/dart2js/unconditional_dartio_import_test.dart
new file mode 100644
index 0000000..d6c869a
--- /dev/null
+++ b/tests/dart2js/unconditional_dartio_import_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2017, 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.
+
+/// Tests that dart2js allows to import dart:io for web clients, but it
+/// continues to indicate that it is not supported (so config-specific imports
+/// continue to have the same semantics as before).
+library unconditional_dartio_import_test;
+
+import 'dart:io' as io; // import is allowed!
+import 'package:expect/expect.dart';
+
+main() {
+  // their APIs throw:
+  Expect.throws(() => new io.File('name').existsSync());
+
+  // ... but environment variable will indicate it is not supported.
+  Expect.isFalse(const bool.fromEnvironment('dart.library.io'));
+}
diff --git a/tests/dart2js/unused_local_const_test.dart b/tests/dart2js/unused_local_const_test.dart
new file mode 100644
index 0000000..5829129
--- /dev/null
+++ b/tests/dart2js/unused_local_const_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.
+
+class A {
+  const A();
+
+  A operator -() => this;
+}
+
+main() {
+  const a = const A();
+  const c = //# 01: compile-time error
+      const bool.fromEnvironment('foo') ? null : -a; //# 01: continued
+}
diff --git a/tests/dart2js/useful_error_message_1_test.dart b/tests/dart2js/useful_error_message_1_test.dart
new file mode 100644
index 0000000..7fbaa6b
--- /dev/null
+++ b/tests/dart2js/useful_error_message_1_test.dart
@@ -0,0 +1,86 @@
+// Copyright (c) 2015, 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 that closures have a useful string that identifies the function by name
+// in error messages.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+confuse(x) => x;
+
+class CCCC {
+  instanceMethod([a, b]) => '[$a, $b]';
+  static staticMethod() => 'hi';
+  // Default `toString` method returns "Instance of 'CCCC'" or similar with a
+  // shorter name if minified.
+}
+
+main() {
+  var c = confuse(new CCCC());
+
+  var instanceString = confuse(c).toString();
+  bool isMinified =
+      instanceString.contains(new RegExp("Instance of '..?.?'")) ||
+          instanceString.contains('minified:');
+  if (!isMinified) {
+    Expect.equals("Instance of 'CCCC'", instanceString);
+  }
+
+  checkContains(String message, String tag) {
+    if (!message.contains(tag)) {
+      if (!isMinified) {
+        Expect.fail('"$message" should contain "$tag"');
+      }
+      // When minified we will accept quoted names up to 3 characters.
+      Expect.isTrue(
+          message.contains(new RegExp("'..?.?'")) ||
+              message.contains("'minified:"),
+          '"$message" should contain minified name');
+    }
+  }
+
+  // We use ArgumentError.value since it prints the value using
+  // Error.safeToString.
+  var e1 = new ArgumentError.value(c);
+  var s1 = '$e1';
+  Expect.isTrue(s1.contains(instanceString),
+      'Error message "$s1" should contain "$instanceString"');
+
+  // Instance method tear-off.
+  var e2 = new ArgumentError.value(confuse(c).instanceMethod);
+  var s2 = '$e2';
+  // Instance method tear-off should contain instance string.
+  Expect.isTrue(s2.contains(instanceString),
+      'Error message "$s2" should contain "$instanceString"');
+  // Instance method tear-off should also name the method.
+  checkContains(s2.replaceAll(instanceString, '*'), "instanceMethod");
+
+  // Top level tear-off.
+  var e3 = new ArgumentError.value(confuse);
+  var s3 = '$e3';
+  checkContains(s3, "confuse");
+  checkContains('$confuse', "confuse");
+
+  // Static method tear-off.
+  var e4 = new ArgumentError.value(CCCC.staticMethod);
+  var s4 = '$e4';
+  checkContains(s4, "staticMethod");
+  checkContains('${CCCC.staticMethod}', "staticMethod");
+
+  // Local anonymous closure.
+  var anon = () => c;
+  var e5 = new ArgumentError.value(anon);
+  var s5 = '$e5';
+  checkContains(s5, "main_closure");
+  checkContains('$anon', "main_closure");
+
+  // Local named closure.
+  localFunction() => c;
+  var e6 = new ArgumentError.value(localFunction);
+  var s6 = '$e6';
+  checkContains(s6, "localFunction");
+  checkContains('$localFunction', "localFunction");
+}
diff --git a/tests/dart2js/while_test.dart b/tests/dart2js/while_test.dart
new file mode 100644
index 0000000..4ac3ec3
--- /dev/null
+++ b/tests/dart2js/while_test.dart
@@ -0,0 +1,75 @@
+// 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 "package:expect/expect.dart";
+
+void while1() {
+  bool cond = true;
+  var result = 0;
+  var x = 0;
+  while (cond) {
+    if (x == 10) cond = false;
+    result += x;
+    x = x + 1;
+  }
+  Expect.equals(55, result);
+}
+
+void while2() {
+  var t = 0;
+  var i = 0;
+  while (i == 0) {
+    t = t + 10;
+    i++;
+  }
+  Expect.equals(10, t);
+}
+
+void while3() {
+  var i = 0;
+  while (i == 1) {
+    Expect.fail('unreachable');
+  }
+}
+
+void while4() {
+  var cond1 = true;
+  var result = 0;
+  var i = 0;
+  while (cond1) {
+    if (i == 9) cond1 = false;
+    var cond2 = true;
+    var j = 0;
+    while (cond2) {
+      if (j == 9) cond2 = false;
+      result = result + 1;
+      j = j + 1;
+    }
+    i = i + 1;
+  }
+  Expect.equals(100, result);
+}
+
+int while5_2() {
+  // The while condition dominates 3 blocks: the body, the block after the loop
+  // and the exit block.
+  while (true) {
+    if (true) {
+      return 499;
+    }
+  }
+  return 0;
+}
+
+void while5() {
+  Expect.equals(499, while5_2());
+}
+
+void main() {
+  while1();
+  while2();
+  while3();
+  while4();
+  while5();
+}
diff --git a/tests/dart2js_2/internal/mock_libraries.dart b/tests/dart2js_2/internal/mock_libraries.dart
index b05e665..74088da 100644
--- a/tests/dart2js_2/internal/mock_libraries.dart
+++ b/tests/dart2js_2/internal/mock_libraries.dart
@@ -147,15 +147,10 @@
   'assertThrow': 'assertThrow(a) {}',
   'assertHelper': 'assertHelper(a) {}',
   'assertUnreachable': 'assertUnreachable() {}',
-  'assertIsSubtype': 'assertIsSubtype(subtype, supertype, message) {}',
   'assertSubtype': 'assertSubtype(object, isField, checks, asField) {}',
-  'assertSubtypeOfRuntimeType': 'assertSubtypeOfRuntimeType(object, type) {}',
   'asyncHelper': 'asyncHelper(object, asyncBody, completer) {}',
   'boolConversionCheck': 'boolConversionCheck(x) {}',
-  'boolTypeCast': 'boolTypeCast(value) {}',
-  'boolTypeCheck': 'boolTypeCheck(value) {}',
   'checkSubtype': 'checkSubtype(object, isField, checks, asField) {}',
-  'checkSubtypeOfRuntimeType': 'checkSubtypeOfRuntimeType(o, t) {}',
   'BoundClosure': r'''abstract class BoundClosure extends Closure {
     var self;
     var target;
@@ -193,8 +188,6 @@
   'ConstantStringMap': 'class ConstantStringMap<K, V> {}',
   'createInvocationMirror': 'createInvocationMirror(a0, a1, a2, a3, a4, a5) {}',
   'createRuntimeType': 'createRuntimeType(a) {}',
-  'doubleTypeCast': 'doubleTypeCast(value) {}',
-  'doubleTypeCheck': 'doubleTypeCheck(value) {}',
   'functionSubtypeCast':
       r'''functionSubtypeCast(Object object, String signatureName,
                               String contextName, var context) {}''',
@@ -204,12 +197,6 @@
         buildNamedFunctionType(null, null, null);
         buildInterfaceType(null, null);
       }''',
-  'functionTypeTest': r'functionTypeTest(f, t) {}',
-  'functionTypeCast': r'functionTypeCast(f, t) { return f; }',
-  'functionTypeCheck': r'functionTypeCheck(f, t) { return f; }',
-  'futureOrTest': r'futureOrTest(f, t) {}',
-  'futureOrCast': r'futureOrCast(f, t) { return f; }',
-  'futureOrCheck': r'futureOrCheck(f, t) { return f; }',
   'getFallThroughError': 'getFallThroughError() {}',
   'getIsolateAffinityTag': 'getIsolateAffinityTag(_) {}',
   'getRuntimeTypeArgumentIntercepted':
@@ -228,41 +215,23 @@
   'Instantiation3': 'class Instantiation3<T1,T2,T3> extends Closure {}',
   'interceptedTypeCast': 'interceptedTypeCast(value, property) {}',
   'interceptedTypeCheck': 'interceptedTypeCheck(value, property) {}',
-  'intTypeCast': 'intTypeCast(value) {}',
-  'intTypeCheck': 'intTypeCheck(value) {}',
   'isJsIndexable': 'isJsIndexable(a, b) {}',
   'JavaScriptIndexingBehavior': 'abstract class JavaScriptIndexingBehavior {}',
   'JSInvocationMirror': r'''
   class JSInvocationMirror {
     get typeArguments => null;
   }''',
-  'listSuperNativeTypeCast': 'listSuperNativeTypeCast(value) {}',
-  'listSuperNativeTypeCheck': 'listSuperNativeTypeCheck(value) {}',
-  'listSuperTypeCast': 'listSuperTypeCast(value) {}',
-  'listSuperTypeCheck': 'listSuperTypeCheck(value) {}',
-  'listTypeCast': 'listTypeCast(value) {}',
-  'listTypeCheck': 'listTypeCheck(value) {}',
   'makeLiteralMap': 'makeLiteralMap(List keyValuePairs) {}',
   'Native': 'class Native {}',
   'NoInline': 'class NoInline {}',
   'ForceInline': 'class ForceInline {}',
   'NoSideEffects': 'class NoSideEffects {}',
   'NoThrows': 'class NoThrows {}',
-  'numberOrStringSuperNativeTypeCast':
-      'numberOrStringSuperNativeTypeCast(value) {}',
-  'numberOrStringSuperNativeTypeCheck':
-      'numberOrStringSuperNativeTypeCheck(value) {}',
-  'numberOrStringSuperTypeCast': 'numberOrStringSuperTypeCast(value) {}',
-  'numberOrStringSuperTypeCheck': 'numberOrStringSuperTypeCheck(value) {}',
-  'numTypeCast': 'numTypeCast(value) {}',
-  'numTypeCheck': 'numTypeCheck(value) {}',
   '_Patch': 'class _Patch { final tag; const _Patch(this.tag); }',
   'patch': 'const patch = const _Patch(null);',
   'patch_full': 'const patch_full = const _Patch("full");',
   'patch_lazy': 'const patch_lazy = const _Patch("lazy");',
   'patch_startup': 'const patch_startup = const _Patch("startup");',
-  'propertyTypeCast': 'propertyTypeCast(x) {}',
-  'propertyTypeCheck': 'propertyTypeCheck(value, property) {}',
   'requiresPreamble': 'requiresPreamble() {}',
   'RuntimeFunctionType': 'class RuntimeFunctionType {}',
   'RuntimeTypeGeneric': 'class RuntimeTypeGeneric {}',
@@ -270,13 +239,6 @@
   'runtimeTypeToString': 'runtimeTypeToString(type, {onTypeVariable(i)}) {}',
   'S': 'S() {}',
   'setRuntimeTypeInfo': 'setRuntimeTypeInfo(a, b) {}',
-  'stringSuperNativeTypeCast': 'stringSuperNativeTypeCast(value) {}',
-  'stringSuperNativeTypeCheck': 'stringSuperNativeTypeCheck(value) {}',
-  'stringSuperTypeCast': 'stringSuperTypeCast(value) {}',
-  'stringSuperTypeCheck': 'stringSuperTypeCheck(value) {}',
-  'stringTypeCast': 'stringTypeCast(x) {}',
-  'stringTypeCheck': 'stringTypeCheck(x) {}',
-  'subtypeCast': 'subtypeCast(object, isField, checks, asField) {}',
   'subtypeOfRuntimeTypeCast': 'subtypeOfRuntimeTypeCast(object, type) {}',
   'throwAbstractClassInstantiationError':
       'throwAbstractClassInstantiationError(className) {}',
diff --git a/tests/dart2js_2/native/inference_of_helper_methods_test.dart b/tests/dart2js_2/native/inference_of_helper_methods_test.dart
deleted file mode 100644
index f0d426c..0000000
--- a/tests/dart2js_2/native/inference_of_helper_methods_test.dart
+++ /dev/null
@@ -1,34 +0,0 @@
-// Copyright (c) 2013, 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.7
-
-import 'native_testing.dart';
-import 'dart:_js_helper' show intTypeCheck;
-
-bool get inComplianceMode {
-  try {
-    String a = (42 as dynamic);
-  } on TypeError catch (e) {
-    return true;
-  }
-  return false;
-}
-
-main() {
-  var a = [];
-  a.add(42);
-  a.add('foo');
-  // By calling directly [intTypeCheck] with an int, we're making the
-  // type inferrer infer that the parameter type of [intTypeCheck] is
-  // always an int, and therefore the method will be compiled to
-  // never throw. So when the backend actually uses the helper for
-  // implementing checked mode semantics (like in the check below),
-  // the check won't fail at runtime.
-  intTypeCheck(42);
-  if (inComplianceMode) {
-    int value;
-    Expect.throws(() => value = a[1], (e) => e is TypeError);
-  }
-}
diff --git a/tests/dart2js_2/regress_42281_test.dart b/tests/dart2js_2/regress_42281_test.dart
new file mode 100644
index 0000000..8b8ce2e
--- /dev/null
+++ b/tests/dart2js_2/regress_42281_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.
+
+class ComponentFactory<T> {
+  @pragma('dart2js:noInline')
+  Type get componentType => T;
+}
+
+var mm = {'String': String, 'int': int};
+var gf1 = ComponentFactory<int>();
+var gf2 = ComponentFactory<dynamic>();
+Map<String, ComponentFactory> mf = {'RegExp': ComponentFactory<RegExp>()};
+
+ComponentFactory test(String s, [Map<String, ComponentFactory> mf2]) {
+  var f = mf[s];
+  if (f == null) {
+    var t = mm[s];
+    if (mf2 != null) f = mf2[s];
+    if (t != null && t != f?.componentType) {
+      print('not match $t');
+      f = gf2;
+    }
+  }
+  return f;
+}
+
+main() {
+  Map<String, ComponentFactory> mf2 = {'int': ComponentFactory<num>()};
+
+  test('String');
+  test('String', mf2);
+  test('int');
+  test('int', mf2);
+  test('RegExp');
+  test('RegExp', mf2);
+}
diff --git a/tests/ffi/ffi.status b/tests/ffi/ffi.status
index 8db64fb..9946ac7 100644
--- a/tests/ffi/ffi.status
+++ b/tests/ffi/ffi.status
@@ -11,6 +11,9 @@
 [ $compiler != dart2analyzer && $compiler != fasta && $runtime != dart_precompiled && $runtime != vm ]
 *: SkipByDesign # FFI is a VM-only feature. (This test suite is part of the default set.)
 
+[ $compiler == dartkp && $system == windows ]
+vmspecific_handle_test: SkipByDesign # Symbols are not exposed on purpose and are not linked in Windows Precompiled. dartbug.com/40579
+
 [ $system != android && $system != linux && $system != macos && $system != windows ]
 *: Skip # FFI not yet supported on other OSes.
 
diff --git a/tests/ffi/vmspecific_handle_test.dart b/tests/ffi/vmspecific_handle_test.dart
new file mode 100644
index 0000000..4548c70
--- /dev/null
+++ b/tests/ffi/vmspecific_handle_test.dart
@@ -0,0 +1,249 @@
+// 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.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=--enable-testing-pragmas
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+
+void main() {
+  testHandle();
+  testReadField();
+  testTrueHandle();
+  testClosureCallback();
+  testReturnHandleInCallback();
+  testPropagateError();
+  testCallbackReturnException();
+  testDeepException();
+  testDeepException2();
+  testNull();
+  testDeepRecursive();
+}
+
+void testHandle() {
+  print("testHandle");
+  final s = SomeClass(123);
+  print("passObjectToC($s)");
+  final result = passObjectToC(s);
+  print("result = $result");
+  Expect.isTrue(identical(s, result));
+}
+
+void testReadField() {
+  final s = SomeClass(123);
+  final result = handleReadFieldValue(s);
+  Expect.equals(s.a, result);
+}
+
+void testTrueHandle() {
+  final result = trueHandle();
+  Expect.isTrue(result);
+}
+
+int globalCounter = 0;
+
+void increaseCounter() {
+  print("increaseCounter");
+  globalCounter++;
+}
+
+void doClosureCallback(Object callback) {
+  print("doClosureCallback");
+  print(callback.runtimeType);
+  print(callback);
+  final callback_as_function = callback as void Function();
+  callback_as_function();
+}
+
+final closureCallbackPointer =
+    Pointer.fromFunction<Void Function(Handle)>(doClosureCallback);
+
+void testClosureCallback() {
+  print("testClosureCallback $closureCallbackPointer");
+  Expect.equals(0, globalCounter);
+  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
+  Expect.equals(1, globalCounter);
+  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
+  Expect.equals(2, globalCounter);
+}
+
+final someObject = SomeClass(12356789);
+
+Object returnHandleCallback() {
+  print("returnHandleCallback returning $someObject");
+  return someObject;
+}
+
+final returnHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(returnHandleCallback);
+
+void testReturnHandleInCallback() {
+  print("testReturnHandleInCallback");
+  final result = returnHandleInCallback(returnHandleCallbackPointer);
+  Expect.isTrue(identical(someObject, result));
+}
+
+class SomeClass {
+  // We use this getter in the native api, don't tree shake it.
+  @pragma("vm:entry-point")
+  final int a;
+  SomeClass(this.a);
+}
+
+void testPropagateError() {
+  final s = SomeOtherClass(123);
+  Expect.throws(() => handleReadFieldValue(s));
+}
+
+class SomeOtherClass {
+  final int notA;
+  SomeOtherClass(this.notA);
+}
+
+final someException = Exception("exceptionHandleCallback exception");
+
+Object exceptionHandleCallback() {
+  print("exceptionHandleCallback throwing ($someException)");
+  throw someException;
+}
+
+final exceptionHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(exceptionHandleCallback);
+
+void testCallbackReturnException() {
+  print("testCallbackReturnException");
+  bool throws = false;
+  try {
+    final result = returnHandleInCallback(exceptionHandleCallbackPointer);
+    print(result);
+  } catch (e) {
+    throws = true;
+    print("caught ($e)");
+    Expect.isTrue(identical(someException, e));
+  }
+  Expect.isTrue(throws);
+}
+
+Object callCAgainFromCallback() {
+  print("callCAgainFromCallback");
+  final s = SomeOtherClass(123);
+  Expect.throws(() => handleReadFieldValue(s));
+  return someObject;
+}
+
+final callCAgainFromCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback);
+
+void testDeepException() {
+  print("testDeepException");
+  final result = returnHandleInCallback(callCAgainFromCallbackPointer);
+  Expect.isTrue(identical(someObject, result));
+}
+
+Object callCAgainFromCallback2() {
+  print("callCAgainFromCallback2");
+  final s = SomeOtherClass(123);
+  handleReadFieldValue(s); // throws.
+  return someObject;
+}
+
+final callCAgainFromCallbackPointer2 =
+    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback2);
+
+void testDeepException2() {
+  print("testDeepException2");
+  Expect.throws(() => returnHandleInCallback(callCAgainFromCallbackPointer2));
+}
+
+Object? returnNullHandleCallback() {
+  print("returnHandleCallback returning null");
+  return null;
+}
+
+final returnNullHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(returnNullHandleCallback);
+
+void testNull() {
+  print("testNull");
+  final result = passObjectToC(null);
+  Expect.isNull(result);
+
+  final result2 = returnHandleInCallback(returnNullHandleCallbackPointer);
+  Expect.isNull(result2);
+}
+
+Object recurseAbove0(int i) {
+  print("recurseAbove0($i)");
+  if (i == 0) {
+    print("throwing");
+    throw someException;
+  }
+  if (i < 0) {
+    print("returning");
+    return someObject;
+  }
+  final result =
+      handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, i - 1);
+  print("return $i");
+  return result;
+}
+
+final recurseAbove0Pointer =
+    Pointer.fromFunction<Handle Function(Int64)>(recurseAbove0);
+
+class SomeClassWithMethod {
+  // We use this method in the native api, don't tree shake it.
+  @pragma("vm:entry-point")
+  Object a(int i) => recurseAbove0(i);
+}
+
+void testDeepRecursive() {
+  // works on arm.
+  Expect.throws(() {
+    handleRecursion(123, recurseAbove0Pointer, 1);
+  });
+
+  Expect.throws(() {
+    handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, 1);
+  });
+
+  Expect.throws(() {
+    recurseAbove0(100);
+  });
+
+  final result = recurseAbove0(101);
+  Expect.isTrue(identical(someObject, result));
+}
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
+
+final passObjectToC = testLibrary.lookupFunction<Handle Function(Handle),
+    Object? Function(Object?)>("PassObjectToC");
+
+final handleReadFieldValue =
+    testLibrary.lookupFunction<Int64 Function(Handle), int Function(Object)>(
+        "HandleReadFieldValue");
+
+final trueHandle = testLibrary
+    .lookupFunction<Handle Function(), Object Function()>("TrueHandle");
+
+final closureCallbackThroughHandle = testLibrary.lookupFunction<
+    Void Function(Pointer<NativeFunction<Void Function(Handle)>>, Handle),
+    void Function(Pointer<NativeFunction<Void Function(Handle)>>,
+        Object)>("ClosureCallbackThroughHandle");
+
+final returnHandleInCallback = testLibrary.lookupFunction<
+    Handle Function(Pointer<NativeFunction<Handle Function()>>),
+    Object Function(
+        Pointer<NativeFunction<Handle Function()>>)>("ReturnHandleInCallback");
+
+final handleRecursion = testLibrary.lookupFunction<
+    Handle Function(
+        Handle, Pointer<NativeFunction<Handle Function(Int64)>>, Int64),
+    Object Function(Object, Pointer<NativeFunction<Handle Function(Int64)>>,
+        int)>("HandleRecursion");
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index f6236e8..8513885 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing dart:ffi extra checks
 //
-// SharedObjects=ffi_test_dynamic_library
+// SharedObjects=ffi_test_dynamic_library ffi_test_functions
 
 import 'dart:ffi';
 
@@ -44,6 +44,7 @@
   testNativeFunctionSignatureInvalidParam();
   testNativeFunctionSignatureInvalidOptionalNamed();
   testNativeFunctionSignatureInvalidOptionalPositional();
+  testHandleVariance();
 }
 
 typedef Int8UnOp = Int8 Function(Int8);
@@ -447,3 +448,31 @@
 class IPointer implements Pointer {} //# 814: compile-time error
 
 class IStruct implements Struct {} //# 815: compile-time error
+
+class MyClass {
+  int x;
+  MyClass(this.x);
+}
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
+
+void testHandleVariance() {
+  // Taking a more specific argument is okay.
+  testLibrary.lookupFunction<Handle Function(Handle), Object Function(MyClass)>(
+      "PassObjectToC");
+
+  // Requiring a more specific return type is not, this requires a cast from
+  // the user.
+  testLibrary.lookupFunction< //# 1000: compile-time error
+      Handle Function(Handle), //# 1000: compile-time error
+      MyClass Function(Object)>("PassObjectToC"); //# 1000: compile-time error
+}
+
+class TestStruct1001 extends Struct {
+  Handle handle; //# 1001: compile-time error
+}
+
+class TestStruct1002 extends Struct {
+  @Handle() //# 1002: compile-time error
+  Object handle; //# 1002: compile-time error
+}
diff --git a/tests/ffi_2/ffi_2.status b/tests/ffi_2/ffi_2.status
index c138d83..0991082 100644
--- a/tests/ffi_2/ffi_2.status
+++ b/tests/ffi_2/ffi_2.status
@@ -8,6 +8,9 @@
 [ $compiler != dart2analyzer && $compiler != fasta && $runtime != dart_precompiled && $runtime != vm ]
 *: SkipByDesign # FFI is a VM-only feature. (This test suite is part of the default set.)
 
+[ $compiler == dartkp && $system == windows ]
+vmspecific_handle_test: SkipByDesign # Symbols are not exposed on purpose and are not linked in Windows Precompiled. dartbug.com/40579
+
 [ $system != android && $system != linux && $system != macos && $system != windows ]
 *: Skip # FFI not yet supported on other OSes.
 
diff --git a/tests/ffi_2/vmspecific_handle_test.dart b/tests/ffi_2/vmspecific_handle_test.dart
new file mode 100644
index 0000000..85afae4
--- /dev/null
+++ b/tests/ffi_2/vmspecific_handle_test.dart
@@ -0,0 +1,249 @@
+// 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.
+//
+// SharedObjects=ffi_test_functions
+// VMOptions=--enable-testing-pragmas
+
+import 'dart:ffi';
+
+import 'package:expect/expect.dart';
+
+import 'dylib_utils.dart';
+
+void main() {
+  testHandle();
+  testReadField();
+  testTrueHandle();
+  testClosureCallback();
+  testReturnHandleInCallback();
+  testPropagateError();
+  testCallbackReturnException();
+  testDeepException();
+  testDeepException2();
+  testNull();
+  testDeepRecursive();
+}
+
+void testHandle() {
+  print("testHandle");
+  final s = SomeClass(123);
+  print("passObjectToC($s)");
+  final result = passObjectToC(s);
+  print("result = $result");
+  Expect.isTrue(identical(s, result));
+}
+
+void testReadField() {
+  final s = SomeClass(123);
+  final result = handleReadFieldValue(s);
+  Expect.equals(s.a, result);
+}
+
+void testTrueHandle() {
+  final result = trueHandle();
+  Expect.isTrue(result);
+}
+
+int globalCounter = 0;
+
+void increaseCounter() {
+  print("increaseCounter");
+  globalCounter++;
+}
+
+void doClosureCallback(Object callback) {
+  print("doClosureCallback");
+  print(callback.runtimeType);
+  print(callback);
+  final callback_as_function = callback as void Function();
+  callback_as_function();
+}
+
+final closureCallbackPointer =
+    Pointer.fromFunction<Void Function(Handle)>(doClosureCallback);
+
+void testClosureCallback() {
+  print("testClosureCallback $closureCallbackPointer");
+  Expect.equals(0, globalCounter);
+  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
+  Expect.equals(1, globalCounter);
+  closureCallbackThroughHandle(closureCallbackPointer, increaseCounter);
+  Expect.equals(2, globalCounter);
+}
+
+final someObject = SomeClass(12356789);
+
+Object returnHandleCallback() {
+  print("returnHandleCallback returning $someObject");
+  return someObject;
+}
+
+final returnHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(returnHandleCallback);
+
+void testReturnHandleInCallback() {
+  print("testReturnHandleInCallback");
+  final result = returnHandleInCallback(returnHandleCallbackPointer);
+  Expect.isTrue(identical(someObject, result));
+}
+
+class SomeClass {
+  // We use this getter in the native api, don't tree shake it.
+  @pragma("vm:entry-point")
+  final int a;
+  SomeClass(this.a);
+}
+
+void testPropagateError() {
+  final s = SomeOtherClass(123);
+  Expect.throws(() => handleReadFieldValue(s));
+}
+
+class SomeOtherClass {
+  final int notA;
+  SomeOtherClass(this.notA);
+}
+
+final someException = Exception("exceptionHandleCallback exception");
+
+Object exceptionHandleCallback() {
+  print("exceptionHandleCallback throwing ($someException)");
+  throw someException;
+}
+
+final exceptionHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(exceptionHandleCallback);
+
+void testCallbackReturnException() {
+  print("testCallbackReturnException");
+  bool throws = false;
+  try {
+    final result = returnHandleInCallback(exceptionHandleCallbackPointer);
+    print(result);
+  } catch (e) {
+    throws = true;
+    print("caught ($e)");
+    Expect.isTrue(identical(someException, e));
+  }
+  Expect.isTrue(throws);
+}
+
+Object callCAgainFromCallback() {
+  print("callCAgainFromCallback");
+  final s = SomeOtherClass(123);
+  Expect.throws(() => handleReadFieldValue(s));
+  return someObject;
+}
+
+final callCAgainFromCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback);
+
+void testDeepException() {
+  print("testDeepException");
+  final result = returnHandleInCallback(callCAgainFromCallbackPointer);
+  Expect.isTrue(identical(someObject, result));
+}
+
+Object callCAgainFromCallback2() {
+  print("callCAgainFromCallback2");
+  final s = SomeOtherClass(123);
+  handleReadFieldValue(s); // throws.
+  return someObject;
+}
+
+final callCAgainFromCallbackPointer2 =
+    Pointer.fromFunction<Handle Function()>(callCAgainFromCallback2);
+
+void testDeepException2() {
+  print("testDeepException2");
+  Expect.throws(() => returnHandleInCallback(callCAgainFromCallbackPointer2));
+}
+
+Object returnNullHandleCallback() {
+  print("returnHandleCallback returning null");
+  return null;
+}
+
+final returnNullHandleCallbackPointer =
+    Pointer.fromFunction<Handle Function()>(returnNullHandleCallback);
+
+void testNull() {
+  print("testNull");
+  final result = passObjectToC(null);
+  Expect.isNull(result);
+
+  final result2 = returnHandleInCallback(returnNullHandleCallbackPointer);
+  Expect.isNull(result2);
+}
+
+Object recurseAbove0(int i) {
+  print("recurseAbove0($i)");
+  if (i == 0) {
+    print("throwing");
+    throw someException;
+  }
+  if (i < 0) {
+    print("returning");
+    return someObject;
+  }
+  final result =
+      handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, i - 1);
+  print("return $i");
+  return result;
+}
+
+final recurseAbove0Pointer =
+    Pointer.fromFunction<Handle Function(Int64)>(recurseAbove0);
+
+class SomeClassWithMethod {
+  // We use this method in the native api, don't tree shake it.
+  @pragma("vm:entry-point")
+  Object a(int i) => recurseAbove0(i);
+}
+
+void testDeepRecursive() {
+  // works on arm.
+  Expect.throws(() {
+    handleRecursion(123, recurseAbove0Pointer, 1);
+  });
+
+  Expect.throws(() {
+    handleRecursion(SomeClassWithMethod(), recurseAbove0Pointer, 1);
+  });
+
+  Expect.throws(() {
+    recurseAbove0(100);
+  });
+
+  final result = recurseAbove0(101);
+  Expect.isTrue(identical(someObject, result));
+}
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
+
+final passObjectToC = testLibrary.lookupFunction<Handle Function(Handle),
+    Object Function(Object)>("PassObjectToC");
+
+final handleReadFieldValue =
+    testLibrary.lookupFunction<Int64 Function(Handle), int Function(Object)>(
+        "HandleReadFieldValue");
+
+final trueHandle = testLibrary
+    .lookupFunction<Handle Function(), Object Function()>("TrueHandle");
+
+final closureCallbackThroughHandle = testLibrary.lookupFunction<
+    Void Function(Pointer<NativeFunction<Void Function(Handle)>>, Handle),
+    void Function(Pointer<NativeFunction<Void Function(Handle)>>,
+        Object)>("ClosureCallbackThroughHandle");
+
+final returnHandleInCallback = testLibrary.lookupFunction<
+    Handle Function(Pointer<NativeFunction<Handle Function()>>),
+    Object Function(
+        Pointer<NativeFunction<Handle Function()>>)>("ReturnHandleInCallback");
+
+final handleRecursion = testLibrary.lookupFunction<
+    Handle Function(
+        Handle, Pointer<NativeFunction<Handle Function(Int64)>>, Int64),
+    Object Function(Object, Pointer<NativeFunction<Handle Function(Int64)>>,
+        int)>("HandleRecursion");
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index 410f33f..5645c2a 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -4,7 +4,7 @@
 //
 // Dart test program for testing dart:ffi extra checks
 //
-// SharedObjects=ffi_test_dynamic_library
+// SharedObjects=ffi_test_dynamic_library ffi_test_functions
 
 import 'dart:ffi';
 
@@ -44,6 +44,7 @@
   testNativeFunctionSignatureInvalidParam();
   testNativeFunctionSignatureInvalidOptionalNamed();
   testNativeFunctionSignatureInvalidOptionalPositional();
+  testHandleVariance();
 }
 
 typedef Int8UnOp = Int8 Function(Int8);
@@ -447,3 +448,31 @@
 class IPointer implements Pointer {} //# 814: compile-time error
 
 class IStruct implements Struct {} //# 815: compile-time error
+
+class MyClass {
+  int x;
+  MyClass(this.x);
+}
+
+final testLibrary = dlopenPlatformSpecific("ffi_test_functions");
+
+void testHandleVariance() {
+  // Taking a more specific argument is okay.
+  testLibrary.lookupFunction<Handle Function(Handle), Object Function(MyClass)>(
+      "PassObjectToC");
+
+  // Requiring a more specific return type is not, this requires a cast from
+  // the user.
+  testLibrary.lookupFunction< //# 1000: compile-time error
+      Handle Function(Handle), //# 1000: compile-time error
+      MyClass Function(Object)>("PassObjectToC"); //# 1000: compile-time error
+}
+
+class TestStruct1001 extends Struct {
+  Handle handle; //# 1001: compile-time error
+}
+
+class TestStruct1002 extends Struct {
+  @Handle() //# 1002: compile-time error
+  Object handle; //# 1002: compile-time error
+}
diff --git a/tests/language/class/override_inference_error_test.dart b/tests/language/class/override_inference_error_test.dart
new file mode 100644
index 0000000..f5dc514
--- /dev/null
+++ b/tests/language/class/override_inference_error_test.dart
@@ -0,0 +1,248 @@
+// 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.
+
+// ignore_for_file: unused_local_variable
+
+// Static tests for inheriting types on overriding members.
+
+// If a member `m` omits any parameter type, or the return type, and
+// one or more of the immediate superinterfaces have a member named
+// `m`: Find the combined member signature `s` for `m` in the immediate
+// superinterfaces. A compile-time error occurs if it does not exist.
+// Otherwise, each missing type annotation of a parameter is obtained
+// from the corresponding parameter in `s`, and the return type, if
+// missing, is obtained from `s`. If there is no corresponding
+// parameter in `s`, the inferred type annotation is `dynamic`.
+//
+// Only types are inherited. Other modifiers and annotations are not.
+// This includes `final`, `required` and any annotations
+// or default values.
+// (The `covariant` keyword is not inherited, but its semantics
+// are so it's impossible to tell the difference).
+//
+// For getters and setters, if both are present, subclasses inherit the type of
+// the corresponding superclass member.
+// If the superclass has only a setter or a getter, subclasses inherit that type
+// for both getters and setters.
+
+// Incompatible `foo` signatures.
+abstract class IIntInt {
+  int foo(int x);
+}
+
+abstract class IIntDouble {
+  double foo(int x);
+}
+
+abstract class IDoubleInt {
+  int foo(double x);
+}
+
+abstract class IDoubleDouble {
+  double foo(double x);
+}
+
+// If the superinterfaces do not have a most specific member signature,
+// then omitting any parameter or return type is an error.
+
+abstract class CInvalid1 implements IIntInt, IIntDouble {
+  /*indent*/ foo(x);
+  //         ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+abstract class CInvalid2 implements IIntInt, IDoubleInt {
+  /*indent*/ foo(x);
+  //         ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+abstract class CInvalid3 implements IIntInt, IDoubleDouble {
+  /*indent*/ foo(x);
+  //         ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+// Even if the conflicting super-parameter/return type is given a type.
+abstract class CInvalid4 implements IIntInt, IIntDouble {
+  Never foo(x);
+  //    ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+abstract class CInvalid5 implements IIntInt, IDoubleInt {
+  /*indent*/ foo(num x);
+  //         ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+// Even if the omitted parameter doesn't exist in the super-interfaces.
+abstract class CInvalid6 implements IIntInt, IDoubleInt {
+  Never foo(num x, [y]);
+  //    ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+// And even if there is no real conflict.
+abstract class IOptx {
+  int foo({int x});
+}
+
+abstract class IOpty {
+  int foo({int y});
+}
+
+abstract class CInvalid7 implements IOptx, IOpty {
+  /*indent*/ foo({int x, int y});
+  //         ^^^
+  // [analyzer] unspecified
+  // [cfe] unspecified
+}
+
+// The type of unconstrained omitted types is `dynamic`.
+class CInherit1 implements IOptx {
+  foo({x = 0, y = 0}) {
+    // Type of `y` is `dynamic`.
+    Object? tmp;
+    y = tmp; // Top type.
+    Null tmp2 = y; // And implicit downcast.
+    y.arglebargle(); // And unsound member invocations.
+
+    // x is exactly int.
+    // Assignable to int and usable as int.
+    int intVar = x;
+    x = x.toRadixString(16).length;
+    // And not dynamic.
+    /*indent*/ x.arglebargle();
+    //           ^^^^^^^^^^^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+
+    // Return type is exactly int.
+    if (x == 0) {
+      num tmp3 = x;
+      return tmp3; // Does not allow returning a supertype of int.
+      //     ^^^^
+      // [analyzer] unspecified
+      // [cfe] unspecified
+    }
+    // Allows returning int.
+    return intVar;
+  }
+
+  // No supertype signature, infer `dynamic` for every type.
+  bar(x) {
+    // x is Object?.
+    Object? tmp;
+    x = tmp; // A top type since Object? is assignable to it.
+    Null tmp2 = x; // Implicit downcast.
+    x.arglebargle(); // Unsafe invocations.
+
+    // Return type is `dynamic` when calling `bar`.
+    var ret = bar(x);
+    ret = tmp;
+    tmp2 = ret;
+    ret.arglebargle();
+
+    // And definitely a top type when returning.
+    return tmp;
+  }
+}
+
+/// Do not inherit `required`.
+class IReq {
+  void foo({required int x}) {}
+}
+
+class CInvalid8 implements IReq {
+  // Do not inherit `required` if there is a type.
+  foo({num x}) {}
+  //       ^
+  // [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
+  // [cfe] unspecified
+}
+
+class CInvalid9 implements IReq {
+  // Do not inherit `required` if there is no type.
+  void foo({x}) {}
+  //       ^
+  // [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
+  // [cfe] unspecified
+}
+
+abstract class INonNullable {
+  foo({num x});
+}
+
+class CInvalid10 implements INonNullable {
+  // Inherit type even when it would be invalid in the supertype, if it had been
+  // non-abstract.
+  foo({x}) {}
+  //   ^
+  // [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
+  // [cfe] unspecified
+}
+
+/// Do not inherit default value implicitly.
+class IDefault {
+  int foo({int x = 0}) => x;
+}
+
+class CInvalid11 implements IDefault {
+  foo({x}) => x;
+  //   ^
+  // [analyzer] COMPILE_TIME_ERROR.MISSING_DEFAULT_VALUE_FOR_PARAMETER
+  // [cfe] unspecified
+  //   ^
+  // [analyzer] STATIC_WARNING.INVALID_OVERRIDE_DIFFERENT_DEFAULT_VALUES_NAMED
+}
+
+// Inherits type variables, even with different names.
+class CGeneric<T> {
+  T foo(T x) => x;
+
+  R bar<R>(R x) => x;
+}
+
+class CInheritGeneric<S> implements CGeneric<S> {
+  foo(x) {
+    // x has type exactly S.
+    // Assignable both ways.
+    S tmp = x;
+    x = tmp;
+    // And not dynamic.
+    /*indent*/ x.arglebargle();
+    //           ^^^^^^^^^^^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+
+    // Return type is S.
+    tmp = foo(x);
+    return tmp;
+  }
+
+  bar<Q>(x) {
+    // x has type exactly Q.
+    // Assignable both ways.
+    Q tmp = x;
+    x = tmp;
+    // And not dynamic.
+    /*indent*/ x.arglebargle();
+    //           ^^^^^^^^^^^
+    // [analyzer] unspecified
+    // [cfe] unspecified
+
+    // Return type is Q.
+    tmp = bar<Q>(x);
+    return tmp;
+  }
+}
+
+main() {}
diff --git a/tests/language/class/override_inference_test.dart b/tests/language/class/override_inference_test.dart
new file mode 100644
index 0000000..8bbd678
--- /dev/null
+++ b/tests/language/class/override_inference_test.dart
@@ -0,0 +1,444 @@
+// 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 that inheriting types on overriding members work as specified.
+
+// ignore_for_file: unused_local_variable
+
+import "package:expect/expect.dart";
+
+// Helper variables.
+int intVar = 0;
+List<int> listIntVar = <int>[];
+int? intQVar;
+List<int?> listIntQVar = <int?>[];
+num numVar = 0;
+List<num> listNumVar = <num>[];
+
+/// Override can work with incompatible superinterfaces,
+/// as long as override is more specific than all of them,
+/// and it specifies all types.
+class IIntOpts {
+  int foo(int x, {int v = 0, required int z}) => x;
+}
+
+class IDoubleOpts {
+  double foo(double x, {double w = 0.0, int z = 1}) => x;
+}
+
+class CNumOpts implements IIntOpts, IDoubleOpts {
+  // Override is more specific than all supertype members.
+  Never foo(num x, {int v = 0, double w = 0.0, int z = 1}) => throw "Never";
+}
+
+// When a type is omitted, the most specific immediate superinterface member
+// signature is used. One such must exist.
+
+class IIntInt {
+  int foo(int x) => x;
+}
+
+class INumInt {
+  int foo(num x) => x.toInt();
+}
+
+class IIntNum {
+  num foo(int x) => x.toInt();
+}
+
+class IInt {
+  void foo(int x) {}
+}
+
+class IIntQ {
+  void foo(int? x) {}
+}
+
+class IOpt1 {
+  void foo([int x = 0]) {}
+}
+
+class IOpt2 {
+  void foo([int x = 0, int y = 0]) {}
+}
+
+class IOptX {
+  void foo({int x = 0}) {}
+}
+
+class IOptXY {
+  void foo({int x = 0, int y = 0}) {}
+}
+
+abstract class IOptA1 {
+  void foo([int x]);
+}
+
+abstract class IOptAX {
+  void foo({int x});
+}
+
+class IReq {
+  void foo({required int x}) {}
+}
+
+// Type is inherited as long as no other type is written.
+// Even if prefixed by `var`, `final`, `required` or `covariant`,
+// or if made optional with or without a default value.
+class CVar implements IIntInt {
+  foo(var x) {
+    // Checks that x is exactly int.
+    // It is assignable in both directions, and it's not dynamic.
+    intVar = x;
+    x = intVar;
+    var xList = [x];
+    listIntVar = xList;
+    return itVar;
+  }
+}
+
+class CFinal implements IInt {
+  foo(final x) {
+    var sameTypeAsX = x;
+    intVar = x;
+    sameTypeAsX = intVar;
+    var xList = [x];
+    listIntVar = xList;
+  }
+}
+
+class COptDefault implements IInt {
+  foo([x = 0]) {
+    intVar = x;
+    x = intVar;
+    var xList = [x];
+    listIntVar = xList;
+  }
+}
+
+// Must use the nullable type when not having a default.
+class COptNoDefault implements IIntQ {
+  foo([x]) {
+    int? tmp = x;
+    x = tmp;
+    var xList = [x];
+    listIntQVar = xList;
+  }
+}
+
+class CReq implements IReq {
+  foo({required x}) {
+    intVar = x;
+    x = intVar;
+    var xList = [x];
+    listIntQVar = xList;
+  }
+}
+
+// Do inherit when specifying `covariant`.
+class CCovar implements IInt {
+  foo(covariant x) {
+    intVar = x;
+    x = intVar;
+    var xList = [x];
+    listIntVar = xList;
+  }
+}
+
+class CCovar2 implements CCovar {
+  // Method was covariant in CCovar.
+  foo(Never x) => 0;
+}
+
+/// A more specific `foo` than [IInt.foo].
+/// Subclass inherits types from most specific superclass member.
+class CInherit1 implements INumInt, IIntNum {
+  foo(x) {
+    // x is num.
+    numVar = x;
+    x = numVar;
+    var xList = [x];
+    listNumVar = xList;
+
+    // return type is int.
+    var ret = foo(x);
+    intVar = ret;
+    ret = intVar;
+    var retList = [ret];
+    listIntVar = retList;
+    return 0;
+  }
+}
+
+class CInherit2 extends INumInt implements IIntNum {
+  foo(x) {
+    numVar = x;
+    x = numVar;
+    var xList = [x];
+    listNumVar = xList;
+
+    var ret = foo(x);
+    intVar = ret;
+    ret = intVar;
+    var retList = [ret];
+    listIntVar = retList;
+    return 0;
+  }
+}
+
+class CInherit3 extends IIntNum implements INumInt {
+  foo(x) {
+    numVar = x;
+    x = numVar;
+    var xList = [x];
+    listNumVar = xList;
+
+    var ret = foo(x);
+    intVar = ret;
+    ret = intVar;
+    var retList = [ret];
+    listIntVar = retList;
+    return intVar;
+  }
+}
+
+class CInherit4 with IIntNum implements INumInt {
+  foo(x) {
+    numVar = x;
+    x = numVar;
+    var xList = [x];
+    listNumVar = xList;
+
+    var ret = foo(x);
+    intVar = ret;
+    ret = intVar;
+    var retList = [ret];
+    listIntVar = retList;
+    return intVar;
+  }
+}
+
+void testInheritFull() {
+  Expect.type<int Function(num)>(CInherit1().foo);
+  Expect.type<int Function(num)>(CInherit2().foo);
+  Expect.type<int Function(num)>(CInherit3().foo);
+  Expect.type<int Function(num)>(CInherit4().foo);
+}
+
+/// Works for optional parameters too.
+
+class COptInherit1 implements IOpt1, IOpt2 {
+  foo([x = 0, y = 0]) {
+    intVar = x;
+    x = intVar;
+    var listX = [x];
+    listIntVar = listX;
+
+    intVar = y;
+    y = intVar;
+    var listY = [y];
+    listIntVar = listY;
+  }
+}
+
+class COptInherit2 implements IOptX, IOptXY {
+  foo({x = 0, y = 0}) {
+    intVar = x;
+    x = intVar;
+    var listX = [x];
+    listIntVar = listX;
+
+    intVar = y;
+    y = intVar;
+    var listY = [y];
+    listIntVar = listY;
+  }
+}
+
+class COptInherit3 implements IIntInt, INumInt {
+  foo(x, [y]) {
+    // Ensure that type is: int Function(num, [dynamic]) .
+    // For static checks only, do not call the method!
+
+    // x is exactly num.
+    numVar = x;
+    x = numVar;
+    var listX = [x];
+    listNumVar = listX;
+
+    // y is dynamic.
+    Object? tmpObject;
+    y = tmpObject; // A top type.
+    Null tmpNull = y; // Implicit downcast.
+    y.arglebargle(); // Unsound member invocations.
+
+    // return type is exactly int.
+    var ret = foo(x, y);
+    intVar = ret;
+    ret = intVar;
+    var retList = [ret];
+    listIntVar = retList;
+    return intVar;
+  }
+}
+
+class COptInherit4 implements IOptA1 {
+  foo([x = 1]) {
+    intVar = x;
+    x = intVar;
+    var listX = [x];
+    listIntVar = listX;
+  }
+}
+
+class COptInherit5 implements IOptAX {
+  foo({x = 1}) {
+    intVar = x;
+    x = intVar;
+    var listX = [x];
+    listIntVar = listX;
+  }
+}
+
+void testInheritOpt() {
+  Expect.type<void Function([int, int])>(COptInherit1().foo);
+  Expect.type<void Function({int x, int y})>(COptInherit2().foo);
+  Expect.type<int Function(num, [dynamic])>(COptInherit3().foo);
+  Expect.type<void Function([int])>(COptInherit4().foo);
+  Expect.type<void Function({int x})>(COptInherit5().foo);
+}
+
+// Do not inherit `final` with the type.
+class IFinal {
+  void foo(final int x) {}
+}
+
+class CInheritFinal implements IFinal {
+  void foo(x) {
+    x = 42;
+    x.toRadixString(16);
+  }
+}
+
+// Also applies to getters and setters.
+class IGetSetInt {
+  int get foo => 0;
+  set foo(int _) {}
+}
+
+class IFieldInt {
+  int foo = 0;
+}
+
+class ILateFieldInt {
+  late int foo;
+}
+
+class IFinalFieldInt {
+  final int foo = 0;
+}
+
+class CInheritGetSet implements IGetSetInt {
+  get foo => throw "whatever";
+  set foo(set) {
+    // For static checking only, do not call.
+    // `set` is assignable both ways to int.
+    intVar = set;
+    set = intVar;
+    var listSet = [set];
+    listIntVar = listSet;
+
+    var get = foo;
+    // get is assignable both ways to int.
+    intVar = get;
+    get = intVar;
+    var listGet = [get];
+    listIntVar = listGet;
+  }
+}
+
+class CInheritField implements IFieldInt {
+  get foo => throw "whatever";
+  set foo(set) {
+    // For static checking only, do not call.
+    // `set` is assignable both ways to int.
+    intVar = set;
+    set = intVar;
+    var listSet = [set];
+    listIntVar = listSet;
+
+    var get = foo;
+    // get is assignable both ways to int.
+    intVar = get;
+    get = intVar;
+    var listGet = [get];
+    listIntVar = listGet;
+  }
+}
+
+class CInheritLateField implements ILateFieldInt {
+  get foo => throw "whatever";
+  set foo(set) {
+    // For static checking only, do not call.
+    // `set` is assignable both ways to int.
+    intVar = set;
+    set = intVar;
+    var listSet = [set];
+    listIntVar = listSet;
+
+    var get = foo;
+    // get is assignable both ways to int.
+    intVar = get;
+    get = intVar;
+    var listGet = [get];
+    listIntVar = listGet;
+  }
+}
+
+class CInheritFinalField implements IFinalFieldInt {
+  get foo => throw "whatever";
+  set foo(set) {
+    // For static checking only, do not call.
+
+    // `set` is assignable both ways to int.
+    intVar = set;
+    set = intVar;
+    var listSet = [set];
+    listIntVar = listSet;
+
+    var get = foo; // Is int.
+    // get is assignable both ways to int.
+    intVar = get;
+    get = intVar;
+    var listGet = [get];
+    listIntVar = listGet;
+  }
+}
+
+class ISetterOnly {
+  set foo(int value) {}
+}
+
+class IInheritSetter implements ISetterOnly {
+  // Infers `int` as return type.
+  get foo => throw "whatever";
+
+  set foo(value) {
+    int tmp = value;
+    value = tmp;
+    var valueList = [value];
+    List<int> list = valueList;
+
+    var get = foo;
+    intVar = get;
+    get = intVar;
+    var getList = [get];
+    list = getList;
+  }
+}
+
+void main() {
+  testInheritFull();
+  testInheritOpt();
+}
diff --git a/tests/language/mixin/illegal_super_use_test.dart b/tests/language/mixin/illegal_super_use_test.dart
index 4796185..89c3a76 100644
--- a/tests/language/mixin/illegal_super_use_test.dart
+++ b/tests/language/mixin/illegal_super_use_test.dart
@@ -76,14 +76,8 @@
 
 class C = Object with M;
 class D = Object with P0;
-//                    ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 class E = Object with M, P1;
-//                       ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 class F = Object with P2, M;
-//                    ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 
 main() {
   var p1 = new P1();
diff --git a/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.dart b/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.dart
new file mode 100644
index 0000000..58d2081
--- /dev/null
+++ b/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.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 "mixin_constructor_parameter_forwarding_test.dart";
+
+// A private class that the mixin application cannot access syntactically,
+// yet it needs an instance of it for the default value.
+class _Private {
+  const _Private();
+}
+
+class B2<T> implements B<T> {
+  final T x;
+  final Object y;
+  const B2(T x, [Object y = const _Private()])
+      : x = x,
+        y = y;
+}
+
+// Leaking the constant value in a non-constant way which cannot be used
+// for the default value of the mixin application.
+Object get privateValue => const _Private();
diff --git a/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart b/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart
new file mode 100644
index 0000000..0aba8b9
--- /dev/null
+++ b/tests/language/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart
@@ -0,0 +1,77 @@
+// 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.
+
+// Tests that mixin application forwarding constructors correctly forward
+// optional parameter default values.
+
+import "package:expect/expect.dart";
+
+import "mixin_constructor_parameter_forwarding_helper.dart"
+    show B2, privateValue;
+
+class B<T> {
+  final T x;
+  final Object y;
+  const B(T x, [Object y = 0])
+      : x = x,
+        y = y;
+  const B.b1(T x, {Object y = 0})
+      : x = x,
+        y = y;
+  const B.b2(T x, [Object y = const <int>[0]])
+      : x = x,
+        y = y;
+}
+
+mixin M1 on B<int> {
+  void check(int x, Object y) {
+    Expect.identical(x, this.x);
+    Expect.identical(y, this.y);
+  }
+}
+
+mixin M2<T> on B<T> {
+  void check(T x, Object y) {
+    Expect.identical(x, this.x);
+    Expect.identical(y, this.y);
+  }
+}
+
+class A1 = B<int> with M1;
+class A2 = B<int> with M2<int>;
+class P1 = B2<int> with M2<int>;
+
+main() {
+  A1(1, 2).check(1, 2);
+  A1.b1(1, y: 2).check(1, 2);
+  A1.b2(1, 2).check(1, 2);
+  A2(1, 2).check(1, 2);
+  A2.b1(1, y: 2).check(1, 2);
+  A2.b2(1, 2).check(1, 2);
+  P1(1, 2).check(1, 2);
+
+  A1(1).check(1, 0);
+  A1.b1(1).check(1, 0);
+  A1.b2(1).check(1, const <int>[0]);
+  A2(1).check(1, 0);
+  A2.b1(1).check(1, 0);
+  A2.b2(1).check(1, const <int>[0]);
+  P1(1).check(1, privateValue);
+
+  const A1(1, 2).check(1, 2);
+  const A1.b1(1, y: 2).check(1, 2);
+  const A1.b2(1, 2).check(1, 2);
+  const A2(1, 2).check(1, 2);
+  const A2.b1(1, y: 2).check(1, 2);
+  const A2.b2(1, 2).check(1, 2);
+  const P1(1, 2).check(1, 2);
+
+  const A1(1).check(1, 0);
+  const A1.b1(1).check(1, 0);
+  const A1.b2(1).check(1, const <int>[0]);
+  const A2(1).check(1, 0);
+  const A2.b1(1).check(1, 0);
+  const A2.b2(1).check(1, const <int>[0]);
+  const P1(1).check(1, privateValue);
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_factory_test.dart b/tests/language/mixin_declaration/mixin_declaration_factory_test.dart
new file mode 100644
index 0000000..fd0e66a
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_factory_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+// A mixin declaration cannot declare any (factory) constructors.
+
+class A {}
+
+class B implements A {
+  const B();
+}
+
+mixin M on A {
+  factory M.foo() => throw "uncalled"; //# 01: compile-time error
+  const factory M.bar() = B; //# 02: compile-time error
+  M.baz(); //# 03: compile-time error
+}
+
+class MA extends A with M {}
+
+class N {
+  // It's OK for a mixin derived from a class to have factory constructors.
+  factory N.quux() => throw "uncalled"; //# none: ok
+  N.bar(); //# 04: compile-time error
+}
+
+class NA extends A with N {}
+
+main() {
+  new MA();
+  new NA();
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart
new file mode 100644
index 0000000..5d99d2f
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_00_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I with M0<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart
new file mode 100644
index 0000000..749d813
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_01_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> on I<T> {}
+
+mixin M1<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I with M0, M1<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart
new file mode 100644
index 0000000..01ae1ae
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_02_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+mixin M1<T> on I<T> {}
+
+///////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 with M0, M1<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart
new file mode 100644
index 0000000..5741700
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_03_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference happens from superclasses to subclasses
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends Object with M0 implements I<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart
new file mode 100644
index 0000000..50d017b
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_04_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 with M0 implements I<int> {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart
new file mode 100644
index 0000000..38e681e
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_05_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<T> implements I<T> {}
+
+mixin M1<T> implements I<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+// Error since class hierarchy is inconsistent
+class A00 extends I<int> with M0<int>, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart
new file mode 100644
index 0000000..14c2416
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_06_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+class I<X> {}
+class J<X> {}
+
+mixin M0<S, T> implements I<S>, J<T> {}
+
+mixin M1<S, T> implements I<S>, J<T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not use implements constraints on mixin
+///////////////////////////////////////////////////////
+
+class A00 extends I<int> with M0 {}
+
+class A01 extends J<int> with M1 {}
+
+// Error since class hierarchy is inconsistent
+class A02 extends A00 implements A01 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart
new file mode 100644
index 0000000..9b16c66
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_07_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+class I<X> {}
+
+mixin M0<X, Y extends Comparable<Y>> on I<X> {}
+
+class M1 implements I<int> {}
+
+//////////////////////////////////////////////////////
+// Inference does not produce super-bounded types
+///////////////////////////////////////////////////////
+
+// M0 is inferred as M0<int, Comparable<dynamic>>
+// Error since super-bounded type not allowed
+class A extends M1 with M0 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart
new file mode 100644
index 0000000..23da50d3
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_08_test.dart
@@ -0,0 +1,21 @@
+// 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.
+
+class I<X, Y> {}
+
+mixin M0<T> implements I<T, int> {}
+
+mixin M1<T> implements I<String, T> {}
+
+//////////////////////////////////////////////////////
+// Inference is not bi-directional
+///////////////////////////////////////////////////////
+
+
+// M0<String>, M1<int> is a solution, but we shouldn't find it
+// M0 inferred as M0<dynamic>
+// M1 inferred as M1<dynamic>
+class A with M0, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart
new file mode 100644
index 0000000..0ebdf97
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_09_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+class I<X, Y> {}
+
+mixin M0<T> implements I<T, List<T>> {}
+
+mixin M1<T> implements I<List<T>, T> {}
+
+//////////////////////////////////////////////////////
+// Inference does not produce infinite types
+///////////////////////////////////////////////////////
+
+// No solution, even with unification, since solution
+// requires that I<List<U0>, U0> == I<U1, List<U1>>
+// for some U0, U1, and hence that:
+// U0 = List<U1>
+// U1 = List<U0>
+// which has no finite solution
+class A with M0, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart
new file mode 100644
index 0000000..00563ef
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_10_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+class I<T> {}
+class J<T> {}
+mixin M0<T> implements I<T>, J<T> {}
+
+//////////////////////////////////////////////////////
+// Over-constrained results are caught
+///////////////////////////////////////////////////////
+
+class A with I<int>, J<double>, M0 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_invalid_11_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_11_test.dart
new file mode 100644
index 0000000..c7de81e
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_invalid_11_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+class I<T> {}
+mixin M1<T> on I<T> {}
+
+//////////////////////////////////////////////////////
+// Mixin type argument inference is not performed on
+// the "on" clause of a mixin
+///////////////////////////////////////////////////////
+
+mixin A00Mixin on I<int>, M1 {} /*@compile-error=unspecified*/
+
+void main() {}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A00_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A00_test.dart
new file mode 100644
index 0000000..f4bc9ea
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A00_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A00 extends I<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A00()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A01_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A01_test.dart
new file mode 100644
index 0000000..02ca387
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A01_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A01 extends C0<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A01()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A02_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A02_test.dart
new file mode 100644
index 0000000..a244f33
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A02_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A02 extends C1<int> with M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A02()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A10_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A10_test.dart
new file mode 100644
index 0000000..074af2a
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A10_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A10 extends I<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A10()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A11_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A11_test.dart
new file mode 100644
index 0000000..a3a1cdb
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A11_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A11 extends C0<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A11()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A12_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A12_test.dart
new file mode 100644
index 0000000..9a1d867
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A12_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class A12 extends C1<int> with M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new A12()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A20_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A20_test.dart
new file mode 100644
index 0000000..77f9287
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A20_test.dart
@@ -0,0 +1,44 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M4 is inferred as M4<int, double>
+class A20 extends C2 with M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M4<int, double>>(new A20()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A21_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A21_test.dart
new file mode 100644
index 0000000..39512ba
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A21_test.dart
@@ -0,0 +1,44 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M4 is inferred as M4<int, double>
+class A21 extends C3 with M2<int>, M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M4<int, double>>(new A21()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A22_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A22_test.dart
new file mode 100644
index 0000000..09b5248
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A22_test.dart
@@ -0,0 +1,47 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M4 is inferred as M4<int, double>
+class A22 extends C2 with M1, M4 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M4<int, double>>(new A22()..check());
+  Expect.type<M1<int>>(new A22()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A23_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A23_test.dart
new file mode 100644
index 0000000..b4ac01c
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A23_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin _M5<T> on I<T> implements J<T> {}
+
+// Inference here puts J<int> in the superclass hierarchy
+class _A23 extends C0<int> with _M5 {}
+
+// Inference here should get J<int> for M4.T
+// if inference for _M5 is done first (correctly)
+// and otherwise J<dynamic>
+class A23 extends _A23 with M4 {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M4<int, int>>(new A23()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A30_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A30_test.dart
new file mode 100644
index 0000000..d420ec1
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A30_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin M5<S, T extends String> on I<S> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M5 is inferred as M5<int, String>
+class A30 extends C0<int> with M5 {
+  void check() {
+    // Verify that M5.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M5.T is exactly String
+    String Function(String) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M5<int, String>>(new A30()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A31_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A31_test.dart
new file mode 100644
index 0000000..59d0f41
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A31_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin M6<S, T extends S> on I<S> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M6 is inferred as M6<int, int>
+class A31 extends C0<int> with M6 {
+  void check() {
+    // Verify that M6.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M6.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+void main() {
+  Expect.type<M6<int, int>>(new A31()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_A42_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A42_test.dart
new file mode 100644
index 0000000..2539a5f
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_A42_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin M7<T> on I<List<T>> {
+  T Function(T) get value0 => (param) => param;
+}
+
+class A40<T> extends I<List<T>> {}
+
+class A41<T> extends A40<Map<T, T>> {}
+
+// M7 is inferred as M7<Map<int, int>>
+class A42 extends A41<int> with M7 {
+  void check() {
+    // Verify that M7.T is exactly Map<int, int>
+    Map<int, int> Function(Map<int, int>) f1 = this.value0;
+  }
+}
+
+void main() {
+  Expect.type<M7<Map<int, int>>>(new A42()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B00_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B00_test.dart
new file mode 100644
index 0000000..3a834f0
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B00_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B00 extends Object with I<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B00()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B01_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B01_test.dart
new file mode 100644
index 0000000..b4086d4
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B01_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B01 extends Object with C1<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B01()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B02_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B02_test.dart
new file mode 100644
index 0000000..2ea1cad
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B02_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B02 extends I<int> with M0<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B02()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B03_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B03_test.dart
new file mode 100644
index 0000000..4e2a42b
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B03_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B03 extends Object with M2<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B03()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B10_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B10_test.dart
new file mode 100644
index 0000000..f299b60
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B10_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B10 extends Object with I<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B10()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B11_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B11_test.dart
new file mode 100644
index 0000000..cc84076
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B11_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B11 extends Object with C1<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B11()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B12_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B12_test.dart
new file mode 100644
index 0000000..d4e76c2
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B12_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B12 extends I<int> with M0<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B12()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_B13_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B13_test.dart
new file mode 100644
index 0000000..da1ed34
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_B13_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class B13 extends Object with M2<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new B13()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C00_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C00_test.dart
new file mode 100644
index 0000000..ed966d3
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C00_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C00 with I<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C00()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C01_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C01_test.dart
new file mode 100644
index 0000000..2157800
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C01_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C01 with C1<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C01()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C02_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C02_test.dart
new file mode 100644
index 0000000..c1f8c8b
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C02_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C02 with I<int>, M0<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C02()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C03_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C03_test.dart
new file mode 100644
index 0000000..32bbd55
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C03_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C03 with M2<int>, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C03()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C10_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C10_test.dart
new file mode 100644
index 0000000..c9613ac
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C10_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C10 with I<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C10()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C11_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C11_test.dart
new file mode 100644
index 0000000..95be3db
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C11_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C11 with C1<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C11()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C12_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C12_test.dart
new file mode 100644
index 0000000..3283072
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C12_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C12 with I<int>, M0<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C12()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_C13_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C13_test.dart
new file mode 100644
index 0000000..b272a64
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_C13_test.dart
@@ -0,0 +1,42 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+// M1 is inferred as M1<int>
+class C13 with M2<int>, M3, M1 {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+void main() {
+  Expect.type<M1<int>>(new C13()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_inference_valid_mixin_applications_test.dart b/tests/language/mixin_declaration/mixin_declaration_inference_valid_mixin_applications_test.dart
new file mode 100644
index 0000000..e65596e
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_inference_valid_mixin_applications_test.dart
@@ -0,0 +1,446 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+///////////////////////////////////////////////////////
+// Tests for inference of type arguments to mixins in
+// class definition mixin applications of the form
+// `class Foo = A with M`
+///////////////////////////////////////////////////////
+
+class I<X> {}
+
+class C0<T> extends I<T> {}
+class C1<T> implements I<T> {}
+
+mixin M0<T> on I<T> {
+}
+
+mixin M1<T> on I<T> {
+  T Function(T) get value => (param) => param;
+}
+
+mixin M2<T> implements I<T> {}
+
+mixin M3<T> on I<T> {}
+
+class J<X> {}
+class C2 extends C1<int> implements J<double> {}
+class C3 extends J<double> {}
+
+mixin M4<S, T> on I<S>, J<T> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from a super class works
+///////////////////////////////////////////////////////
+
+mixin A00Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A00 = I<int> with M1, A00Mixin;
+
+mixin A01Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A01 = C0<int> with M1, A01Mixin;
+
+mixin A02Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A02 = C1<int> with M1, A02Mixin;
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+///////////////////////////////////////////////////////
+
+mixin B00Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B00 = Object with I<int>, M1, B00Mixin;
+
+mixin B01Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B01 = Object with C1<int>, M1, B01Mixin;
+
+mixin B02Mixin on M0<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B02 = I<int> with M0<int>, M1, B02Mixin;
+
+mixin B03Mixin on M2<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B03 = Object with M2<int>, M1, B03Mixin;
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+// with the shorthand syntax
+///////////////////////////////////////////////////////
+
+mixin C00Mixin on M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C00 = Object with I<int>, M1, C00Mixin;
+
+mixin C01Mixin on C1<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C01 = Object with C1<int>, M1, C01Mixin;
+
+mixin C02Mixin on M0<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C02 = Object with I<int>, M0<int>, M1, C02Mixin;
+
+mixin C03Mixin on M2<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C03 = Object with M2<int>, M1, C03Mixin;
+
+///////////////////////////////////////////////////////
+// Inference of two mixins from a super class works
+///////////////////////////////////////////////////////
+
+mixin A10Mixin on M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A10 = I<int> with M3, M1, A10Mixin;
+
+mixin A11Mixin on C0<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A11 = C0<int> with M3, M1, A11Mixin;
+
+mixin A12Mixin on C1<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class A12 = C1<int> with M3, M1, A12Mixin;
+
+///////////////////////////////////////////////////////
+// Inference of two mixins from another mixin works
+///////////////////////////////////////////////////////
+
+mixin B10Mixin on I<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B10 = Object with I<int>, M3, M1, B10Mixin;
+
+mixin B11Mixin on C1<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B11 = Object with C1<int>, M3, M1, B11Mixin;
+
+mixin B12Mixin on I<int>, M0<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B12 = I<int> with M0<int>, M3, M1, B12Mixin;
+
+mixin B13Mixin on M2<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class B13 = Object with M2<int>, M3, M1, B13Mixin;
+
+///////////////////////////////////////////////////////
+// Inference of a single mixin from another mixin works
+// with the shorthand syntax
+///////////////////////////////////////////////////////
+
+mixin C10Mixin on I<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C10 = Object with I<int>, M3, M1, C10Mixin;
+
+mixin C11Mixin on C1<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C11 = Object with C1<int>, M3, M1, C11Mixin;
+
+mixin C12Mixin on I<int>, M0<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C12 = Object with I<int>, M0<int>, M3, M1, C12Mixin;
+
+mixin C13Mixin on M2<int>, M3<int>, M1<int> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+  }
+}
+
+// M1 is inferred as M1<int>
+class C13 = Object with M2<int>, M3, M1, C13Mixin;
+
+
+///////////////////////////////////////////////////////
+// Inference from multiple constraints works
+///////////////////////////////////////////////////////
+
+
+mixin A20Mixin on C2, M4<int, double> {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+// M4 is inferred as M4<int, double>
+class A20 = C2 with M4, A20Mixin;
+
+mixin A21Mixin on C3, M2<int>, M4<int, double> {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+// M4 is inferred as M4<int, double>
+class A21 = C3 with M2<int>, M4, A21Mixin;
+
+mixin A22Mixin on C2, M1<int>, M4<int, double> {
+  void check() {
+    // Verify that M1.T is exactly int
+    int Function(int) f = this.value;
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly double
+    double Function(double) f1 = this.value1;
+  }
+}
+
+// M4 is inferred as M4<int, double>
+class A22 = C2 with M1, M4, A22Mixin;
+
+mixin _M5<T> on I<T> implements J<T> {}
+
+// Inference here puts J<int> in the superclass hierarchy
+class _A23 extends C0<int> with _M5 {}
+
+mixin A23Mixin on _A23, M4<int, int> {
+  void check() {
+    // Verify that M4.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M4.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+// Inference here should get J<int> for M4.T
+// if inference for _A23 is done first (correctly)
+// and otherwise J<dynamic>
+class A23 = _A23 with M4, A23Mixin;
+
+///////////////////////////////////////////////////////
+// Unconstrained parameters go to bounds
+///////////////////////////////////////////////////////
+
+mixin M5<S, T extends String> on I<S> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin M6<S, T extends S> on I<S> {
+  S Function(S) get value0 => (param) => param;
+  T Function(T) get value1 => (param) => param;
+}
+
+mixin A30Mixin on C0<int>, M5<int, String> {
+  void check() {
+    // Verify that M5.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M5.T is exactly String
+    String Function(String) f1 = this.value1;
+  }
+}
+
+// M5 is inferred as M5<int, String>
+class A30 = C0<int> with M5, A30Mixin;
+
+mixin A31Mixin on C0<int>, M6<int, int> {
+  void check() {
+    // Verify that M6.S is exactly int
+    int Function(int) f0 = this.value0;
+    // Verify that M6.T is exactly int
+    int Function(int) f1 = this.value1;
+  }
+}
+
+// M6 is inferred as M6<int, int>
+class A31 = C0<int> with M6, A31Mixin;
+
+///////////////////////////////////////////////////////
+// Non-trivial constraints should work
+///////////////////////////////////////////////////////
+
+mixin M7<T> on I<List<T>> {
+  T Function(T) get value0 => (param) => param;
+}
+
+class A40<T> extends I<List<T>> {}
+
+class A41<T> extends A40<Map<T, T>> {}
+
+mixin A42Mixin on A41<int>, M7<Map<int, int>> {
+  void check() {
+    // Verify that M7.T is exactly Map<int, int>
+    Map<int, int> Function(Map<int, int>) f1 = this.value0;
+  }
+}
+
+// M7 is inferred as M7<Map<int, int>>
+class A42 = A41<int> with M7, A42Mixin;
+
+void main() {
+  Expect.type<M1<int>>(new A00()..check());
+  Expect.type<M1<int>>(new A01()..check());
+  Expect.type<M1<int>>(new A02()..check());
+
+  Expect.type<M1<int>>(new B00()..check());
+  Expect.type<M1<int>>(new B01()..check());
+  Expect.type<M1<int>>(new B02()..check());
+  Expect.type<M1<int>>(new B03()..check());
+
+  Expect.type<M1<int>>(new C00()..check());
+  Expect.type<M1<int>>(new C01()..check());
+  Expect.type<M1<int>>(new C02()..check());
+  Expect.type<M1<int>>(new C03()..check());
+
+  Expect.type<M1<int>>(new A10()..check());
+  Expect.type<M1<int>>(new A11()..check());
+  Expect.type<M1<int>>(new A12()..check());
+
+  Expect.type<M1<int>>(new B10()..check());
+  Expect.type<M1<int>>(new B11()..check());
+  Expect.type<M1<int>>(new B12()..check());
+  Expect.type<M1<int>>(new B13()..check());
+
+  Expect.type<M1<int>>(new C10()..check());
+  Expect.type<M1<int>>(new C11()..check());
+  Expect.type<M1<int>>(new C12()..check());
+  Expect.type<M1<int>>(new C13()..check());
+
+  Expect.type<M4<int, double>>(new A20()..check());
+  Expect.type<M4<int, double>>(new A21()..check());
+  Expect.type<M4<int, double>>(new A22()..check());
+  Expect.type<M1<int>>(new A22()..check());
+  Expect.type<M4<int, int>>(new A23()..check());
+
+  Expect.type<M5<int, String>>(new A30()..check());
+  Expect.type<M6<int, int>>(new A31()..check());
+
+  Expect.type<M7<Map<int, int>>>(new A42()..check());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart
new file mode 100644
index 0000000..08e33a6
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_application_supertype_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various invalid mixin applications where the supertype doesn't
+// implement the super-interfaces.
+
+abstract class UnaryNum {
+  num foo(num x) => x;
+}
+
+abstract class UnaryInt {
+  num foo(int x) => x;
+}
+
+mixin M1 on UnaryNum {}
+
+class _ = Object with M1; //# 01: compile-time error
+class _ = Null with M1; //# 02: compile-time error
+class _ = UnaryInt with M1;  //# 03: compile-time error
+
+mixin M2 on UnaryNum, UnaryInt {}
+
+class _ = UnaryInt with M2;  //# 04: compile-time error
+class _ = UnaryNum with M2;  //# 05: compile-time error
+
+// Note that it is not sufficient for the application to declare that it
+// implements the super-interface.
+abstract class _ = Object with M1 implements UnaryNum;  //# 06: compile-time error
+
+// Nor is it sufficient, in the case of an anonymous mixin application, for the
+// containing class to declare that it implements the super-interface.
+abstract class _ extends Object with M1 implements UnaryNum {}  //# 07: compile-time error
+
+main() {
+  // M1 and M2 are valid types.
+  Expect.notType<M1>(null);
+  Expect.notType<M2>(null);
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_override_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_override_test.dart
new file mode 100644
index 0000000..2b4da04
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_override_test.dart
@@ -0,0 +1,66 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various invalid super-constraints for mixin declarations.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+// Overides must still be valid, wrt. signatures and types.
+
+mixin M3 on UnaryNum {
+  // M3.foo is a valid override of UnaryNum.foo
+  num foo(num x) => super.foo(x) * 2;
+}
+
+// Invalid signature override (overriding optional parameter with required).
+class C3 implements UnaryNum {
+  // C3.foo is a valid override of UnaryNum.foo
+  num foo([num x = 17]) => x;
+}
+// M3.foo is not a valid override for C3.foo.
+class A3 extends C3 //
+    with M3 //# 06: compile-time error
+{}
+
+// Invalid type override (overriding `int` return with `num` return).
+class C4 implements UnaryNum {
+  // C4.foo is a valid override of UnaryNum.foo
+  int foo(num x) => x.toInt();
+}
+// M3.foo is not a valid override for C4.foo.
+class A4 extends C4 //
+    with M3 //# 07: compile-time error
+{}
+
+// It's not required to have an implementation of members which are not super-
+// invoked, if the application class is abstract.
+abstract class C5 {
+  num foo(num x);
+  num bar(num x);
+}
+mixin M5 on C5 {
+  num baz(num x) => super.foo(x);
+}
+abstract class C5Foo implements C5 {
+  num foo(num x) => x;
+}
+abstract class C5Bar implements C5 {
+  num bar(num x) => x;
+}
+
+// Valid abstract class, super-invocation of foo hits implementation,
+// even if bar is still abstract.
+abstract class A5Foo = C5Foo with M5;
+// Invalid since super-invocaton of foo does not hit concrete implementation.
+abstract class _ = C5Bar with M5;  //# 08: compile-time error
+
+class A5FooConcrete = A5Foo with C5Bar;
+
+main() {
+  Expect.equals(42, A5FooConcrete().baz(42));
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart
new file mode 100644
index 0000000..8e5e9ae
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_superinvocation_test.dart
@@ -0,0 +1,61 @@
+// 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.
+
+// Test various invalid super-invocations for mixin declarations.
+
+abstract class UnaryInt {
+  num foo(int x);
+}
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryOptionalNum {
+  num foo([num x]);
+}
+
+// Mixins may contain super-invocations.
+// The super-invocation must be valid against the combined super-interfaces
+// (i.e., valid against the most specific of them for that method).
+
+mixin M1 on UnaryNum {
+  void bar() {
+    super.foo(); //# 01: compile-time error
+    super.foo(1, 2); //# 02: compile-time error
+    super.foo("not num"); //# 03: compile-time error
+    super.bar; //# 04: compile-time error
+    super + 2; //# 05: compile-time error
+  }
+}
+
+mixin M2 on UnaryNum, UnaryInt {
+  void bar() {
+    super.foo(4.2); // Allows most specific type.
+    super.foo(1, 2); //# 06: compile-time error
+    super.foo("not num"); //# 07: compile-time error
+  }
+}
+
+mixin M3 on UnaryNum, UnaryOptionalNum {
+  void bar() {
+    super.foo(4.2);
+    super.foo();     //# 10: ok
+    super.foo(1, 2); //# 08: compile-time error
+    super.foo("not num"); //# 09: compile-time error
+  }
+}
+
+class C1 implements UnaryNum, UnaryInt, UnaryOptionalNum {
+  num foo([num x = 37.0]) => x;
+}
+
+class A1 = C1 with M1;
+class A2 = C1 with M2;
+class A3 = C1 with M3;
+main() {
+  A1().bar();
+  A2().bar();
+  A3().bar();
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_syntax_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_syntax_test.dart
new file mode 100644
index 0000000..0ff26d6
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_syntax_test.dart
@@ -0,0 +1,64 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various invalid syntax combinations.
+
+// You cannot prefix "mixin" with anything.
+abstract //# 01: compile-time error
+static //# 02: compile-time error
+const //# 03: compile-time error
+mixin M0 {}
+
+// Cannot use "extends".
+mixin M1 //
+  extends A //# 04: compile-time error
+{}
+
+// On-clause must be before implements clause.
+mixin M2
+  implements B //# 05: compile-time error
+  on A
+{}
+
+// Cannot use "on" on class declarations.
+class C0 //
+  on A //# 06: compile-time error
+{}
+
+// Type parameters must not be empty.
+mixin M3 //
+  <> //# 07: compile-time error
+{}
+
+// Super-class restrictions and implements must be well-formed.
+mixin M4 on List
+  <UndeclaredType> //# 08: compile-time error
+{}
+mixin M5 implements List
+  <UndeclaredType> //# 09: compile-time error
+{}
+
+mixin M6 {
+  // Mixins cannot have constructors (or members with same name as mixin).
+  factory M6() {} //# 10: compile-time error
+  M6() {} //# 11: compile-time error
+  M6.foo(); //# 12: compile-time error
+  get M6 => 42; //# 13: compile-time error
+}
+
+// Cannot declare local mixins.
+class C {
+  static mixin M {}; //# 14: compile-time error
+  mixin M {} //# 15: compile-time error
+}
+
+// Just to have some types.
+class A {}
+class B {}
+
+main() {
+  new C();
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_type_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_type_test.dart
new file mode 100644
index 0000000..0fad558
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_type_test.dart
@@ -0,0 +1,49 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various invalid type-declaration combinations.
+
+// Types must be class types.
+mixin M on void {} //# 01: compile-time error
+mixin M on double {} //# 02: compile-time error
+mixin M on FutureOr<int> {} //# 03: compile-time error
+mixin M on FunType {} //# 04: compile-time error
+
+mixin M implements void {} //# 05: compile-time error
+mixin M implements double {} //# 06: compile-time error
+mixin M implements FutureOr<int> {} //# 07: compile-time error
+mixin M implements FunType {} //# 08: compile-time error
+
+// Types must be extensible.
+mixin M on bool {} //# 09: compile-time error
+mixin M on num {} //# 10: compile-time error
+mixin M on int {} //# 11: compile-time error
+mixin M on double {} //# 12: compile-time error
+mixin M on Null {} //# 13: compile-time error
+mixin M on String {} //# 14: compile-time error
+mixin M implements bool {} //# 15: compile-time error
+mixin M implements num {} //# 16: compile-time error
+mixin M implements int {} //# 17: compile-time error
+mixin M implements double {} //# 18: compile-time error
+mixin M implements Null {} //# 19: compile-time error
+mixin M implements String {} //# 20: compile-time error
+
+// Mixin type cannot depend on itself
+mixin M on M {} //# 21: compile-time error
+mixin M implements M {} //# 22: compile-time error
+
+// Types must exist and be valid
+mixin M on Undeclared {} //# 23: compile-time error
+mixin M on A<int> {} //# 24: compile-time error
+mixin M implements Undeclared {} //# 25: compile-time error
+mixin M implements A<int> {} //# 26: compile-time error
+
+main() {}
+
+// Just to have some types.
+class A {}
+class B {}
+typedef FuntType = int Function(int);
diff --git a/tests/language/mixin_declaration/mixin_declaration_invalid_usage_test.dart b/tests/language/mixin_declaration/mixin_declaration_invalid_usage_test.dart
new file mode 100644
index 0000000..83e50b4d
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_invalid_usage_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+mixin Mixin // cannot `extend` anything.
+  extends M //# 01: compile-time error
+  extends Object //# 02: compile-time error
+{}
+
+// You cannot extend a mixin.
+class Class // cannot extend a mixin
+  extends Mixin //# 03: compile-time error
+{}
+
+void main() {
+  // Cannot instantiate a mixin.
+  new Mixin();  //# 04: compile-time error
+  new Class();
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_nsm_test.dart b/tests/language/mixin_declaration/mixin_declaration_nsm_test.dart
new file mode 100644
index 0000000..ccfde7b
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_nsm_test.dart
@@ -0,0 +1,39 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+abstract class Bar {
+  String bar();
+}
+
+abstract class Foo {
+  String foo();
+}
+
+mixin M implements Bar {
+  dynamic noSuchMethod(i) => "M:${i.memberName == #foo ? "foo" : "bar"}";
+}
+
+abstract class C {
+  dynamic noSuchMethod(i) => "C:${i.memberName == #foo ? "foo" : "bar"}";
+}
+
+abstract class D {
+  String foo() => "D:foo";
+  String bar() => "D:bar";
+}
+
+class A1 extends Foo with M {}
+class A2 extends C with M implements Foo {}
+class A3 extends D with M implements Foo {}
+
+main() {
+  Expect.equals("M:foo", A1().foo());
+  Expect.equals("M:bar", A1().bar());
+  Expect.equals("M:foo", A2().foo());
+  Expect.equals("M:bar", A2().bar());
+  Expect.equals("D:foo", A3().foo());
+  Expect.equals("D:bar", A3().bar());
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_on_keyword_test.dart b/tests/language/mixin_declaration/mixin_declaration_on_keyword_test.dart
new file mode 100644
index 0000000..f4cc1f1
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_on_keyword_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// The `on` word is not a reserved word or built-in identifier.
+// It's a purely contextual keyword.
+// A type can have the name `on`, and even a mixin.
+
+class A {}
+
+mixin on on A {}
+
+mixin M on on {}
+
+mixin M2 implements on {}
+
+class B = A with on;
+class C = B with M;
+class D = Object with M2;
+
+main() {
+  Expect.type<on>(B());
+  Expect.type<on>(C());
+  Expect.type<on>(D());
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_static_scope_test.dart b/tests/language/mixin_declaration/mixin_declaration_static_scope_test.dart
new file mode 100644
index 0000000..29780f3
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_static_scope_test.dart
@@ -0,0 +1,36 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// A mixin declaration introduces a static scope.
+// Instance members keep seeing this scope when mixed in.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+mixin M1 on UnaryNum {
+  static int counter = 0;
+  static int next() => ++counter;
+  int count() => foo(next()) as int;
+}
+
+class C1 implements UnaryNum {
+  static int counter = 87;
+  static int next() => 42;
+  num foo(num x) => x * 10;
+}
+
+class A1 = C1 with M1;
+
+main() {
+  Expect.equals(0, M1.counter);
+  Expect.equals(1, M1.next());
+  Expect.equals(2, M1.next());
+  var a = A1();
+  Expect.equals(30, a.count());
+  Expect.equals(40, a.count());
+  Expect.equals(5, M1.next());
+}
diff --git a/tests/language/mixin_declaration/mixin_declaration_subtype_test.dart b/tests/language/mixin_declaration/mixin_declaration_subtype_test.dart
new file mode 100644
index 0000000..172bb23
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_subtype_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// A mixin declaration introduces a type.
+
+// A mixin with multiple super-types and implemented types.
+class A {}
+class B {}
+class I {}
+class J {}
+
+mixin M on A, B implements I, J {}
+
+class C implements A, B {}
+
+class D = C with M;
+
+// Same, with generics.
+class GA<T> {}
+class GB<T> {}
+class GI<T> {}
+class GJ<T> {}
+
+mixin GM<T> on GA<T>, GB<List<T>> implements GI<Iterable<T>>, GJ<Set<T>> {}
+
+class GC<T> implements GA<T>, GB<List<T>> {}
+
+class GD<T> = GC<T> with GM<T>;
+
+main() {
+  Expect.subtype<M, A>();
+  Expect.subtype<M, B>();
+  Expect.subtype<M, I>();
+  Expect.subtype<M, J>();
+  Expect.subtype<D, M>();
+  Expect.subtype<D, C>();
+  Expect.notSubtype<M, C>();
+  Expect.notSubtype<C, M>();
+
+  Expect.subtype<GM<int>, GA<int>>();
+  Expect.subtype<GM<int>, GB<List<int>>>();
+  Expect.subtype<GM<int>, GI<Iterable<int>>>();
+  Expect.subtype<GM<int>, GJ<Set<int>>>();
+  Expect.subtype<GD<int>, GM<int>>();
+  Expect.subtype<GD<int>, GC<int>>();
+  Expect.notSubtype<GM<int>, GC<int>>();
+  Expect.notSubtype<GC<int>, GM<int>>();
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_superinvocation_application_test.dart b/tests/language/mixin_declaration/mixin_declaration_superinvocation_application_test.dart
new file mode 100644
index 0000000..eee21d8
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_superinvocation_application_test.dart
@@ -0,0 +1,77 @@
+// 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.
+
+// Test various invalid mixin applications due to insufficient super-invoked
+// methods.
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryOptionalNum {
+  num foo([num x]);
+}
+
+// When a mixin is applied, the super-invoked methods must have
+// a concrete implementation in the superclass which satisfies
+// the signature in the super-interfaces.
+
+mixin M1 on UnaryNum {
+  num bar() {
+    return super.foo(42.0);
+  }
+}
+
+mixin M11 on UnaryNum {
+  num bar() {
+    return 0.0;
+  }
+  num foo(num x) {
+    return super.foo(42.0);
+  }
+}
+
+// The super-invoked method must be non-abstract.
+class A1 extends UnaryNum //
+    with M1 //# 04: compile-time error
+    with M11 //# 05: compile-time error
+    with M1, M11 //# 06: compile-time error
+    with M11, M1 //# 07: compile-time error
+{
+  // M1.bar does super.foo and UnaryNum has no implementation.
+  num foo(num x) => x;
+}
+
+// The super-invoked method must satisfy the most specific signature
+// among super-interfaces of the mixin.
+class C1 {
+  num foo(num x) => x;
+}
+
+abstract class C2 extends C1 implements UnaryOptionalNum {
+  num foo([num x]);
+}
+
+mixin M2 on UnaryOptionalNum {
+  num bar() {
+    // Allowed, super.foo has signature num Function([num]).
+    return super.foo(42.0);
+  }
+}
+
+class A2 extends C2 //
+    with M2 //# 08: compile-time error
+{
+  // M2.bar does a super.foo, so C2.foo must satisfy the super-interface of M2.
+  // It doesn't, even if the super-call would succeed against C1.foo.
+  num foo([num x = 0]) => x;
+}
+
+main() {
+  A1().bar(); //# 04: continued
+  A1().bar(); //# 05: continued
+  A1().bar(); //# 06: continued
+  A1().bar(); //# 07: continued
+  A2().bar(); //# 08: continued
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_supertype_compatible_test.dart b/tests/language/mixin_declaration/mixin_declaration_supertype_compatible_test.dart
new file mode 100644
index 0000000..5307979
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_supertype_compatible_test.dart
@@ -0,0 +1,73 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various invalid super-constraints for mixin declarations.
+
+abstract class BinaryNumInt {
+  num foo(num x, int y);
+}
+
+abstract class BinaryIntNum {
+  num foo(int x, num y);
+}
+
+abstract class GetterNumNum {
+  num Function(num) get foo;
+}
+
+abstract class GetterIntInt {
+  int Function(int) get foo;
+}
+
+abstract class UnaryInt {
+  num foo(int x);
+}
+
+abstract class UnaryNum {
+  num foo(num x);
+}
+
+abstract class UnaryString {
+  num foo(String x);
+}
+
+// The super-interfaces must be *compatible*.
+// Any member declared by more than one super-interface must have at
+// least one most-specific signature among the super-interfaces.
+
+// Incompatible member kinds, one is a getter, the other a method.
+mixin _ on UnaryNum, GetterNumNum {} //# 01: compile-time error
+
+// Incompatible signature structure, unary vs binary.
+mixin _ on UnaryNum, BinaryNumInt {} //# 02: compile-time error
+
+// Incompatible method parameter type, neither is more specific.
+mixin _ on UnaryNum, UnaryString {} //# 03: compile-time error
+
+// Compatible types for each parameter, but still no most specific signature.
+mixin _ on BinaryNumInt, BinaryIntNum {} //# 04: compile-time error
+
+// Incompatible return type for getter.
+mixin _ on GetterNumNum, GetterIntInt {} //# 05: compile-time error
+
+
+// Mixin is valid when one signature is more specific.
+mixin M1 on UnaryNum, UnaryInt {
+  // May call the method in a super-invocation, at the most specific type.
+  num bar() {
+    return super.foo(42.0);
+  }
+}
+
+class C1 implements UnaryNum, UnaryInt {
+  num foo(num x) => x;
+}
+
+class A1 = C1 with M1;
+
+main() {
+  Expect.equals(42.0, A1().bar());
+}
\ No newline at end of file
diff --git a/tests/language/mixin_declaration/mixin_declaration_syntax_test.dart b/tests/language/mixin_declaration/mixin_declaration_syntax_test.dart
new file mode 100644
index 0000000..e7334db
--- /dev/null
+++ b/tests/language/mixin_declaration/mixin_declaration_syntax_test.dart
@@ -0,0 +1,428 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Test various combinations of valid mixin declarations.
+
+// Class unrelated to everything else here, just Object with a toString.
+class O {
+  String toString() => "O";
+}
+
+abstract class A {
+  String toString() => "A";
+  String methodA() => "A:${this}.A";
+}
+
+class B implements A {
+  String toString() => "B";
+  String methodA() => "B:${this}.A";
+  String methodB() => "B:${this}.B";
+}
+
+class C extends A {
+  String toString() => "C";
+  String methodA() => "C:${this}.A->${super.methodA()}";
+  String methodC() => "C:${this}.C";
+}
+
+class AIJ implements A, I, J {
+  String toString() => "AIJ";
+  String methodA() => "AIJ:${this}.A";
+  String methodI() => "AIJ:${this}.I";
+  String methodJ() => "AIJ:${this}.J";
+}
+
+class BC extends C implements B {
+  String toString() => "BC";
+  String methodA() => "BC:${this}.A->${super.methodA()}";
+  String methodB() => "BC:${this}.B";
+  String methodC() => "BC:${this}.C->${super.methodC()}";
+}
+
+// Interfaces.
+abstract class I {
+  String methodI();
+}
+abstract class J {
+  String methodJ();
+}
+
+// Simple mixin with no super-invocations, no super restrictions
+// and no interfaces implemented.
+mixin M {
+  String toString() => "?&M";
+  String methodM() => "M:${this}.M";
+}
+
+
+// Mixin which uses the implicit "on Object" to do a super-invocation.
+mixin MO {
+  String toString() => "${super.toString()}&MO";
+  String methodMO() => "MO:${this}.MO";
+}
+
+
+// Mixin with "implements" clause.
+mixin MOiIJ implements I, J {
+  String toString() => "${super.toString()}&MOiIJ";
+  String methodMOiIJ() => "MOiIJ:${this}.MOiIJ";
+  String methodI() => "MOiIJ:${this}.I";
+  String methodJ() => "MOiIJ:${this}.J";
+}
+
+
+// Mixin with single non-Object super-constraint.
+mixin MA on A {
+  String toString() => "${super.toString()}&MA";
+  String methodMA() => "MA:${this}.MA";
+  String methodA() => "MA:${this}.A->${super.methodA()}";
+}
+
+
+// Mixin with super-restriction implementing other interfaces.
+mixin MAiBC on A implements B, C {
+  String toString() => "${super.toString()}&MAiBC";
+  String methodMAiBC() => "MAiBC:${this}.MAiBC";
+  String methodA() => "MAiBC:${this}.A->${super.methodA()}";
+  String methodB() => "MAiBC:${this}.B";
+  String methodC() => "MAiBC:${this}.C";
+}
+
+// Mixin with "implements" clause.
+mixin MBiIJ on B implements I, J {
+  String toString() => "${super.toString()}&MBiIJ";
+  String methodMOiIJ() => "MBiIJ:${this}.MBiIJ";
+  String methodI() => "MBiIJ:${this}.I";
+  String methodJ() => "MBiIJ:${this}.J";
+}
+
+
+// Mixin on more than one class.
+mixin MBC on B, C {
+  String toString() => "${super.toString()}&MBC";
+  String methodMBC() => "MBC:${this}.MBC";
+  String methodA() => "MBC:${this}.A->${super.methodA()}";
+  String methodB() => "MBC:${this}.B->${super.methodB()}";
+  String methodC() => "MBC:${this}.C->${super.methodC()}";
+}
+
+
+// One with everything.
+mixin MBCiIJ on B, C implements I, J {
+  String toString() => "${super.toString()}&MBCiIJ";
+  String methodMBCiIJ() => "MBCiIJ:${this}.MBCiIJ";
+  String methodA() => "MBCiIJ:${this}.A->${super.methodA()}";
+  String methodB() => "MBCiIJ:${this}.B->${super.methodB()}";
+  String methodC() => "MBCiIJ:${this}.C->${super.methodC()}";
+  String methodI() => "MBCiIJ:${this}.I";
+  String methodJ() => "MBCiIJ:${this}.J";
+}
+
+
+// Abstract mixin, doesn't implement its interface.
+mixin MiIJ implements I, J {
+  String toString() => "${super.toString()}&MiIJ";
+}
+
+
+// Applications of the mixins.
+
+class COaM = O with M;
+
+class COaM_2 extends O with M {}
+
+class CBaM = B with M;
+
+class CBaM_2 extends B with M {}
+
+class COaMO = O with MO;
+
+class COaMO_2 extends O with MO {}
+
+class CBaMO = B with MO;
+
+class CBaMO_2 extends B with MO {}
+
+class COaMOiIJ = O with MOiIJ;
+
+class COaMOiIJ_2 extends O with MOiIJ {}
+
+class CBaMBiIJ = B with MBiIJ;
+
+class CBaMBiIJ_2 extends B with MBiIJ {}
+
+class CAaMA = A with MA;
+
+class CAaMA_2 extends A with MA {}
+
+class CBaMA = B with MA;
+
+class CBaMA_2 extends B with MA {}
+
+class CAaMAiBC = A with MAiBC;
+
+class CAaMAiBC_2 extends A with MAiBC {}
+
+class CBaMAiBC = B with MAiBC;
+
+class CBaMAiBC_2 extends B with MAiBC {}
+
+class CBCaMBC = BC with MBC;
+
+class CBCaMBC_2 extends BC with MBC {}
+
+class CAaMAiBCaMBC = CAaMAiBC with MBC;
+
+class CAaMAiBCaMBC_2 extends CAaMAiBC with MBC {}
+
+class CBCaMBCiIJ = BC with MBCiIJ;
+
+class CBCaMBCiIJ_2 extends BC with MBCiIJ {}
+
+class CAaMAiBCaMBCiIJ = CAaMAiBC with MBCiIJ;
+
+class CAaMAiBCaMBCiIJ_2 extends CAaMAiBC with MBCiIJ {}
+
+// Abstract mixin application does not implement I and J.
+abstract class OaMiIJ = O with MiIJ;
+
+// Concrete subclass of abstract mixin appliction
+class COaMiIJ extends OaMiIJ {
+  String toString() => "${super.toString()}:COaMiIJ";
+  String methodI() => "COaMiIJ:${this}.I";
+  String methodJ() => "COaMiIJ:${this}.J";
+}
+
+// Abstract class with mixin application and does not implement I and J.
+abstract class OaMiIJ_2 extends O with MiIJ {}
+
+// Concrete subclass of abstract mixin appliction
+class COaMiIJ_2 extends OaMiIJ_2 {
+  String toString() => "${super.toString()}:COaMiIJ";
+  String methodI() => "COaMiIJ:${this}.I";
+  String methodJ() => "COaMiIJ:${this}.J";
+}
+
+// Test of `class C with M` syntax.
+class CwithM with M {}
+class CeOwithM extends Object with M {}
+
+// Test that the mixin applications behave as expected.
+void main() {
+  {
+    for (dynamic o in [COaM(), COaM_2()]) {
+      Expect.type<O>(o);
+      Expect.type<M>(o);
+      Expect.equals("?&M", "$o");
+      Expect.equals("M:$o.M", o.methodM());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaM(), CBaM_2()]) {
+      Expect.type<B>(o);
+      Expect.type<M>(o);
+      Expect.equals("?&M", "$o");
+      Expect.equals("B:$o.B", o.methodB());
+      Expect.equals("M:$o.M", (o as M).methodM());
+    }
+  }
+
+  {
+    for (dynamic o in [COaMO(), COaMO_2()]) {
+      Expect.type<O>(o);
+      Expect.type<MO>(o);
+      Expect.equals("O&MO", "$o");
+      Expect.equals("MO:$o.MO", o.methodMO());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMO(), CBaMO_2()]) {
+      Expect.type<B>(o);
+      Expect.type<MO>(o);
+      Expect.equals("B&MO", "$o");
+      Expect.equals("MO:$o.MO", (o as MO).methodMO());
+      // Re-assign to cancel out type promotion from previous "as" expression.
+      o = o as dynamic;
+      Expect.equals("B:$o.B", o.methodB());
+    }
+  }
+
+  {
+    for (dynamic o in [COaMOiIJ(), COaMOiIJ_2()]) {
+      Expect.type<O>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.type<MOiIJ>(o);
+      Expect.equals("O&MOiIJ", "$o");
+      Expect.equals("MOiIJ:$o.MOiIJ", o.methodMOiIJ());
+      Expect.equals("MOiIJ:$o.I", o.methodI());
+      Expect.equals("MOiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMBiIJ(), CBaMBiIJ_2()]) {
+      Expect.type<B>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.type<MBiIJ>(o);
+      Expect.equals("B&MBiIJ", "$o");
+      Expect.equals("MBiIJ:$o.MBiIJ", o.methodMOiIJ());
+      Expect.equals("B:$o.B", o.methodB());
+      Expect.equals("MBiIJ:$o.I", o.methodI());
+      Expect.equals("MBiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    for (dynamic o in [CAaMA(), CAaMA_2()]) {
+      Expect.type<A>(o);
+      Expect.type<MA>(o);
+      Expect.equals("A&MA", "$o");
+      Expect.equals("MA:$o.MA", o.methodMA());
+      Expect.equals("MA:$o.A->A:$o.A", o.methodA());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMA(), CBaMA_2()]) {
+      Expect.type<B>(o);
+      Expect.type<MA>(o);
+      Expect.equals("B&MA", "$o");
+      Expect.equals("MA:$o.MA", (o as MA).methodMA());
+      Expect.equals("MA:$o.A->B:$o.A", (o as MA).methodA());
+      // Re-assign to cancel out type promotion from previous "as" expression.
+      o = o as dynamic;
+      Expect.equals("B:$o.B", o.methodB());
+    }
+  }
+
+  {
+    for (dynamic o in [CAaMAiBC(), CAaMAiBC_2()]) {
+      Expect.type<A>(o);
+      Expect.type<B>(o);
+      Expect.type<C>(o);
+      Expect.type<MAiBC>(o);
+      Expect.equals("A&MAiBC", "$o");
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MAiBC:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MAiBC:$o.B", o.methodB());
+      Expect.equals("MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBaMAiBC(), CBaMAiBC_2()]) {
+      Expect.type<A>(o);
+      Expect.type<B>(o);
+      Expect.type<C>(o);
+      Expect.type<MAiBC>(o);
+      Expect.equals("B&MAiBC", "$o");
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MAiBC:$o.A->B:$o.A", o.methodA());
+      Expect.equals("MAiBC:$o.B", o.methodB());
+      Expect.equals("MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBCaMBC(), CBCaMBC_2()]) {
+      Expect.type<BC>(o);
+      Expect.type<MBC>(o);
+      Expect.equals("BC&MBC", "$o");
+      Expect.equals("MBC:$o.MBC", o.methodMBC());
+      Expect.equals("MBC:$o.A->BC:$o.A->C:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MBC:$o.B->BC:$o.B", o.methodB());
+      Expect.equals("MBC:$o.C->BC:$o.C->C:$o.C", o.methodC());
+    }
+  }
+
+  {
+    // Mixin on top of mixin application.
+    for (dynamic o in [CAaMAiBCaMBC(), CAaMAiBCaMBC_2()]) {
+      Expect.type<CAaMAiBC>(o);
+      Expect.type<MBC>(o);
+      Expect.equals("A&MAiBC&MBC", "$o");
+      Expect.equals("MBC:$o.MBC", (o as MBC).methodMBC());
+      // Re-assign to cancel out type promotion from previous "as" expression.
+      o = o as dynamic;
+      Expect.equals("MAiBC:$o.MAiBC", o.methodMAiBC());
+      Expect.equals("MBC:$o.A->MAiBC:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MBC:$o.B->MAiBC:$o.B", o.methodB());
+      Expect.equals("MBC:$o.C->MAiBC:$o.C", o.methodC());
+    }
+  }
+
+  {
+    for (dynamic o in [CBCaMBCiIJ(), CBCaMBCiIJ_2()]) {
+      Expect.type<BC>(o);
+      Expect.type<MBCiIJ>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("BC&MBCiIJ", "$o");
+      Expect.equals("MBCiIJ:$o.MBCiIJ", o.methodMBCiIJ());
+      Expect.equals("MBCiIJ:$o.A->BC:$o.A->C:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MBCiIJ:$o.B->BC:$o.B", o.methodB());
+      Expect.equals("MBCiIJ:$o.C->BC:$o.C->C:$o.C", o.methodC());
+      Expect.equals("MBCiIJ:$o.I", o.methodI());
+      Expect.equals("MBCiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    // Mixin on top of mixin application.
+    for (dynamic o in [CAaMAiBCaMBCiIJ(), CAaMAiBCaMBCiIJ_2()]) {
+      Expect.type<CAaMAiBC>(o);
+      Expect.type<MBCiIJ>(o);
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("A&MAiBC&MBCiIJ", "$o");
+      Expect.equals("MBCiIJ:$o.MBCiIJ", o.methodMBCiIJ());
+      Expect.equals("MAiBC:$o.MAiBC", (o as CAaMAiBC).methodMAiBC());
+      // Re-assign to cancel out type promotion from previous "as" expression.
+      o = o as dynamic;
+      Expect.equals("MBCiIJ:$o.A->MAiBC:$o.A->A:$o.A", o.methodA());
+      Expect.equals("MBCiIJ:$o.B->MAiBC:$o.B", o.methodB());
+      Expect.equals("MBCiIJ:$o.C->MAiBC:$o.C", o.methodC());
+      Expect.equals("MBCiIJ:$o.I", o.methodI());
+      Expect.equals("MBCiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  {
+    // Abstract mixin application, concrete subclass.
+    for (dynamic o in [COaMiIJ(), COaMiIJ_2()]) {
+      Expect.type<O>(o);
+      Expect.type<MiIJ>(o);
+      Expect.isTrue(o is OaMiIJ || o is OaMiIJ_2,
+          "`$o` should subtype OaMiIJ or OaMiIJ_2");
+      Expect.type<I>(o);
+      Expect.type<J>(o);
+      Expect.equals("O&MiIJ:COaMiIJ", "$o");
+      Expect.equals("COaMiIJ:$o.I", o.methodI());
+      Expect.equals("COaMiIJ:$o.J", o.methodJ());
+    }
+  }
+
+  Expect.equals(CeOwithM().toString(), CwithM().toString());
+
+  {
+    // Regression test for private fields.
+    var c = PrivateFieldClass();
+    Expect.equals(42, c._foo);
+  }
+}
+
+
+mixin PrivateFieldMixin {
+  int _foo = 40;
+}
+
+class PrivateFieldClass with PrivateFieldMixin {
+  int get _foo => super._foo + 2;
+}
diff --git a/tests/language/nnbd/never/never_error_test.dart b/tests/language/nnbd/never/never_error_test.dart
index 9ce7609..0d6acbd 100644
--- a/tests/language/nnbd/never/never_error_test.dart
+++ b/tests/language/nnbd/never/never_error_test.dart
@@ -55,7 +55,7 @@
     staticErrorIfNotNever(x == x);
     staticErrorIfNotNever(x == 3);
     staticErrorIfNotNever(3 == x);
-//  ^^^^^^^^^^^^^^^^^
+//  ^^^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] Inferred type argument 'bool' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
   }
@@ -81,14 +81,14 @@
   {
     var t = NeverExt(x).neverMethod();
     staticErrorIfNotNever(t);
-//  ^^^^^^^^^^^^^^^^^
+//  ^^^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] Inferred type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
   }
   {
     var t = ObjectExt(x).objectMethod();
     staticErrorIfNotNever(t);
-//  ^^^^^^^^^^^^^^^^^
+//  ^^^^^^^^^^^^^^^^^^^^^
 // [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
 // [cfe] Inferred type argument 'int' doesn't conform to the bound 'Never' of the type variable 'T' on 'staticErrorIfNotNever'.
   }
diff --git a/tests/language/nnbd/type_equality/regress42246_test.dart b/tests/language/nnbd/type_equality/regress42246_test.dart
new file mode 100644
index 0000000..685739e
--- /dev/null
+++ b/tests/language/nnbd/type_equality/regress42246_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+/// Tests that type arguments in function types contain the correct nullability
+/// after tearing them off.
+
+import 'package:expect/expect.dart';
+
+typedef voidToNullableInt = int? Function();
+typedef nullableSToVoid = void Function<S>(S?);
+typedef voidToNullableS = S? Function<S>();
+
+class A<T> {
+  T? fn() => null;
+  void gn<S>(S? param) {}
+  S? hn<S>() => null;
+}
+
+main() {
+  var a = A<int>();
+  Expect.equals(voidToNullableInt, a.fn.runtimeType);
+  Expect.equals(nullableSToVoid, a.gn.runtimeType);
+  Expect.equals(voidToNullableS, a.hn.runtimeType);
+}
diff --git a/tests/language/operator/and_operation_on_non_integer_operand_test.dart b/tests/language/operator/and_operation_on_non_integer_operand_test.dart
new file mode 100644
index 0000000..36b4a04
--- /dev/null
+++ b/tests/language/operator/and_operation_on_non_integer_operand_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for dart2js that used to miscompile boolean add operations
+// if one of the operands was an int and the other was not (issue 22427).
+
+import "package:expect/expect.dart";
+
+class NotAnInt {
+  NotAnInt operator &(b) => this;
+}
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+id(x) => x;
+
+main() {
+  var a = id(new NotAnInt());
+  Expect.equals(a, a & 5 & 2);
+}
diff --git a/tests/language/operator/arithmetic_canonicalization_test.dart b/tests/language/operator/arithmetic_canonicalization_test.dart
new file mode 100644
index 0000000..2447fa4
--- /dev/null
+++ b/tests/language/operator/arithmetic_canonicalization_test.dart
@@ -0,0 +1,39 @@
+// Copyright (c) 2013, 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 canonicalization of simple arithmetic equivalences.
+// VMOptions=--optimization-counter-threshold=20 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+main() {
+  for (var i = 0; i < 50; i++) {
+    Expect.isTrue(mul1double(i) is double);
+    Expect.equals(i.toDouble(), mul1double(i));
+    Expect.equals(0.0, mul0double(i));
+    Expect.equals(i.toDouble(), add0double(i));
+
+    Expect.equals(i, mul1int(i));
+    Expect.equals(i, add0int(i));
+    Expect.equals(0, mul0int(i));
+    Expect.equals(0, and0(i));
+    Expect.equals(i, and1(i));
+    Expect.equals(i, or0(i));
+    Expect.equals(i, xor0(i));
+  }
+
+  Expect.isTrue(mul0double(double.nan).isNaN);
+  Expect.isFalse(add0double(-0.0).isNegative);
+}
+
+mul1double(x) => 1.0 * x;
+mul0double(x) => 0.0 * x;
+add0double(x) => 0.0 + x;
+
+mul1int(x) => 1 * x;
+mul0int(x) => 0 * x;
+add0int(x) => 0 + x;
+and0(x) => 0 & x;
+or0(x) => 0 | x;
+xor0(x) => 0 ^ x;
+and1(x) => (-1) & x;
diff --git a/tests/language/operator/arithmetic_int64_test.dart b/tests/language/operator/arithmetic_int64_test.dart
new file mode 100644
index 0000000..6354af0
--- /dev/null
+++ b/tests/language/operator/arithmetic_int64_test.dart
@@ -0,0 +1,28 @@
+// 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.
+// Dart test program to test arithmetic operations.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+library arithmetic_test;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+class ArithmeticTest {
+  static runOne() {
+    // Math functions.
+    Expect.equals(1234567890123456789, int.parse("1234567890123456789"));
+    Expect.equals(-1234567890123456789, int.parse("-1234567890123456789"));
+    Expect.equals(9223372036854775807, int.parse("9223372036854775807"));
+    Expect.equals(-9223372036854775808, int.parse("-9223372036854775808"));
+  }
+
+  static testMain() {
+    runOne();
+  }
+}
+
+main() {
+  ArithmeticTest.testMain();
+}
diff --git a/tests/language/operator/arithmetic_smi_overflow_test.dart b/tests/language/operator/arithmetic_smi_overflow_test.dart
new file mode 100644
index 0000000..1a4eec1
--- /dev/null
+++ b/tests/language/operator/arithmetic_smi_overflow_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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 test program to test arithmetic operations.
+
+// VMOptions=--optimization_counter_threshold=5 --no-background_compilation
+
+import "package:expect/expect.dart";
+
+main() {
+  for (var i = 0; i < 10; i++) {
+    Expect.equals(0x40000000, (i - i) - -1073741824);
+    Expect.equals(0x4000000000000000, (i - i) - -4611686018427387904);
+  }
+}
diff --git a/tests/language/operator/arithmetic_test.dart b/tests/language/operator/arithmetic_test.dart
new file mode 100644
index 0000000..7784f35
--- /dev/null
+++ b/tests/language/operator/arithmetic_test.dart
@@ -0,0 +1,564 @@
+// 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.
+// Dart test program to test arithmetic operations.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+library arithmetic_test;
+
+import "package:expect/expect.dart";
+import 'dart:math';
+
+class ArithmeticTest {
+  static bool exceptionCaughtParseInt(String s) {
+    try {
+      int.parse(s);
+      return false;
+    } on FormatException catch (e) {
+      return true;
+    }
+  }
+
+  static bool exceptionCaughtParseDouble(String s) {
+    try {
+      double.parse(s);
+      return false;
+    } on FormatException catch (e) {
+      return true;
+    }
+  }
+
+  static bool toIntThrowsUnsupportedError(String str) {
+    // No exception allowed for parse double.
+    double d = double.parse(str);
+    try {
+      var a = d.toInt();
+      return false;
+    } on UnsupportedError catch (e) {
+      return true;
+    }
+  }
+
+  static runOne() {
+    var a = 22;
+    var b = 4;
+    // Smi & smi.
+    Expect.equals(26, a + b);
+    Expect.equals(18, a - b);
+    Expect.equals(88, a * b);
+    Expect.equals(5, a ~/ b);
+    Expect.equals(5.5, a / b);
+    Expect.equals(2.0, 10 / 5);
+    Expect.equals(2, a % b);
+    Expect.equals(2, a.remainder(b));
+    // Smi corner cases.
+    for (int i = 0; i < 80; i++) {
+      a = -(1 << i);
+      b = -1;
+      Expect.equals(1 << i, a ~/ b);
+    }
+    a = 22;
+    var c = 4.0;
+    // Smi & double.
+    Expect.equals(26.0, a + c);
+    Expect.equals(18.0, a - c);
+    Expect.equals(88.0, a * c);
+    Expect.equals(5, a ~/ c);
+    Expect.equals(5.5, a / c);
+    Expect.equals(2.0, a % c);
+    Expect.equals(2.0, a.remainder(c));
+    var d = 22.0;
+    b = 4;
+    // Double & smi.
+    Expect.equals(26.0, d + b);
+    Expect.equals(18.0, d - b);
+    Expect.equals(88.0, d * b);
+    Expect.equals(5, d ~/ b);
+    Expect.equals(5.5, d / b);
+    Expect.equals(2.0, d % b);
+    Expect.equals(2.0, d.remainder(b));
+    d = 22.0;
+    c = 4.0;
+    // Double & double.
+    Expect.equals(26.0, d + c);
+    Expect.equals(18.0, d - c);
+    Expect.equals(88.0, d * c);
+    Expect.equals(5, d ~/ c);
+    Expect.equals(5.5, d / c);
+    Expect.equals(2.0, d % c);
+    Expect.equals(2.0, d.remainder(c));
+
+    // Special int operations.
+    Expect.equals(2, (2).floor());
+    Expect.equals(2, (2).ceil());
+    Expect.equals(2, (2).round());
+    Expect.equals(2, (2).truncate());
+
+    Expect.equals(-2, (-2).floor());
+    Expect.equals(-2, (-2).ceil());
+    Expect.equals(-2, (-2).round());
+    Expect.equals(-2, (-2).truncate());
+
+    // Note that this number fits into 53 bits of a double.
+    int big = 123456789012345;
+
+    Expect.equals(big, big.floor());
+    Expect.equals(big, big.ceil());
+    Expect.equals(big, big.round());
+    Expect.equals(big, big.truncate());
+    big = -big;
+    Expect.equals(big, big.floor());
+    Expect.equals(big, big.ceil());
+    Expect.equals(big, big.round());
+    Expect.equals(big, big.truncate());
+
+    // Test if double is contagious. The assignment will check the type.
+    {
+      double d = 1 + 1.0;
+    }
+    {
+      double d = 1.0 + 1;
+    }
+    {
+      double d = 1 * 1.0;
+    }
+    {
+      double d = 0 * 1.0;
+    }
+    {
+      double d = 1.0 * 0;
+    }
+    {
+      double d = 1 / 1.0;
+    }
+    {
+      double d = 1.0 / 0;
+    }
+    {
+      double d = 1 - 1.0;
+    }
+    {
+      double d = 1.0 - 1;
+    }
+    {
+      double d = big * 1.0;
+    }
+    {
+      double d = 1.0 * big;
+    }
+
+    // Reset big to positive value.
+    big = 123456789012345;
+    // -- isNegative --.
+    // Smi.
+    Expect.equals(false, (0).isNegative);
+    Expect.equals(false, (1).isNegative);
+    Expect.equals(true, (-1).isNegative);
+    // Big.
+    Expect.equals(false, big.isNegative);
+    Expect.equals(true, (-big).isNegative);
+    // Double.
+    // TODO(srdjan): enable the following test once isNegative works.
+    // Expect.equals(true, (-0.0).isNegative);
+    Expect.equals(false, (0.0).isNegative);
+    Expect.equals(false, (2.0).isNegative);
+    Expect.equals(true, (-2.0).isNegative);
+
+    double negateDouble(double x) {
+      return -x;
+    }
+
+    Expect.isTrue(negateDouble(0.0).isNegative);
+    Expect.isFalse(negateDouble(-0.0).isNegative);
+    Expect.isTrue(negateDouble(3.5e3).isNegative);
+    Expect.isFalse(negateDouble(-3.5e3).isNegative);
+
+    // Constants.
+    final nan = 0.0 / 0.0;
+    final infinity = 1.0 / 0.0;
+
+    // -- isInfinite --.
+    // Smi.
+    Expect.equals(false, (0).isInfinite);
+    Expect.equals(false, (1).isInfinite);
+    Expect.equals(false, (-1).isInfinite);
+    // Big.
+    Expect.equals(false, big.isInfinite);
+    Expect.equals(false, (-big).isInfinite);
+    // Double.
+    Expect.equals(false, (0.0).isInfinite);
+    Expect.equals(true, infinity.isInfinite);
+    Expect.equals(true, (-infinity).isInfinite);
+    Expect.equals(false, (12.0).isInfinite);
+    Expect.equals(false, (-12.0).isInfinite);
+    Expect.equals(false, nan.isInfinite);
+
+    // -- isNaN --.
+    // Smi.
+    Expect.equals(false, (0).isNaN);
+    Expect.equals(false, (1).isNaN);
+    Expect.equals(false, (-1).isNaN);
+    // Big.
+    Expect.equals(false, big.isNaN);
+    Expect.equals(false, (-big).isNaN);
+    // Double.
+    Expect.equals(true, nan.isNaN);
+    Expect.equals(false, (12.0).isNaN);
+    Expect.equals(false, infinity.isNaN);
+
+    // -- abs --.
+    // Smi.
+    Expect.equals(0, (0).abs());
+    Expect.equals(2, (2).abs());
+    Expect.equals(2, (-2).abs());
+    // Big.
+    Expect.equals(big, big.abs());
+    Expect.equals(big, (-big).abs());
+    // Double.
+    Expect.equals(false, (0.0).abs().isNegative);
+    Expect.equals(false, (-0.0).abs().isNegative);
+    Expect.equals(2.0, (2.0).abs());
+    Expect.equals(2.0, (-2.0).abs());
+
+    // -- ceil --.
+    // Smi.
+    Expect.equals(0, (0).ceil());
+    Expect.equals(1, (1).ceil());
+    Expect.equals(-1, (-1).ceil());
+    // Big.
+    Expect.equals(big, big.ceil());
+    Expect.equals(-big, (-big).ceil());
+    // Double.
+    Expect.equals(0, (0.0).ceil());
+    Expect.equals(false, (0.0).ceil().isNegative);
+    Expect.equals(1, (0.1).ceil());
+    Expect.equals(1, double.minPositive.ceil());
+    Expect.equals(1, (0.49999999999999994).ceil());
+    Expect.equals(0, (-0.0).ceil());
+    Expect.equals(0, (-0.3).ceil());
+    Expect.isTrue((-0.0).ceil() is int);
+    Expect.isTrue((-0.3).ceil() is int);
+    Expect.equals(0, (-0.49999999999999994).ceil());
+    Expect.equals(3, (2.1).ceil());
+    Expect.equals(-2, (-2.1).ceil());
+
+    // -- floor --.
+    // Smi.
+    Expect.equals(0, (0).floor());
+    Expect.equals(1, (1).floor());
+    Expect.equals(-1, (-1).floor());
+    // Big.
+    Expect.equals(big, big.floor());
+    Expect.equals(-big, (-big).floor());
+    // Double.
+    Expect.equals(0, (0.0).floor());
+    Expect.equals(0, (0.1).floor());
+    Expect.equals(0, (0.49999999999999994).floor());
+    Expect.equals(0, double.minPositive.floor());
+    Expect.isTrue((0.0).floor() is int);
+    Expect.isTrue((0.1).floor() is int);
+    Expect.equals(0, (-0.0).floor());
+    Expect.isTrue((-0.0).floor() is int);
+    Expect.equals(-1, (-0.1).floor());
+    Expect.equals(2, (2.1).floor());
+    Expect.equals(-3, (-2.1).floor());
+    Expect.equals(-1.0, (-0.49999999999999994).floor());
+    Expect.equals(-3.0, (-2.1).floor());
+
+    // -- truncate --.
+    // Smi.
+    Expect.equals(0, (0).truncate());
+    Expect.equals(1, (1).truncate());
+    Expect.equals(-1, (-1).truncate());
+    // Big.
+    Expect.equals(big, big.truncate());
+    Expect.equals(-big, (-big).truncate());
+    // Double.
+    Expect.equals(0, (0.0).truncate());
+    Expect.equals(0, (0.1).truncate());
+    Expect.isTrue((0.0).truncate() is int);
+    Expect.isTrue((0.1).truncate() is int);
+    Expect.equals(0, (-0.0).truncate());
+    Expect.equals(0, (-0.3).truncate());
+    Expect.isTrue((-0.0).truncate() is int);
+    Expect.isTrue((-0.3).truncate() is int);
+    Expect.equals(2, (2.1).truncate());
+    Expect.equals(-2, (-2.1).truncate());
+
+    int b1 = (1234567890123.0).truncate();
+    int b2 = (1234567890124.0).truncate();
+    Expect.equals(b2, b1 + 1.0);
+
+    // -- round --.
+    // Smi.
+    Expect.equals(0, (0).round());
+    Expect.equals(1, (1).round());
+    Expect.equals(-1, (-1).round());
+    // Big.
+    Expect.equals(big, big.round());
+    Expect.equals(-big, (-big).round());
+    // Double.
+    Expect.equals(3, (2.6).round());
+    Expect.equals(-3, (-2.6).round());
+    Expect.equals(0, (0.0).round());
+    Expect.equals(0, (0.1).round());
+    Expect.equals(3, (2.5).round());
+    Expect.equals(-3, (-2.5).round());
+    Expect.isFalse((0.0).round().isNegative);
+    Expect.isFalse((0.1).round().isNegative);
+    Expect.equals(0, (-0.0).round());
+    Expect.equals(0, (-0.3).round());
+    Expect.equals(2, (2.1).round());
+    Expect.equals(-2, (-2.1).round());
+    Expect.equals(1, (0.5).round());
+    Expect.equals(-1, (-0.5).round());
+    Expect.isTrue((-0.0).round() is int);
+    Expect.isTrue((-0.3).round() is int);
+    Expect.isTrue((-0.5).round() is int);
+    Expect.equals(2, (1.5).round());
+    Expect.equals(-2, (-1.5).round());
+    Expect.equals(1, (0.99).round());
+
+    // -- toInt --.
+    // Smi.
+    Expect.equals(0, (0).toInt());
+    Expect.equals(1, (1).toInt());
+    Expect.equals(-1, (-1).toInt());
+    // Type checks.
+    {
+      int i = (0).toInt();
+    }
+    {
+      int i = (1).toInt();
+    }
+    {
+      int i = (-1).toInt();
+    }
+    // Big.
+    Expect.equals(big, big.toInt());
+    Expect.equals(-big, (-big).toInt());
+    {
+      int i = big.toInt();
+    }
+    {
+      int i = (-big).toInt();
+    }
+    // Double.
+    Expect.equals(1234567890123, (1234567890123.0).toInt());
+    Expect.equals(-1234567890123, (-1234567890123.0).toInt());
+    {
+      int i = (1234567890123.0).toInt();
+    }
+    {
+      int i = (-1234567890123.0).toInt();
+    }
+    // 32bit Smi border cases.
+    Expect.equals(-1073741824, (-1073741824.0).toInt());
+    Expect.equals(-1073741825, (-1073741825.0).toInt());
+    Expect.equals(1073741823, (1073741823.0).toInt());
+    Expect.equals(1073741824, (1073741824.0).toInt());
+
+    {
+      int i = (-1073741824.0).toInt();
+    }
+    {
+      int i = (-1073741825.0).toInt();
+    }
+    {
+      int i = (1073741823.0).toInt();
+    }
+    {
+      int i = (1073741824.0).toInt();
+    }
+
+    // -- toDouble --.
+    // Smi.
+    Expect.equals(0.0, (0).toDouble());
+    Expect.equals(1.0, (1).toDouble());
+    Expect.equals(-1.0, (-1).toDouble());
+    // Type checks.
+    {
+      double d = (0).toDouble();
+    }
+    {
+      double d = (1).toDouble();
+    }
+    {
+      double d = (-1).toDouble();
+    }
+    // Big.
+    Expect.equals(big, big.toInt());
+    Expect.equals(-big, (-big).toInt());
+    {
+      int i = big.toInt();
+    }
+    {
+      int i = (-big).toInt();
+    }
+
+    // Math functions.
+    Expect.equals(2.0, sqrt(4.0));
+    Expect.approxEquals(1.0, sin(3.14159265 / 2.0));
+    Expect.approxEquals(-1.0, cos(3.14159265));
+
+    Expect.equals(12, int.parse("12"));
+    Expect.equals(-12, int.parse("-12"));
+    Expect.equals(9007199254740991, int.parse("9007199254740991"));
+    Expect.equals(-9007199254740991, int.parse("-9007199254740991"));
+    // Type checks.
+    {
+      int i = int.parse("12");
+    }
+    {
+      int i = int.parse("-12");
+    }
+    {
+      int i = int.parse("1234567890123456789");
+    }
+    {
+      int i = int.parse("-1234567890123456789");
+    }
+    {
+      int i = int.parse("9223372036854775807");
+    }
+    {
+      int i = int.parse("-9223372036854775808");
+    }
+
+    Expect.equals(1.2, double.parse("1.2"));
+    Expect.equals(-1.2, double.parse("-1.2"));
+    // Type checks.
+    {
+      double d = double.parse("1.2");
+    }
+    {
+      double d = double.parse("-1.2");
+    }
+    {
+      double d = double.parse("0");
+    }
+
+    // Random
+    {
+      Random rand = new Random();
+      double d = rand.nextDouble();
+    }
+
+    Expect.equals(false, exceptionCaughtParseInt("22"));
+    Expect.equals(true, exceptionCaughtParseInt("alpha"));
+    Expect.equals(true, exceptionCaughtParseInt("-alpha"));
+    Expect.equals(false, exceptionCaughtParseDouble("22.2"));
+    Expect.equals(true, exceptionCaughtParseDouble("alpha"));
+    Expect.equals(true, exceptionCaughtParseDouble("-alpha"));
+
+    Expect.equals(false, double.parse("1.2").isNaN);
+    Expect.equals(false, double.parse("1.2").isInfinite);
+
+    Expect.equals(true, double.parse("NaN").isNaN);
+    Expect.equals(true, double.parse("Infinity").isInfinite);
+    Expect.equals(true, double.parse("-Infinity").isInfinite);
+
+    Expect.equals(false, double.parse("NaN").isNegative);
+    Expect.equals(false, double.parse("Infinity").isNegative);
+    Expect.equals(true, double.parse("-Infinity").isNegative);
+
+    Expect.equals("NaN", double.parse("NaN").toString());
+    Expect.equals("Infinity", double.parse("Infinity").toString());
+    Expect.equals("-Infinity", double.parse("-Infinity").toString());
+
+    Expect.equals(false, toIntThrowsUnsupportedError("1.2"));
+    Expect.equals(true, toIntThrowsUnsupportedError("Infinity"));
+    Expect.equals(true, toIntThrowsUnsupportedError("-Infinity"));
+    Expect.equals(true, toIntThrowsUnsupportedError("NaN"));
+
+    // Min/max
+    Expect.equals(1, min(1, 12));
+    Expect.equals(12, max(1, 12));
+    Expect.equals(1.0, min(1.0, 12.0));
+    Expect.equals(12.0, max(1.0, 12.0));
+    Expect.equals(false, 1.0 < min(1.0, 12.0));
+    Expect.equals(true, 1.0 < max(1.0, 12.0));
+
+    // Hashcode
+    Expect.equals(false, (3.4).hashCode == (1.2).hashCode);
+    Expect.equals(true, (1.2).hashCode == (1.2).hashCode);
+    Expect.equals(false, (3).hashCode == (1).hashCode);
+    Expect.equals(true, (10).hashCode == (10).hashCode);
+  }
+
+  static int div(a, b) => a ~/ b;
+
+  static void testSmiDivDeopt() {
+    var a = -0x40000000;
+    var b = -1;
+    for (var i = 0; i < 10; i++) Expect.equals(0x40000000, div(a, b));
+  }
+
+  static int divMod(a, b) => a ~/ b + a % b;
+
+  static void testSmiDivModDeopt() {
+    var a = -0x40000000;
+    var b = -1;
+    for (var i = 0; i < 10; i++) Expect.equals(0x40000000, divMod(a, b));
+  }
+
+  static double sinCosSub(double a) => sin(a) - cos(a);
+
+  static double sinCosAddCos(double a) => sin(a) * cos(a) + cos(a);
+
+  static void testSinCos() {
+    var e = sin(1.234) - cos(1.234);
+    var f = sin(1.234) * cos(1.234) + cos(1.234);
+
+    for (var i = 0; i < 20; i++) {
+      Expect.approxEquals(e, sinCosSub(1.234));
+      Expect.approxEquals(f, sinCosAddCos(1.234));
+    }
+    Expect.approxEquals(1.0, sinCosSub(3.14159265));
+    Expect.approxEquals(1.0, sinCosSub(3.14159265 / 2.0));
+  }
+
+  // Test fix for issue 16592.
+  static void testSinCosNoUse() {
+    for (var i = 0; i < 20; i++) {
+      sin(i);
+      cos(i);
+    }
+  }
+
+  static mySqrt(var x) => sqrt(x);
+
+  static testSqrtDeopt() {
+    for (var i = 0; i < 10; i++) mySqrt(4.0);
+    Expect.equals(2.0, mySqrt(4.0));
+    Expect.throws(() => mySqrt("abc"));
+  }
+
+  static self_equality(x) {
+    return x == x;
+  }
+
+  static testDoubleEquality() {
+    Expect.isFalse(self_equality(double.nan));
+    for (int i = 0; i < 20; i++) {
+      self_equality(3.0);
+    }
+    Expect.isFalse(self_equality(double.nan));
+  }
+
+  static testMain() {
+    for (int i = 0; i < 20; i++) {
+      runOne();
+      testSmiDivDeopt();
+      testSmiDivModDeopt();
+      testSqrtDeopt();
+      testDoubleEquality();
+      testSinCos();
+      testSinCosNoUse();
+    }
+  }
+}
+
+main() {
+  ArithmeticTest.testMain();
+}
diff --git a/tests/language/operator/bit_operations_test.dart b/tests/language/operator/bit_operations_test.dart
new file mode 100644
index 0000000..c6fd13c
--- /dev/null
+++ b/tests/language/operator/bit_operations_test.dart
@@ -0,0 +1,238 @@
+// 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.
+// Dart test for testing bitwise operations.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+void main() {
+  for (int i = 0; i < 4; i++) {
+    test();
+  }
+}
+
+void test() {
+  Expect.equals(3, (3 & 7));
+  Expect.equals(7, (3 | 7));
+  Expect.equals(4, (3 ^ 7));
+  Expect.equals(25, (100 >> 2));
+  Expect.equals(400, (100 << 2));
+  Expect.equals(-25, (-100 >> 2));
+  Expect.equals(-101, ~100);
+  Expect.equals(0, 1 << 64);
+  Expect.equals(0, -1 << 64);
+  Expect.equals(0x40000000, 0x04000000 << 4);
+  Expect.equals(0x4000000000000000, 0x0400000000000000 << 4);
+  Expect.equals(0, ~ -1);
+  Expect.equals(-1, ~0);
+
+  Expect.equals(0, 1 >> 160);
+  Expect.equals(-1, -1 >> 160);
+
+  Expect.equals(0x1000000000000001, 0x1000000000000001 & 0x1000100F00000001);
+  Expect.equals(0x1, 0x1 & 0x1000100F00000001);
+  Expect.equals(0x1, 0x1000100F00000001 & 0x1);
+
+  Expect.equals(0x1000100F00000001, 0x1000000000000001 | 0x1000100F00000001);
+  Expect.equals(0x1000100F00000011, 0x11 | 0x1000100F00000001);
+  Expect.equals(0x1000100F00000011, 0x1000100F00000001 | 0x11);
+
+  Expect.equals(0x0F00000000000000, 0x0F00000000000001 ^ 0x0000000000000001);
+  Expect.equals(0x31, 0x0F00000000000001 ^ 0x0F00000000000030);
+  Expect.equals(0x0F00000000000031, 0x0F00000000000001 ^ 0x30);
+  Expect.equals(0x0F00000000000031, 0x30 ^ 0x0F00000000000001);
+
+  Expect.equals(0x000000000000000F, 0x000000000000000F7 >> 4);
+  Expect.equals(15, 0xF00000000 >> 32);
+  Expect.equals(1030792151040, 16492674416655 >> 4);
+
+  Expect.equals(0x00000000000000F0, 0xF00000000000000F << 4);
+  Expect.equals(0xF00000000, 15 << 32);
+
+  testNegativeValueShifts();
+  testPositiveValueShifts();
+  testNoMaskingOfShiftCount();
+  testNegativeCountShifts();
+  for (int i = 0; i < 20; i++) {
+    testCornerCasesRightShifts();
+    testRightShift64Bit();
+    testLeftShift64Bit();
+    testLeftShift64BitWithOverflow1();
+    testLeftShift64BitWithOverflow2();
+    testLeftShift64BitWithOverflow3();
+  }
+
+  // Test precedence.
+  testPrecedence(4, 5, 3, 1);
+  testPrecedence(3, 4, 5, 9);
+  testPrecedence(0x5c71, 0x6b92, 0x7654, 0x7d28);
+
+  // Test more special cases.
+  testRightShift65();
+}
+
+void testCornerCasesRightShifts() {
+  var v32 = 0xFF000000;
+  var v64 = 0xFF00000000000000;
+  Expect.equals(0x3, v32 >> 0x1E);
+  Expect.equals(0x1, v32 >> 0x1F);
+  Expect.equals(0x0, v32 >> 0x20);
+  Expect.equals(-1, v64 >> 0x3E);
+  Expect.equals(-1, v64 >> 0x3F);
+  Expect.equals(-1, v64 >> 0x40);
+}
+
+void testRightShift64Bit() {
+  var t = 0x1ffffffff;
+  Expect.equals(0xffffffff, t >> 1);
+}
+
+void testLeftShift64Bit() {
+  var t = 0xffffffff;
+  Expect.equals(0xffffffff, t << 0);
+  Expect.equals(0x1fffffffe, t << 1);
+  Expect.equals(0x7fffffff80000000, t << 31);
+  Expect.equals(0x8000000000000000, (t + 1) << 31);
+}
+
+void testLeftShift64BitWithOverflow1() {
+  var t = 0xffffffff;
+  Expect.equals(0, 2 * (t + 1) << 31); //# 03: ok
+}
+
+void testLeftShift64BitWithOverflow2() {
+  var t = 0xffffffff;
+  Expect.equals(0, 4 * (t + 1) << 31); //# 04: ok
+}
+
+void testLeftShift64BitWithOverflow3() {
+  var t = 0xffffffff;
+  Expect.equals(0x8000000000000000, (t + 1) << 31);
+}
+
+void testNegativeCountShifts() {
+  bool throwOnLeft(a, b) {
+    try {
+      var x = a << b;
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+
+  bool throwOnRight(a, b) {
+    try {
+      var x = a >> b;
+      return false;
+    } catch (e) {
+      return true;
+    }
+  }
+
+  Expect.isTrue(throwOnLeft(12, -3));
+  Expect.isTrue(throwOnRight(12, -3));
+  for (int i = 0; i < 20; i++) {
+    Expect.isFalse(throwOnLeft(12, 3));
+    Expect.isFalse(throwOnRight(12, 3));
+  }
+}
+
+void testNegativeValueShifts() {
+  for (int value = 0; value > -100; value--) {
+    for (int i = 0; i < 300; i++) {
+      int b = (value << i) >> i;
+      if (i < (64 - value.bitLength)) {
+        // No bits lost.
+        Expect.equals(value, b);
+      } else if (i >= 64) {
+        // All bits are shifted out.
+        Expect.equals(0, b);
+      } else {
+        // Some bits are lost.
+        int masked_value = value & ((1 << (64 - i)) - 1);
+        int signbit = masked_value & (1 << (63 - i));
+        int signmask = (signbit != 0) ? (-1 << (64 - i)) : 0;
+        Expect.equals(signmask | masked_value, b);
+      }
+    }
+  }
+}
+
+void testPositiveValueShifts() {
+  for (int value = 0; value < 100; value++) {
+    for (int i = 0; i < 300; i++) {
+      int b = (value << i) >> i;
+      if (i < (64 - value.bitLength)) {
+        Expect.equals(value, b);
+      } else if (i >= 64) {
+        Expect.equals(0, b);
+      } else {
+        // Some bits are lost.
+        int masked_value = value & ((1 << (64 - i)) - 1);
+        int signbit = masked_value & (1 << (63 - i));
+        int signmask = (signbit != 0) ? (-1 << (64 - i)) : 0;
+        Expect.equals(signmask | masked_value, b);
+      }
+    }
+  }
+}
+
+void testNoMaskingOfShiftCount() {
+  // Shifts which would behave differently if shift count was masked into a
+  // range.
+  Expect.equals(0, 0 >> 256);
+  Expect.equals(0, 1 >> 256);
+  Expect.equals(0, 2 >> 256);
+  Expect.equals(0, shiftRight(0, 256));
+  Expect.equals(0, shiftRight(1, 256));
+  Expect.equals(0, shiftRight(2, 256));
+
+  for (int shift = 1; shift <= 256; shift++) {
+    Expect.equals(0, shiftRight(1, shift));
+    Expect.equals(-1, shiftRight(-1, shift));
+    if (shift < 63) {
+      Expect.equals(true, shiftLeft(1, shift) > shiftLeft(1, shift - 1));
+    } else if (shift > 64) {
+      Expect.equals(
+          true, (shiftLeft(1, shift) == 0) && (shiftLeft(1, shift - 1) == 0));
+    }
+  }
+}
+
+int shiftLeft(int a, int b) {
+  return a << b;
+}
+
+int shiftRight(int a, int b) {
+  return a >> b;
+}
+
+void testPrecedence(int a, int b, int c, int d) {
+  // & binds stronger than ^, which binds stronger than |.
+  int result = a & b ^ c | d & b ^ c;
+  Expect.equals(((a & b) ^ c) | ((d & b) ^ c), result); //     &^|
+  Expect.notEquals((a & (b ^ c)) | (d & (b ^ c)), result); //  ^&|
+  Expect.notEquals((a & b) ^ (c | (d & b)) ^ c, result); //    &|^
+  Expect.notEquals((a & b) ^ ((c | d) & b) ^ c, result); //    |&^
+  Expect.notEquals(a & (b ^ (c | d)) & (b ^ c), result); //    |^&
+  Expect.notEquals(a & ((b ^ c) | d) & (b ^ c), result); //    ^|&
+  // Binds stronger than relational operators.
+  Expect.equals((a & b) < (c & d), a & b < c & d);
+  // Binds weaker than shift operators.
+  Expect.equals((a & (b << c)) ^ d, a & b << c ^ d);
+  Expect.notEquals((a & b) << (c ^ d), a & b << c ^ d);
+}
+
+@pragma('vm:never-inline')
+rightShift65Noinline(a) => a >> 65;
+
+testRightShift65() {
+  var a = 0x5f22334455667788;
+  var b = -0x5f22334455667788;
+
+  for (var i = 0; i < 20; ++i) {
+    Expect.equals(0, rightShift65Noinline(a));
+    Expect.equals(-1, rightShift65Noinline(b));
+  }
+}
diff --git a/tests/language/operator/bit_shift_test.dart b/tests/language/operator/bit_shift_test.dart
new file mode 100644
index 0000000..1f00423
--- /dev/null
+++ b/tests/language/operator/bit_shift_test.dart
@@ -0,0 +1,58 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+constants() {
+  Expect.equals(0, 499 >> 33);
+  Expect.equals(0, (499 << 33) & 0xFFFFFFFF);
+  Expect.equals(0, (499 << 32) >> 65);
+  Expect.equals(0, (499 << 32) << 65);
+}
+
+foo(i) {
+  if (i != 0) {
+    y--;
+    foo(i - 1);
+    y++;
+  }
+}
+
+var y;
+
+// id returns [x] in a way that should be difficult to predict statically.
+id(x) {
+  y = x;
+  foo(10);
+  return y;
+}
+
+interceptors() {
+  Expect.equals(0, id(499) >> 33);
+  Expect.equals(0, (id(499) << 33) & 0xFFFFFFFF);
+  Expect.equals(0, id(499 << 32) >> 65);
+  Expect.equals(0, id(499 << 32) << 65);
+}
+
+speculative() {
+  var a = id(499);
+  var b = id(499 << 32);
+  for (int i = 0; i < 1; i++) {
+    Expect.equals(0, a >> 33);
+    Expect.equals(0, (a << 33) & 0xFFFFFFFF);
+    Expect.equals(0, b >> 65);
+    Expect.equals(0, b << 65);
+  }
+}
+
+// JavaScript shifts by the amount modulo 32. That is x << y is equivalent to
+// x << (y & 0x1F). Dart does not.
+main() {
+  for (var i = 0; i < 10; ++i) {
+    constants();
+    interceptors();
+    speculative();
+  }
+}
diff --git a/tests/language/operator/comparison_test.dart b/tests/language/operator/comparison_test.dart
new file mode 100644
index 0000000..59d7005
--- /dev/null
+++ b/tests/language/operator/comparison_test.dart
@@ -0,0 +1,325 @@
+// 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.
+// Dart test program for testing comparison operators.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  static bool STRICT_EQ(a, b) {
+    return identical(a, b);
+  }
+
+  static bool STRICT_NE(a, b) {
+    return !identical(a, b);
+  }
+
+  static bool EQ(a, b) {
+    return a == b;
+  }
+
+  static bool NE(a, b) {
+    return a != b;
+  }
+
+  static bool LT(a, b) {
+    return a < b;
+  }
+
+  static bool LE(a, b) {
+    return a <= b;
+  }
+
+  static bool GT(a, b) {
+    return a > b;
+  }
+
+  static bool GE(a, b) {
+    return a >= b;
+  }
+}
+
+class A {
+  var b;
+
+  A(x) : b = x {}
+}
+
+class ComparisonTest {
+  static testMain() {
+    var a = new A(0);
+    var b = new A(1);
+    Expect.isTrue(Helper.STRICT_EQ(a, a));
+    Expect.isFalse(Helper.STRICT_EQ(a, b));
+    Expect.isFalse(Helper.STRICT_EQ(b, a));
+    Expect.isTrue(Helper.STRICT_EQ(b, b));
+
+    Expect.isFalse(Helper.STRICT_NE(a, a));
+    Expect.isTrue(Helper.STRICT_NE(a, b));
+    Expect.isTrue(Helper.STRICT_NE(b, a));
+    Expect.isFalse(Helper.STRICT_NE(b, b));
+
+    Expect.isTrue(Helper.STRICT_EQ(false, false));
+    Expect.isFalse(Helper.STRICT_EQ(false, true));
+    Expect.isFalse(Helper.STRICT_EQ(true, false));
+    Expect.isTrue(Helper.STRICT_EQ(true, true));
+
+    Expect.isFalse(Helper.STRICT_NE(false, false));
+    Expect.isTrue(Helper.STRICT_NE(false, true));
+    Expect.isTrue(Helper.STRICT_NE(true, false));
+    Expect.isFalse(Helper.STRICT_NE(true, true));
+
+    Expect.isTrue(Helper.STRICT_EQ(false, false));
+    Expect.isFalse(Helper.STRICT_EQ(false, true));
+    Expect.isFalse(Helper.STRICT_EQ(true, false));
+    Expect.isTrue(Helper.STRICT_EQ(true, true));
+
+    Expect.isFalse(Helper.STRICT_NE(false, false));
+    Expect.isTrue(Helper.STRICT_NE(false, true));
+    Expect.isTrue(Helper.STRICT_NE(true, false));
+    Expect.isFalse(Helper.STRICT_NE(true, true));
+
+    Expect.isTrue(Helper.EQ(false, false));
+    Expect.isFalse(Helper.EQ(false, true));
+    Expect.isFalse(Helper.EQ(true, false));
+    Expect.isTrue(Helper.EQ(true, true));
+
+    Expect.isFalse(Helper.NE(false, false));
+    Expect.isTrue(Helper.NE(false, true));
+    Expect.isTrue(Helper.NE(true, false));
+    Expect.isFalse(Helper.NE(true, true));
+
+    Expect.isTrue(Helper.STRICT_EQ(-1, -1));
+    Expect.isTrue(Helper.STRICT_EQ(0, 0));
+    Expect.isTrue(Helper.STRICT_EQ(1, 1));
+    Expect.isFalse(Helper.STRICT_EQ(-1, 0));
+    Expect.isFalse(Helper.STRICT_EQ(-1, 1));
+    Expect.isFalse(Helper.STRICT_EQ(0, 1));
+
+    Expect.isFalse(Helper.STRICT_NE(-1, -1));
+    Expect.isFalse(Helper.STRICT_NE(0, 0));
+    Expect.isFalse(Helper.STRICT_NE(1, 1));
+    Expect.isTrue(Helper.STRICT_NE(-1, 0));
+    Expect.isTrue(Helper.STRICT_NE(-1, 1));
+    Expect.isTrue(Helper.STRICT_NE(0, 1));
+
+    Expect.isTrue(Helper.EQ(-1, -1));
+    Expect.isTrue(Helper.EQ(0, 0));
+    Expect.isTrue(Helper.EQ(1, 1));
+    Expect.isFalse(Helper.EQ(-1, 0));
+    Expect.isFalse(Helper.EQ(-1, 1));
+    Expect.isFalse(Helper.EQ(0, 1));
+
+    Expect.isFalse(Helper.NE(-1, -1));
+    Expect.isFalse(Helper.NE(0, 0));
+    Expect.isFalse(Helper.NE(1, 1));
+    Expect.isTrue(Helper.NE(-1, 0));
+    Expect.isTrue(Helper.NE(-1, 1));
+    Expect.isTrue(Helper.NE(0, 1));
+
+    Expect.isFalse(Helper.LT(-1, -1));
+    Expect.isFalse(Helper.LT(0, 0));
+    Expect.isFalse(Helper.LT(1, 1));
+    Expect.isTrue(Helper.LT(-1, 0));
+    Expect.isTrue(Helper.LT(-1, 1));
+    Expect.isTrue(Helper.LT(0, 1));
+    Expect.isFalse(Helper.LT(0, -1));
+    Expect.isFalse(Helper.LT(1, -1));
+    Expect.isFalse(Helper.LT(1, 0));
+
+    Expect.isTrue(Helper.LE(-1, -1));
+    Expect.isTrue(Helper.LE(0, 0));
+    Expect.isTrue(Helper.LE(1, 1));
+    Expect.isTrue(Helper.LE(-1, 0));
+    Expect.isTrue(Helper.LE(-1, 1));
+    Expect.isTrue(Helper.LE(0, 1));
+    Expect.isFalse(Helper.LE(0, -1));
+    Expect.isFalse(Helper.LE(1, -1));
+    Expect.isFalse(Helper.LE(1, 0));
+
+    Expect.isFalse(Helper.GT(-1, -1));
+    Expect.isFalse(Helper.GT(0, 0));
+    Expect.isFalse(Helper.GT(1, 1));
+    Expect.isFalse(Helper.GT(-1, 0));
+    Expect.isFalse(Helper.GT(-1, 1));
+    Expect.isFalse(Helper.GT(0, 1));
+    Expect.isTrue(Helper.GT(0, -1));
+    Expect.isTrue(Helper.GT(1, -1));
+    Expect.isTrue(Helper.GT(1, 0));
+
+    Expect.isTrue(Helper.GE(-1, -1));
+    Expect.isTrue(Helper.GE(0, 0));
+    Expect.isTrue(Helper.GE(1, 1));
+    Expect.isFalse(Helper.GE(-1, 0));
+    Expect.isFalse(Helper.GE(-1, 1));
+    Expect.isFalse(Helper.GE(0, 1));
+    Expect.isTrue(Helper.GE(0, -1));
+    Expect.isTrue(Helper.GE(1, -1));
+    Expect.isTrue(Helper.GE(1, 0));
+
+    Expect.isTrue(Helper.STRICT_EQ(-1.0, -1.0));
+    Expect.isTrue(Helper.STRICT_EQ(0.0, 0.0));
+    Expect.isTrue(Helper.STRICT_EQ(1.0, 1.0));
+    Expect.isFalse(Helper.STRICT_EQ(-1.0, 0.0));
+    Expect.isFalse(Helper.STRICT_EQ(-1.0, 1.0));
+    Expect.isFalse(Helper.STRICT_EQ(0.0, 1.0));
+
+    Expect.isFalse(Helper.STRICT_NE(-1.0, -1.0));
+    Expect.isFalse(Helper.STRICT_NE(0.0, 0.0));
+    Expect.isFalse(Helper.STRICT_NE(1.0, 1.0));
+    Expect.isTrue(Helper.STRICT_NE(-1.0, 0.0));
+    Expect.isTrue(Helper.STRICT_NE(-1.0, 1.0));
+    Expect.isTrue(Helper.STRICT_NE(0.0, 1.0));
+
+    Expect.isTrue(Helper.EQ(-1.0, -1.0));
+    Expect.isTrue(Helper.EQ(0.0, 0.0));
+    Expect.isTrue(Helper.EQ(1.0, 1.0));
+    Expect.isFalse(Helper.EQ(-1.0, 0.0));
+    Expect.isFalse(Helper.EQ(-1.0, 1.0));
+    Expect.isFalse(Helper.EQ(0.0, 1.0));
+
+    Expect.isFalse(Helper.NE(-1.0, -1.0));
+    Expect.isFalse(Helper.NE(0.0, 0.0));
+    Expect.isFalse(Helper.NE(1.0, 1.0));
+    Expect.isTrue(Helper.NE(-1.0, 0.0));
+    Expect.isTrue(Helper.NE(-1.0, 1.0));
+    Expect.isTrue(Helper.NE(0.0, 1.0));
+
+    Expect.isFalse(Helper.LT(-1.0, -1.0));
+    Expect.isFalse(Helper.LT(0.0, 0.0));
+    Expect.isFalse(Helper.LT(1.0, 1.0));
+    Expect.isTrue(Helper.LT(-1.0, 0.0));
+    Expect.isTrue(Helper.LT(-1.0, 1.0));
+    Expect.isTrue(Helper.LT(0.0, 1.0));
+    Expect.isFalse(Helper.LT(0.0, -1.0));
+    Expect.isFalse(Helper.LT(1.0, -1.0));
+    Expect.isFalse(Helper.LT(1.0, 0.0));
+
+    Expect.isTrue(Helper.LE(-1.0, -1.0));
+    Expect.isTrue(Helper.LE(0.0, 0.0));
+    Expect.isTrue(Helper.LE(1.0, 1.0));
+    Expect.isTrue(Helper.LE(-1.0, 0.0));
+    Expect.isTrue(Helper.LE(-1.0, 1.0));
+    Expect.isTrue(Helper.LE(0.0, 1.0));
+    Expect.isFalse(Helper.LE(0.0, -1.0));
+    Expect.isFalse(Helper.LE(1.0, -1.0));
+    Expect.isFalse(Helper.LE(1.0, 0.0));
+
+    Expect.isFalse(Helper.GT(-1.0, -1.0));
+    Expect.isFalse(Helper.GT(0.0, 0.0));
+    Expect.isFalse(Helper.GT(1.0, 1.0));
+    Expect.isFalse(Helper.GT(-1.0, 0.0));
+    Expect.isFalse(Helper.GT(-1.0, 1.0));
+    Expect.isFalse(Helper.GT(0.0, 1.0));
+    Expect.isTrue(Helper.GT(0.0, -1.0));
+    Expect.isTrue(Helper.GT(1.0, -1.0));
+    Expect.isTrue(Helper.GT(1.0, 0.0));
+
+    Expect.isTrue(Helper.GE(-1.0, -1.0));
+    Expect.isTrue(Helper.GE(0.0, 0.0));
+    Expect.isTrue(Helper.GE(1.0, 1.0));
+    Expect.isFalse(Helper.GE(-1.0, 0.0));
+    Expect.isFalse(Helper.GE(-1.0, 1.0));
+    Expect.isFalse(Helper.GE(0.0, 1.0));
+    Expect.isTrue(Helper.GE(0.0, -1.0));
+    Expect.isTrue(Helper.GE(1.0, -1.0));
+    Expect.isTrue(Helper.GE(1.0, 0.0));
+
+    Expect.isTrue(Helper.EQ(null, null));
+    Expect.isFalse(Helper.EQ(null, "Str"));
+    Expect.isTrue(Helper.NE(null, 2));
+    Expect.isFalse(Helper.NE(null, null));
+
+    Expect.isTrue(Helper.STRICT_EQ(null, null));
+    Expect.isFalse(Helper.STRICT_EQ(null, "Str"));
+    Expect.isTrue(Helper.STRICT_NE(null, 2));
+    Expect.isFalse(Helper.STRICT_NE(null, null));
+
+    Expect.isFalse(Helper.GT(1, 1.2));
+    Expect.isTrue(Helper.GT(3, 1.2));
+    Expect.isTrue(Helper.GT(2.0, 1));
+    Expect.isFalse(Helper.GT(3.1, 4));
+
+    Expect.isFalse(Helper.GE(1, 1.2));
+    Expect.isTrue(Helper.GE(3, 1.2));
+    Expect.isTrue(Helper.GE(2.0, 1));
+    Expect.isFalse(Helper.GE(3.1, 4));
+    Expect.isTrue(Helper.GE(2.0, 2));
+    Expect.isTrue(Helper.GE(2, 2.0));
+
+    Expect.isTrue(Helper.LT(1, 1.2));
+    Expect.isFalse(Helper.LT(3, 1.2));
+    Expect.isFalse(Helper.LT(2.0, 1));
+    Expect.isTrue(Helper.LT(3.1, 4));
+
+    Expect.isTrue(Helper.LE(1, 1.2));
+    Expect.isFalse(Helper.LE(3, 1.2));
+    Expect.isFalse(Helper.LE(2.0, 1));
+    Expect.isTrue(Helper.LE(3.1, 4));
+    Expect.isTrue(Helper.LE(2.0, 2));
+    Expect.isTrue(Helper.LE(2, 2.0));
+
+    // Bignums.
+    Expect.isTrue(Helper.LE(0xF00000000005, 0xF00000000006));
+    Expect.isTrue(Helper.LE(0xF00000000005, 0xF00000000005));
+    Expect.isFalse(Helper.LE(0xF00000000006, 0xF00000000005));
+    Expect.isTrue(Helper.LE(12, 0xF00000000005));
+    Expect.isTrue(Helper.LE(12.2, 0xF00000000005));
+
+    Expect.isTrue(Helper.EQ(4294967295, 4.294967295e9));
+    Expect.isTrue(Helper.EQ(4.294967295e9, 4294967295));
+    Expect.isFalse(Helper.EQ(4.294967295e9, 42));
+    Expect.isFalse(Helper.EQ(42, 4.294967295e9));
+    Expect.isFalse(Helper.EQ(4294967295, 42));
+    Expect.isFalse(Helper.EQ(42, 4294967295));
+
+    // Fractions & mixed
+    Expect.isTrue(Helper.EQ(1.0, 1));
+    Expect.isTrue(Helper.EQ(1.0, 1));
+    Expect.isTrue(Helper.EQ(1, 1.0));
+    Expect.isTrue(Helper.EQ(1, 1.0));
+    Expect.isTrue(Helper.EQ(1.1, 1.1));
+    Expect.isTrue(Helper.EQ(1.1, 1.1));
+    Expect.isTrue(Helper.EQ(1.1, 1.1));
+
+    Expect.isFalse(Helper.GT(1, 1.2));
+    Expect.isTrue(Helper.GT(1.2, 1));
+    Expect.isTrue(Helper.GT(1.2, 1.1));
+    Expect.isTrue(Helper.GT(1.2, 1.1));
+    Expect.isTrue(Helper.GT(1.2, 1.1));
+
+    Expect.isTrue(Helper.LT(1, 1.2));
+    Expect.isFalse(Helper.LT(1.2, 1));
+    Expect.isFalse(Helper.LT(1.2, 1.1));
+    Expect.isFalse(Helper.LT(1.2, 1.1));
+    Expect.isFalse(Helper.LT(1.2, 1.1));
+
+    Expect.isFalse(Helper.GE(1.1, 1.2));
+    Expect.isFalse(Helper.GE(1.1, 1.2));
+    Expect.isTrue(Helper.GE(1.2, 1.2));
+    Expect.isTrue(Helper.GE(1.2, 1.2));
+
+    // With non-number classes.
+    Expect.isFalse(Helper.EQ(1, "eeny"));
+    Expect.isFalse(Helper.EQ("meeny", 1));
+    Expect.isFalse(Helper.EQ(1.1, "miny"));
+    Expect.isFalse(Helper.EQ("moe", 1.1));
+    Expect.isFalse(Helper.EQ(1.1, "catch"));
+    Expect.isFalse(Helper.EQ("the", 1.1));
+
+    // With null.
+    Expect.isFalse(Helper.EQ(1, null));
+    Expect.isFalse(Helper.EQ(null, 1));
+    Expect.isFalse(Helper.EQ(1.1, null));
+    Expect.isFalse(Helper.EQ(null, 1.1));
+    Expect.isFalse(Helper.EQ(1.1, null));
+    Expect.isFalse(Helper.EQ(null, 1.1));
+
+    // TODO(srdjan): Clarify behaviour of greater/less comparisons
+    // between numbers and non-numbers.
+  }
+}
+
+main() {
+  ComparisonTest.testMain();
+}
diff --git a/tests/language/operator/compound_assignment_test.dart b/tests/language/operator/compound_assignment_test.dart
new file mode 100644
index 0000000..99ec15b
--- /dev/null
+++ b/tests/language/operator/compound_assignment_test.dart
@@ -0,0 +1,123 @@
+// 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.
+// Tests that lhs of a compound assignment is executed only once.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import "package:expect/expect.dart";
+
+class Indexed {
+  Indexed()
+      : _f = new List<dynamic>.filled(10, null),
+        count = 0 {
+    _f[0] = 100;
+    _f[1] = 200;
+  }
+  operator [](i) {
+    count++;
+    return _f;
+  }
+
+  var count;
+  var _f;
+}
+
+var result;
+
+class A {
+  get field {
+    result.add(1);
+    return 1;
+  }
+
+  set field(value) {}
+
+  static get static_field {
+    result.add(0);
+    return 1;
+  }
+
+  static set static_field(value) {
+    result.add(1);
+  }
+}
+
+class CompoundAssignmentOperatorTest {
+  static void testIndexed() {
+    Indexed indexed = new Indexed();
+    Expect.equals(0, indexed.count);
+    var tmp = indexed[0];
+    Expect.equals(1, indexed.count);
+    Expect.equals(100, indexed[4][0]);
+    Expect.equals(2, indexed.count);
+    Expect.equals(100, indexed[4][0]++);
+    Expect.equals(3, indexed.count);
+    Expect.equals(101, indexed[4][0]);
+    Expect.equals(4, indexed.count);
+    indexed[4][0] += 10;
+    Expect.equals(5, indexed.count);
+    Expect.equals(111, indexed[4][0]);
+    var i = 0;
+    indexed[3][i++] += 1;
+    Expect.equals(1, i);
+  }
+
+  static testIndexedMore() {
+    result = [];
+    array() {
+      result.add(0);
+      return [0];
+    }
+
+    index() {
+      result.add(1);
+      return 0;
+    }
+
+    middle() {
+      result.add(2);
+    }
+
+    sequence(a, b, c) {
+      result.add(3);
+    }
+
+    sequence(array()[index()] += 1, middle(), array()[index()] += 1);
+    Expect.listEquals([0, 1, 2, 0, 1, 3], result);
+  }
+
+  static testIndexedMoreMore() {
+    result = [];
+    middle() {
+      result.add(2);
+    }
+
+    obj() {
+      result.add(0);
+      return new A();
+    }
+
+    sequence(a, b, c) {
+      result.add(3);
+    }
+
+    sequence(obj().field += 1, middle(), obj().field += 1);
+    Expect.listEquals([0, 1, 2, 0, 1, 3], result);
+
+    result = [];
+    sequence(A.static_field++, middle(), A.static_field++);
+    Expect.listEquals([0, 1, 2, 0, 1, 3], result);
+  }
+
+  static void testMain() {
+    for (int i = 0; i < 20; i++) {
+      testIndexed();
+      testIndexedMore();
+      testIndexedMoreMore();
+    }
+  }
+}
+
+main() {
+  CompoundAssignmentOperatorTest.testMain();
+}
diff --git a/tests/language/operator/cond_expr_test.dart b/tests/language/operator/cond_expr_test.dart
new file mode 100644
index 0000000..7bcc477
--- /dev/null
+++ b/tests/language/operator/cond_expr_test.dart
@@ -0,0 +1,26 @@
+// 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.
+// Check that conditional expressions can contain assignment expressions.
+
+import "package:expect/expect.dart";
+
+var e1, e2;
+
+f(a) => a < 0 ? e1 = -1 : e2 = 1;
+
+main() {
+  e1 = 0;
+  e2 = 0;
+  var r = f(-100);
+  Expect.equals(-1, r);
+  Expect.equals(-1, e1);
+  Expect.equals(0, e2);
+
+  e1 = 0;
+  e2 = 0;
+  r = f(100);
+  Expect.equals(1, r);
+  Expect.equals(0, e1);
+  Expect.equals(1, e2);
+}
diff --git a/tests/language/operator/div_by_zero_test.dart b/tests/language/operator/div_by_zero_test.dart
new file mode 100644
index 0000000..cb67d68
--- /dev/null
+++ b/tests/language/operator/div_by_zero_test.dart
@@ -0,0 +1,33 @@
+// 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.
+// Dart test program to test integer div by zero.
+
+import "package:expect/expect.dart";
+
+class DivByZeroTest {
+  static double divBy(int a, int b) {
+    var result = a / b;
+    return 1.0 * result;
+  }
+
+  static bool moustacheDivBy(int a, int b) {
+    var val = null;
+    try {
+      val = a ~/ b;
+    } catch (e) {
+      return true;
+    }
+    print("Should not have gotten: $val");
+    return false;
+  }
+
+  static void testMain() {
+    Expect.isTrue(divBy(0, 0).isNaN);
+    Expect.isTrue(moustacheDivBy(0, 0));
+  }
+}
+
+main() {
+  DivByZeroTest.testMain();
+}
diff --git a/tests/language/operator/div_with_power_of_two2_test.dart b/tests/language/operator/div_with_power_of_two2_test.dart
new file mode 100644
index 0000000..ef58026
--- /dev/null
+++ b/tests/language/operator/div_with_power_of_two2_test.dart
@@ -0,0 +1,152 @@
+// Copyright (c) 2013, 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 division by power of two.
+// Test that results before and after optimization are the same.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// [function, [list of tuples argument/result]].
+var expectedResults = [
+  [
+    divBy1,
+    [
+      [134217730, 134217730],
+      [-134217730, -134217730],
+      [10, 10],
+      [-10, -10]
+    ]
+  ],
+  [
+    divByNeg1,
+    [
+      [134217730, -134217730],
+      [-134217730, 134217730],
+      [10, -10],
+      [-10, 10]
+    ]
+  ],
+  [
+    divBy2,
+    [
+      [134217730, 67108865],
+      [-134217730, -67108865],
+      [10, 5],
+      [-10, -5]
+    ]
+  ],
+  [
+    divByNeg2,
+    [
+      [134217730, -67108865],
+      [-134217730, 67108865],
+      [10, -5],
+      [-10, 5]
+    ]
+  ],
+  [
+    divBy4,
+    [
+      [134217730, 33554432],
+      [-134217730, -33554432],
+      [10, 2],
+      [-10, -2]
+    ]
+  ],
+  [
+    divByNeg4,
+    [
+      [134217730, -33554432],
+      [-134217730, 33554432],
+      [10, -2],
+      [-10, 2]
+    ]
+  ],
+  [
+    divBy134217728,
+    [
+      [134217730, 1],
+      [-134217730, -1],
+      [10, 0],
+      [-10, 0]
+    ]
+  ],
+  [
+    divByNeg134217728,
+    [
+      [134217730, -1],
+      [-134217730, 1],
+      [10, 0],
+      [-10, 0]
+    ]
+  ],
+  // Use different functions for 64 bit arguments.
+  [
+    divBy4_,
+    [
+      [549755813990, 137438953497],
+      [-549755813990, -137438953497],
+      [288230925907525632, 72057731476881408],
+      [-288230925907525632, -72057731476881408]
+    ]
+  ],
+  [
+    divByNeg4_,
+    [
+      [549755813990, -137438953497],
+      [-549755813990, 137438953497],
+      [288230925907525632, -72057731476881408],
+      [-288230925907525632, 72057731476881408]
+    ]
+  ],
+  [
+    divBy549755813888,
+    [
+      [549755813990, 1],
+      [-549755813990, -1],
+      [288230925907525632, 524289],
+      [-288230925907525632, -524289]
+    ]
+  ],
+  [
+    divByNeg549755813888,
+    [
+      [549755813990, -1],
+      [-549755813990, 1],
+      [288230925907525632, -524289],
+      [-288230925907525632, 524289]
+    ]
+  ],
+];
+
+divBy0(a) => a ~/ 0;
+divBy1(a) => a ~/ 1;
+divByNeg1(a) => a ~/ -1;
+divBy2(a) => a ~/ 2;
+divByNeg2(a) => a ~/ -2;
+divBy4(a) => a ~/ 4;
+divByNeg4(a) => a ~/ -4;
+divBy134217728(a) => a ~/ 134217728;
+divByNeg134217728(a) => a ~/ -134217728;
+
+divBy4_(a) => a ~/ 4;
+divByNeg4_(a) => a ~/ -4;
+divBy549755813888(a) => a ~/ 549755813888;
+divByNeg549755813888(a) => a ~/ -549755813888;
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    for (var e in expectedResults) {
+      Function f = e[0] as Function;
+      List values = e[1] as List;
+      for (var v in values) {
+        int arg = v[0];
+        int res = v[1];
+        Expect.equals(res, f(arg));
+      }
+    }
+    Expect.throws(() => divBy0(4),
+        (e) => e is IntegerDivisionByZeroException || e is UnsupportedError);
+  }
+}
diff --git a/tests/language/operator/div_with_power_of_two_test.dart b/tests/language/operator/div_with_power_of_two_test.dart
new file mode 100644
index 0000000..98f8d13a
--- /dev/null
+++ b/tests/language/operator/div_with_power_of_two_test.dart
@@ -0,0 +1,150 @@
+// Copyright (c) 2013, 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 division by power of two.
+// Test that results before and after optimization are the same.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// [function, [list of tuples argument/result]].
+var expectedResults = [
+  [
+    divBy1,
+    [
+      [134217730, 134217730],
+      [-134217730, -134217730],
+      [10, 10],
+      [-10, -10]
+    ]
+  ],
+  [
+    divByNeg1,
+    [
+      [134217730, -134217730],
+      [-134217730, 134217730],
+      [10, -10],
+      [-10, 10]
+    ]
+  ],
+  [
+    divBy2,
+    [
+      [134217730, 67108865],
+      [-134217730, -67108865],
+      [10, 5],
+      [-10, -5]
+    ]
+  ],
+  [
+    divByNeg2,
+    [
+      [134217730, -67108865],
+      [-134217730, 67108865],
+      [10, -5],
+      [-10, 5]
+    ]
+  ],
+  [
+    divBy4,
+    [
+      [134217730, 33554432],
+      [-134217730, -33554432],
+      [10, 2],
+      [-10, -2]
+    ]
+  ],
+  [
+    divByNeg4,
+    [
+      [134217730, -33554432],
+      [-134217730, 33554432],
+      [10, -2],
+      [-10, 2]
+    ]
+  ],
+  [
+    divBy134217728,
+    [
+      [134217730, 1],
+      [-134217730, -1],
+      [10, 0],
+      [-10, 0]
+    ]
+  ],
+  [
+    divByNeg134217728,
+    [
+      [134217730, -1],
+      [-134217730, 1],
+      [10, 0],
+      [-10, 0]
+    ]
+  ],
+  // Use different functions for 64 bit arguments.
+  [
+    divBy4_,
+    [
+      [549755813990, 137438953497],
+      [-549755813990, -137438953497],
+      [288230925907525632, 72057731476881408],
+      [-288230925907525632, -72057731476881408]
+    ]
+  ],
+  [
+    divByNeg4_,
+    [
+      [549755813990, -137438953497],
+      [-549755813990, 137438953497],
+      [288230925907525632, -72057731476881408],
+      [-288230925907525632, 72057731476881408]
+    ]
+  ],
+  [
+    divBy549755813888,
+    [
+      [549755813990, 1],
+      [-549755813990, -1],
+      [288230925907525632, 524289],
+      [-288230925907525632, -524289]
+    ]
+  ],
+  [
+    divByNeg549755813888,
+    [
+      [549755813990, -1],
+      [-549755813990, 1],
+      [288230925907525632, -524289],
+      [-288230925907525632, 524289]
+    ]
+  ],
+];
+
+divBy0(a) => a ~/ 0;
+divBy1(a) => a ~/ 1;
+divByNeg1(a) => a ~/ -1;
+divBy2(a) => a ~/ 2;
+divByNeg2(a) => a ~/ -2;
+divBy4(a) => a ~/ 4;
+divByNeg4(a) => a ~/ -4;
+divBy134217728(a) => a ~/ 134217728;
+divByNeg134217728(a) => a ~/ -134217728;
+
+divBy4_(a) => a ~/ 4;
+divByNeg4_(a) => a ~/ -4;
+divBy549755813888(a) => a ~/ 549755813888;
+divByNeg549755813888(a) => a ~/ -549755813888;
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    for (var e in expectedResults) {
+      Function f = e[0] as Function;
+      List values = e[1] as List;
+      for (var v in values) {
+        int arg = v[0];
+        int res = v[1];
+        Expect.equals(res, f(arg));
+      }
+    }
+  }
+}
diff --git a/tests/language/operator/equality_test.dart b/tests/language/operator/equality_test.dart
new file mode 100644
index 0000000..69d8572
--- /dev/null
+++ b/tests/language/operator/equality_test.dart
@@ -0,0 +1,83 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+class A {
+  bool _result;
+  A(this._result);
+  operator ==(x) {
+    return _result;
+  }
+}
+
+opaque(x) => [x, 1, 'y'][0]; // confuse the optimizers.
+
+class Death {
+  operator ==(x) {
+    throw 'Dead!';
+  }
+}
+
+death() => opaque(new Death());
+nullFn() => opaque(null);
+
+tests() {
+  var alwaysTrue = new A(true);
+  var alwaysFalse = new A(false);
+  Expect.isFalse(alwaysFalse == alwaysFalse);
+  Expect.isTrue(alwaysFalse != alwaysFalse);
+  Expect.isTrue(alwaysTrue == alwaysTrue);
+  Expect.isTrue(alwaysTrue == 5);
+  Expect.isFalse(alwaysTrue == null);
+  Expect.isFalse(null == alwaysTrue);
+  Expect.isTrue(alwaysTrue != null);
+  Expect.isTrue(null != alwaysTrue);
+  Expect.isTrue(null == null);
+  Expect.isFalse(null != null);
+
+  Expect.throws(() => death() == 5);
+  Expect.isFalse(death() == nullFn());
+  Expect.isFalse(nullFn() == death());
+  Expect.isTrue(nullFn() == nullFn());
+  Expect.isTrue(death() != nullFn());
+  Expect.isTrue(nullFn() != death());
+  Expect.isFalse(nullFn() != nullFn());
+
+  if (death() == nullFn()) {
+    throw "failed";
+  }
+  if (death() != nullFn()) {} else {
+    throw "failed";
+  }
+}
+
+boolEqualityPositiveA(a) => a == true;
+boolEqualityNegativeA(a) => a != true;
+
+boolEqualityPositiveB(a) => true == a;
+boolEqualityNegativeB(a) => true != a;
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    tests();
+    // Do not inline calls to prevent constant folding.
+    Expect.isTrue(boolEqualityPositiveA(true));
+    Expect.isFalse(boolEqualityPositiveA(false));
+    Expect.isFalse(boolEqualityNegativeA(true));
+    Expect.isTrue(boolEqualityNegativeA(false));
+
+    Expect.isTrue(boolEqualityPositiveB(true));
+    Expect.isFalse(boolEqualityPositiveB(false));
+    Expect.isFalse(boolEqualityNegativeB(true));
+    Expect.isTrue(boolEqualityNegativeB(false));
+  }
+
+  // Deoptimize.
+  Expect.isFalse(boolEqualityPositiveA(1));
+  Expect.isTrue(boolEqualityNegativeA("hi"));
+  Expect.isFalse(boolEqualityPositiveB(2.0));
+  Expect.isTrue(boolEqualityNegativeB([]));
+}
diff --git a/tests/language/operator/equals_test.dart b/tests/language/operator/equals_test.dart
new file mode 100644
index 0000000..109c7c6
--- /dev/null
+++ b/tests/language/operator/equals_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to infer [:super == null:]
+// always returns an int.
+
+import 'package:expect/expect.dart';
+
+class A {
+  operator ==(other) => 42; /*@compile-error=unspecified*/
+}
+
+class B extends A {
+  foo() => (super == null) + 4; /*@compile-error=unspecified*/
+}
+
+main() {
+  Expect.throwsNoSuchMethodError(() => new B().foo());
+}
diff --git a/tests/language/operator/incr_op_test.dart b/tests/language/operator/incr_op_test.dart
new file mode 100644
index 0000000..edabac9
--- /dev/null
+++ b/tests/language/operator/incr_op_test.dart
@@ -0,0 +1,82 @@
+// 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.
+// Dart test program for testing increment operator.
+
+import "package:expect/expect.dart";
+
+class A {
+  static var yy;
+  static set y(v) {
+    yy = v;
+  }
+
+  static get y {
+    return yy;
+  }
+}
+
+class IncrOpTest {
+  var x;
+  static var y;
+
+  IncrOpTest() {}
+
+  static testMain() {
+    var a = 3;
+    var c = a++ + 1;
+    Expect.equals(4, c);
+    Expect.equals(4, a);
+    c = a-- + 1;
+    Expect.equals(5, c);
+    Expect.equals(3, a);
+
+    c = --a + 1;
+    Expect.equals(3, c);
+    Expect.equals(2, a);
+
+    c = 2 + ++a;
+    Expect.equals(5, c);
+    Expect.equals(3, a);
+
+    var obj = new IncrOpTest();
+    obj.x = 100;
+    Expect.equals(100, obj.x);
+    obj.x++;
+    Expect.equals(101, obj.x);
+    Expect.equals(102, ++obj.x);
+    Expect.equals(102, obj.x++);
+    Expect.equals(103, obj.x);
+
+    A.y = 55;
+    Expect.equals(55, A.y++);
+    Expect.equals(56, A.y);
+    Expect.equals(57, ++A.y);
+    Expect.equals(57, A.y);
+    Expect.equals(56, --A.y);
+
+    IncrOpTest.y = 55;
+    Expect.equals(55, IncrOpTest.y++);
+    Expect.equals(56, IncrOpTest.y);
+    Expect.equals(57, ++IncrOpTest.y);
+    Expect.equals(57, IncrOpTest.y);
+    Expect.equals(56, --IncrOpTest.y);
+
+    var list = [0, 1, 2, 3];
+    for (int i = 0; i < list.length; i++) {
+      list[i]++;
+    }
+    for (int i = 0; i < list.length; i++) {
+      Expect.equals(i + 1, list[i]);
+      ++list[i];
+    }
+    Expect.equals(1 + 2, list[1]);
+    Expect.equals(1 + 2, list[1]--);
+    Expect.equals(1 + 1, list[1]);
+    Expect.equals(1 + 0, --list[1]);
+  }
+}
+
+main() {
+  IncrOpTest.testMain();
+}
diff --git a/tests/language/operator/index_evaluation_order_test.dart b/tests/language/operator/index_evaluation_order_test.dart
new file mode 100644
index 0000000..dabd62e
--- /dev/null
+++ b/tests/language/operator/index_evaluation_order_test.dart
@@ -0,0 +1,50 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class B {
+  int value;
+  List trace;
+  B(this.trace) : value = 100;
+  operator [](index) {
+    trace.add(-3);
+    trace.add(index);
+    trace.add(this.value);
+    this.value = this.value + 1;
+    return this;
+  }
+
+  operator []=(index, value) {
+    trace.add(-5);
+    trace.add(index);
+    trace.add(value.value);
+    this.value = this.value + 1;
+  }
+
+  operator +(int value) {
+    trace.add(-4);
+    trace.add(this.value);
+    trace.add(value);
+    this.value = this.value + 1;
+    return this;
+  }
+}
+
+B getB(trace) {
+  trace.add(-1);
+  return new B(trace);
+}
+
+int getIndex(trace) {
+  trace.add(-2);
+  return 42;
+}
+
+main() {
+  List trace = [];
+  getB(trace)[getIndex(trace)] += 37;
+
+  Expect.listEquals([-1, -2, -3, 42, 100, -4, 101, 37, -5, 42, 102], trace);
+}
diff --git a/tests/language/operator/index_test.dart b/tests/language/operator/index_test.dart
new file mode 100644
index 0000000..40cdb2a
--- /dev/null
+++ b/tests/language/operator/index_test.dart
@@ -0,0 +1,38 @@
+// 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.
+// Dart test program for testing index operators.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  static int fibonacci(int n) {
+    int a = 0, b = 1, i = 0;
+    while (i++ < n) {
+      a = a + b;
+      b = a - b;
+    }
+    return a;
+  }
+}
+
+class IndexTest {
+  static const ID_IDLE = 0;
+
+  static testMain() {
+    var a = new List<dynamic>.filled(10, null);
+    Expect.equals(10, a.length);
+    for (int i = 0; i < a.length; i++) {
+      a[i] = Helper.fibonacci(i);
+    }
+    a[ID_IDLE] = Helper.fibonacci(0);
+    for (int i = 2; i < a.length; i++) {
+      Expect.equals(a[i - 2] + a[i - 1], a[i]);
+    }
+    Expect.equals(515, a[3] = 515);
+  }
+}
+
+main() {
+  IndexTest.testMain();
+}
diff --git a/tests/language/operator/integer_division_by_zero_test.dart b/tests/language/operator/integer_division_by_zero_test.dart
new file mode 100644
index 0000000..03cd661
--- /dev/null
+++ b/tests/language/operator/integer_division_by_zero_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, 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 integer division by zero.
+// Test that results before and after optimization are the same.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+divBy0(a) => a ~/ 0;
+
+main() {
+  Expect.throws(() => divBy0(4), (e) => e is IntegerDivisionByZeroException);
+}
diff --git a/tests/language/operator/invalid_assignment_to_postfix_increment_runtime_test.dart b/tests/language/operator/invalid_assignment_to_postfix_increment_runtime_test.dart
new file mode 100644
index 0000000..6998367
--- /dev/null
+++ b/tests/language/operator/invalid_assignment_to_postfix_increment_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+void f(int x, int y) {
+
+
+
+}
+
+main() {
+  f(1, 2);
+}
diff --git a/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart b/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart
new file mode 100644
index 0000000..b26b284
--- /dev/null
+++ b/tests/language/operator/invalid_assignment_to_postfix_increment_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+void f(int x, int y, int? z) {
+  x++ = y;
+//^^^
+// [analyzer] SYNTACTIC_ERROR.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
+//^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNABLE_SELECTOR
+// ^
+// [cfe] Illegal assignment to non-assignable expression.
+  x++ += y;
+//^^^
+// [analyzer] SYNTACTIC_ERROR.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
+//^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNABLE_SELECTOR
+// ^
+// [cfe] Illegal assignment to non-assignable expression.
+  z++ ??= y;
+//^
+// [analyzer] STATIC_WARNING.UNCHECKED_USE_OF_NULLABLE_VALUE
+//^^^
+// [analyzer] SYNTACTIC_ERROR.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE
+//^^^
+// [analyzer] SYNTACTIC_ERROR.MISSING_ASSIGNABLE_SELECTOR
+// ^
+// [cfe] Illegal assignment to non-assignable expression.
+}
+
+main() {
+  f(1, 2, 3);
+}
diff --git a/tests/language/operator/left_shift_test.dart b/tests/language/operator/left_shift_test.dart
new file mode 100644
index 0000000..7f151b1
--- /dev/null
+++ b/tests/language/operator/left_shift_test.dart
@@ -0,0 +1,13 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+main() {
+  for (int i = 0; i < 80; i++) {
+    var a = -1 << i;
+    var b = -1;
+    Expect.equals(1 << i, a ~/ b);
+  }
+}
diff --git a/tests/language/operator/literal_unary_plus_test.dart b/tests/language/operator/literal_unary_plus_test.dart
new file mode 100644
index 0000000..8a2530d
--- /dev/null
+++ b/tests/language/operator/literal_unary_plus_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+// There is no unary plus operator in Dart.
+
+main() {
+  var a = + 1; //      //# 01: syntax error
+  var x = +"foo"; //   //# 02: syntax error
+  var x = + "foo"; //  //# 03: syntax error
+}
diff --git a/tests/language/operator/logical_expression2_test.dart b/tests/language/operator/logical_expression2_test.dart
new file mode 100644
index 0000000..04a05e94
--- /dev/null
+++ b/tests/language/operator/logical_expression2_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2014, 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";
+
+// Regression test for issue 17149.
+
+int globalCounter = 0;
+
+void nonInlinedUse(Object object) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) nonInlinedUse(object);
+  if (object is! String) globalCounter++;
+}
+
+int confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
+  return x;
+}
+
+main() {
+  var o = ["foo", 499][confuse(1)];
+
+  // The `o is String` check in the rhs of the logical or must not be
+  // propagated to the `if` body.
+  if ((o is num) || (o is String && true)) {
+    nonInlinedUse(o);
+  }
+  Expect.equals(1, globalCounter);
+}
diff --git a/tests/language/operator/logical_expression3_test.dart b/tests/language/operator/logical_expression3_test.dart
new file mode 100644
index 0000000..9d6efa9
--- /dev/null
+++ b/tests/language/operator/logical_expression3_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2014, 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";
+
+bool nonInlinedNumTypeCheck(Object object) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return nonInlinedNumTypeCheck(object);
+  }
+  return object is num;
+}
+
+int confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
+  return x;
+}
+
+main() {
+  var o = ["foo", 499][confuse(0)];
+
+  // When the lhs of a logical or fails, it must not assume that all negative is
+  // checks in it, have failed.
+  // Here, the `o is! num` check succeeds, but the length test failed.
+  if ((o is! num && o.length == 4) || (nonInlinedNumTypeCheck(o))) { /*@compile-error=unspecified*/
+    Expect.fail("Type-check failed");
+  }
+}
diff --git a/tests/language/operator/logical_expression4_test.dart b/tests/language/operator/logical_expression4_test.dart
new file mode 100644
index 0000000..1442434
--- /dev/null
+++ b/tests/language/operator/logical_expression4_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2014, 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";
+
+bool nonInlinedNumTypeCheck(Object object) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return nonInlinedNumTypeCheck(object);
+  }
+  return object is num;
+}
+
+int confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
+  return x;
+}
+
+main() {
+  var o = ["foo", 499][confuse(0)];
+
+  // The is-checks in the '!' must not be propagated to the if-body.
+  // This was a bug in dart2js.
+  if (!(o is num && o is num)) {
+    Expect.isFalse((nonInlinedNumTypeCheck(o)));
+  }
+}
diff --git a/tests/language/operator/logical_expression5_test.dart b/tests/language/operator/logical_expression5_test.dart
new file mode 100644
index 0000000..f918604
--- /dev/null
+++ b/tests/language/operator/logical_expression5_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2014, 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';
+
+bool nonInlinedNumTypeCheck(Object object) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return nonInlinedNumTypeCheck(object);
+  }
+  return object is num;
+}
+
+bool nonInlinedStringTypeCheck(Object object) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    return nonInlinedStringTypeCheck(object);
+  }
+  return object is String;
+}
+
+int confuse(x) {
+  if (new DateTime.now().millisecondsSinceEpoch == 42) return confuse(x - 1);
+  return x;
+}
+
+main() {
+  var o = ["foo", 499][confuse(0)];
+
+  // The is-checks in the '!' must not be propagated to the if-body, but
+  // the second is-check should.
+  if (!(o is num) && o is String) {
+    Expect.isFalse((nonInlinedNumTypeCheck(o)));
+    Expect.isTrue((nonInlinedStringTypeCheck(o)));
+  }
+}
diff --git a/tests/language/operator/logical_expression_test.dart b/tests/language/operator/logical_expression_test.dart
new file mode 100644
index 0000000..c12f026
--- /dev/null
+++ b/tests/language/operator/logical_expression_test.dart
@@ -0,0 +1,119 @@
+// Copyright (c) 2014, 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 test program for testing if statement.
+
+import "package:expect/expect.dart";
+
+// For logical-or conditions dart2js sometimes inlined expressions, leading to
+// completely broken programs.
+
+int globalCounter = 0;
+
+falseWithSideEffect() {
+  bool confuse() => new DateTime.now().millisecondsSinceEpoch == 42;
+
+  var result = confuse();
+
+  // Make it harder to inline.
+  if (result) {
+    try {
+      try {
+        if (confuse()) falseWithSideEffect();
+        if (confuse()) return 499;
+      } catch (e) {
+        rethrow;
+      }
+    } catch (e) {
+      rethrow;
+    }
+  }
+  globalCounter++;
+  return result;
+}
+
+falseWithoutSideEffect() {
+  bool confuse() => new DateTime.now().millisecondsSinceEpoch == 42;
+
+  var result = confuse();
+
+  // Make it harder to inline.
+  if (result) {
+    try {
+      try {
+        if (confuse()) falseWithSideEffect();
+        if (confuse()) return 499;
+      } catch (e) {
+        rethrow;
+      }
+    } catch (e) {
+      rethrow;
+    }
+  }
+  return result;
+}
+
+testLogicalOr() {
+  globalCounter = 0;
+  bool cond1 = falseWithSideEffect();
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  Expect.equals(1, globalCounter);
+
+  cond1 = (falseWithSideEffect() == 499);
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 || falseWithoutSideEffect()) Expect.fail("must be false");
+  Expect.equals(2, globalCounter);
+}
+
+List globalList = [];
+void testLogicalOr2() {
+  globalList.clear();
+  testValueOr([]);
+  testValueOr(null);
+  Expect.listEquals([1, 2, 3], globalList);
+}
+
+void testValueOr(List? list) {
+  if (list == null) globalList.add(1);
+  if (list == null || list.contains("2")) globalList.add(2);
+  if (list == null || list.contains("3")) globalList.add(3);
+}
+
+testLogicalAnd() {
+  globalCounter = 0;
+  bool cond1 = falseWithSideEffect();
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  Expect.equals(1, globalCounter);
+
+  cond1 = (falseWithSideEffect() == 499);
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  if (cond1 && falseWithoutSideEffect()) Expect.fail("must be false");
+  Expect.equals(2, globalCounter);
+}
+
+void testLogicalAnd2() {
+  globalList.clear();
+  testValueAnd([]);
+  testValueAnd(null);
+  Expect.listEquals([1, 2, 3], globalList);
+}
+
+void testValueAnd(List? list) {
+  if (list == null) globalList.add(1);
+  if (list == null && globalList.contains(1)) globalList.add(2);
+  if (list == null && globalList.contains(1)) globalList.add(3);
+}
+
+main() {
+  testLogicalOr();
+  testLogicalOr2();
+
+  testLogicalAnd();
+  testLogicalAnd2();
+}
diff --git a/tests/language/operator/mint_arithmetic_test.dart b/tests/language/operator/mint_arithmetic_test.dart
new file mode 100644
index 0000000..ee29858
--- /dev/null
+++ b/tests/language/operator/mint_arithmetic_test.dart
@@ -0,0 +1,95 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+// Test arithmetic on 64-bit integers.
+
+test_and_1() {
+  try {
+    // Avoid optimizing this function.
+    f(a, b) {
+      var s = b;
+      var t = a & s;
+      return t == b;
+    }
+
+    var x = 0xffffffff;
+    for (var i = 0; i < 20; i++) f(x, 0);
+    Expect.equals(true, f(x, 0));
+    Expect.equals(false, f(x, -1)); // Triggers deoptimization.
+  } finally {}
+}
+
+test_and_2() {
+  try {
+    // Avoid optimizing this function.
+    f(a, b) {
+      return a & b;
+    }
+
+    var x = 0xffffffff;
+    for (var i = 0; i < 20; i++) f(x, x);
+    Expect.equals(x, f(x, x));
+    Expect.equals(1234, f(0xffffffff, 1234));
+    Expect.equals(0x100000001, f(0x100000001, -1));
+    Expect.equals(-0x40000000, f(-0x40000000, -1));
+    Expect.equals(0x40000000, f(0x40000000, -1));
+    Expect.equals(0x3fffffff, f(0x3fffffff, -1));
+  } finally {}
+}
+
+test_xor_1() {
+  try {
+    // Avoid optimizing this function.
+    f(a, b) {
+      var s = b;
+      var t = a ^ s;
+      return t;
+    }
+
+    var x = 0xffffffff;
+    for (var i = 0; i < 20; i++) f(x, x);
+    Expect.equals(0, f(x, x));
+    Expect.equals(-x - 1, f(x, -1));
+    var y = 0xffffffffffffffff;
+    Expect.equals(-y - 1, f(y, -1)); // Triggers deoptimization.
+  } finally {}
+}
+
+test_or_1() {
+  try {
+    // Avoid optimizing this function.
+    f(a, b) {
+      var s = b;
+      var t = a | s;
+      return t;
+    }
+
+    var x = 0xffffffff;
+    for (var i = 0; i < 20; i++) f(x, x);
+    Expect.equals(x, f(x, x));
+    Expect.equals(-1, f(x, -1));
+    var y = 0xffffffffffffffff;
+    Expect.equals(-1, f(y, -1)); // Triggers deoptimization.
+  } finally {}
+}
+
+test_func(x, y) => (x & y) + 1.0;
+
+test_mint_double_op() {
+  for (var i = 0; i < 20; i++) test_func(4294967295, 1);
+  Expect.equals(2.0, test_func(4294967295, 1));
+}
+
+main() {
+  for (var i = 0; i < 5; i++) {
+    test_and_1();
+    test_and_2();
+    test_xor_1();
+    test_or_1();
+    test_mint_double_op();
+  }
+}
diff --git a/tests/language/operator/modulo_test.dart b/tests/language/operator/modulo_test.dart
new file mode 100644
index 0000000..ae55626
--- /dev/null
+++ b/tests/language/operator/modulo_test.dart
@@ -0,0 +1,95 @@
+// Copyright (c) 2013, 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 test optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+main() {
+  // Prime IC cache.
+  noDom(1);
+  noDom(-1);
+  for (int i = -30; i < 30; i++) {
+    Expect.equals(i % 256, foo(i));
+    Expect.equals(i % -256, boo(i));
+    Expect.throws(() => hoo(i), (e) => e is IntegerDivisionByZeroException);
+
+    Expect.equals(i ~/ 254 + i % 254, fooTwo(i));
+    Expect.equals(i ~/ -254 + i % -254, booTwo(i));
+    Expect.throws(() => hooTwo(i), (e) => e is IntegerDivisionByZeroException);
+    if (i > 0) {
+      Expect.equals(i % 10, noDom(i));
+    } else {
+      Expect.equals(i ~/ 10, noDom(i));
+    }
+    Expect.equals((i ~/ 10) + (i % 10) + (i % 10), threeOp(i));
+    Expect.equals((i ~/ 10) + (i ~/ 12) + (i % 10) + (i % 12), fourOp(i));
+
+    // Zero test is done outside the loop.
+    if (i < 0) {
+      Expect.equals(i % -i, foo2(i));
+      Expect.equals(i ~/ -i + i % -i, fooTwo2(i));
+    } else if (i > 0) {
+      Expect.equals(i % i, foo2(i));
+      Expect.equals(i ~/ i + i % i, fooTwo2(i));
+    }
+  }
+  Expect.throws(() => foo2(0), (e) => e is IntegerDivisionByZeroException);
+  Expect.throws(() => fooTwo2(0), (e) => e is IntegerDivisionByZeroException);
+}
+
+foo(i) => i % 256; // This will get optimized to AND instruction.
+boo(i) => i % -256;
+hoo(i) => i % 0;
+
+fooTwo(i) => i ~/ 254 + i % 254;
+booTwo(i) => i ~/ -254 + i % -254;
+hooTwo(i) => i ~/ 0 + i % 0;
+
+noDom(a) {
+  var x;
+  if (a > 0) {
+    x = a % 10;
+  } else {
+    x = a ~/ 10;
+  }
+  return x;
+}
+
+threeOp(a) {
+  var x = a ~/ 10;
+  var y = a % 10;
+  var z = a % 10;
+  return x + y + z;
+}
+
+fourOp(a) {
+  var x0 = a ~/ 10;
+  var x1 = a ~/ 12;
+  var y0 = a % 10;
+  var y1 = a % 12;
+  return x0 + x1 + y0 + y1;
+}
+
+foo2(i) {
+  // Make sure x has a range computed.
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i % x;
+}
+
+fooTwo2(i) {
+  // Make sure x has a range computed.
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i ~/ x + i % x;
+}
diff --git a/tests/language/operator/mul_recipr_test.dart b/tests/language/operator/mul_recipr_test.dart
new file mode 100644
index 0000000..a79be78
--- /dev/null
+++ b/tests/language/operator/mul_recipr_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, 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 test program checking that optimizations are not too aggressive and
+// incorrect:
+// - (a * (1.0 / b))
+//
+// VMOptions=--optimization-counter-threshold=8 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+var xx = 23.0;
+
+main() {
+  xx = 1e-6;
+  scaleIt(1e-310);
+  Expect.isTrue(xx.isInfinite);
+  for (int i = 0; i < 10; i++) {
+    xx = 24.0;
+    scaleIt(6.0);
+    Expect.equals(4.0, xx);
+  }
+  xx = 1e-6;
+  scaleIt(1e-310);
+  Expect.isTrue(xx.isInfinite);
+}
+
+scaleIt(double b) {
+  scale(1.0 / b);
+}
+
+scale(a) {
+  xx *= a;
+}
diff --git a/tests/language/operator/multi_assign_test.dart b/tests/language/operator/multi_assign_test.dart
new file mode 100644
index 0000000..d88a63a
--- /dev/null
+++ b/tests/language/operator/multi_assign_test.dart
@@ -0,0 +1,26 @@
+// 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.
+// Dart test program testing multiple assignment.
+
+import "package:expect/expect.dart";
+
+class MultiAssignTest {
+  static testMain() {
+    var i, j, k;
+    i = j = k = 11;
+    Expect.equals(11, i);
+    Expect.equals(11, j);
+    Expect.equals(11, k);
+
+    var m;
+    var n = m = k = 55;
+    Expect.equals(55, m);
+    Expect.equals(55, n);
+    Expect.equals(55, k);
+  }
+}
+
+main() {
+  MultiAssignTest.testMain();
+}
diff --git a/tests/language/operator/negate_and_method_negate_test.dart b/tests/language/operator/negate_and_method_negate_test.dart
new file mode 100644
index 0000000..98a0063
--- /dev/null
+++ b/tests/language/operator/negate_and_method_negate_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// This checks that it is possible to have a method named negate as
+// well as unary- operator.
+
+class Foo {
+  operator -() => 42;
+  negate() => 87;
+}
+
+main() {
+  Expect.equals(42, -new Foo());
+  Expect.equals(87, new Foo().negate());
+}
diff --git a/tests/language/operator/operations_on_non_num_operand_test.dart b/tests/language/operator/operations_on_non_num_operand_test.dart
new file mode 100644
index 0000000..8a98bb3
--- /dev/null
+++ b/tests/language/operator/operations_on_non_num_operand_test.dart
@@ -0,0 +1,145 @@
+// Copyright (c) 2015, 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.
+
+/// Regression test for dart2js that used to miscompile boolean and operations
+/// if one of the operands was an int and the other was not (issue 22427).
+///
+/// Extended to all operations as there is a risk of similar bugs with other
+/// operators, e.g. `a % 2` _looks_ like it might be 0 or 1.
+
+import "package:expect/expect.dart";
+
+@pragma('dart2js:assumeDynamic')
+@pragma('dart2js:noInline')
+confuse(x) => x;
+
+class Thing1 {
+  operator &(b) => this;
+  operator |(b) => this;
+  operator ^(b) => this;
+  operator <<(b) => this;
+  operator >>(b) => this;
+
+  operator +(b) => this;
+  operator -(b) => this;
+  operator *(b) => this;
+  operator /(b) => this;
+  operator ~/(b) => this;
+  operator %(b) => this;
+  remainder(b) => this;
+
+  operator <(b) => this;
+  operator <=(b) => this;
+  operator >(b) => this;
+  operator >=(b) => this;
+}
+
+class Thing2 {
+  @pragma('dart2js:noInline')
+  operator &(b) => this;
+  @pragma('dart2js:noInline')
+  operator |(b) => this;
+  @pragma('dart2js:noInline')
+  operator ^(b) => this;
+  @pragma('dart2js:noInline')
+  operator <<(b) => this;
+  @pragma('dart2js:noInline')
+  operator >>(b) => this;
+
+  @pragma('dart2js:noInline')
+  operator +(b) => this;
+  @pragma('dart2js:noInline')
+  operator -(b) => this;
+  @pragma('dart2js:noInline')
+  operator *(b) => this;
+  @pragma('dart2js:noInline')
+  operator /(b) => this;
+  @pragma('dart2js:noInline')
+  operator ~/(b) => this;
+  @pragma('dart2js:noInline')
+  operator %(b) => this;
+  @pragma('dart2js:noInline')
+  remainder(b) => this;
+
+  @pragma('dart2js:noInline')
+  operator <(b) => this;
+  @pragma('dart2js:noInline')
+  operator <=(b) => this;
+  @pragma('dart2js:noInline')
+  operator >(b) => this;
+  @pragma('dart2js:noInline')
+  operator >=(b) => this;
+}
+
+confused() {
+  var a = new Thing1();
+  Expect.equals(a, confuse(a) & 5 & 2);
+  Expect.equals(a, confuse(a) | 5 | 2);
+  Expect.equals(a, confuse(a) ^ 5 ^ 2);
+  Expect.equals(a, confuse(a) << 5 << 2);
+  Expect.equals(a, confuse(a) >> 5 >> 2);
+
+  Expect.equals(a, confuse(a) + 5 + 2);
+  Expect.equals(a, confuse(a) - 5 - 2);
+  Expect.equals(a, confuse(a) * 5 * 2);
+  Expect.equals(a, confuse(a) / 5 / 2);
+  Expect.equals(a, confuse(a) % 5 % 2);
+  Expect.equals(a, confuse(a) ~/ 5 ~/ 2);
+  Expect.equals(a, confuse(a).remainder(5).remainder(2));
+
+  Expect.equals(a, (confuse(a) < 5) < 2);
+  Expect.equals(a, (confuse(a) <= 5) <= 2);
+  Expect.equals(a, (confuse(a) > 5) > 2);
+  Expect.equals(a, (confuse(a) >= 5) >= 2);
+}
+
+direct1() {
+  var a = new Thing1();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+direct2() {
+  var a = new Thing2();
+  Expect.equals(a, a & 5 & 2);
+  Expect.equals(a, a | 5 | 2);
+  Expect.equals(a, a ^ 5 ^ 2);
+  Expect.equals(a, a << 5 << 2);
+  Expect.equals(a, a >> 5 >> 2);
+
+  Expect.equals(a, a + 5 + 2);
+  Expect.equals(a, a - 5 - 2);
+  Expect.equals(a, a * 5 * 2);
+  Expect.equals(a, a / 5 / 2);
+  Expect.equals(a, a % 5 % 2);
+  Expect.equals(a, a ~/ 5 ~/ 2);
+  Expect.equals(a, a.remainder(5).remainder(2));
+
+  Expect.equals(a, (a < 5) < 2);
+  Expect.equals(a, (a <= 5) <= 2);
+  Expect.equals(a, (a > 5) > 2);
+  Expect.equals(a, (a >= 5) >= 2);
+}
+
+main() {
+  confused();
+  direct1();
+  direct2();
+}
diff --git a/tests/language/operator/operator1_test.dart b/tests/language/operator/operator1_test.dart
new file mode 100644
index 0000000..5ba6722
--- /dev/null
+++ b/tests/language/operator/operator1_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+/// Operator functions cannot be static.
+
+class C {
+  static operator +(int index) {
+//^^^^^^
+// [analyzer] SYNTACTIC_ERROR.STATIC_OPERATOR
+// [cfe] Operators can't be static.
+    return index;
+  }
+}
+
+main() {
+  C();
+}
diff --git a/tests/language/operator/operator2_test.dart b/tests/language/operator/operator2_test.dart
new file mode 100644
index 0000000..dca3eda
--- /dev/null
+++ b/tests/language/operator/operator2_test.dart
@@ -0,0 +1,54 @@
+// 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.
+// Operator dart test program.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  int i;
+  Helper(int val) : i = val {}
+  operator [](int index) {
+    return i + index;
+  }
+
+  void operator []=(int index, int val) {
+    i = val;
+  }
+}
+
+main() {
+  Helper obj = new Helper(10);
+  Expect.equals(10, obj.i);
+  obj[10] = 20;
+  Expect.equals(30, obj[10]);
+
+  regress32754();
+}
+
+// Regression test for https://github.com/dart-lang/sdk/issues/32754
+class C {
+  operator []=(i, value) {
+    value = 'OOPS';
+  }
+}
+
+class C2 {
+  late int data;
+  operator []=(i, value) {
+    // The return expression must be evaluated, then ignored.
+    return () {
+      data = i + value;
+      return null;
+    }();
+  }
+}
+
+regress32754() {
+  var c = new C();
+  Expect.equals('ok', c[0] = 'ok');
+
+  var c2 = new C2();
+  Expect.equals(23, c2[100] = 23);
+  Expect.equals(123, c2.data);
+}
diff --git a/tests/language/operator/operator3_test.dart b/tests/language/operator/operator3_test.dart
new file mode 100644
index 0000000..98e9571
--- /dev/null
+++ b/tests/language/operator/operator3_test.dart
@@ -0,0 +1,20 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  operator -() => this;
+  toString() => "5";
+  abs() => "correct";
+}
+
+// This triggered a bug in Dart2Js: the speculative type optimization assigned
+// type "number" to 'a' and then to '-a'. In the bailout version the type for
+// 'a' was removed, but the type for '-a' was kept.
+foo(a) => -(-a);
+
+main() {
+  Expect.equals("correct", foo(new A()).abs());
+}
diff --git a/tests/language/operator/operator4_test.dart b/tests/language/operator/operator4_test.dart
new file mode 100644
index 0000000..e203a16
--- /dev/null
+++ b/tests/language/operator/operator4_test.dart
@@ -0,0 +1,27 @@
+// 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 "package:expect/expect.dart";
+
+class A {
+  operator <(other) => 1;
+}
+
+// This triggered a bug in Dart2Js: relational operators were not correctly
+// boolified.
+foo(a) {
+  try {
+    if (a < a) {
+      return "bad";
+    } else {
+      return 499;
+    }
+  } on TypeError catch (e) {
+    return 499;
+  }
+}
+
+main() {
+  Expect.equals(499, foo(new A()));
+}
diff --git a/tests/language/operator/operator5_test.dart b/tests/language/operator/operator5_test.dart
new file mode 100644
index 0000000..a6d177d
--- /dev/null
+++ b/tests/language/operator/operator5_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  operator ==(other) => 1; /*@compile-error=unspecified*/
+  operator <(other) => null; /*@compile-error=unspecified*/
+  operator <=(other) => 499; /*@compile-error=unspecified*/
+  operator >(other) => "foo"; /*@compile-error=unspecified*/
+  operator >=(other) => 42; /*@compile-error=unspecified*/
+}
+
+// This triggered a bug in Dart2Js: equality operator was always boolified.
+equals(a) {
+  Expect.equals(1, a == a);
+}
+
+less(a) {
+  Expect.equals(null, a < a);
+}
+
+lessEqual(a) {
+  Expect.equals(499, a <= a);
+}
+
+greater(a) {
+  Expect.equals("foo", a > a);
+}
+
+greaterEqual(a) {
+  Expect.equals(42, a >= a);
+}
+
+main() {
+  var a = new A();
+  equals(a);
+  less(a);
+  lessEqual(a);
+  greater(a);
+  greaterEqual(a);
+}
diff --git a/tests/language/operator/operator6_test.dart b/tests/language/operator/operator6_test.dart
new file mode 100644
index 0000000..05990a9
--- /dev/null
+++ b/tests/language/operator/operator6_test.dart
@@ -0,0 +1,29 @@
+// 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 "package:expect/expect.dart";
+
+class OperatorTest {
+  OperatorTest() {}
+
+  static testMain() {
+    var op1 = new Operator(1);
+    var op2 = new Operator(2);
+    Expect.equals(~1, ~op1);
+  }
+}
+
+class Operator {
+  int value;
+
+  Operator(this.value);
+
+  operator ~() {
+    return ~value;
+  }
+}
+
+main() {
+  OperatorTest.testMain();
+}
diff --git a/tests/language/operator/operator7_test.dart b/tests/language/operator/operator7_test.dart
new file mode 100644
index 0000000..ff43b64
--- /dev/null
+++ b/tests/language/operator/operator7_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+/// No "===" operator.
+
+class C {
+  operator ===(int index) {
+  //       ^
+  // [analyzer] SYNTACTIC_ERROR.UNSUPPORTED_OPERATOR
+  // [cfe] The '===' operator is not supported.
+    return index;
+  }
+}
+
+main() {
+  C();
+}
diff --git a/tests/language/operator/operator_test.dart b/tests/language/operator/operator_test.dart
new file mode 100644
index 0000000..2d1b16b
--- /dev/null
+++ b/tests/language/operator/operator_test.dart
@@ -0,0 +1,138 @@
+// 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 "package:expect/expect.dart";
+
+class OperatorTest {
+  static int i1 = -1;
+  static int i2 = -1;
+
+  OperatorTest() {}
+
+  static testMain() {
+    var op1 = new Operator(1);
+    var op2 = new Operator(2);
+    Expect.equals(3, op1 + op2);
+    Expect.equals(-1, op1 - op2);
+    Expect.equals(0.5, op1 / op2);
+    Expect.equals(0, op1 ~/ op2);
+    Expect.equals(2, op1 * op2);
+    Expect.equals(1, op1 % op2);
+    Expect.equals(true, !(op1 == op2));
+    Expect.equals(true, op1 < op2);
+    Expect.equals(true, !(op1 > op2));
+    Expect.equals(true, op1 <= op2);
+    Expect.equals(true, !(op1 >= op2));
+    Expect.equals(3, (op1 | op2));
+    Expect.equals(3, (op1 ^ op2));
+    Expect.equals(0, (op1 & op2));
+    Expect.equals(4, (op1 << op2));
+    Expect.equals(0, (op1 >> op2));
+    Expect.equals(-1, -op1);
+
+    op1.value += op2.value;
+    Expect.equals(3, op1.value);
+
+    op2.value += (op2.value += op2.value);
+    Expect.equals(6, op2.value);
+
+    op2.value -= (op2.value -= op2.value);
+    Expect.equals(6, op2.value);
+
+    op1.value = op2.value = 42;
+    Expect.equals(42, op1.value);
+    Expect.equals(42, op2.value);
+
+    i1 = i2 = 42;
+    Expect.equals(42, i1);
+    Expect.equals(42, i2);
+    i1 += 7;
+    Expect.equals(49, i1);
+    i1 += (i2 = 17);
+    Expect.equals(66, i1);
+    Expect.equals(17, i2);
+
+    i1 += i2 += 3;
+    Expect.equals(86, i1);
+    Expect.equals(20, i2);
+  }
+}
+
+class Operator {
+  int value;
+
+  Operator(this.value);
+
+  operator +(Operator other) {
+    return value + other.value;
+  }
+
+  operator -(Operator other) {
+    return value - other.value;
+  }
+
+  operator /(Operator other) {
+    return value / other.value;
+  }
+
+  operator *(Operator other) {
+    return value * other.value;
+  }
+
+  operator %(Operator other) {
+    return value % other.value;
+  }
+
+  operator ==(dynamic other) {
+    return value == other.value;
+  }
+
+  operator <(Operator other) {
+    return value < other.value;
+  }
+
+  operator >(Operator other) {
+    return value > other.value;
+  }
+
+  operator <=(Operator other) {
+    return value <= other.value;
+  }
+
+  operator >=(Operator other) {
+    return value >= other.value;
+  }
+
+  operator |(Operator other) {
+    return value | other.value;
+  }
+
+  operator ^(Operator other) {
+    return value ^ other.value;
+  }
+
+  operator &(Operator other) {
+    return value & other.value;
+  }
+
+  operator <<(Operator other) {
+    return value << other.value;
+  }
+
+  operator >>(Operator other) {
+    return value >> other.value;
+  }
+
+  operator ~/(Operator other) {
+    return value ~/ other.value;
+  }
+
+  operator -() {
+    return -value;
+  }
+}
+
+main() {
+  OperatorTest.testMain();
+}
diff --git a/tests/language/operator/positive_bit_operations_test.dart b/tests/language/operator/positive_bit_operations_test.dart
new file mode 100644
index 0000000..396360c
--- /dev/null
+++ b/tests/language/operator/positive_bit_operations_test.dart
@@ -0,0 +1,144 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+constants() {
+  Expect.equals(0x80000000, 0x80000000 | 0);
+  Expect.equals(0x80000001, 0x80000000 | 1);
+  Expect.equals(0x80000000, 0x80000000 | 0x80000000);
+  Expect.equals(0xFFFFFFFF, 0xFFFF0000 | 0xFFFF);
+  Expect.equals(0x80000000, 0x80000000 & 0xFFFFFFFF);
+  Expect.equals(0x80000000, 0x80000000 & 0x80000000);
+  Expect.equals(0x80000000, 0x80000000 & 0xF0000000);
+  Expect.equals(0x80000000, 0xFFFFFFFF & 0x80000000);
+  Expect.equals(0x80000000, 0x80000000 ^ 0);
+  Expect.equals(0xFFFFFFFF, 0x80000000 ^ 0x7FFFFFFF);
+  Expect.equals(0xFFFFFFFF, 0x7FFFFFFF ^ 0x80000000);
+  Expect.equals(0xF0000000, 0x70000000 ^ 0x80000000);
+  Expect.equals(0x80000000, 1 << 31);
+  Expect.equals(0xFFFFFFF0, 0xFFFFFFF << 4);
+  Expect.equals(0x7FFFFFFF, 0xFFFFFFFF >> 1);
+  Expect.equals(
+      0xFFFFFFFC,
+      ((((((0xFFFFFFF << 4) // 0xFFFFFFF0
+                          >>
+                          1) // 0x7FFFFFF8
+                      |
+                      0x80000000) // 0xFFFFFFF8
+                  >>
+                  2) // 0x3FFFFFFE
+              ^
+              0x40000000) // 0x7FFFFFFE
+          <<
+          1));
+}
+
+foo(i) {
+  if (i != 0) {
+    y--;
+    foo(i - 1);
+    y++;
+  }
+}
+
+var y;
+
+// id returns [x] in a way that should be difficult to predict statically.
+id(x) {
+  y = x;
+  foo(10);
+  return y;
+}
+
+interceptors() {
+  Expect.equals(0x80000000, id(0x80000000) | id(0));
+  Expect.equals(0x80000001, id(0x80000000) | id(1));
+  Expect.equals(0x80000000, id(0x80000000) | id(0x80000000));
+  Expect.equals(0xFFFFFFFF, id(0xFFFF0000) | id(0xFFFF));
+  Expect.equals(0x80000000, id(0x80000000) & id(0xFFFFFFFF));
+  Expect.equals(0x80000000, id(0x80000000) & id(0x80000000));
+  Expect.equals(0x80000000, id(0x80000000) & id(0xF0000000));
+  Expect.equals(0x80000000, id(0xFFFFFFFF) & id(0x80000000));
+  Expect.equals(0x80000000, id(0x80000000) ^ id(0));
+  Expect.equals(0xFFFFFFFF, id(0x80000000) ^ id(0x7FFFFFFF));
+  Expect.equals(0xFFFFFFFF, id(0x7FFFFFFF) ^ id(0x80000000));
+  Expect.equals(0xF0000000, id(0x70000000) ^ id(0x80000000));
+  Expect.equals(0x80000000, id(1) << id(31));
+  Expect.equals(0xFFFFFFF0, id(0xFFFFFFF) << id(4));
+  Expect.equals(0x7FFFFFFF, id(0xFFFFFFFF) >> id(1));
+  Expect.equals(
+      0xFFFFFFFC,
+      ((((((id(0xFFFFFFF) << 4) // 0xFFFFFFF0
+                          >>
+                          1) // 0x7FFFFFF8
+                      |
+                      0x80000000) // 0xFFFFFFF8
+                  >>
+                  2) // 0x3FFFFFFE
+              ^
+              0x40000000) // 0x7FFFFFFE
+          <<
+          1));
+}
+
+speculative() {
+  var a = id(0x80000000);
+  var b = id(0);
+  var c = id(1);
+  var d = id(0xFFFF0000);
+  var e = id(0xFFFF);
+  var f = id(0xFFFFFFFF);
+  var g = id(0xF0000000);
+  var h = id(0x7FFFFFFF);
+  var j = id(0x70000000);
+  var k = id(31);
+  var l = id(4);
+  var m = id(0xFFFFFFF);
+  for (int i = 0; i < 1; i++) {
+    Expect.equals(0x80000000, a | b);
+    Expect.equals(0x80000001, a | c);
+    Expect.equals(0x80000000, a | a);
+    Expect.equals(0xFFFFFFFF, d | e);
+    Expect.equals(0x80000000, a & f);
+    Expect.equals(0x80000000, a & a);
+    Expect.equals(0x80000000, a & g);
+    Expect.equals(0x80000000, f & a);
+    Expect.equals(0x80000000, a ^ b);
+    Expect.equals(0xFFFFFFFF, a ^ h);
+    Expect.equals(0xFFFFFFFF, h ^ a);
+    Expect.equals(0xF0000000, j ^ a);
+    Expect.equals(0x80000000, c << k);
+    Expect.equals(0xFFFFFFF0, m << l);
+    Expect.equals(0x7FFFFFFF, f >> c);
+    Expect.equals(
+        0xFFFFFFFC,
+        ((((((m << 4) // 0xFFFFFFF0
+                            >>
+                            1) // 0x7FFFFFF8
+                        |
+                        0x80000000) // 0xFFFFFFF8
+                    >>
+                    2) // 0x3FFFFFFE
+                ^
+                0x40000000) // 0x7FFFFFFE
+            <<
+            1));
+  }
+}
+
+// Due to bad precedence rules this example was broken in Dart2Js.
+precedence() {
+  Expect.equals(0x80000000, -1 & 0x80000000);
+  Expect.equals(0x80000000, id(-1) & 0x80000000);
+  Expect.equals(0x80000000, ~(~(0x80000000)));
+  Expect.equals(0x80000000, ~(~(id(0x80000000))));
+}
+
+main() {
+  constants();
+  interceptors();
+  speculative();
+  precedence();
+}
diff --git a/tests/language/operator/precedence_test.dart b/tests/language/operator/precedence_test.dart
new file mode 100644
index 0000000..d22ca89
--- /dev/null
+++ b/tests/language/operator/precedence_test.dart
@@ -0,0 +1,179 @@
+// Copyright (c) 2017, 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 test program to test operation precedence.
+
+library precedence_test;
+
+import "package:expect/expect.dart";
+
+main() {
+  testBang();
+  testIndexWithPrefixAdd();
+  testIndexWithPostfixAdd();
+  testTilde();
+  testUnaryPrefixWithAdd();
+  testUnaryPostfixWithAdd();
+  testUnaryPrefixWithMultiply();
+  testUnaryPostfixWithMultiply();
+}
+
+void testBang() {
+  int x = 3;
+
+  Expect.equals(!true == false, true);
+  Expect.equals(!x.isEven, true);
+  Expect.equals(!(++x).isEven, false);
+  Expect.equals(x, 4);
+  Expect.equals(!(x++).isEven, false);
+  Expect.equals(x, 5);
+}
+
+void testIndexWithPrefixAdd() {
+  var x = <int>[3];
+
+  Expect.equals(++x[0] + 3, 7);
+  Expect.equals(x[0], 4);
+  Expect.equals(++x[0] - 3, 2);
+  Expect.equals(x[0], 5);
+  Expect.equals(--x[0] + 4, 8);
+  Expect.equals(x[0], 4);
+  Expect.equals(--x[0] - 4, -1);
+  Expect.equals(x[0], 3);
+
+  Expect.equals(3 + ++x[0], 7);
+  Expect.equals(x[0], 4);
+  Expect.equals(3 - ++x[0], -2);
+  Expect.equals(x[0], 5);
+  Expect.equals(4 + --x[0], 8);
+  Expect.equals(x[0], 4);
+  Expect.equals(4 - --x[0], 1);
+  Expect.equals(x[0], 3);
+}
+
+void testIndexWithPostfixAdd() {
+  var x = <int>[3];
+
+  Expect.equals(x[0]++ + 3, 6);
+  Expect.equals(x[0], 4);
+  Expect.equals(x[0]++ - 3, 1);
+  Expect.equals(x[0], 5);
+  Expect.equals(x[0]-- + 4, 9);
+  Expect.equals(x[0], 4);
+  Expect.equals(x[0]-- - 4, 0);
+  Expect.equals(x[0], 3);
+
+  Expect.equals(3 + x[0]++, 6);
+  Expect.equals(x[0], 4);
+  Expect.equals(3 - x[0]++, -1);
+  Expect.equals(x[0], 5);
+  Expect.equals(4 + x[0]--, 9);
+  Expect.equals(x[0], 4);
+  Expect.equals(4 - x[0]--, 0);
+  Expect.equals(x[0], 3);
+}
+
+void testTilde() {
+  int x = 3;
+
+  Expect.equals(~x.sign, ~(x.sign));
+  Expect.equals(~x + 7, (~3) + 7);
+
+  Expect.equals(~++x + 7, (~4) + 7);
+  Expect.equals(x, 4);
+  Expect.equals(~x++ + 7, (~4) + 7);
+  Expect.equals(x, 5);
+
+  Expect.equals(~ --x + 7, (~4) + 7);
+  Expect.equals(x, 4);
+  Expect.equals(~x-- + 7, (~4) + 7);
+  Expect.equals(x, 3);
+}
+
+void testUnaryPrefixWithAdd() {
+  int x = 3;
+
+  Expect.equals(++x + 3, 7);
+  Expect.equals(x, 4);
+  Expect.equals(++x - 3, 2);
+  Expect.equals(x, 5);
+  Expect.equals(--x + 4, 8);
+  Expect.equals(x, 4);
+  Expect.equals(--x - 4, -1);
+  Expect.equals(x, 3);
+
+  Expect.equals(3 + ++x, 7);
+  Expect.equals(x, 4);
+  Expect.equals(3 - ++x, -2);
+  Expect.equals(x, 5);
+  Expect.equals(4 + --x, 8);
+  Expect.equals(x, 4);
+  Expect.equals(4 - --x, 1);
+  Expect.equals(x, 3);
+}
+
+void testUnaryPostfixWithAdd() {
+  int x = 3;
+
+  Expect.equals(x++ + 3, 6);
+  Expect.equals(x, 4);
+  Expect.equals(x++ - 3, 1);
+  Expect.equals(x, 5);
+  Expect.equals(x-- + 4, 9);
+  Expect.equals(x, 4);
+  Expect.equals(x-- - 4, 0);
+  Expect.equals(x, 3);
+
+  Expect.equals(3 + x++, 6);
+  Expect.equals(x, 4);
+  Expect.equals(3 - x++, -1);
+  Expect.equals(x, 5);
+  Expect.equals(4 + x--, 9);
+  Expect.equals(x, 4);
+  Expect.equals(4 - x--, 0);
+  Expect.equals(x, 3);
+}
+
+void testUnaryPrefixWithMultiply() {
+  int x = 3;
+
+  Expect.equals(++x * 3, 12);
+  Expect.equals(x, 4);
+  Expect.equals(++x / 5, 1.0);
+  Expect.equals(x, 5);
+  Expect.equals(--x * 3, 12);
+  Expect.equals(x, 4);
+  Expect.equals(--x / 4, 0.75);
+  Expect.equals(x, 3);
+
+  Expect.equals(3 * ++x, 12);
+  Expect.equals(x, 4);
+  Expect.equals(5 / ++x, 1.0);
+  Expect.equals(x, 5);
+  Expect.equals(3 * --x, 12);
+  Expect.equals(x, 4);
+  Expect.equals(6 / --x, 2.0);
+  Expect.equals(x, 3);
+}
+
+void testUnaryPostfixWithMultiply() {
+  int x = 3;
+
+  Expect.equals(x++ * 3, 9);
+  Expect.equals(x, 4);
+  Expect.equals(x++ / 4, 1.0);
+  Expect.equals(x, 5);
+  Expect.equals(x-- * 3, 15);
+  Expect.equals(x, 4);
+  Expect.equals(x-- / 4, 1.0);
+  Expect.equals(x, 3);
+
+  Expect.equals(3 * x++, 9);
+  Expect.equals(x, 4);
+  Expect.equals(3 / x++, 0.75);
+  Expect.equals(x, 5);
+  Expect.equals(4 * x--, 20);
+  Expect.equals(x, 4);
+  Expect.equals(4 / x--, 1.0);
+  Expect.equals(x, 3);
+}
diff --git a/tests/language/operator/round_test.dart b/tests/language/operator/round_test.dart
new file mode 100644
index 0000000..e1b3c3e
--- /dev/null
+++ b/tests/language/operator/round_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, 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 of a common rounding bug.
+///
+/// This bug is common in JavaScript implementations because the ECMA-262
+/// specification of JavaScript incorrectly claims:
+///
+///     The value of [:Math.round(x):] is the same as the value of
+///     [:Math.floor(x+0.5):], except when x is 0 or is less than 0 but greater
+///     than or equal to -0.5; for these cases [:Math.round(x):] returns 0, but
+///     [:Math.floor(x+0.5):] returns +0.
+///
+/// However, 0.49999999999999994 + 0.5 is 1 and 9007199254740991 + 0.5 is
+/// 9007199254740992, so you cannot implement Math.round in terms of
+/// Math.floor.
+
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals(0, (0.49999999999999994).round());
+  Expect.equals(0, (-0.49999999999999994).round());
+
+  Expect.equals(9007199254740991, (9007199254740991.0).round());
+  Expect.equals(-9007199254740991, (-9007199254740991.0).round());
+}
diff --git a/tests/language/operator/smi_type_test.dart b/tests/language/operator/smi_type_test.dart
new file mode 100644
index 0000000..dddfdbe
--- /dev/null
+++ b/tests/language/operator/smi_type_test.dart
@@ -0,0 +1,36 @@
+// Copyright (c) 2013, 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.
+// VMOptions=--optimization-counter-threshold=8
+
+import "package:expect/expect.dart";
+
+main() {
+  // Make instance-of polymorphic.
+  isNum([]);
+  isNumRaw([]);
+  isNotNum([]);
+  isNotInt([]);
+  for (int i = 0; i < 20; i++) {
+    Expect.isTrue(isNum(i));
+    Expect.isTrue(isNumRaw(i));
+    Expect.isFalse(isNotNum(i));
+    Expect.isFalse(isNotInt(i));
+  }
+}
+
+isNum(a) {
+  return a is Comparable<num>;
+}
+
+isNumRaw(a) {
+  return a is Comparable;
+}
+
+isNotNum(a) {
+  return a is Comparable<String>;
+}
+
+isNotInt(a) {
+  return a is Comparable<double>;
+}
diff --git a/tests/language/operator/ternary_test.dart b/tests/language/operator/ternary_test.dart
new file mode 100644
index 0000000..240034d
--- /dev/null
+++ b/tests/language/operator/ternary_test.dart
@@ -0,0 +1,35 @@
+// 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.
+// Dart test for testing the ternary operator.
+
+import "package:expect/expect.dart";
+
+class TernaryTest {
+  static true_cond() {
+    return true;
+  }
+
+  static false_cond() {
+    return false;
+  }
+
+  static foo() {
+    return -4;
+  }
+
+  static moo() {
+    return 5;
+  }
+
+  static testMain() {
+    Expect.equals(
+        -4, (TernaryTest.true_cond() ? TernaryTest.foo() : TernaryTest.moo()));
+    Expect.equals(
+        5, (TernaryTest.false_cond() ? TernaryTest.foo() : TernaryTest.moo()));
+  }
+}
+
+main() {
+  TernaryTest.testMain();
+}
diff --git a/tests/language/operator/truncdiv_test.dart b/tests/language/operator/truncdiv_test.dart
new file mode 100644
index 0000000..bd043d1
--- /dev/null
+++ b/tests/language/operator/truncdiv_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2013, 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 test optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+main() {
+  for (int i = -30; i < 30; i++) {
+    Expect.equals(i % 9, foo(i, 9));
+    // Zero test is done outside the loop.
+    if (i < 0) {
+      Expect.equals(i ~/ -i, foo2(i));
+    } else if (i > 0) {
+      Expect.equals(i ~/ i, foo2(i));
+    }
+  }
+  // We don't specify the exact exception type here, that is covered in
+  // truncdiv_zero_test. The correct answer is IntegerDivisionByZeroException,
+  // but the web platform has only one num type and can't distinguish between
+  // int and double, so it throws UnsupportedError (the behaviour for double).
+  Expect.throws(() => foo2(0));
+}
+
+foo(i, x) => i % x;
+
+foo2(i) {
+  // Make sure x has a range computed.
+  var x = 0;
+  if (i < 0) {
+    x = -i;
+  } else {
+    x = i;
+  }
+  return i ~/ x;
+}
diff --git a/tests/language/operator/truncdiv_uint32_test.dart b/tests/language/operator/truncdiv_uint32_test.dart
new file mode 100644
index 0000000..46930a4
--- /dev/null
+++ b/tests/language/operator/truncdiv_uint32_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, 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.
+
+var a = [0xFFFFFFFF];
+
+main() {
+  if (a[0] ~/ 1 != 0xFFFFFFFF) throw 'Test failed';
+}
diff --git a/tests/language/operator/truncdiv_zero_test.dart b/tests/language/operator/truncdiv_zero_test.dart
new file mode 100644
index 0000000..34cecc3
--- /dev/null
+++ b/tests/language/operator/truncdiv_zero_test.dart
@@ -0,0 +1,14 @@
+// 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.
+// Dart test optimization of modulo operator on Smi.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr
+
+import "package:expect/expect.dart";
+
+import "truncdiv_test.dart" as truncdiv_test show foo, foo2;
+
+main() {
+  Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo(12, 0));
+  Expect.throws<IntegerDivisionByZeroException>(() => truncdiv_test.foo2(0));
+}
diff --git a/tests/language/operator/unary2_test.dart b/tests/language/operator/unary2_test.dart
new file mode 100644
index 0000000..a799339
--- /dev/null
+++ b/tests/language/operator/unary2_test.dart
@@ -0,0 +1,24 @@
+// 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.
+// Dart test for testing binary operations.
+
+import "package:expect/expect.dart";
+
+class UnaryTest {
+  static foo() {
+    return -4;
+  }
+
+  static moo() {
+    return 5;
+  }
+
+  static testMain() {
+    Expect.equals(1, (UnaryTest.foo() + UnaryTest.moo()));
+  }
+}
+
+main() {
+  UnaryTest.testMain();
+}
diff --git a/tests/language/operator/unary_plus_test.dart b/tests/language/operator/unary_plus_test.dart
new file mode 100644
index 0000000..ac6e9ce
--- /dev/null
+++ b/tests/language/operator/unary_plus_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.
+
+/// There is no unary plus operator in Dart.
+
+main() {
+  var a = 1;
+  var b = +a;
+  //      ^
+  // [analyzer] SYNTACTIC_ERROR.MISSING_IDENTIFIER
+  // [cfe] '+' is not a prefix operator.
+}
diff --git a/tests/language/operator/unary_test.dart b/tests/language/operator/unary_test.dart
new file mode 100644
index 0000000..d2421c0
--- /dev/null
+++ b/tests/language/operator/unary_test.dart
@@ -0,0 +1,25 @@
+// 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 "package:expect/expect.dart";
+
+// Dart test for testing binary operations.
+
+class UnaryTest {
+  static foo() {
+    return 4;
+  }
+
+  static moo() {
+    return 5;
+  }
+
+  static testMain() {
+    Expect.equals(9.0, (UnaryTest.foo() + UnaryTest.moo()));
+  }
+}
+
+main() {
+  UnaryTest.testMain();
+}
diff --git a/tests/language/operator/unsigned_right_shift_test.dart b/tests/language/operator/unsigned_right_shift_test.dart
new file mode 100644
index 0000000..ddbaf51
--- /dev/null
+++ b/tests/language/operator/unsigned_right_shift_test.dart
@@ -0,0 +1,230 @@
+// 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=triple-shift
+
+import "package:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+// The >>> operator is (again) supported by Dart
+// (This test does not test int.operator>>>, such a test belongs in the corelib
+// test collection. Const uses of int.operator>>> is tested elsewhere as well).
+
+/// Syntactically tricky coincidences containing >>> and >>>=.
+/// DO NOT FORMAT THIS FILE. There should not be a space between >>> and =.
+typedef F3<T extends List<List<int>>>= T Function();
+typedef F4<T extends List<List<List<int>>>>= T Function();
+typedef F5<T extends List<List<List<List<int>>>>>= T Function();
+typedef F6<T extends List<List<List<List<List<int>>>>>>= T Function();
+class E3<T extends List<List<int>>> {}
+class E4<T extends List<List<List<int>>>> {}
+class E5<T extends List<List<List<List<int>>>>> {}
+class E6<T extends List<List<List<List<List<int>>>>>> {}
+
+main() {
+  // >>> is an overridable operator.
+  const c1 = C(1);
+  const c2 = C(2);
+  Expect.identical(c2, c1 >>> c2);
+
+  /// It combines to an assignment operator.
+  C c = c1;
+  c >>>= c2;
+  Expect.identical(c2, c);
+
+  // Operand needs to have correct type for typed invocation.
+  c1 //
+     >>> 4 //# 01: compile-time error
+     >>> "string" //# 02: compile-time error
+  ;
+  c //
+     >>>= 4 //# 03: compile-time error
+  ;
+
+  // Dynamic invocations are allowed, and check types at run-time.
+  dynamic d = c1;
+  Expect.identical(c2, d >>> c2);
+  Expect.throws(() => d >>> 4);
+
+  // There is a symbol for >>>, both as constructed and literal.
+  Expect.identical(const Symbol(">>>"), #>>>);
+
+  // No such method can catch dynamic invocations of >>>:
+  dynamic nsm = NSM();
+  Invocation invocation = nsm >>> c2;
+  Expect.isTrue(invocation.isMethod);
+  Expect.isFalse(invocation.isAccessor);
+  Expect.equals(#>>>, invocation.memberName);
+  Expect.equals(1, invocation.positionalArguments.length);
+  Expect.identical(c2, invocation.positionalArguments[0]);
+  Expect.equals(0, invocation.namedArguments.length);
+
+  invocation = (nsm >>>= c2);
+  Expect.isTrue(invocation.isMethod);
+  Expect.isFalse(invocation.isAccessor);
+  Expect.equals(#>>>, invocation.memberName);
+  Expect.equals(1, invocation.positionalArguments.length);
+  Expect.identical(c2, invocation.positionalArguments[0]);
+  Expect.equals(0, invocation.namedArguments.length);
+
+  // And unimplemented interface methods.
+  ShiftNSM shnsm = ShiftNSM();
+  invocation = shnsm >>> c2;
+  Expect.isTrue(invocation.isMethod);
+  Expect.isFalse(invocation.isAccessor);
+  Expect.equals(#>>>, invocation.memberName);
+  Expect.equals(1, invocation.positionalArguments.length);
+  Expect.identical(c2, invocation.positionalArguments[0]);
+  Expect.equals(0, invocation.namedArguments.length);
+
+  // If there is an interface, we must match it, even if the call
+  // otherwise goes to noSuchMethod.
+  shnsm //
+      >>> 4 //# 04: compile-time error
+  ;
+
+  /// A type error in the nSM return value is caught.
+  dynamic badNSM = BadNSM();
+  Expect.throws(() => badNSM >>> "not an int", (e) => e != "Unreachable");
+  Expect.throws(() => badNSM >>> 4, (e) => e != "Unreachable");
+
+  asyncStart();
+  () async {
+    // Operands can be asynchronous.
+    var fc1 = Future.value(c1);
+    var fc2 = Future.value(c2);
+    Expect.identical(c2, (await fc1) >>> (await fc2));
+    /// The operator itself can be async.
+    var async = Async();
+    Expect.identical(c1, await (async >>> c1));
+
+    var asyncStar = AsyncStar();
+    int count = 0;
+    await for (var v in asyncStar >>> c1) {
+      count++;
+      Expect.identical(c1, v);
+    }
+    Expect.equals(1, count);
+    asyncEnd();
+  }();
+
+  {
+    var syncStar = SyncStar();
+    int count = 0;
+    for (var v in syncStar >>> c1) {
+      count++;
+      Expect.identical(c1, v);
+    }
+    Expect.equals(1, count);
+  }
+
+  // >>> has same precedence as >> (and <<), is left associative.
+  // Binds weaker than addition/multiplication, stronger than other bitwise
+  // operators and comparisons.
+  final a = Assoc("*");
+  Expect.equals("((~*)>>>(~*))", "${~a >>> ~a}");
+  Expect.equals("((*+*)>>>(*+*))", "${a + a >>> a + a}");
+  Expect.equals("((*/*)>>>(*/*))", "${a / a >>> a / a}");
+  Expect.equals("(((*>>*)>>>*)>>*)", "${a >> a >>> a >> a}");
+  Expect.equals("((*&(*>>>*))&*)", "${a & a >>> a & a}");
+  Expect.equals("((*|(*>>>*))|*)", "${a | a >>> a | a}");
+  Expect.equals("((*^(*>>>*))^*)", "${a ^ a >>> a ^ a}");
+  Expect.equals("(*<(*>>>*))", "${a < a >>> a}");
+  Expect.equals("((*>>>*)<*)", "${a >>> a < a}");
+
+  var res = a;
+  res >>>= a;
+  res >>>= a;
+  Expect.equals("((*>>>*)>>>*)", "$res");
+
+  // Exercise the type declarations below.
+  E3<List<List<int>>>();
+  E4<List<List<List<int>>>>();
+  E5<List<List<List<List<int>>>>>();
+  E6<List<List<List<List<List<int>>>>>>();
+  Expect.type<F3<List<List<int>>>>(() => <List<int>>[]);
+  Expect.type<F4<List<List<List<int>>>>>(() => <List<List<int>>>[]);
+  Expect.type<F5<List<List<List<List<int>>>>>>(() => <List<List<List<int>>>>[]);
+  Expect.type<F6<List<List<List<List<List<int>>>>>>>(
+      () => <List<List<List<List<int>>>>>[]);
+}
+
+/// Class with a simple overridden `operator>>>`.
+class C {
+  final int id;
+  const C(this. id);
+  C operator >>>(C other) => other;
+  String toString() => "C($id)";
+}
+
+/// Invalid declarations of `>>>` operator.
+class Invalid {
+  // Overridable operator must have exactly one required parameter.
+  Object operator>>>() => null;  //# arg0: compile-time error
+  Object operator>>>(v1, v2) => null;  //# arg2: compile-time error
+  Object operator>>>([v1]) => null;  //# argOpt: compile-time error
+  Object operator>>>({v1}) => null;  //# argNam: compile-time error
+}
+
+/// Class with noSuchMethod and no `>>>` operator.
+class NSM {
+  dynamic noSuchMethod(Invocation invocation) {
+    return invocation;
+  }
+}
+
+/// Class with nSM and abstract `>>>` (implicit typed forwarder).
+class ShiftNSM extends NSM {
+  dynamic operator>>>(C o);
+}
+
+/// Class with nSM and abstract `>>>` where nSM returns wrong type.
+class BadNSM {
+  int operator>>>(int n);
+  dynamic noSuchMethod(Invocation i) {
+    if (i.memberName == #>>>) {
+      if (i.positionalArguments.first is! int) throw "Unreachable";
+      return "notAnInt";
+    }
+    return super.noSuchMethod(i);
+  }
+}
+
+/// Class with an `async` implementation of `operator >>>`
+class Async {
+  Future<C> operator >>>(C value) async => value;
+}
+
+/// Class with an `async*` implementation of `operator >>>`
+class AsyncStar {
+  Stream<C> operator >>>(C value) async* {
+    yield value;
+  }
+}
+
+/// Class with a `sync*` implementation of `operator >>>`
+class SyncStar {
+  Iterable<C> operator >>>(C value) sync* {
+    yield value;
+  }
+}
+
+/// Helper class to record precedence and associativity of operators.
+class Assoc {
+  final String ops;
+  Assoc(this.ops);
+  Assoc operator ~() => Assoc("(~${this})");
+  Assoc operator +(Assoc other) => Assoc("(${this}+$other)");
+  Assoc operator /(Assoc other) => Assoc("(${this}/$other)");
+  Assoc operator &(Assoc other) => Assoc("(${this}&$other)");
+  Assoc operator |(Assoc other) => Assoc("(${this}|$other)");
+  Assoc operator ^(Assoc other) => Assoc("(${this}^$other)");
+  Assoc operator >(Assoc other) => Assoc("(${this}>$other)");
+  Assoc operator >>(Assoc other) => Assoc("(${this}>>$other)");
+  Assoc operator >>>(Assoc other) => Assoc("(${this}>>>$other)");
+  Assoc operator <(Assoc other) => Assoc("(${this}<$other)");
+  Assoc operator >=(Assoc other) => Assoc("(${this}>=$other)");
+  Assoc operator <=(Assoc other) => Assoc("(${this}<=$other)");
+  String toString() => ops;
+}
diff --git a/tests/language/operator/unsupported_runtime_test.dart b/tests/language/operator/unsupported_runtime_test.dart
new file mode 100644
index 0000000..57eb8b8
--- /dev/null
+++ b/tests/language/operator/unsupported_runtime_test.dart
@@ -0,0 +1,32 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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 handling of unsupported operators.
+
+library unsupported_operators;
+
+class C {
+  m() {
+    print(
+
+        null);
+    print(
+
+        null);
+  }
+}
+
+void main() {
+  new C().m();
+  new C().m();
+  print(
+
+      null);
+  print(
+
+      null);
+}
diff --git a/tests/language/operator/unsupported_test.dart b/tests/language/operator/unsupported_test.dart
new file mode 100644
index 0000000..5649260
--- /dev/null
+++ b/tests/language/operator/unsupported_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2013, 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 handling of unsupported operators.
+
+library unsupported_operators;
+
+class C {
+  m() {
+    print(
+          super ===
+          //    ^
+          // [analyzer] SYNTACTIC_ERROR.UNSUPPORTED_OPERATOR
+          // [cfe] The '===' operator is not supported.
+          //    ^
+          // [cfe] The string '===' isn't a user-definable operator.
+        null);
+    print(
+          super !==
+          //    ^
+          // [analyzer] SYNTACTIC_ERROR.UNSUPPORTED_OPERATOR
+          // [cfe] The '!==' operator is not supported.
+          //    ^
+          // [cfe] The string '!==' isn't a user-definable operator.
+        null);
+  }
+}
+
+void main() {
+  new C().m();
+  new C().m();
+  print(
+        "foo" ===
+        //    ^
+        // [analyzer] SYNTACTIC_ERROR.UNSUPPORTED_OPERATOR
+        // [cfe] The '===' operator is not supported.
+        //    ^
+        // [cfe] The string '===' isn't a user-definable operator.
+      null);
+  print(
+        "foo" !==
+        //    ^
+        // [analyzer] SYNTACTIC_ERROR.UNSUPPORTED_OPERATOR
+        // [cfe] The '!==' operator is not supported.
+        //    ^
+        // [cfe] The string '!==' isn't a user-definable operator.
+      null);
+}
diff --git a/tests/language/override/inheritance_field_test.dart b/tests/language/override/inheritance_field_test.dart
index 3843c91..847de4d 100644
--- a/tests/language/override/inheritance_field_test.dart
+++ b/tests/language/override/inheritance_field_test.dart
@@ -40,7 +40,7 @@
   void set field12(int _) {} //# 52: ok
   num field13 = 0; //# 53: compile-time error
   set field14(num _) {} //# 54: compile-time error
-  num field15 = 0; //# 55: ok
+  num field15 = 0; //# 55: compile-time error
 }
 
 class B extends A {
diff --git a/tests/language/override/inheritance_setter_test.dart b/tests/language/override/inheritance_setter_test.dart
index f709c75..5aa2cca 100644
--- a/tests/language/override/inheritance_setter_test.dart
+++ b/tests/language/override/inheritance_setter_test.dart
@@ -9,7 +9,7 @@
   void set setter4(num x) {} //# 004: compile-time error
   void set setter5(num x) {} //# 005: ok
   void set setter6(num x) {} //# 006: compile-time error
-  void set setter7(num x) {} //# 007: ok
+  void set setter7(num x) {} //# 007: compile-time error
 }
 
 class B extends A {
diff --git a/tests/language/parameter/bad_named2_runtime_test.dart b/tests/language/parameter/bad_named2_runtime_test.dart
new file mode 100644
index 0000000..5e30826
--- /dev/null
+++ b/tests/language/parameter/bad_named2_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Dart test program for testing bad named parameters.
+
+class BadNamedParameters2Test {
+  int foo(int a) {
+    // Although no optional named parameters are declared, we must check that
+    // no named arguments are passed in, either here or in the resolving stub.
+    return a;
+  }
+}
+
+main() {
+  BadNamedParameters2Test np = new BadNamedParameters2Test();
+
+  // No formal parameter named b.
+
+}
diff --git a/tests/language/parameter/bad_named2_test.dart b/tests/language/parameter/bad_named2_test.dart
new file mode 100644
index 0000000..131909b
--- /dev/null
+++ b/tests/language/parameter/bad_named2_test.dart
@@ -0,0 +1,24 @@
+// 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.
+// Dart test program for testing bad named parameters.
+
+class BadNamedParameters2Test {
+  int foo(int a) {
+    // Although no optional named parameters are declared, we must check that
+    // no named arguments are passed in, either here or in the resolving stub.
+    return a;
+  }
+}
+
+main() {
+  BadNamedParameters2Test np = new BadNamedParameters2Test();
+
+  // No formal parameter named b.
+  np.foo(b: 25);
+  //    ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+  // [cfe] Too few positional arguments: 1 required, 0 given.
+  //     ^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+}
diff --git a/tests/language/parameter/bad_named_parameters_test.dart b/tests/language/parameter/bad_named_parameters_test.dart
new file mode 100644
index 0000000..35b1e79
--- /dev/null
+++ b/tests/language/parameter/bad_named_parameters_test.dart
@@ -0,0 +1,52 @@
+// 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.
+// Dart test program for testing bad named parameters.
+
+import "package:expect/expect.dart";
+
+class BadNamedParametersTest {
+  int f42(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f52(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+}
+
+main() {
+  BadNamedParametersTest np = new BadNamedParametersTest();
+
+  // Parameter b passed twice.
+  np.f42(10, 25, b: 25);
+  //    ^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+  // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+
+  // Parameter x does not exist.
+  np.f42(10, 25, x: 99);
+  //    ^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+  // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+
+  // Parameter b1 does not exist.
+  np.f52(10, b: 25, b1: 99, c: 35);
+  //                ^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+  // [cfe] No named parameter with the name 'b1'.
+
+  // Too many parameters.
+  np.f42(10, 20, 30, 40);
+  //    ^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+  // [cfe] Too many positional arguments: 1 allowed, but 4 found.
+
+  // Too few parameters.
+  np.f42(b: 25);
+  //    ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+  // [cfe] Too few positional arguments: 1 required, 0 given.
+}
diff --git a/tests/language/parameter/bad_named_runtime_test.dart b/tests/language/parameter/bad_named_runtime_test.dart
new file mode 100644
index 0000000..8d4a861
--- /dev/null
+++ b/tests/language/parameter/bad_named_runtime_test.dart
@@ -0,0 +1,38 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Dart test program for testing bad named parameters.
+
+import "package:expect/expect.dart";
+
+class BadNamedParametersTest {
+  int f42(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f52(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+}
+
+main() {
+  BadNamedParametersTest np = new BadNamedParametersTest();
+
+  // Parameter b passed twice.
+
+
+  // Parameter x does not exist.
+
+
+  // Parameter b1 does not exist.
+
+
+  // Too many parameters.
+
+
+  // Too few parameters.
+
+}
diff --git a/tests/language/parameter/default_test.dart b/tests/language/parameter/default_test.dart
new file mode 100644
index 0000000..3e5b990
--- /dev/null
+++ b/tests/language/parameter/default_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, 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 C {
+  foo(a
+      : 1 // //# 01: syntax error
+      = 1 // //# 02: syntax error
+      ) {
+    print(a);
+  }
+
+  static bar(a
+      : 1 // //# 03: syntax error
+      = 1 // //# 04: syntax error
+      ) {
+    print(a);
+  }
+}
+
+baz(a
+    : 1 // //# 05: syntax error
+    = 1 // //# 06: syntax error
+    ) {
+  print(a);
+}
+
+main() {
+  foo(a
+      : 1 // //# 07: syntax error
+      = 1 // //# 08: syntax error
+      ) {
+    print(a);
+  }
+
+  foo(1);
+
+  new C().foo(2);
+
+  C.bar(3);
+
+  baz(4);
+}
diff --git a/tests/language/parameter/initializer1_test.dart b/tests/language/parameter/initializer1_test.dart
new file mode 100644
index 0000000..34465a4
--- /dev/null
+++ b/tests/language/parameter/initializer1_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.
+
+/// Fails because this.x parameter is used in a function.
+
+class Foo {
+  var x;
+  foo(this.x) {}
+  //  ^^^^
+  // [analyzer] SYNTACTIC_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+  //  ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+}
+
+main() {
+  Foo().foo(2);
+}
diff --git a/tests/language/parameter/initializer2_test.dart b/tests/language/parameter/initializer2_test.dart
new file mode 100644
index 0000000..da775e2
--- /dev/null
+++ b/tests/language/parameter/initializer2_test.dart
@@ -0,0 +1,81 @@
+// 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 "package:expect/expect.dart";
+
+// Test Parameter Intializer.
+
+class ParameterInitializer2Test {
+  static testMain() {
+    var a = new A(123);
+    Expect.equals(123, a.x);
+
+    var b = new B(123);
+    Expect.equals(123, b.x);
+
+    var c = new C(123);
+    Expect.equals(123, c.x);
+
+    var d = new D(123);
+    Expect.equals(123, d.x);
+
+    var e = new E(1);
+    Expect.equals(4, e.x);
+
+    var f = new F(1, 2, 3, 4);
+    Expect.equals(4, f.z);
+  }
+}
+
+// untyped
+class A {
+  A(this.x) {}
+  int x;
+}
+
+// typed
+class B {
+  B(int this.x) {}
+  int x;
+}
+
+// const typed
+class C {
+  const C(int this.x);
+  final int x;
+}
+
+// const untyped
+class D {
+  const D(this.x);
+  final x;
+}
+
+// make sure this.<X> references work properly in the constructor scope.
+class E {
+  E(this.x) {
+    var myVar = this.x * 2;
+    this.x = myVar + 1;
+    x = myVar + 2;
+    var foo = x + 1;
+  }
+  int x;
+}
+
+// mixed
+class F {
+  F(x, this.y_, int w, int this.z)
+      : x_ = x,
+        w_ = w {}
+  F.foobar(this.z, int this.x_, int this.az_) {}
+  int x_;
+  late int y_;
+  late int w_;
+  int z;
+  late int az_;
+}
+
+main() {
+  ParameterInitializer2Test.testMain();
+}
diff --git a/tests/language/parameter/initializer3_test.dart b/tests/language/parameter/initializer3_test.dart
new file mode 100644
index 0000000..bf81a6d
--- /dev/null
+++ b/tests/language/parameter/initializer3_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+/// Fails because this.x parameter is used in a factory.
+
+class Foo {
+  var x;
+  factory Foo(this.x) => new Foo.named();
+  //          ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_FACTORY_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+  Foo.named() {}
+}
+
+main() {
+  Foo(2);
+}
diff --git a/tests/language/parameter/initializer4_test.dart b/tests/language/parameter/initializer4_test.dart
new file mode 100644
index 0000000..49cf633
--- /dev/null
+++ b/tests/language/parameter/initializer4_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.
+
+/// Fails because this.x parameter is used in a static function.
+
+class Foo {
+  var x;
+  static foo(this.x) {}
+  //         ^^^^
+  // [analyzer] SYNTACTIC_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+}
+
+main() {
+  Foo.foo(1);
+}
diff --git a/tests/language/parameter/initializer5_test.dart b/tests/language/parameter/initializer5_test.dart
new file mode 100644
index 0000000..8bdd968
--- /dev/null
+++ b/tests/language/parameter/initializer5_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+// Use the this.x parameter in an initializer expression.
+
+class Foo {
+  var x, y;
+  Foo(this.x) : y = x {}
+}
+
+main() {
+  new Foo(12);
+}
diff --git a/tests/language/parameter/initializer6_test.dart b/tests/language/parameter/initializer6_test.dart
new file mode 100644
index 0000000..9a5ebda
--- /dev/null
+++ b/tests/language/parameter/initializer6_test.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";
+
+/// It is a compile-time error if a named formal parameter begins with an '_'.
+
+class Foo {
+  num _y;
+  Foo.private({this._y: 77}) {}
+  //           ^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.PRIVATE_OPTIONAL_PARAMETER
+  //                ^
+  // [cfe] An optional named parameter can't start with '_'.
+}
+
+main() {
+  Foo.private(_y: 222);
+}
diff --git a/tests/language/parameter/initializer7_test.dart b/tests/language/parameter/initializer7_test.dart
new file mode 100644
index 0000000..b1bca78
--- /dev/null
+++ b/tests/language/parameter/initializer7_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.
+
+/// Fails because this.x parameter is used in a setter.
+
+class Foo {
+  var x;
+  set y(this.x) {}
+  //    ^^^^
+  // [analyzer] SYNTACTIC_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+  //    ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+}
+
+main() {
+  Foo().y = 2;
+}
diff --git a/tests/language/parameter/initializer_test.dart b/tests/language/parameter/initializer_test.dart
new file mode 100644
index 0000000..1696703
--- /dev/null
+++ b/tests/language/parameter/initializer_test.dart
@@ -0,0 +1,82 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class ParameterInitializerTest {
+  static testMain() {
+    var obj = new Foo.untyped(1);
+    Expect.equals(1, obj.x);
+
+    obj = new Foo.subtype(7);
+    Expect.equals(7, obj.x);
+
+    obj = new Foo.optional(111);
+    Expect.equals(111, obj.x);
+
+    obj = new Foo.optional();
+    Expect.equals(5, obj.x);
+
+    obj = new Foo(1);
+    Expect.equals(2, obj.x);
+
+    obj = new SubFoo(42);
+    Expect.equals(1, obj.x);
+
+    obj = new SubSubFoo(42);
+    Expect.equals(1, obj.x);
+  }
+}
+
+class Foo {
+  Foo(num this.x) {
+    // Reference to x must resolve to the field.
+    x++;
+    Expect.equals(this.x, x);
+  }
+
+  Foo.untyped(this.x) {}
+  Foo.subtype(int this.x) {}
+  Foo.optional([this.x = 5]) {}
+
+  num x;
+}
+
+class SubFoo extends Foo {
+  SubFoo(num y)
+      : x_ = 0,
+        super(y) {
+    // Subfoo.setter of x has been invoked in the Foo constructor.
+    Expect.equals(x, 1);
+    Expect.equals(x_, 1);
+
+    // The super.x will resolved to the field in Foo.
+    Expect.equals(super.x, y);
+  }
+
+  get x {
+    return x_;
+  }
+
+  set x(num val) {
+    x_ = val;
+  }
+
+  num x_;
+}
+
+class SubSubFoo extends SubFoo {
+  SubSubFoo(num y) : super(y) {
+    // Subfoo.setter of x has been invoked in the Foo constructor.
+    Expect.equals(x, 1);
+    Expect.equals(x_, 1);
+
+    // There is no way to get to the field in Foo.
+    Expect.equals(super.x, 1);
+  }
+}
+
+main() {
+  ParameterInitializerTest.testMain();
+}
diff --git a/tests/language/parameter/metadata_test.dart b/tests/language/parameter/metadata_test.dart
new file mode 100644
index 0000000..a2ab741
--- /dev/null
+++ b/tests/language/parameter/metadata_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2014, 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 that metadata annotations can be handled on nested parameters.
+
+test(
+     @deprecated //   //# 01: ok
+    f(
+       @deprecated // //# 02: ok
+        a,
+       @deprecated // //# 03: ok
+        g(
+         @deprecated //# 04: ok
+            b))?) {}
+
+main() {
+  test(null);
+}
diff --git a/tests/language/parameter/name_conflict_test.dart b/tests/language/parameter/name_conflict_test.dart
new file mode 100644
index 0000000..3f238da
--- /dev/null
+++ b/tests/language/parameter/name_conflict_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+foo(t0) {
+  var a = t0, b = baz(), c = bar();
+  if (t0 == 'foo') {
+    // Force a SSA swapping problem where dart2js used to use 't0' as
+    // a temporary variable.
+    var tmp = c;
+    c = b;
+    b = tmp;
+  }
+
+  Expect.equals('foo', a);
+  Expect.equals('foo', t0);
+  Expect.equals('bar', b);
+  Expect.equals('baz', c);
+}
+
+bar() => 'bar';
+baz() => 'baz';
+
+main() {
+  foo('foo');
+}
diff --git a/tests/language/parameter/named2_test.dart b/tests/language/parameter/named2_test.dart
new file mode 100644
index 0000000..3d6f658
--- /dev/null
+++ b/tests/language/parameter/named2_test.dart
@@ -0,0 +1,14 @@
+// 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.
+// Dart test program for testing named parameters.
+// You may not provide the same parameter as both a positional and a named argument.
+
+int test(int a, [int? b]) {
+  return a;
+}
+
+main() {
+  // Parameter b passed twice, as positional and named.
+  test(10, 25, b: 26); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/parameter/named3_test.dart b/tests/language/parameter/named3_test.dart
new file mode 100644
index 0000000..03f87a2
--- /dev/null
+++ b/tests/language/parameter/named3_test.dart
@@ -0,0 +1,14 @@
+// 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.
+// Dart test program for testing named parameters.
+// Specifying named argument for not existing named parameter is run time error.
+
+int test(int a, [int? b]) {
+  return a;
+}
+
+main() {
+  // 1 positional arg, as expected. Param x does not exist.
+  test(10, x: 99); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/parameter/named4_test.dart b/tests/language/parameter/named4_test.dart
new file mode 100644
index 0000000..5701758
--- /dev/null
+++ b/tests/language/parameter/named4_test.dart
@@ -0,0 +1,19 @@
+// 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.
+// Dart test program for testing named parameters.
+// Specifying named argument for not existing named parameter is run time error.
+
+// This test is very similar to NamedParameters3Test, but exercises a
+// different corner case in the frog compiler. frog wasn't detecting unused
+// named arguments when no other arguments were expected. So, this test
+// purposely passes the exact number of positional parameters.
+
+int test(int a) {
+  return a;
+}
+
+main() {
+  // 1 positional arg, as expected. Param x does not exist.
+  test(10, x: 99); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/parameter/named_aggregated_runtime_test.dart b/tests/language/parameter/named_aggregated_runtime_test.dart
new file mode 100644
index 0000000..20e3ebe
--- /dev/null
+++ b/tests/language/parameter/named_aggregated_runtime_test.dart
@@ -0,0 +1,57 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Dart test program for testing named parameters.
+
+class TypeTester<T> {}
+
+// Expect compile-time error as no default values are allowed
+// in closure type definitions.
+typedef void Callback([String msg
+
+]);
+
+class NamedParametersAggregatedTests {
+  static int F31(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int f_missing_comma(a
+
+  ) =>
+  a;
+
+  var _handler = null;
+
+  // Expect compile-time error as no default values
+  // are allowed in closure type.
+  void InstallCallback(
+      void cb({String msg
+
+      })?) {
+    _handler = cb;
+  }
+}
+
+main() {
+  // Expect compile-time error due to missing comma in function definition.
+  NamedParametersAggregatedTests.f_missing_comma(10
+
+  );
+
+  // Expect compile-time error due to duplicate named argument.
+  NamedParametersAggregatedTests.F31(10, b: 25
+
+
+  );
+
+  // Expect compile-time error due to missing positional argument.
+
+
+  new TypeTester<Callback>();
+
+  (new NamedParametersAggregatedTests()).InstallCallback(null);
+}
diff --git a/tests/language/parameter/named_aggregated_test.dart b/tests/language/parameter/named_aggregated_test.dart
new file mode 100644
index 0000000..61de489f
--- /dev/null
+++ b/tests/language/parameter/named_aggregated_test.dart
@@ -0,0 +1,61 @@
+// 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.
+// Dart test program for testing named parameters.
+
+class TypeTester<T> {}
+
+// Expect compile-time error as no default values are allowed
+// in closure type definitions.
+typedef void Callback([String msg = ""]);
+//                                ^
+// [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
+// [cfe] Can't have a default value in a function type.
+
+class NamedParametersAggregatedTests {
+  static int F31(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int f_missing_comma(a [b = 42]) => a;
+  //                           ^
+  // [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+  // [cfe] Expected ')' before this.
+
+  var _handler = null;
+
+  // Expect compile-time error as no default values
+  // are allowed in closure type.
+  void InstallCallback(void cb({String? msg : null})?) {
+  //                            ^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPED_PARAMETER
+  //                                        ^
+  // [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
+  // [cfe] Can't have a default value in a function type.
+    _handler = cb;
+  }
+}
+
+main() {
+  // Expect compile-time error due to missing comma in function definition.
+  NamedParametersAggregatedTests.f_missing_comma(10, 25);
+  //                                            ^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+  // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+
+  // Expect compile-time error due to duplicate named argument.
+  NamedParametersAggregatedTests.F31(10, b: 25, b:35);
+  //                                            ^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_NAMED_ARGUMENT
+  // [cfe] Duplicated named argument 'b'.
+
+  // Expect compile-time error due to missing positional argument.
+  NamedParametersAggregatedTests.F31(b: 25, c: 35);
+  //                                ^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.NOT_ENOUGH_POSITIONAL_ARGUMENTS
+  // [cfe] Too few positional arguments: 1 required, 0 given.
+
+  new TypeTester<Callback>();
+
+  (new NamedParametersAggregatedTests()).InstallCallback(null);
+}
diff --git a/tests/language/parameter/named_clash_test.dart b/tests/language/parameter/named_clash_test.dart
new file mode 100644
index 0000000..aefcbf8
--- /dev/null
+++ b/tests/language/parameter/named_clash_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, 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';
+
+class Foo {
+  m({a, b, c}) {
+    try {} catch (e) {} // no inline
+    return 'Foo $a $b $c';
+  }
+}
+
+class Bar {
+  m(z, {a$b, c}) {
+    try {} catch (e) {} // no inline
+    var ab = a$b;
+    return 'Bar $z $ab $c';
+  }
+}
+
+inscrutable(xs, i) => i == 0 ? xs[0] : inscrutable(xs.sublist(1), i - 1);
+
+main() {
+  var list = [new Foo(), new Bar()];
+  var foo = inscrutable(list, 0);
+  var bar = inscrutable(list, 1);
+
+  Expect.equals(r'Foo a b c', foo.m(a: 'a', b: 'b', c: 'c'));
+  Expect.equals(r'Bar z a$b c', bar.m('z', a$b: r'a$b', c: 'c'));
+
+  Expect.throwsNoSuchMethodError(() => foo.m('z', a$b: r'a$b', c: 'c'));
+  Expect.throwsNoSuchMethodError(() => bar.m(a: 'a', b: 'b', c: 'c'));
+}
diff --git a/tests/language/parameter/named_count_test.dart b/tests/language/parameter/named_count_test.dart
new file mode 100644
index 0000000..80f9e38
--- /dev/null
+++ b/tests/language/parameter/named_count_test.dart
@@ -0,0 +1,33 @@
+// 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 "package:expect/expect.dart";
+
+// Test for named parameter called 'count'.
+
+class TestClass {
+  TestClass();
+
+  method([count]) => count;
+
+  static staticMethod([count]) => count;
+}
+
+globalMethod([count]) => count;
+
+main() {
+  var obj = new TestClass();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(0));
+  Expect.equals("", obj.method(""));
+
+  Expect.equals(null, TestClass.staticMethod());
+  Expect.equals(true, TestClass.staticMethod(true));
+  Expect.equals(false, TestClass.staticMethod(false));
+
+  Expect.equals(null, globalMethod());
+  Expect.equals(true, globalMethod(true));
+  Expect.equals(false, globalMethod(false));
+}
diff --git a/tests/language/parameter/named_default_eq_runtime_test.dart b/tests/language/parameter/named_default_eq_runtime_test.dart
new file mode 100644
index 0000000..dd1bb4d
--- /dev/null
+++ b/tests/language/parameter/named_default_eq_runtime_test.dart
@@ -0,0 +1,104 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2016, 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.
+
+// Check that both `=` and `:` are allowed for named parameters.
+
+import "package:expect/expect.dart";
+
+// Default values are not allowed on typedefs.
+
+
+typedef functype({x, y, z});
+
+int topF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+
+class A {
+  int x;
+  int y;
+  int z;
+  A({this.x = 3, this.y: 5, z}) : z = z ?? 2;
+  A.redirect({int x = 3, int y: 5, int? z}) : this(x: x, y: y, z: z);
+  factory A.factory({int x = 3, int y: 5, int? z}) =>
+      new A(x: x, y: y, z: z ?? 2);
+  factory A.redirectFactory({int x, int y, int z}) = A;
+
+  // Default values are not allowed on redirecting factory constructors.
+
+
+
+  int get value => x * y * z;
+
+  static int staticF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  int instanceF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+}
+
+main() {
+  // Reference the type, or dart2js won't see that the declaration is invalid
+
+
+  var a = new A();
+
+  int local({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  var expr = ({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  var tearOff = a.instanceF;
+
+  test(function) {
+    Expect.equals(30, function());
+    Expect.equals(70, function(x: 7));
+    Expect.equals(42, function(y: 7));
+    Expect.equals(28, function(x: 7, y: 2));
+    Expect.equals(15, function(z: 1));
+    Expect.equals(21, function(y: 7, z: 1));
+    Expect.equals(35, function(x: 7, z: 1));
+    Expect.equals(14, function(x: 7, y: 2, z: 1));
+    Expect.isTrue(function is functype);
+  }
+
+  test(topF);
+  test(A.staticF);
+  test(a.instanceF);
+  test(local);
+  test(expr);
+  test(tearOff);
+
+  // Can't tear off constructors.
+  Expect.equals(30, new A().value);
+  Expect.equals(70, new A(x: 7).value);
+  Expect.equals(42, new A(y: 7).value);
+  Expect.equals(28, new A(x: 7, y: 2).value);
+  Expect.equals(15, new A(z: 1).value);
+  Expect.equals(21, new A(y: 7, z: 1).value);
+  Expect.equals(35, new A(x: 7, z: 1).value);
+  Expect.equals(14, new A(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.redirect().value);
+  Expect.equals(70, new A.redirect(x: 7).value);
+  Expect.equals(42, new A.redirect(y: 7).value);
+  Expect.equals(28, new A.redirect(x: 7, y: 2).value);
+  Expect.equals(15, new A.redirect(z: 1).value);
+  Expect.equals(21, new A.redirect(y: 7, z: 1).value);
+  Expect.equals(35, new A.redirect(x: 7, z: 1).value);
+  Expect.equals(14, new A.redirect(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.factory().value);
+  Expect.equals(70, new A.factory(x: 7).value);
+  Expect.equals(42, new A.factory(y: 7).value);
+  Expect.equals(28, new A.factory(x: 7, y: 2).value);
+  Expect.equals(15, new A.factory(z: 1).value);
+  Expect.equals(21, new A.factory(y: 7, z: 1).value);
+  Expect.equals(35, new A.factory(x: 7, z: 1).value);
+  Expect.equals(14, new A.factory(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.redirectFactory().value);
+  Expect.equals(70, new A.redirectFactory(x: 7).value);
+  Expect.equals(42, new A.redirectFactory(y: 7).value);
+  Expect.equals(28, new A.redirectFactory(x: 7, y: 2).value);
+  Expect.equals(15, new A.redirectFactory(z: 1).value);
+  Expect.equals(21, new A.redirectFactory(y: 7, z: 1).value);
+  Expect.equals(35, new A.redirectFactory(x: 7, z: 1).value);
+  Expect.equals(14, new A.redirectFactory(x: 7, y: 2, z: 1).value);
+}
diff --git a/tests/language/parameter/named_default_eq_test.dart b/tests/language/parameter/named_default_eq_test.dart
new file mode 100644
index 0000000..89ea2bb
--- /dev/null
+++ b/tests/language/parameter/named_default_eq_test.dart
@@ -0,0 +1,108 @@
+// Copyright (c) 2016, 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.
+
+// Check that both `=` and `:` are allowed for named parameters.
+
+import "package:expect/expect.dart";
+
+// Default values are not allowed on typedefs.
+typedef F1({x = 3, y});
+//            ^
+// [analyzer] SYNTACTIC_ERROR.DEFAULT_VALUE_IN_FUNCTION_TYPE
+// [cfe] Can't have a default value in a function type.
+
+typedef functype({x, y, z});
+
+int topF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+
+class A {
+  int x;
+  int y;
+  int z;
+  A({this.x = 3, this.y: 5, z}) : z = z ?? 2;
+  A.redirect({int x = 3, int y: 5, int? z}) : this(x: x, y: y, z: z);
+  factory A.factory({int x = 3, int y: 5, int? z}) =>
+      new A(x: x, y: y, z: z ?? 2);
+  factory A.redirectFactory({int x, int y, int z}) = A;
+
+  // Default values are not allowed on redirecting factory constructors.
+  factory A.badRedirectFactory({int x = 3, int y}) =
+  //                                ^
+  // [analyzer] COMPILE_TIME_ERROR.DEFAULT_VALUE_IN_REDIRECTING_FACTORY_CONSTRUCTOR
+  //                                    ^
+  // [cfe] Can't have a default value here because any default values of 'A' would be used instead.
+      A;
+
+  int get value => x * y * z;
+
+  static int staticF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  int instanceF({x = 3, y: 5, z}) => x * y * (z ?? 2);
+}
+
+main() {
+  // Reference the type, or dart2js won't see that the declaration is invalid
+  F1? _ = null;
+
+  var a = new A();
+
+  int local({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  var expr = ({x = 3, y: 5, z}) => x * y * (z ?? 2);
+  var tearOff = a.instanceF;
+
+  test(function) {
+    Expect.equals(30, function());
+    Expect.equals(70, function(x: 7));
+    Expect.equals(42, function(y: 7));
+    Expect.equals(28, function(x: 7, y: 2));
+    Expect.equals(15, function(z: 1));
+    Expect.equals(21, function(y: 7, z: 1));
+    Expect.equals(35, function(x: 7, z: 1));
+    Expect.equals(14, function(x: 7, y: 2, z: 1));
+    Expect.isTrue(function is functype);
+  }
+
+  test(topF);
+  test(A.staticF);
+  test(a.instanceF);
+  test(local);
+  test(expr);
+  test(tearOff);
+
+  // Can't tear off constructors.
+  Expect.equals(30, new A().value);
+  Expect.equals(70, new A(x: 7).value);
+  Expect.equals(42, new A(y: 7).value);
+  Expect.equals(28, new A(x: 7, y: 2).value);
+  Expect.equals(15, new A(z: 1).value);
+  Expect.equals(21, new A(y: 7, z: 1).value);
+  Expect.equals(35, new A(x: 7, z: 1).value);
+  Expect.equals(14, new A(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.redirect().value);
+  Expect.equals(70, new A.redirect(x: 7).value);
+  Expect.equals(42, new A.redirect(y: 7).value);
+  Expect.equals(28, new A.redirect(x: 7, y: 2).value);
+  Expect.equals(15, new A.redirect(z: 1).value);
+  Expect.equals(21, new A.redirect(y: 7, z: 1).value);
+  Expect.equals(35, new A.redirect(x: 7, z: 1).value);
+  Expect.equals(14, new A.redirect(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.factory().value);
+  Expect.equals(70, new A.factory(x: 7).value);
+  Expect.equals(42, new A.factory(y: 7).value);
+  Expect.equals(28, new A.factory(x: 7, y: 2).value);
+  Expect.equals(15, new A.factory(z: 1).value);
+  Expect.equals(21, new A.factory(y: 7, z: 1).value);
+  Expect.equals(35, new A.factory(x: 7, z: 1).value);
+  Expect.equals(14, new A.factory(x: 7, y: 2, z: 1).value);
+
+  Expect.equals(30, new A.redirectFactory().value);
+  Expect.equals(70, new A.redirectFactory(x: 7).value);
+  Expect.equals(42, new A.redirectFactory(y: 7).value);
+  Expect.equals(28, new A.redirectFactory(x: 7, y: 2).value);
+  Expect.equals(15, new A.redirectFactory(z: 1).value);
+  Expect.equals(21, new A.redirectFactory(y: 7, z: 1).value);
+  Expect.equals(35, new A.redirectFactory(x: 7, z: 1).value);
+  Expect.equals(14, new A.redirectFactory(x: 7, y: 2, z: 1).value);
+}
diff --git a/tests/language/parameter/named_parameters_test.dart b/tests/language/parameter/named_parameters_test.dart
new file mode 100644
index 0000000..35fcd92
--- /dev/null
+++ b/tests/language/parameter/named_parameters_test.dart
@@ -0,0 +1,145 @@
+// 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.
+// Dart test program for testing named parameters.
+
+import "package:expect/expect.dart";
+
+class NamedParametersTest {
+  static int F00() {
+    return 0;
+  }
+
+  int f11() {
+    return 0;
+  }
+
+  static int F11(int a) {
+    return a;
+  }
+
+  int f22(int a) {
+    return a;
+  }
+
+  static int F10([int b = 20]) {
+    return b;
+  }
+
+  int f21([int b = 20]) {
+    return b;
+  }
+
+  static int F21(int a, [int b = 20]) {
+    return 100 * a + b;
+  }
+
+  int f32(int a, [int b = 20]) {
+    return 100 * a + b;
+  }
+
+  static int F31(int a, [int b = 20, int c = 30]) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f42(int a, [int b = 20, int c = 30]) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int F41(int a, [int b = 20, int? c, int d = 40]) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+
+  int f52(int a, [int b = 20, int? c, int d = 40]) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+
+  static testMain() {
+    NamedParametersTest np = new NamedParametersTest();
+    Expect.equals(0, F00());
+    Expect.equals(0, np.f11());
+    Expect.equals(10, F11(10));
+    Expect.equals(10, np.f22(10));
+    Expect.equals(20, F10());
+    Expect.equals(20, np.f21());
+    Expect.equals(20, F10(20));
+    Expect.equals(20, np.f21(20));
+    Expect.equals(20, F10(b:20));
+    //                    ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'b'.
+    Expect.equals(20, np.f21(b:20));
+    //                       ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'b'.
+    Expect.equals(1020, F21(10));
+    Expect.equals(1020, np.f32(10));
+    Expect.equals(1025, F21(10, 25));
+    Expect.equals(1025, np.f32(10, 25));
+    Expect.equals(1025, F21(10, b:25));
+    //                          ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'b'.
+    Expect.equals(1025, np.f32(10, b:25));
+    //                             ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'b'.
+    Expect.equals(102030, F31(10));
+    Expect.equals(102030, np.f42(10));
+    Expect.equals(102530, F31(10, 25));
+    Expect.equals(102530, np.f42(10, 25));
+    Expect.equals(102035, F31(10, c:35));
+    //                            ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+    Expect.equals(102035, np.f42(10, c:35));
+    //                               ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+    Expect.equals(102535, F31(10, 25, 35));
+    Expect.equals(102535, np.f42(10, 25, 35));
+    Expect.equals(102535, F31(10, 25, c:35));
+    //                                ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+    Expect.equals(102535, np.f42(10, 25, c:35));
+    //                                   ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+    Expect.equals(10200040, F41(10));
+    Expect.equals(10200040, np.f52(10));
+    Expect.equals(10203540, F41(10, c:35));
+    //                              ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+    Expect.equals(10203540, np.f52(10, c:35));
+    //                                 ^
+    // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_NAMED_PARAMETER
+    // [cfe] No named parameter with the name 'c'.
+  }
+}
+
+abstract class I {
+  factory I() = C;
+  int mul(int a, [int factor]);
+}
+
+class C implements I {
+  int mul(int a, [int factor = 10]) {
+    return a * factor;
+  }
+}
+
+hello(msg, to, {from}) => '${from} sent ${msg} to ${to}';
+message() => hello("gladiolas", "possums", from: "Edna");
+
+main() {
+  NamedParametersTest.testMain();
+  var i = new I();
+  Expect.equals(100, i.mul(10));
+  Expect.equals(1000, i.mul(10, 100));
+  var c = new C();
+  Expect.equals(100, c.mul(10));
+  Expect.equals(1000, c.mul(10, 100));
+  Expect.equals("Edna sent gladiolas to possums", message());
+}
diff --git a/tests/language/parameter/named_passing_false_test.dart b/tests/language/parameter/named_passing_false_test.dart
new file mode 100644
index 0000000..f58cee1
--- /dev/null
+++ b/tests/language/parameter/named_passing_false_test.dart
@@ -0,0 +1,46 @@
+// 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 "package:expect/expect.dart";
+
+// Dart test program for testing named parameters with 'false' passed as an
+// argument.
+
+class TestClass {
+  TestClass();
+
+  bool? method([bool? value]) => value;
+  bool? method2({bool? value}) => value;
+
+  static bool? staticMethod([bool? value]) => value;
+  static bool? staticMethod2({bool? value}) => value;
+}
+
+bool? globalMethod([bool? value]) => value;
+bool? globalMethod2({bool? value}) => value;
+
+main() {
+  var obj = new TestClass();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(null, obj.method2());
+  Expect.equals(true, obj.method(true));
+  Expect.equals(true, obj.method2(value: true));
+  Expect.equals(false, obj.method(false));
+  Expect.equals(false, obj.method2(value: false));
+
+  Expect.equals(null, TestClass.staticMethod());
+  Expect.equals(null, TestClass.staticMethod2());
+  Expect.equals(true, TestClass.staticMethod(true));
+  Expect.equals(true, TestClass.staticMethod2(value: true));
+  Expect.equals(false, TestClass.staticMethod(false));
+  Expect.equals(false, TestClass.staticMethod2(value: false));
+
+  Expect.equals(null, globalMethod());
+  Expect.equals(null, globalMethod2());
+  Expect.equals(true, globalMethod(true));
+  Expect.equals(true, globalMethod2(value: true));
+  Expect.equals(false, globalMethod(false));
+  Expect.equals(false, globalMethod2(value: false));
+}
diff --git a/tests/language/parameter/named_passing_falsy_test.dart b/tests/language/parameter/named_passing_falsy_test.dart
new file mode 100644
index 0000000..e17b75a
--- /dev/null
+++ b/tests/language/parameter/named_passing_falsy_test.dart
@@ -0,0 +1,56 @@
+// 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 "package:expect/expect.dart";
+
+// Dart test program for testing named parameters with various values that might
+// be implemented as 'falsy' values in a JavaScript implementation.
+
+class TestClass {
+  TestClass();
+
+  method([value = 100]) => value;
+  method2({value: 100}) => value;
+
+  static staticMethod([value = 200]) => value;
+  static staticMethod2({value: 200}) => value;
+}
+
+globalMethod([value = 300]) => value;
+globalMethod2({value: 300}) => value;
+
+const testValues = const [0, 0.0, '', false, null];
+
+testFunction(f, f2) {
+  Expect.isTrue(f() >= 100);
+  for (var v in testValues) {
+    Expect.equals(v, f(v));
+    Expect.equals(v, f2(value: v));
+  }
+}
+
+main() {
+  var obj = new TestClass();
+
+  Expect.equals(100, obj.method());
+  Expect.equals(100, obj.method2());
+  Expect.equals(200, TestClass.staticMethod());
+  Expect.equals(200, TestClass.staticMethod2());
+  Expect.equals(300, globalMethod());
+  Expect.equals(300, globalMethod2());
+
+  for (var v in testValues) {
+    Expect.equals(v, obj.method(v));
+    Expect.equals(v, obj.method2(value: v));
+    Expect.equals(v, TestClass.staticMethod(v));
+    Expect.equals(v, TestClass.staticMethod2(value: v));
+    Expect.equals(v, globalMethod(v));
+    Expect.equals(v, globalMethod2(value: v));
+  }
+
+  // Test via indirect call.
+  testFunction(obj.method, obj.method2);
+  testFunction(TestClass.staticMethod, TestClass.staticMethod2);
+  testFunction(globalMethod, globalMethod2);
+}
diff --git a/tests/language/parameter/named_passing_null_test.dart b/tests/language/parameter/named_passing_null_test.dart
new file mode 100644
index 0000000..a1a1fbb
--- /dev/null
+++ b/tests/language/parameter/named_passing_null_test.dart
@@ -0,0 +1,46 @@
+// 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 "package:expect/expect.dart";
+
+// Dart test program for testing named parameters with 'null' passed as an
+// argument.
+
+class TestClass {
+  TestClass();
+
+  num? method([value = 100]) => value;
+  num? method2({value: 100}) => value;
+
+  static num? staticMethod([value = 200]) => value;
+  static num? staticMethod2({value: 200}) => value;
+}
+
+num? globalMethod([value = 300]) => value;
+num? globalMethod2({value: 300}) => value;
+
+main() {
+  var obj = new TestClass();
+
+  Expect.equals(100, obj.method());
+  Expect.equals(100, obj.method2());
+  Expect.equals(50, obj.method(50));
+  Expect.equals(50, obj.method2(value: 50));
+  Expect.equals(null, obj.method(null));
+  Expect.equals(null, obj.method2(value: null));
+
+  Expect.equals(200, TestClass.staticMethod());
+  Expect.equals(200, TestClass.staticMethod2());
+  Expect.equals(50, TestClass.staticMethod(50));
+  Expect.equals(50, TestClass.staticMethod2(value: 50));
+  Expect.equals(null, TestClass.staticMethod(null));
+  Expect.equals(null, TestClass.staticMethod2(value: null));
+
+  Expect.equals(300, globalMethod());
+  Expect.equals(300, globalMethod2());
+  Expect.equals(50, globalMethod(50));
+  Expect.equals(50, globalMethod2(value: 50));
+  Expect.equals(null, globalMethod(null));
+  Expect.equals(null, globalMethod2(value: null));
+}
diff --git a/tests/language/parameter/named_passing_zero_test.dart b/tests/language/parameter/named_passing_zero_test.dart
new file mode 100644
index 0000000..02afcfe
--- /dev/null
+++ b/tests/language/parameter/named_passing_zero_test.dart
@@ -0,0 +1,46 @@
+// 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 "package:expect/expect.dart";
+
+// Dart test program for testing named parameters with zero passed as an
+// argument.
+
+class TestClass {
+  TestClass();
+
+  num method([num value = 100]) => value;
+  num method2({num value: 100}) => value;
+
+  static num staticMethod([num value = 200]) => value;
+  static num staticMethod2({num value: 200}) => value;
+}
+
+num globalMethod([num value = 300]) => value;
+num globalMethod2({num value: 300}) => value;
+
+main() {
+  var obj = new TestClass();
+
+  Expect.equals(100, obj.method());
+  Expect.equals(100, obj.method2());
+  Expect.equals(7, obj.method(7));
+  Expect.equals(7, obj.method2(value: 7));
+  Expect.equals(0, obj.method(0));
+  Expect.equals(0, obj.method2(value: 0));
+
+  Expect.equals(200, TestClass.staticMethod());
+  Expect.equals(200, TestClass.staticMethod2());
+  Expect.equals(7, TestClass.staticMethod(7));
+  Expect.equals(7, TestClass.staticMethod2(value: 7));
+  Expect.equals(0, TestClass.staticMethod(0));
+  Expect.equals(0, TestClass.staticMethod2(value: 0));
+
+  Expect.equals(300, globalMethod());
+  Expect.equals(300, globalMethod2());
+  Expect.equals(7, globalMethod(7));
+  Expect.equals(7, globalMethod2(value: 7));
+  Expect.equals(0, globalMethod(0));
+  Expect.equals(0, globalMethod2(value: 0));
+}
diff --git a/tests/language/parameter/named_regression_test.dart b/tests/language/parameter/named_regression_test.dart
new file mode 100644
index 0000000..a702464
--- /dev/null
+++ b/tests/language/parameter/named_regression_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// A regression test for dart2js bug 6015.
+
+class Fisk {
+  foo({b, a: true}) {
+    if (b == null) return;
+    throw 'broken';
+  }
+
+  bar({a, b: true}) {
+    if (a == null) return;
+    throw 'broken';
+  }
+}
+
+main() {
+  new Fisk().foo(a: true);
+  new Fisk().bar(b: true);
+}
diff --git a/tests/language/parameter/named_runtime_test.dart b/tests/language/parameter/named_runtime_test.dart
new file mode 100644
index 0000000..fa99c3f
--- /dev/null
+++ b/tests/language/parameter/named_runtime_test.dart
@@ -0,0 +1,118 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Dart test program for testing named parameters.
+
+import "package:expect/expect.dart";
+
+class NamedParametersTest {
+  static int F00() {
+    return 0;
+  }
+
+  int f11() {
+    return 0;
+  }
+
+  static int F11(int a) {
+    return a;
+  }
+
+  int f22(int a) {
+    return a;
+  }
+
+  static int F10([int b = 20]) {
+    return b;
+  }
+
+  int f21([int b = 20]) {
+    return b;
+  }
+
+  static int F21(int a, [int b = 20]) {
+    return 100 * a + b;
+  }
+
+  int f32(int a, [int b = 20]) {
+    return 100 * a + b;
+  }
+
+  static int F31(int a, [int b = 20, int c = 30]) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f42(int a, [int b = 20, int c = 30]) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int F41(int a, [int b = 20, int? c, int d = 40]) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+
+  int f52(int a, [int b = 20, int? c, int d = 40]) {
+    return 100 * (100 * (100 * a + b) + (c == null ? 0 : c)) + d;
+  }
+
+  static testMain() {
+    NamedParametersTest np = new NamedParametersTest();
+    Expect.equals(0, F00());
+    Expect.equals(0, np.f11());
+    Expect.equals(10, F11(10));
+    Expect.equals(10, np.f22(10));
+    Expect.equals(20, F10());
+    Expect.equals(20, np.f21());
+    Expect.equals(20, F10(20));
+    Expect.equals(20, np.f21(20));
+
+
+    Expect.equals(1020, F21(10));
+    Expect.equals(1020, np.f32(10));
+    Expect.equals(1025, F21(10, 25));
+    Expect.equals(1025, np.f32(10, 25));
+
+
+    Expect.equals(102030, F31(10));
+    Expect.equals(102030, np.f42(10));
+    Expect.equals(102530, F31(10, 25));
+    Expect.equals(102530, np.f42(10, 25));
+
+
+    Expect.equals(102535, F31(10, 25, 35));
+    Expect.equals(102535, np.f42(10, 25, 35));
+
+
+    Expect.equals(10200040, F41(10));
+    Expect.equals(10200040, np.f52(10));
+
+
+  }
+}
+
+abstract class I {
+  factory I() = C;
+  int mul(int a, [int factor]);
+}
+
+class C implements I {
+  int mul(int a, [int factor = 10]) {
+    return a * factor;
+  }
+}
+
+hello(msg, to, {from}) => '${from} sent ${msg} to ${to}';
+message() => hello("gladiolas", "possums", from: "Edna");
+
+main() {
+  NamedParametersTest.testMain();
+  var i = new I();
+  Expect.equals(100, i.mul(10));
+  Expect.equals(1000, i.mul(10, 100));
+  var c = new C();
+  Expect.equals(100, c.mul(10));
+  Expect.equals(1000, c.mul(10, 100));
+  Expect.equals("Edna sent gladiolas to possums", message());
+}
diff --git a/tests/language/parameter/named_type_runtime_test.dart b/tests/language/parameter/named_type_runtime_test.dart
new file mode 100644
index 0000000..a3a8ff1
--- /dev/null
+++ b/tests/language/parameter/named_type_runtime_test.dart
@@ -0,0 +1,30 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+//
+// Dart test program for testing optional named parameters in type tests.
+
+main() {
+  Function anyFunction;
+  void acceptFunNumOptBool(void funNumOptBool(num n, {bool b})) {}
+  ;
+  void funNum(num n) {}
+  ;
+  void funNumBool(num n, bool b) {}
+  ;
+  void funNumOptBool(num n, {bool b: true}) {}
+  ;
+  void funNumOptBoolX(num n, {bool x: true}) {}
+  ;
+  anyFunction = funNum;
+  anyFunction = funNumBool;
+  anyFunction = funNumOptBool;
+  anyFunction = funNumOptBoolX;
+  acceptFunNumOptBool(funNumOptBool);
+
+
+
+}
diff --git a/tests/language/parameter/named_type_test.dart b/tests/language/parameter/named_type_test.dart
new file mode 100644
index 0000000..f246025
--- /dev/null
+++ b/tests/language/parameter/named_type_test.dart
@@ -0,0 +1,36 @@
+// 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.
+//
+// Dart test program for testing optional named parameters in type tests.
+
+main() {
+  Function anyFunction;
+  void acceptFunNumOptBool(void funNumOptBool(num n, {bool b})) {}
+  ;
+  void funNum(num n) {}
+  ;
+  void funNumBool(num n, bool b) {}
+  ;
+  void funNumOptBool(num n, {bool b: true}) {}
+  ;
+  void funNumOptBoolX(num n, {bool x: true}) {}
+  ;
+  anyFunction = funNum;
+  anyFunction = funNumBool;
+  anyFunction = funNumOptBool;
+  anyFunction = funNumOptBoolX;
+  acceptFunNumOptBool(funNumOptBool);
+  acceptFunNumOptBool(funNum);
+  //                  ^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'void Function(num)' can't be assigned to the parameter type 'void Function(num, {bool b})'.
+  acceptFunNumOptBool(funNumBool);
+  //                  ^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'void Function(num, bool)' can't be assigned to the parameter type 'void Function(num, {bool b})'.
+  acceptFunNumOptBool(funNumOptBoolX);
+  //                  ^^^^^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'void Function(num, {bool x})' can't be assigned to the parameter type 'void Function(num, {bool b})'.
+}
diff --git a/tests/language/parameter/named_with_conversions_test.dart b/tests/language/parameter/named_with_conversions_test.dart
new file mode 100644
index 0000000..58e85f5
--- /dev/null
+++ b/tests/language/parameter/named_with_conversions_test.dart
@@ -0,0 +1,140 @@
+// 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.
+//
+// Test named arguments work as expected regardless of whether the function or
+// method is called via function call syntax or method call syntax.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+Validate(tag, a, b) {
+  // tag encodes which parameters are passed in with values a: 111, b: 222.
+  if (tag == 'ab') {
+    Expect.equals(a, 111);
+    Expect.equals(b, 222);
+  }
+  if (tag == 'a') {
+    Expect.equals(a, 111);
+    Expect.equals(b, 20);
+  }
+  if (tag == 'b') {
+    Expect.equals(a, 10);
+    Expect.equals(b, 222);
+  }
+  if (tag == '') {
+    Expect.equals(a, 10);
+    Expect.equals(b, 20);
+  }
+}
+
+class HasMethod {
+  int calls;
+
+  HasMethod() : calls = 0 {}
+
+  foo(tag, [a = 10, b = 20]) {
+    calls += 1;
+    Validate(tag, a, b);
+  }
+
+  foo2(tag, {a: 10, b: 20}) {
+    calls += 1;
+    Validate(tag, a, b);
+  }
+}
+
+class HasField {
+  int calls = 0;
+  var foo, foo2;
+
+  HasField() {
+    foo = makeFoo(this);
+    foo2 = makeFoo2(this);
+  }
+
+  makeFoo(owner) {
+    // This function is closed-over 'owner'.
+    return (tag, [a = 10, b = 20]) {
+      owner.calls += 1;
+      Validate(tag, a, b);
+    };
+  }
+
+  makeFoo2(owner) {
+    // This function is closed-over 'owner'.
+    return (tag, {a: 10, b: 20}) {
+      owner.calls += 1;
+      Validate(tag, a, b);
+    };
+  }
+}
+
+class NamedParametersWithConversionsTest {
+  static checkException(thunk) {
+    bool threw = false;
+    try {
+      thunk();
+    } catch (e) {
+      threw = true;
+    }
+    Expect.isTrue(threw);
+  }
+
+  static testMethodCallSyntax(a) {
+    a.foo('');
+    a.foo('a', 111);
+    a.foo('ab', 111, 222);
+    a.foo2('a', a: 111);
+    a.foo2('b', b: 222);
+    a.foo2('ab', a: 111, b: 222);
+    a.foo2('ab', b: 222, a: 111);
+
+    Expect.equals(7, a.calls);
+
+    checkException(() => a.foo()); //                  Too few arguments.
+    checkException(() => a.foo('abc', 1, 2, 3)); //    Too many arguments.
+    checkException(() => a.foo2('c', c: 1)); //        Bad name.
+    checkException(() => a.foo2('c', a: 111, c: 1)); // Bad name.
+
+    Expect.equals(7, a.calls);
+  }
+
+  static testFunctionCallSyntax(a) {
+    var f = a.foo;
+    var f2 = a.foo2;
+    f('');
+    f('a', 111);
+    f('ab', 111, 222);
+    f2('a', a: 111);
+    f2('b', b: 222);
+    f2('ab', a: 111, b: 222);
+    f2('ab', b: 222, a: 111);
+
+    Expect.equals(7, a.calls);
+
+    checkException(() => f()); //                   Too few arguments.
+    checkException(() => f('abc', 1, 2, 3)); //     Too many arguments.
+    checkException(() => f2('c', c: 1)); //         Bad name.
+    checkException(() => f2('c', a: 111, c: 1)); // Bad name.
+
+    Expect.equals(7, a.calls);
+  }
+
+  static testMain() {
+    // 'Plain' calls where the method/field syntax matches the object.
+    testMethodCallSyntax(new HasMethod());
+    testFunctionCallSyntax(new HasField());
+
+    // 'Conversion' calls where method/field call syntax does not match the
+    // object.
+    testMethodCallSyntax(new HasField());
+    testFunctionCallSyntax(new HasMethod());
+  }
+}
+
+main() {
+  for (var i = 0; i < 20; i++) {
+    NamedParametersWithConversionsTest.testMain();
+  }
+}
diff --git a/tests/language/parameter/named_with_dollars_test.dart b/tests/language/parameter/named_with_dollars_test.dart
new file mode 100644
index 0000000..9088af4
--- /dev/null
+++ b/tests/language/parameter/named_with_dollars_test.dart
@@ -0,0 +1,91 @@
+// 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 "package:expect/expect.dart";
+
+// Test to stress Frog's named parameter scheme.
+
+main() {
+  testDollar();
+  testPsycho();
+}
+
+class TestClass {
+  method({a, b, a$b, a$$b}) => [a, b, a$b, a$$b];
+
+  psycho({$, $$, $$$, $$$$}) => [$, $$, $$$, $$$$];
+}
+
+globalMethod({a, b, a$b, a$$b}) => [a, b, a$b, a$$b];
+
+format(thing) {
+  if (thing == null) return '-';
+  if (thing is List) {
+    var fragments = ['['];
+    var sep;
+    for (final item in thing) {
+      if (sep != null) fragments.add(sep);
+      sep = ', ';
+      fragments.add(format(item));
+    }
+    fragments.add(']');
+    return fragments.join();
+  }
+  return thing.toString();
+}
+
+// Hopefully inscrutable to static analysis.
+makeTestClass(n) => [new TestClass(), new Decoy(), 'string'][n % 3];
+
+class Decoy {
+  method([a$b, b, a]) {
+    throw new UnimplementedError();
+  }
+
+  psycho([$$$, $$, $]) {
+    throw new UnimplementedError();
+  }
+}
+
+testDollar() {
+  Expect.equals('[]', format([]));
+
+  Expect.equals('[-, -, -, -]', format(globalMethod()));
+  Expect.equals('[1, 2, -, -]', format(globalMethod(a: 1, b: 2)));
+  Expect.equals('[1, 2, -, -]', format(globalMethod(b: 2, a: 1)));
+  Expect.equals('[-, -, 3, -]', format(globalMethod(a$b: 3)));
+  Expect.equals('[-, -, -, 4]', format(globalMethod(a$$b: 4)));
+
+  TestClass t = new TestClass(); // Statically typed.
+
+  Expect.equals('[-, -, -, -]', format(t.method()));
+  Expect.equals('[1, 2, -, -]', format(t.method(a: 1, b: 2)));
+  Expect.equals('[1, 2, -, -]', format(t.method(b: 2, a: 1)));
+  Expect.equals('[-, -, 3, -]', format(t.method(a$b: 3)));
+  Expect.equals('[-, -, -, 4]', format(t.method(a$$b: 4)));
+
+  var obj = makeTestClass(0);
+
+  Expect.equals('[-, -, -, -]', format(obj.method()));
+  Expect.equals('[1, 2, -, -]', format(obj.method(a: 1, b: 2)));
+  Expect.equals('[1, 2, -, -]', format(obj.method(b: 2, a: 1)));
+  Expect.equals('[-, -, 3, -]', format(obj.method(a$b: 3)));
+  Expect.equals('[-, -, -, 4]', format(obj.method(a$$b: 4)));
+}
+
+testPsycho() {
+  TestClass t = new TestClass(); // Statically typed.
+
+  Expect.equals('[1, 2, 3, -]', format(t.psycho($: 1, $$: 2, $$$: 3)));
+  Expect.equals('[1, 2, 3, -]', format(t.psycho($$$: 3, $$: 2, $: 1)));
+  Expect.equals('[1, 2, -, -]', format(t.psycho($: 1, $$: 2)));
+  Expect.equals('[-, -, -, 4]', format(t.psycho($$$$: 4)));
+
+  var obj = makeTestClass(0);
+
+  Expect.equals('[1, 2, -, -]', format(obj.psycho($: 1, $$: 2)));
+  Expect.equals('[-, -, -, 4]', format(obj.psycho($$$$: 4)));
+  Expect.equals('[1, 2, 3, -]', format(obj.psycho($: 1, $$: 2, $$$: 3)));
+  Expect.equals('[1, 2, 3, -]', format(obj.psycho($$$: 3, $$: 2, $: 1)));
+}
diff --git a/tests/language/parameter/named_with_object_property_names_test.dart b/tests/language/parameter/named_with_object_property_names_test.dart
new file mode 100644
index 0000000..e4005b6
--- /dev/null
+++ b/tests/language/parameter/named_with_object_property_names_test.dart
@@ -0,0 +1,245 @@
+// 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 "package:expect/expect.dart";
+
+// Test for named parameter with the name of a JavaScript property found on
+// 'Object'.  For such a NAME, foo.NAME may exist in an empty map, i.e.
+//    'toString' in {} --> true.
+
+main() {
+  // Test properties found on instances of Object in Chrome 15 and Firefox 6.
+  test_constructor();
+  test_hasOwnProperty();
+  test_isPrototypeOf();
+  test_propertyIsEnumerable();
+  test_toSource();
+  test_toLocaleString();
+  test_toString();
+  test_unwatch();
+  test_valueOf();
+  test_watch();
+}
+
+// 'constructor' property.
+
+class TestClass_constructor {
+  method({constructor}) => constructor;
+  static staticMethod({constructor}) => constructor;
+}
+
+globalMethod_constructor({constructor}) => constructor;
+
+test_constructor() {
+  var obj = new TestClass_constructor();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(constructor: 0));
+
+  Expect.equals(null, TestClass_constructor.staticMethod());
+  Expect.equals(0, TestClass_constructor.staticMethod(constructor: 0));
+
+  Expect.equals(null, globalMethod_constructor());
+  Expect.equals(0, globalMethod_constructor(constructor: 0));
+}
+
+// 'hasOwnProperty' property.
+
+class TestClass_hasOwnProperty {
+  method({hasOwnProperty}) => hasOwnProperty;
+  static staticMethod({hasOwnProperty}) => hasOwnProperty;
+}
+
+globalMethod_hasOwnProperty({hasOwnProperty}) => hasOwnProperty;
+
+test_hasOwnProperty() {
+  var obj = new TestClass_hasOwnProperty();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(hasOwnProperty: 0));
+
+  Expect.equals(null, TestClass_hasOwnProperty.staticMethod());
+  Expect.equals(0, TestClass_hasOwnProperty.staticMethod(hasOwnProperty: 0));
+
+  Expect.equals(null, globalMethod_hasOwnProperty());
+  Expect.equals(0, globalMethod_hasOwnProperty(hasOwnProperty: 0));
+}
+
+// 'isPrototypeOf' property.
+
+class TestClass_isPrototypeOf {
+  method({isPrototypeOf}) => isPrototypeOf;
+  static staticMethod({isPrototypeOf}) => isPrototypeOf;
+}
+
+globalMethod_isPrototypeOf({isPrototypeOf}) => isPrototypeOf;
+
+test_isPrototypeOf() {
+  var obj = new TestClass_isPrototypeOf();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(isPrototypeOf: 0));
+
+  Expect.equals(null, TestClass_isPrototypeOf.staticMethod());
+  Expect.equals(0, TestClass_isPrototypeOf.staticMethod(isPrototypeOf: 0));
+
+  Expect.equals(null, globalMethod_isPrototypeOf());
+  Expect.equals(0, globalMethod_isPrototypeOf(isPrototypeOf: 0));
+}
+
+// 'propertyIsEnumerable' property.
+
+class TestClass_propertyIsEnumerable {
+  method({propertyIsEnumerable}) => propertyIsEnumerable;
+  static staticMethod({propertyIsEnumerable}) => propertyIsEnumerable;
+}
+
+globalMethod_propertyIsEnumerable({propertyIsEnumerable}) =>
+    propertyIsEnumerable;
+
+test_propertyIsEnumerable() {
+  var obj = new TestClass_propertyIsEnumerable();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(propertyIsEnumerable: 0));
+
+  Expect.equals(null, TestClass_propertyIsEnumerable.staticMethod());
+  Expect.equals(
+      0, TestClass_propertyIsEnumerable.staticMethod(propertyIsEnumerable: 0));
+
+  Expect.equals(null, globalMethod_propertyIsEnumerable());
+  Expect.equals(0, globalMethod_propertyIsEnumerable(propertyIsEnumerable: 0));
+}
+
+// 'toSource' property.
+
+class TestClass_toSource {
+  method({toSource}) => toSource;
+  static staticMethod({toSource}) => toSource;
+}
+
+globalMethod_toSource({toSource}) => toSource;
+
+test_toSource() {
+  var obj = new TestClass_toSource();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(toSource: 0));
+
+  Expect.equals(null, TestClass_toSource.staticMethod());
+  Expect.equals(0, TestClass_toSource.staticMethod(toSource: 0));
+
+  Expect.equals(null, globalMethod_toSource());
+  Expect.equals(0, globalMethod_toSource(toSource: 0));
+}
+
+// 'toLocaleString' property.
+
+class TestClass_toLocaleString {
+  method({toLocaleString}) => toLocaleString;
+  static staticMethod({toLocaleString}) => toLocaleString;
+}
+
+globalMethod_toLocaleString({toLocaleString}) => toLocaleString;
+
+test_toLocaleString() {
+  var obj = new TestClass_toLocaleString();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(toLocaleString: 0));
+
+  Expect.equals(null, TestClass_toLocaleString.staticMethod());
+  Expect.equals(0, TestClass_toLocaleString.staticMethod(toLocaleString: 0));
+
+  Expect.equals(null, globalMethod_toLocaleString());
+  Expect.equals(0, globalMethod_toLocaleString(toLocaleString: 0));
+}
+
+// 'toString' property.
+
+class TestClass_toString {
+  method({toString}) => toString;
+  static staticMethod({toString}) => toString;
+}
+
+globalMethod_toString({toString}) => toString;
+
+test_toString() {
+  var obj = new TestClass_toString();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(toString: 0));
+
+  Expect.equals(null, TestClass_toString.staticMethod());
+  Expect.equals(0, TestClass_toString.staticMethod(toString: 0));
+
+  Expect.equals(null, globalMethod_toString());
+  Expect.equals(0, globalMethod_toString(toString: 0));
+}
+
+// 'unwatch' property.
+
+class TestClass_unwatch {
+  method({unwatch}) => unwatch;
+  static staticMethod({unwatch}) => unwatch;
+}
+
+globalMethod_unwatch({unwatch}) => unwatch;
+
+test_unwatch() {
+  var obj = new TestClass_unwatch();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(unwatch: 0));
+
+  Expect.equals(null, TestClass_unwatch.staticMethod());
+  Expect.equals(0, TestClass_unwatch.staticMethod(unwatch: 0));
+
+  Expect.equals(null, globalMethod_unwatch());
+  Expect.equals(0, globalMethod_unwatch(unwatch: 0));
+}
+
+// 'valueOf' property.
+
+class TestClass_valueOf {
+  method({valueOf}) => valueOf;
+  static staticMethod({valueOf}) => valueOf;
+}
+
+globalMethod_valueOf({valueOf}) => valueOf;
+
+test_valueOf() {
+  var obj = new TestClass_valueOf();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(valueOf: 0));
+
+  Expect.equals(null, TestClass_valueOf.staticMethod());
+  Expect.equals(0, TestClass_valueOf.staticMethod(valueOf: 0));
+
+  Expect.equals(null, globalMethod_valueOf());
+  Expect.equals(0, globalMethod_valueOf(valueOf: 0));
+}
+
+// 'watch' property.
+
+class TestClass_watch {
+  method({watch}) => watch;
+  static staticMethod({watch}) => watch;
+}
+
+globalMethod_watch({watch}) => watch;
+
+test_watch() {
+  var obj = new TestClass_watch();
+
+  Expect.equals(null, obj.method());
+  Expect.equals(0, obj.method(watch: 0));
+
+  Expect.equals(null, TestClass_watch.staticMethod());
+  Expect.equals(0, TestClass_watch.staticMethod(watch: 0));
+
+  Expect.equals(null, globalMethod_watch());
+  Expect.equals(0, globalMethod_watch(watch: 0));
+}
diff --git a/tests/language/parameter/optional_named_runtime_test.dart b/tests/language/parameter/optional_named_runtime_test.dart
new file mode 100644
index 0000000..3b863b9
--- /dev/null
+++ b/tests/language/parameter/optional_named_runtime_test.dart
@@ -0,0 +1,106 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// Dart test program for testing optional named parameters.
+
+import "package:expect/expect.dart";
+
+class OptionalNamedParametersTest {
+  static int F00() {
+    return 0;
+  }
+
+  int f11() {
+    return 0;
+  }
+
+  static int F11(int a) {
+    return a;
+  }
+
+  int f22(int a) {
+    return a;
+  }
+
+  static int F10({int b: 20}) {
+    return b;
+  }
+
+  int f21({int b: 20}) {
+    return b;
+  }
+
+  static int F21(int a, {int b: 20}) {
+    return 100 * a + b;
+  }
+
+  int f32(int a, {int b: 20}) {
+    return 100 * a + b;
+  }
+
+  static int F31(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f42(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int F41(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
+  }
+
+  int f52(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
+  }
+
+  static void test() {
+    OptionalNamedParametersTest np = new OptionalNamedParametersTest();
+    Expect.equals(0, F00());
+    Expect.equals(0, np.f11());
+    Expect.equals(10, F11(10));
+    Expect.equals(10, np.f22(10));
+    Expect.equals(20, F10());
+    Expect.equals(20, np.f21());
+
+
+    Expect.equals(20, F10(b: 20));
+    Expect.equals(20, np.f21(b: 20));
+    Expect.equals(1020, F21(10));
+    Expect.equals(1020, np.f32(10));
+
+
+    Expect.equals(1025, F21(10, b: 25));
+    Expect.equals(1025, np.f32(10, b: 25));
+    Expect.equals(102030, F31(10));
+    Expect.equals(102030, np.f42(10));
+
+
+    Expect.equals(102530, F31(10, b: 25));
+    Expect.equals(102530, np.f42(10, b: 25));
+    Expect.equals(102035, F31(10, c: 35));
+    Expect.equals(102035, np.f42(10, c: 35));
+    Expect.equals(102535, F31(10, b: 25, c: 35));
+    Expect.equals(102535, np.f42(10, b: 25, c: 35));
+
+
+    Expect.equals(102535, F31(10, c: 35, b: 25));
+    Expect.equals(102535, np.f42(10, c: 35, b: 25));
+    Expect.equals(10200040, F41(10));
+    Expect.equals(10200040, np.f52(10));
+    Expect.equals(10203540, F41(10, c: 35));
+    Expect.equals(10203540, np.f52(10, c: 35));
+    Expect.equals(10250045, F41(10, d: 45, b: 25));
+
+    Expect.equals(10250045, np.f52(10, d: 45, b: 25));
+    Expect.equals(10253545, F41(10, d: 45, c: 35, b: 25));
+    Expect.equals(10253545, np.f52(10, d: 45, c: 35, b: 25));
+  }
+}
+
+main() {
+  OptionalNamedParametersTest.test();
+}
diff --git a/tests/language/parameter/optional_named_test.dart b/tests/language/parameter/optional_named_test.dart
new file mode 100644
index 0000000..20413ad
--- /dev/null
+++ b/tests/language/parameter/optional_named_test.dart
@@ -0,0 +1,130 @@
+// 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.
+// Dart test program for testing optional named parameters.
+
+import "package:expect/expect.dart";
+
+class OptionalNamedParametersTest {
+  static int F00() {
+    return 0;
+  }
+
+  int f11() {
+    return 0;
+  }
+
+  static int F11(int a) {
+    return a;
+  }
+
+  int f22(int a) {
+    return a;
+  }
+
+  static int F10({int b: 20}) {
+    return b;
+  }
+
+  int f21({int b: 20}) {
+    return b;
+  }
+
+  static int F21(int a, {int b: 20}) {
+    return 100 * a + b;
+  }
+
+  int f32(int a, {int b: 20}) {
+    return 100 * a + b;
+  }
+
+  static int F31(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  int f42(int a, {int b: 20, int c: 30}) {
+    return 100 * (100 * a + b) + c;
+  }
+
+  static int F41(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
+  }
+
+  int f52(int a, {int b: 20, int? c, int d: 40}) {
+    return 100 * (100 * (100 * a + b) + ((c != null) ? c : 0)) + d;
+  }
+
+  static void test() {
+    OptionalNamedParametersTest np = new OptionalNamedParametersTest();
+    Expect.equals(0, F00());
+    Expect.equals(0, np.f11());
+    Expect.equals(10, F11(10));
+    Expect.equals(10, np.f22(10));
+    Expect.equals(20, F10());
+    Expect.equals(20, np.f21());
+    Expect.equals(20, F10(20));
+    //                   ^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 0 allowed, but 1 found.
+    Expect.equals(20, np.f21(20));
+    //                      ^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 0 allowed, but 1 found.
+    Expect.equals(20, F10(b: 20));
+    Expect.equals(20, np.f21(b: 20));
+    Expect.equals(1020, F21(10));
+    Expect.equals(1020, np.f32(10));
+    Expect.equals(1025, F21(10, 25));
+    //                     ^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(1025, np.f32(10, 25));
+    //                        ^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(1025, F21(10, b: 25));
+    Expect.equals(1025, np.f32(10, b: 25));
+    Expect.equals(102030, F31(10));
+    Expect.equals(102030, np.f42(10));
+    Expect.equals(102530, F31(10, 25));
+    //                       ^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(102530, np.f42(10, 25));
+    //                          ^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(102530, F31(10, b: 25));
+    Expect.equals(102530, np.f42(10, b: 25));
+    Expect.equals(102035, F31(10, c: 35));
+    Expect.equals(102035, np.f42(10, c: 35));
+    Expect.equals(102535, F31(10, b: 25, c: 35));
+    Expect.equals(102535, np.f42(10, b: 25, c: 35));
+    Expect.equals(102535, F31(10, 25, c:35));
+    //                       ^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(102535, np.f42(10, 25, c:35));
+    //                          ^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(102535, F31(10, c: 35, b: 25));
+    Expect.equals(102535, np.f42(10, c: 35, b: 25));
+    Expect.equals(10200040, F41(10));
+    Expect.equals(10200040, np.f52(10));
+    Expect.equals(10203540, F41(10, c: 35));
+    Expect.equals(10203540, np.f52(10, c: 35));
+    Expect.equals(10250045, F41(10, d: 45, b: 25));
+    Expect.equals(10250045, F41(10, 25, d:45));
+    //                         ^^^^^^^^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS_COULD_BE_NAMED
+    // [cfe] Too many positional arguments: 1 allowed, but 2 found.
+    Expect.equals(10250045, np.f52(10, d: 45, b: 25));
+    Expect.equals(10253545, F41(10, d: 45, c: 35, b: 25));
+    Expect.equals(10253545, np.f52(10, d: 45, c: 35, b: 25));
+  }
+}
+
+main() {
+  OptionalNamedParametersTest.test();
+}
diff --git a/tests/language/parameter/param_test.dart b/tests/language/parameter/param_test.dart
new file mode 100644
index 0000000..b0be01d
--- /dev/null
+++ b/tests/language/parameter/param_test.dart
@@ -0,0 +1,24 @@
+// 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.
+// Dart test program for testing params.
+
+import "package:expect/expect.dart";
+
+class Helper {
+  static int foo(int i) {
+    var b;
+    b = i + 1;
+    return b;
+  }
+}
+
+class ParamTest {
+  static testMain() {
+    Expect.equals(2, Helper.foo(1));
+  }
+}
+
+main() {
+  ParamTest.testMain();
+}
diff --git a/tests/language/parameter/parameter1_test.dart b/tests/language/parameter/parameter1_test.dart
new file mode 100644
index 0000000..4c8c0a0
--- /dev/null
+++ b/tests/language/parameter/parameter1_test.dart
@@ -0,0 +1,18 @@
+// 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.
+// Dart test program for testing params.
+
+class Param1Test {
+  // TODO(asiva): Should we try to interpret 1 above as an int? In order to
+  // avoid a type error with --enable_type_checks, the type of i below is
+  // changed from int to String.
+  // static int testMain(String s, int i) { return i; }
+  static int testMain() {
+    return 0;
+  }
+}
+
+main() {
+  Param1Test.testMain();
+}
diff --git a/tests/language/parameter/parameter2_test.dart b/tests/language/parameter/parameter2_test.dart
new file mode 100644
index 0000000..2f075a1
--- /dev/null
+++ b/tests/language/parameter/parameter2_test.dart
@@ -0,0 +1,63 @@
+// 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.
+// Dart test program for testing function type parameters.
+
+import "package:expect/expect.dart";
+
+class Param2Test {
+  static forEach(List<int> a, int f(int k)) {
+    for (int i = 0; i < a.length; i++) {
+      a[i] = f(a[i]);
+    }
+  }
+
+  static int apply(f(int k), int arg) {
+    var res = f(arg);
+    return res;
+  }
+
+  static exists(List<int> a, f(e)) {
+    for (int i = 0; i < a.length; i++) {
+      if (f(a[i])) return true;
+    }
+    return false;
+  }
+
+  static testMain() {
+    int square(int x) {
+      return x * x;
+    }
+
+    Expect.equals(4, apply(square, 2));
+    Expect.equals(100, apply(square, 10));
+
+    var v = [1, 2, 3, 4, 5, 6];
+    forEach(v, square);
+    Expect.equals(1, v[0]);
+    Expect.equals(4, v[1]);
+    Expect.equals(9, v[2]);
+    Expect.equals(16, v[3]);
+    Expect.equals(25, v[4]);
+    Expect.equals(36, v[5]);
+
+    isOdd(element) {
+      return element % 2 == 1;
+    }
+
+    Expect.equals(true, exists([3, 5, 7, 11, 13], isOdd));
+    Expect.equals(false, exists([2, 4, 10], isOdd));
+    Expect.equals(false, exists([], isOdd));
+
+    v = [4, 5, 7];
+    Expect.equals(true, exists(v, (e) => e % 2 == 1));
+    Expect.equals(false, exists(v, (e) => e == 6));
+
+    var isZero = (e) => e == 0;
+    Expect.equals(false, exists(v, isZero));
+  }
+}
+
+main() {
+  Param2Test.testMain();
+}
diff --git a/tests/language/parameter/positional_type_runtime_test.dart b/tests/language/parameter/positional_type_runtime_test.dart
new file mode 100644
index 0000000..87d1516
--- /dev/null
+++ b/tests/language/parameter/positional_type_runtime_test.dart
@@ -0,0 +1,26 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+//
+// Dart test program for testing optional positional parameters in type tests.
+
+main() {
+  Function anyFunction;
+  void acceptFunNumOptBool(void funNumOptBool(num n, [bool b])) {}
+  void funNum(num n) {}
+  void funNumBool(num n, bool b) {}
+  void funNumOptBool(num n, [bool b = true]) {}
+  void funNumOptBoolX(num n, [bool x = true]) {}
+
+  anyFunction = funNum;
+  anyFunction = funNumBool;
+  anyFunction = funNumOptBool;
+  anyFunction = funNumOptBoolX;
+  acceptFunNumOptBool(funNumOptBool);
+  acceptFunNumOptBool(funNumOptBoolX);
+
+
+}
diff --git a/tests/language/parameter/positional_type_test.dart b/tests/language/parameter/positional_type_test.dart
new file mode 100644
index 0000000..5920e68
--- /dev/null
+++ b/tests/language/parameter/positional_type_test.dart
@@ -0,0 +1,29 @@
+// 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.
+//
+// Dart test program for testing optional positional parameters in type tests.
+
+main() {
+  Function anyFunction;
+  void acceptFunNumOptBool(void funNumOptBool(num n, [bool b])) {}
+  void funNum(num n) {}
+  void funNumBool(num n, bool b) {}
+  void funNumOptBool(num n, [bool b = true]) {}
+  void funNumOptBoolX(num n, [bool x = true]) {}
+
+  anyFunction = funNum;
+  anyFunction = funNumBool;
+  anyFunction = funNumOptBool;
+  anyFunction = funNumOptBoolX;
+  acceptFunNumOptBool(funNumOptBool);
+  acceptFunNumOptBool(funNumOptBoolX);
+  acceptFunNumOptBool(funNum);
+  //                  ^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'void Function(num)' can't be assigned to the parameter type 'void Function(num, [bool])'.
+  acceptFunNumOptBool(funNumBool);
+  //                  ^^^^^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'void Function(num, bool)' can't be assigned to the parameter type 'void Function(num, [bool])'.
+}
diff --git a/tests/language/parameter/types_specialization_test.dart b/tests/language/parameter/types_specialization_test.dart
new file mode 100644
index 0000000..532a7a7
--- /dev/null
+++ b/tests/language/parameter/types_specialization_test.dart
@@ -0,0 +1,32 @@
+// 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.
+// Test that we invalidate parameter type optimization in the presence
+// of optional parameters.
+
+import "package:expect/expect.dart";
+
+class A {
+  void foo(bool firstInvocation, [a = 42, b = 'foo']) {
+    if (firstInvocation) {
+      Expect.isTrue(a is String);
+      Expect.isTrue(b is int);
+    } else {
+      Expect.isTrue(a is int);
+      Expect.isTrue(b is String);
+    }
+  }
+}
+
+test() {
+  // This call to [A.foo] will be in the queue after [A.foo] has been
+  // compiled with the optimistic type assumptions.
+  new A().foo(false);
+}
+
+main() {
+  test();
+  // This call to [A.foo] will be the first in the queue, and dart2js
+  // will optimize the method with these parameter types.
+  new A().foo(true, 'bar', 42);
+}
diff --git a/tests/language/reg_exp/reg_exp2_test.dart b/tests/language/reg_exp/reg_exp2_test.dart
new file mode 100644
index 0000000..b864dd3
--- /dev/null
+++ b/tests/language/reg_exp/reg_exp2_test.dart
@@ -0,0 +1,34 @@
+// 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.
+// Dart test for testing regular expressions in Dart.
+
+import "package:expect/expect.dart";
+
+class RegExp2Test {
+  static String? findImageTag_(String text, String extensions) {
+    final re = new RegExp('src="(http://\\S+\\.(${extensions}))"');
+    print('REGEXP findImageTag_ $extensions text: \n$text');
+    final match = re.firstMatch(text);
+    print('REGEXP findImageTag_ $extensions SUCCESS');
+    if (match != null) {
+      return match[1];
+    } else {
+      return null;
+    }
+  }
+
+  static testMain() {
+    String text =
+        '''<img src="http://cdn.archinect.net/images/514x/c0/c0p3qo202oxp0e6z.jpg" width="514" height="616" border="0" title="" alt=""><em><p>My last entry was in December of 2009. I suppose I never was particularly good about updating this thing, but it seems a bit ridiculous that I couldn't be bothered to post once about the many, many things that have gone on since then. My apologies. I guess I could start by saying that the world looks like a very different place than it did back in second year.</p></em>
+
+''';
+    String extensions = 'jpg|jpeg|png';
+    String? tag = findImageTag_(text, extensions);
+    Expect.isNotNull(tag);
+  }
+}
+
+main() {
+  RegExp2Test.testMain();
+}
diff --git a/tests/language/reg_exp/reg_exp3_test.dart b/tests/language/reg_exp/reg_exp3_test.dart
new file mode 100644
index 0000000..cb375a5
--- /dev/null
+++ b/tests/language/reg_exp/reg_exp3_test.dart
@@ -0,0 +1,23 @@
+// 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.
+// Dart test for testing regular expressions in Dart.
+
+import "package:expect/expect.dart";
+
+class RegExp3Test {
+  static testMain() {
+    var i = 2000;
+    try {
+      RegExp exp = new RegExp("[");
+      i = 100; // Should not reach here.
+    } on FormatException catch (e) {
+      i = 0;
+    }
+    Expect.equals(0, i);
+  }
+}
+
+main() {
+  RegExp3Test.testMain();
+}
diff --git a/tests/language/reg_exp/reg_exp4_test.dart b/tests/language/reg_exp/reg_exp4_test.dart
new file mode 100644
index 0000000..208f1bd
--- /dev/null
+++ b/tests/language/reg_exp/reg_exp4_test.dart
@@ -0,0 +1,26 @@
+// 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.
+// Dart test for testing regular expressions in Dart.
+
+class RegEx2Test {
+  static void testMain() {
+    final helloPattern = new RegExp("with (hello)");
+    String s = "this is a string with hello somewhere";
+    Match? match = helloPattern.firstMatch(s);
+    if (match != null) {
+      print("got match");
+      int groupCount = match.groupCount;
+      print("groupCount is $groupCount");
+      print("group 0 is ${match.group(0)}");
+      print("group 1 is ${match.group(1)}");
+    } else {
+      print("match not round");
+    }
+    print("done");
+  }
+}
+
+main() {
+  RegEx2Test.testMain();
+}
diff --git a/tests/language/reg_exp/reg_exp_test.dart b/tests/language/reg_exp/reg_exp_test.dart
new file mode 100644
index 0000000..f606600
--- /dev/null
+++ b/tests/language/reg_exp/reg_exp_test.dart
@@ -0,0 +1,84 @@
+// 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.
+// Dart test for testing regular expressions in Dart.
+
+import "package:expect/expect.dart";
+
+void main() {
+  RegExp exp = new RegExp(r"(\w+)");
+  String str = "Parse my string";
+  List<Match> matches = exp.allMatches(str).toList();
+  Expect.equals(3, matches.length);
+  Expect.equals("Parse", matches[0].group(0));
+  Expect.equals("my", matches[1].group(0));
+  Expect.equals("string", matches[2].group(0));
+
+  // Check that allMatches progresses correctly for empty matches, and that
+  // it includes the empty match at the end position.
+  exp = new RegExp("a?");
+  str = "babba";
+  Expect.listEquals(["", "a", "", "", "a", ""],
+      exp.allMatches(str).map((x) => x[0]).toList());
+
+  // Check that allMatches works with optional start index.
+  exp = new RegExp("as{2}");
+  str = "assassin";
+  Expect.equals(2, exp.allMatches(str).length);
+  Expect.equals(2, exp.allMatches(str, 0).length);
+  Expect.equals(1, exp.allMatches(str, 1).length);
+  Expect.equals(0, exp.allMatches(str, 4).length);
+  Expect.equals(0, exp.allMatches(str, str.length).length);
+  Expect.throws(() => exp.allMatches(str, -1));
+  Expect.throws(() => exp.allMatches(str, str.length + 1));
+
+  exp = new RegExp(".*");
+  Expect.equals("", exp.allMatches(str, str.length).single[0]);
+
+  // The "^" must only match at the beginning of the string.
+  // Using a start-index doesn't change where the string starts.
+  exp = new RegExp("^ass");
+  Expect.equals(1, exp.allMatches(str, 0).length);
+  Expect.equals(0, exp.allMatches(str, 3).length);
+
+  // Regression test for http://dartbug.com/2980
+  exp = new RegExp("^", multiLine: true); // Any zero-length match will work.
+  str = "foo\nbar\nbaz";
+  Expect.equals(" foo\n bar\n baz", str.replaceAll(exp, " "));
+
+  exp = new RegExp(r"(\w+)");
+  Expect.isNull(exp.matchAsPrefix(" xyz ab"));
+  Expect.isNull(exp.matchAsPrefix(" xyz ab", 0));
+
+  var m = exp.matchAsPrefix(" xyz ab", 1)!;
+  Expect.equals("xyz", m[0]);
+  Expect.equals("xyz", m[1]);
+  Expect.equals(1, m.groupCount);
+
+  m = exp.matchAsPrefix(" xyz ab", 2)!;
+  Expect.equals("yz", m[0]);
+  Expect.equals("yz", m[1]);
+  Expect.equals(1, m.groupCount);
+
+  m = exp.matchAsPrefix(" xyz ab", 3)!;
+  Expect.equals("z", m[0]);
+  Expect.equals("z", m[1]);
+  Expect.equals(1, m.groupCount);
+
+  Expect.isNull(exp.matchAsPrefix(" xyz ab", 4));
+
+  m = exp.matchAsPrefix(" xyz ab", 5)!;
+  Expect.equals("ab", m[0]);
+  Expect.equals("ab", m[1]);
+  Expect.equals(1, m.groupCount);
+
+  m = exp.matchAsPrefix(" xyz ab", 6)!;
+  Expect.equals("b", m[0]);
+  Expect.equals("b", m[1]);
+  Expect.equals(1, m.groupCount);
+
+  Expect.isNull(exp.matchAsPrefix(" xyz ab", 7));
+
+  Expect.throws(() => exp.matchAsPrefix(" xyz ab", -1));
+  Expect.throws(() => exp.matchAsPrefix(" xyz ab", 8));
+}
diff --git a/tests/language/regress/r24720_test.dart b/tests/language/regress/r24720_test.dart
new file mode 100644
index 0000000..4f24001
--- /dev/null
+++ b/tests/language/regress/r24720_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for r24720.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+class B extends A<int> {
+  B() : this.foo();
+  B.foo();
+}
+
+main() {
+  Expect.isTrue(new B() is B);
+  Expect.isTrue(new B() is A<int>);
+  Expect.isFalse(new B() is A<String>);
+}
diff --git a/tests/language/regress/regress10204_test.dart b/tests/language/regress/regress10204_test.dart
new file mode 100644
index 0000000..1f1619e
--- /dev/null
+++ b/tests/language/regress/regress10204_test.dart
@@ -0,0 +1,38 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to miscompile
+// [A.visitInvokeDynamicMethod].
+
+import "package:expect/expect.dart";
+
+var a = 2;
+
+class Tupe {
+  const Tupe();
+  get instructionType => a == 2 ? this : new A();
+  refine(a, b) => '$a$b';
+}
+
+class Node {
+  final selector = null;
+  var inputs = {"a": const Tupe(), "b": const Tupe()};
+  bool isCallOnInterceptor = false;
+
+  getDartReceiver() {
+    return isCallOnInterceptor ? inputs["a"] : inputs["b"];
+  }
+}
+
+class A {
+  visitInvokeDynamicMethod(node) {
+    var receiverType = node.getDartReceiver().instructionType;
+    return receiverType.refine(node.selector, node.selector);
+  }
+}
+
+main() {
+  Expect.equals(
+      'nullnull', [new A()].last.visitInvokeDynamicMethod(new Node()));
+}
diff --git a/tests/language/regress/regress10321_test.dart b/tests/language/regress/regress10321_test.dart
new file mode 100644
index 0000000..fb35dcd
--- /dev/null
+++ b/tests/language/regress/regress10321_test.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2013, 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";
+
+// Regression test for dart2js that used to miscompile [A.foo].
+
+var global = 54;
+
+class A {
+  int a = 0;
+  int b = 42;
+  final int c = global;
+  foo() {
+    int start = a - 1;
+    a = 54;
+    if (b == 42) {
+      b = 32;
+    } else {
+      b = 42;
+    }
+    Expect.equals(-1, start);
+  }
+
+  bar() {
+    int start = a - c - 1;
+    a = 42;
+    if (b == 42) {
+      b = 32;
+    } else {
+      b = 42;
+    }
+    Expect.equals(-55, start);
+  }
+}
+
+main() {
+  new A().foo();
+  new A().bar();
+}
diff --git a/tests/language/regress/regress10561_test.dart b/tests/language/regress/regress10561_test.dart
new file mode 100644
index 0000000..16e0cca
--- /dev/null
+++ b/tests/language/regress/regress10561_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to miscompile classes
+// extending HashMap, because HashMap is patched.
+
+import "package:expect/expect.dart";
+
+import 'dart:collection';
+
+class Foo extends Expando {}
+
+main() {
+  Expect.isNull(new Foo()[new Object()]);
+}
diff --git a/tests/language/regress/regress10581_test.dart b/tests/language/regress/regress10581_test.dart
new file mode 100644
index 0000000..a499544
--- /dev/null
+++ b/tests/language/regress/regress10581_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for https://code.google.com/p/dart/issues/detail?id=10581.
+
+import 'package:expect/expect.dart';
+
+abstract class AxesObject {
+  Update();
+}
+
+String result = '';
+
+class Point2DObject extends AxesObject {
+  Update() {
+    result += 'P';
+  }
+}
+
+class BestFitObject extends AxesObject {
+  Update() {
+    result += 'B';
+  }
+}
+
+class Foo {
+  AddAxesObject(type) {
+    AxesObject? a = null;
+    switch (type) {
+      case 100:
+        a = new Point2DObject();
+        break;
+      case 200:
+        a = new BestFitObject();
+        break;
+    }
+    if (a != null) {
+      a.Update();
+    }
+  }
+
+  AddAxesObject2(type) {
+    AxesObject? a = null;
+    if (type == 100) {
+      a = new Point2DObject();
+    } else if (type == 200) {
+      a = new BestFitObject();
+    }
+    if (a != null) {
+      a.Update();
+    }
+  }
+}
+
+main() {
+  var f = new Foo();
+  f.AddAxesObject(100);
+  f.AddAxesObject(200);
+  f.AddAxesObject2(100);
+  f.AddAxesObject2(200);
+  Expect.equals('PBPB', result);
+}
diff --git a/tests/language/regress/regress10721_test.dart b/tests/language/regress/regress10721_test.dart
new file mode 100644
index 0000000..f454483
--- /dev/null
+++ b/tests/language/regress/regress10721_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2013, 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";
+
+void main() {
+  Expect.equals('', useParameterInClosure(1));
+  Expect.equals(43, updateParameterInClosure(1)());
+}
+
+String useParameterInClosure(arg1, {int? arg2}) {
+  if (arg1 is Map) {
+    return arg1.keys.map((key) => arg1[key]).first;
+  } else {
+    return '';
+  }
+}
+
+Function updateParameterInClosure(arg1) {
+  if (arg1 is Map) {
+    return () => arg1 = 42;
+  } else {
+    return () => arg1 = arg1 + 42;
+  }
+}
diff --git a/tests/language/regress/regress10747_test.dart b/tests/language/regress/regress10747_test.dart
new file mode 100644
index 0000000..46fb8bd
--- /dev/null
+++ b/tests/language/regress/regress10747_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2013, 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";
+
+class B<T> {}
+
+class A<T> {
+  var field;
+  A(this.field);
+  asTypeVariable() => field as T;
+  asBOfT() => field as B<T>;
+}
+
+main() {
+  Expect.equals(42, new A<int>(42).asTypeVariable());
+  Expect.throwsTypeError(() => new A<String>(42).asTypeVariable());
+
+  var b = new B<int>();
+  Expect.equals(b, new A<int>(b).asBOfT());
+  Expect.throwsTypeError(() => new A<String>(b).asBOfT());
+}
diff --git a/tests/language/regress/regress10783_test.dart b/tests/language/regress/regress10783_test.dart
new file mode 100644
index 0000000..ff1014d
--- /dev/null
+++ b/tests/language/regress/regress10783_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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";
+
+class C {
+  foo(int y) {
+    return y;
+  }
+}
+
+main() {
+  for (var b in [
+    [false, 'pig']
+  ]) {
+    var c;
+    if (b[0] as bool) c = new C();
+    Expect.throwsNoSuchMethodError(() => print(c.foo(b[1])));
+  }
+}
diff --git a/tests/language/regress/regress10996_lib.dart b/tests/language/regress/regress10996_lib.dart
new file mode 100644
index 0000000..77071a2
--- /dev/null
+++ b/tests/language/regress/regress10996_lib.dart
@@ -0,0 +1,10 @@
+// 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.
+
+library regress_10996_lib;
+
+var a = 3;
+var b = 4;
+var c = 5;
+var d = 6;
diff --git a/tests/language/regress/regress10996_test.dart b/tests/language/regress/regress10996_test.dart
new file mode 100644
index 0000000..eee0095
--- /dev/null
+++ b/tests/language/regress/regress10996_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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 "regress10996_lib.dart" as lib;
+
+foo(a, [b]) {
+  return a + b + lib.a + lib.b;
+}
+
+bar(c, {d}) {
+  return c + d + lib.c + lib.d;
+}
+
+main() {
+  Expect.equals(1 + 2 + 3 + 4, foo(1, 2));
+  Expect.equals(7 + 8 + 3 + 4, foo(7, 8));
+  Expect.equals(3 + 4 + 5 + 6, bar(3, d: 4));
+  Expect.equals(7 + 8 + 5 + 6, bar(7, d: 8));
+}
diff --git a/tests/language/regress/regress11010_test.dart b/tests/language/regress/regress11010_test.dart
new file mode 100644
index 0000000..12f6609
--- /dev/null
+++ b/tests/language/regress/regress11010_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, 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.
+
+// We used to have an issue in dart2js where calling a top-level or
+// static field wouldn't register the 'call' selector correctly.
+var caller = new Caller();
+
+class Caller {
+  call(a, b) => a + b;
+}
+
+main() {
+  if (caller(42, 87) != 42 + 87) {
+    throw 'unexpected result';
+  }
+}
diff --git a/tests/language/regress/regress11724_runtime_test.dart b/tests/language/regress/regress11724_runtime_test.dart
new file mode 100644
index 0000000..6cf180d
--- /dev/null
+++ b/tests/language/regress/regress11724_runtime_test.dart
@@ -0,0 +1,12 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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";
+
+void main() {
+
+}
diff --git a/tests/language/regress/regress11724_test.dart b/tests/language/regress/regress11724_test.dart
new file mode 100644
index 0000000..ddf3925
--- /dev/null
+++ b/tests/language/regress/regress11724_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2013, 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";
+
+void main() {
+  method(<int>[]);
+//^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.UNDEFINED_FUNCTION
+// [cfe] Method not found: 'method'.
+}
diff --git a/tests/language/regress/regress11793_test.dart b/tests/language/regress/regress11793_test.dart
new file mode 100644
index 0000000..1cb3de5
--- /dev/null
+++ b/tests/language/regress/regress11793_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js, whose value range analysis phase
+// assumed loop phis that were integer necessarily had integer inputs.
+
+var array = const [0, 0.5];
+var globalB = array[0];
+var otherArray = [5];
+
+main() {
+  var b = globalB;
+  var a = b + 1;
+  if (otherArray[0] == 0) {
+    // Use a non-existing selector to prevent adding a bailout check.
+    (a as dynamic).noSuch();
+    a = otherArray[0];
+  }
+
+  // Use [a] to make sure it does not become dead code.
+  var f = array[a as int];
+
+  // Add an integer check on [b].
+  var d = array[b as int];
+
+  // This instruction will be GVN to the same value as [a].
+  // By being GVN'ed, [e] will have its type changed from integer
+  // to number: because of the int type check on [b], we know
+  // [: b + 1 :] returns an integer.
+  // However we update this instruction with the previous [: b + 1 :]
+  // that did not have that information and therefore only knows that
+  // the instruction returns a number.
+  var e = b + 1;
+
+  // Introduce a loop phi that has [e] as header input, and [e++] as
+  // update input. By having [e] as input, dart2js will compute an
+  // integer type for the phi. However, after GVN, [e] becomes a
+  // number.
+
+  while (otherArray[0] == 0) {
+    // Use [e] as an index for an array so that the value range
+    // analysis tries to compute a range for [e].
+    otherArray[e as int] = (d + f) as int;
+    e++;
+  }
+}
diff --git a/tests/language/regress/regress11800_test.dart b/tests/language/regress/regress11800_test.dart
new file mode 100644
index 0000000..881d8c7
--- /dev/null
+++ b/tests/language/regress/regress11800_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2013, 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.
+// VMOptions=--optimization-counter-threshold=10
+
+import "package:expect/expect.dart";
+
+// Test correct register allocation with a value used twice at the same
+// instruction.
+test(List a, int v) {
+  a[v] = v;
+}
+
+main() {
+  var list = new List<dynamic>.filled(2, null);
+  for (var i = 0; i < 20; i++) test(list, 1);
+  Expect.equals(null, list[0]);
+  Expect.equals(1, list[1]);
+}
diff --git a/tests/language/regress/regress12023_test.dart b/tests/language/regress/regress12023_test.dart
new file mode 100644
index 0000000..5e1a936b
--- /dev/null
+++ b/tests/language/regress/regress12023_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, 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";
+
+void main() {
+  List test = ["f", "5", "s", "6"];
+  int length = test.length;
+  for (int i = 0; i < length;) {
+    var action = test[i++];
+    switch (action) {
+      case "f":
+      case "s":
+        action = test[i - 1];
+        int value = int.parse(test[i++]);
+        if (action == "f") {
+          Expect.equals(5, value);
+        } else {
+          Expect.equals(6, value);
+        }
+        break;
+    }
+  }
+}
diff --git a/tests/language/regress/regress12118_test.dart b/tests/language/regress/regress12118_test.dart
new file mode 100644
index 0000000..fea6996
--- /dev/null
+++ b/tests/language/regress/regress12118_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for issue 12118 which caused a crash in dart2js.
+
+const X = 42;
+
+class A {
+  final x;
+  A({this.x: X});
+}
+
+class B extends A {}
+
+void main() {
+  if (new B().x != 42) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/regress/regress12284_test.dart b/tests/language/regress/regress12284_test.dart
new file mode 100644
index 0000000..4164c44
--- /dev/null
+++ b/tests/language/regress/regress12284_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2013, 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 "../compiler_annotations.dart";
+
+class A {
+  int field = -1;
+
+  @DontInline()
+  A(param) {
+    // Currently defeat inlining by using a closure.
+    var bar = () => 42;
+    field = param + 42;
+  }
+  A.redirect() : this('foo');
+}
+
+main() {
+  Expect.equals(42 + 42, new A(42).field);
+  // TODO(jmesserly): DDC throws an nSM if the argument types mismatch,
+  // instead of a TypeError.
+  // https://github.com/dart-lang/dev_compiler/issues/534
+  Expect.throws(() => new A.redirect(),
+      (e) => e is ArgumentError || e is TypeError || e is NoSuchMethodError);
+}
diff --git a/tests/language/regress/regress12288_test.dart b/tests/language/regress/regress12288_test.dart
new file mode 100644
index 0000000..ca3f71c
--- /dev/null
+++ b/tests/language/regress/regress12288_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2013, 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.
+
+main() {
+  var parent = new Element(null);
+  var child = new Element(parent);
+  var result = child.path0.length;
+  if (result != 2) {
+    throw "Expected 2, but child.path0.length was $result";
+  }
+}
+
+class Element {
+  final Element? parent;
+
+  Element(this.parent);
+
+  List<Element> get path0 {
+    if (parent == null) {
+      return <Element>[this];
+    } else {
+      var list = parent!.path0;
+      list.add(this);
+      return list;
+    }
+  }
+}
diff --git a/tests/language/regress/regress12336_test.dart b/tests/language/regress/regress12336_test.dart
new file mode 100644
index 0000000..029c3f1
--- /dev/null
+++ b/tests/language/regress/regress12336_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to generate wrong code for
+// [foo].
+
+import "package:expect/expect.dart";
+import "../compiler_annotations.dart";
+
+main() {
+  var result = foo(1, 2);
+  Expect.equals(1, result[0]);
+  Expect.equals(2, result[1]);
+
+  result = foo([], 2);
+  Expect.equals(0, result[0]);
+  Expect.listEquals([], result[1]);
+}
+
+@DontInline()
+foo(a, b) {
+  () => 42;
+  if (a is List) {
+    var saved = a as List;
+    // By having two HTypeKnown SSA instructions for [a], dart2js was
+    // confused when updating the phis at exit of this block.
+    a = a.length;
+    b = saved;
+  }
+  return [a, b];
+}
diff --git a/tests/language/regress/regress124683_test.dart b/tests/language/regress/regress124683_test.dart
new file mode 100644
index 0000000..d305903
--- /dev/null
+++ b/tests/language/regress/regress124683_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Regression test for ddc failure triggered by
+// https://dart-review.googlesource.com/c/sdk/+/124683
+
+class Class {
+  String toString() {
+    void local() {}
+
+    return '${runtimeType.toString()}';
+  }
+}
+
+main() {
+  new Class().toString();
+}
diff --git a/tests/language/regress/regress12561_test.dart b/tests/language/regress/regress12561_test.dart
new file mode 100644
index 0000000..12acf0e
--- /dev/null
+++ b/tests/language/regress/regress12561_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, 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";
+
+class C {
+  noSuchMethod(int x, int y) => x + y; /*@compile-error=unspecified*/
+}
+
+main() {
+  Expect.throws(() => new C().foo, (e) => e is Error); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/regress/regress12615_test.dart b/tests/language/regress/regress12615_test.dart
new file mode 100644
index 0000000..02511c9
--- /dev/null
+++ b/tests/language/regress/regress12615_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+// Test that try-catch works properly in the VM.
+
+main() {
+  void test() {
+    f() {
+      try {} catch (e) {}
+    }
+
+    try {} catch (e) {}
+  }
+
+  test();
+}
diff --git a/tests/language/regress/regress13179_test.dart b/tests/language/regress/regress13179_test.dart
new file mode 100644
index 0000000..bcbba33
--- /dev/null
+++ b/tests/language/regress/regress13179_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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";
+
+int count = 0;
+
+void f([void f([Null x])? = f]) {
+  count++;
+  if (f != null) {
+    f(null);
+  }
+}
+
+main() {
+  f();
+  Expect.equals(2, count);
+}
diff --git a/tests/language/regress/regress13494_test.dart b/tests/language/regress/regress13494_test.dart
new file mode 100644
index 0000000..9e239c6
--- /dev/null
+++ b/tests/language/regress/regress13494_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js. Test that the argument to an unresolved static
+// getter is only evaluated once.
+
+import "package:expect/expect.dart";
+
+int i = 0;
+
+p(x) => i++;
+
+class A {}
+
+main() {
+  bool caught = false;
+  try {
+    A.unknown = p(2); /*@compile-error=unspecified*/
+  } catch (_) {
+    caught = true;
+  }
+  Expect.isTrue(caught);
+  Expect.equals(1, i);
+}
diff --git a/tests/language/regress/regress13556_test.dart b/tests/language/regress/regress13556_test.dart
new file mode 100644
index 0000000..b9388d6
--- /dev/null
+++ b/tests/language/regress/regress13556_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to crash when resolving the
+// @B() annotation.
+
+class A {
+  final a;
+  const A({this.a});
+}
+
+class B extends A {
+  const B();
+}
+
+@B()
+main() {}
diff --git a/tests/language/regress/regress1363_lib.dart b/tests/language/regress/regress1363_lib.dart
new file mode 100644
index 0000000..fdbbba6
--- /dev/null
+++ b/tests/language/regress/regress1363_lib.dart
@@ -0,0 +1,14 @@
+// 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.
+
+library Issue1363;
+
+class C {}
+
+class Cup<T> {
+  var foo;
+  Cup(this.foo);
+
+  T getContents() => foo;
+}
diff --git a/tests/language/regress/regress1363_runtime_test.dart b/tests/language/regress/regress1363_runtime_test.dart
new file mode 100644
index 0000000..9a73e4b
--- /dev/null
+++ b/tests/language/regress/regress1363_runtime_test.dart
@@ -0,0 +1,30 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+// VMOptions=--enable_type_checks
+
+library Issue1363Test.dart;
+
+import 'regress1363_lib.dart' as lib;
+
+main() {
+  new C().test();
+}
+
+class C {
+  late lib.Cup<lib.C> libCup;
+  late lib.Cup<C> myCup;
+
+  C();
+
+  test() {
+    myCup = new lib.Cup<C>(new C());
+    libCup = new lib.Cup<lib.C>(new lib.C());
+
+    C contents = myCup.getContents(); // expect no warning or error
+
+  }
+}
diff --git a/tests/language/regress/regress1363_test.dart b/tests/language/regress/regress1363_test.dart
new file mode 100644
index 0000000..a6cab7b
--- /dev/null
+++ b/tests/language/regress/regress1363_test.dart
@@ -0,0 +1,31 @@
+// 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.
+// VMOptions=--enable_type_checks
+
+library Issue1363Test.dart;
+
+import 'regress1363_lib.dart' as lib;
+
+main() {
+  new C().test();
+}
+
+class C {
+  late lib.Cup<lib.C> libCup;
+  late lib.Cup<C> myCup;
+
+  C();
+
+  test() {
+    myCup = new lib.Cup<C>(new C());
+    libCup = new lib.Cup<lib.C>(new lib.C());
+
+    C contents = myCup.getContents(); // expect no warning or error
+    contents = libCup.getContents();
+    //         ^^^^^^^^^^^^^^^^^^^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    //                ^
+    // [cfe] A value of type 'C/*1*/' can't be assigned to a variable of type 'C/*2*/'.
+  }
+}
diff --git a/tests/language/regress/regress13673_test.dart b/tests/language/regress/regress13673_test.dart
new file mode 100644
index 0000000..b510c61
--- /dev/null
+++ b/tests/language/regress/regress13673_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, 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";
+
+class Bar {
+  Type field;
+  Bar(this.field);
+  foo() => field;
+}
+
+dynamic topLevel = new Bar(String).foo();
+
+main() {
+  Expect.isTrue(topLevel is Type);
+}
diff --git a/tests/language/regress/regress14014_2_test.dart b/tests/language/regress/regress14014_2_test.dart
new file mode 100644
index 0000000..c1193b9
--- /dev/null
+++ b/tests/language/regress/regress14014_2_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, 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 that a type variable used in a parameter of a constructor that
+// has a closure in its initializer list does not lead to a crash in
+// dart2js.
+
+class A<T> {
+  A(f);
+}
+
+class B<T> extends A<T> {
+  B({void f(T foo)?})
+      : super((T a) {
+          f = (a) => 42;
+        });
+}
+
+main() {
+  var t = new B<int>();
+}
diff --git a/tests/language/regress/regress14014_3_test.dart b/tests/language/regress/regress14014_3_test.dart
new file mode 100644
index 0000000..72e93a2
--- /dev/null
+++ b/tests/language/regress/regress14014_3_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, 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 that an is check on a function type involving type parameters
+// does not crash dart2js, when the is test is in the initializer list
+// of a constructor.
+
+class A<T> {
+  var f;
+  A(this.f);
+}
+
+typedef foo<T>(T a);
+
+class B<T> extends A<T> {
+  B({required void f(T foo)}) : super(() => f is foo<T>);
+}
+
+main() {
+  var t = new B<int>(f: (int a) => 42);
+  if (!t.f()) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/regress/regress14014_test.dart b/tests/language/regress/regress14014_test.dart
new file mode 100644
index 0000000..c887a33
--- /dev/null
+++ b/tests/language/regress/regress14014_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, 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 A<T> {
+  A(f);
+}
+
+class B<T> extends A<T> {
+  B() : super((T param) => 42);
+}
+
+main() {
+  var t = new B<int>();
+}
diff --git a/tests/language/regress/regress14105_test.dart b/tests/language/regress/regress14105_test.dart
new file mode 100644
index 0000000..fe2179f
--- /dev/null
+++ b/tests/language/regress/regress14105_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for Issue 14105.
+
+typedef UsedAsFieldType();
+
+class ClassOnlyForRti {
+  UsedAsFieldType? field;
+}
+
+class A<T> {
+  var field;
+}
+
+use(a) => a.field = "";
+
+var useFieldSetter = use;
+
+main() {
+  var a = new A<ClassOnlyForRti>();
+  useFieldSetter(a);
+  print(a is A<int>);
+}
diff --git a/tests/language/regress/regress14242_test.dart b/tests/language/regress/regress14242_test.dart
new file mode 100644
index 0000000..118a8e0
--- /dev/null
+++ b/tests/language/regress/regress14242_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to crash on type literals
+// used in a cascade send.
+
+class A {
+  var bar;
+  var foo = {};
+}
+
+main() {
+  var a = new A();
+  a
+    ..foo[Object] = 54
+    ..bar = 42;
+  if (a.foo.keys.first is! Type) {
+    throw 'Test failed';
+  }
+}
diff --git a/tests/language/regress/regress14348_test.dart b/tests/language/regress/regress14348_test.dart
new file mode 100644
index 0000000..96ac17d
--- /dev/null
+++ b/tests/language/regress/regress14348_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 14348.
+
+import "package:collection/equality.dart";
+
+main() {
+  const Equality<Iterable> eq = const UnorderedIterableEquality();
+  const Equality<Map<dynamic, Iterable>> mapeq =
+      const MapEquality<dynamic, Iterable>(values: eq);
+}
diff --git a/tests/language/regress/regress15606_runtime_test.dart b/tests/language/regress/regress15606_runtime_test.dart
new file mode 100644
index 0000000..539a0d7
--- /dev/null
+++ b/tests/language/regress/regress15606_runtime_test.dart
@@ -0,0 +1,29 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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 Foo<T> {}
+
+var a = [new Object(), 42];
+
+bar(x, y) {}
+
+main() {
+  while (false) {
+    // Comply to inlining heuristics.
+    // Use an unresolved prefix.
+    var foo =
+
+        bar(
+      // Make dart2js generate a call to setRuntimeTypeInfo.
+      new Foo<int>(),
+      // Use a one-shot interceptor.
+      a[0].toString());
+
+    // Do an is test on `Foo` to require setRuntimeTypeInfo.
+    print(foo is Foo<int>);
+  }
+}
diff --git a/tests/language/regress/regress15606_test.dart b/tests/language/regress/regress15606_test.dart
new file mode 100644
index 0000000..3891202
--- /dev/null
+++ b/tests/language/regress/regress15606_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, 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 Foo<T> {}
+
+var a = [new Object(), 42];
+
+bar(x, y) {}
+
+main() {
+  while (false) {
+    // Comply to inlining heuristics.
+    // Use an unresolved prefix.
+    var foo =
+      Unresolved.
+//    ^^^^^^^^^^
+// [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+// [cfe] Getter not found: 'Unresolved'.
+        bar(
+      // Make dart2js generate a call to setRuntimeTypeInfo.
+      new Foo<int>(),
+      // Use a one-shot interceptor.
+      a[0].toString());
+
+    // Do an is test on `Foo` to require setRuntimeTypeInfo.
+    print(foo is Foo<int>);
+  }
+}
diff --git a/tests/language/regress/regress15702_test.dart b/tests/language/regress/regress15702_test.dart
new file mode 100644
index 0000000..072182d
--- /dev/null
+++ b/tests/language/regress/regress15702_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2013, 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.
+
+main() {
+  Amount stake = new Amount(2.5);
+  if ((stake.value * 10).toInt() != 25) {
+    throw 'Test failed';
+  }
+}
+
+class Amount {
+  num value;
+  Amount(this.value);
+}
diff --git a/tests/language/regress/regress15720_test.dart b/tests/language/regress/regress15720_test.dart
new file mode 100644
index 0000000..638fc98
--- /dev/null
+++ b/tests/language/regress/regress15720_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Regression test for dart2js, issue 15720.
+
+class B {}
+
+confuse(x) {
+  if (new DateTime.now() == 42) return confuse(x);
+  return x;
+}
+
+main() {
+  Set<B> set = new Set<B>.from([]);
+
+  confuse(499);
+  confuse(set);
+
+  // Dart2js used to reuse a variable name, overwriting the `set` variable with
+  // one of the B's.
+  var t1 = new B();
+  var t2 = new B();
+  var t3 = new B();
+  var t4 = new B();
+
+  set.addAll([t1, t2, t3, t4]);
+  confuse(7);
+
+  set.addAll([t1, t2, t3, t4]);
+}
diff --git a/tests/language/regress/regress1578_test.dart b/tests/language/regress/regress1578_test.dart
new file mode 100644
index 0000000..ad355ae
--- /dev/null
+++ b/tests/language/regress/regress1578_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Regression test for issue 1578.
+
+]~<)$
+// [error line 7, column 1, length 1]
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_EXECUTABLE
+// [cfe] Expected a declaration, but got ']'.
+// [error line 7, column 2, length 1]
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_EXECUTABLE
+// [cfe] Expected a declaration, but got '~'.
+//^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_EXECUTABLE
+// [cfe] Expected a declaration, but got '<'.
+// ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_EXECUTABLE
+// [cfe] Expected a declaration, but got ')'.
+//  ^
+// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
+// [cfe] Expected ';' after this.
+//  ^
+// [analyzer] SYNTACTIC_ERROR.MISSING_CONST_FINAL_VAR_OR_TYPE
+// [cfe] Variables must be declared using the keywords 'const', 'final', 'var' or a type name.
diff --git a/tests/language/regress/regress16640_test.dart b/tests/language/regress/regress16640_test.dart
new file mode 100644
index 0000000..8fe8399
--- /dev/null
+++ b/tests/language/regress/regress16640_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 16640.
+
+class Segment extends SegmentGen {}
+
+class SegmentGen extends ConceptEntity<Segment> {}
+
+class ConceptEntity<E> {}
+
+main() {
+  new ConceptEntity<Segment>();
+}
diff --git a/tests/language/regress/regress17382_test.dart b/tests/language/regress/regress17382_test.dart
new file mode 100644
index 0000000..275c1b8
--- /dev/null
+++ b/tests/language/regress/regress17382_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 17382.
+
+import 'package:expect/expect.dart';
+
+var mCalled = false;
+
+m(x) {
+  mCalled = true;
+  return x;
+}
+
+main() {
+  try {
+    tl(m(0)); /*@compile-error=unspecified*/
+  } catch (e) {}
+  Expect.isTrue(mCalled);
+}
diff --git a/tests/language/regress/regress1751477_lib1.dart b/tests/language/regress/regress1751477_lib1.dart
new file mode 100644
index 0000000..b0398a1
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib1.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib1;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib1_func() {}
diff --git a/tests/language/regress/regress1751477_lib11.dart b/tests/language/regress/regress1751477_lib11.dart
new file mode 100644
index 0000000..8b73628
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib11.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib11;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib11_func() {}
diff --git a/tests/language/regress/regress1751477_lib2.dart b/tests/language/regress/regress1751477_lib2.dart
new file mode 100644
index 0000000..61c0756
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib2.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib2;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib2_func() {}
diff --git a/tests/language/regress/regress1751477_lib21.dart b/tests/language/regress/regress1751477_lib21.dart
new file mode 100644
index 0000000..d3a8546
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib21.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib21;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib21_func() {}
diff --git a/tests/language/regress/regress1751477_lib3.dart b/tests/language/regress/regress1751477_lib3.dart
new file mode 100644
index 0000000..caec885
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib3.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib3;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib3_func() {}
diff --git a/tests/language/regress/regress1751477_lib31.dart b/tests/language/regress/regress1751477_lib31.dart
new file mode 100644
index 0000000..93412ad
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib31.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib31;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib31_func() {}
diff --git a/tests/language/regress/regress1751477_lib4.dart b/tests/language/regress/regress1751477_lib4.dart
new file mode 100644
index 0000000..e12cb88
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib4.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib4;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib4_func() {}
diff --git a/tests/language/regress/regress1751477_lib41.dart b/tests/language/regress/regress1751477_lib41.dart
new file mode 100644
index 0000000..a4c5536
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib41.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib41;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib41_func() {}
diff --git a/tests/language/regress/regress1751477_lib5.dart b/tests/language/regress/regress1751477_lib5.dart
new file mode 100644
index 0000000..2049e28
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib5.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib5;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib5_func() {}
diff --git a/tests/language/regress/regress1751477_lib51.dart b/tests/language/regress/regress1751477_lib51.dart
new file mode 100644
index 0000000..31bff9f
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib51.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib51;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib51_func() {}
diff --git a/tests/language/regress/regress1751477_lib6.dart b/tests/language/regress/regress1751477_lib6.dart
new file mode 100644
index 0000000..9255cfd
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib6.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib6;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib6_func() {}
diff --git a/tests/language/regress/regress1751477_lib61.dart b/tests/language/regress/regress1751477_lib61.dart
new file mode 100644
index 0000000..93a4ac3
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib61.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib61;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib61_func() {}
diff --git a/tests/language/regress/regress1751477_lib7.dart b/tests/language/regress/regress1751477_lib7.dart
new file mode 100644
index 0000000..35fe1d1
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib7.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib7;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib7_func() {}
diff --git a/tests/language/regress/regress1751477_lib71.dart b/tests/language/regress/regress1751477_lib71.dart
new file mode 100644
index 0000000..e80f0c5
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib71.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib71;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib71_func() {}
diff --git a/tests/language/regress/regress1751477_lib8.dart b/tests/language/regress/regress1751477_lib8.dart
new file mode 100644
index 0000000..e4240a0
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib8.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib8;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib8_func() {}
diff --git a/tests/language/regress/regress1751477_lib81.dart b/tests/language/regress/regress1751477_lib81.dart
new file mode 100644
index 0000000..050e005
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib81.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib81;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib91.dart';
+
+lib81_func() {}
diff --git a/tests/language/regress/regress1751477_lib9.dart b/tests/language/regress/regress1751477_lib9.dart
new file mode 100644
index 0000000..fea7a64
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib9.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib9;
+
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib1.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+import 'regress1751477_lib91.dart';
+
+lib9_func() {}
diff --git a/tests/language/regress/regress1751477_lib91.dart b/tests/language/regress/regress1751477_lib91.dart
new file mode 100644
index 0000000..d122125
--- /dev/null
+++ b/tests/language/regress/regress1751477_lib91.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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.
+
+library lib91;
+
+import 'regress1751477_lib1.dart';
+import 'regress1751477_lib2.dart';
+import 'regress1751477_lib3.dart';
+import 'regress1751477_lib4.dart';
+import 'regress1751477_lib5.dart';
+import 'regress1751477_lib6.dart';
+import 'regress1751477_lib7.dart';
+import 'regress1751477_lib8.dart';
+import 'regress1751477_lib9.dart';
+
+import 'regress1751477_lib11.dart';
+import 'regress1751477_lib21.dart';
+import 'regress1751477_lib31.dart';
+import 'regress1751477_lib41.dart';
+import 'regress1751477_lib51.dart';
+import 'regress1751477_lib61.dart';
+import 'regress1751477_lib71.dart';
+import 'regress1751477_lib81.dart';
+
+lib91_func() {}
diff --git a/tests/language/regress/regress1751477_test.dart b/tests/language/regress/regress1751477_test.dart
new file mode 100644
index 0000000..647fa90
--- /dev/null
+++ b/tests/language/regress/regress1751477_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, 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 'regress1751477_lib1.dart' deferred as lib1;
+import 'regress1751477_lib2.dart' deferred as lib2;
+import 'regress1751477_lib3.dart' deferred as lib3;
+import 'regress1751477_lib4.dart' deferred as lib4;
+import 'regress1751477_lib5.dart' deferred as lib5;
+import 'regress1751477_lib6.dart' deferred as lib6;
+import 'regress1751477_lib7.dart' deferred as lib7;
+import 'regress1751477_lib8.dart' deferred as lib8;
+import 'regress1751477_lib9.dart' deferred as lib9;
+
+main() {
+  lib1.loadLibrary().then((_) {
+    lib2.loadLibrary().then((_) {
+      lib3.loadLibrary().then((_) {
+        lib4.loadLibrary().then((_) {
+          lib5.loadLibrary().then((_) {
+            lib6.loadLibrary().then((_) {
+              lib7.loadLibrary().then((_) {
+                lib8.loadLibrary().then((_) {
+                  lib9.loadLibrary().then((_) {});
+                });
+              });
+            });
+          });
+        });
+      });
+    });
+  });
+}
diff --git a/tests/language/regress/regress18435_test.dart b/tests/language/regress/regress18435_test.dart
new file mode 100644
index 0000000..267562f
--- /dev/null
+++ b/tests/language/regress/regress18435_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 18435.
+
+import "package:expect/expect.dart";
+
+main() {
+  const MISSING_VALUE = "MISSING_VALUE";
+
+  void foo([var p1 = MISSING_VALUE, var p2 = MISSING_VALUE]) {
+    Expect.equals("P1", p1);
+    Expect.equals("P2", p2);
+  }
+
+  void bar([var p1 = "MISSING_VALUE", var p2 = "MISSING_VALUE"]) {
+    Expect.equals("P1", p1);
+    Expect.equals("P2", p2);
+  }
+
+  foo("P1", "P2");
+  bar("P1", "P2");
+}
diff --git a/tests/language/regress/regress18628_1_runtime_test.dart b/tests/language/regress/regress18628_1_runtime_test.dart
new file mode 100644
index 0000000..56d7377
--- /dev/null
+++ b/tests/language/regress/regress18628_1_runtime_test.dart
@@ -0,0 +1,23 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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.
+
+// This test checks for a regression found in Dart Editor: the
+// analyzer was treating [Type] as more specific than any type
+// variable (generic parameter).
+//
+// https://code.google.com/p/dart/issues/detail?id=18628
+
+class C<T> {
+  // This line is supposed to cause the warning; the other commented
+  // line just doesn't make sense without this line.
+
+}
+
+main() {
+  C<Type> c = new C<Type>();
+
+}
diff --git a/tests/language/regress/regress18628_1_test.dart b/tests/language/regress/regress18628_1_test.dart
new file mode 100644
index 0000000..3f2bef3
--- /dev/null
+++ b/tests/language/regress/regress18628_1_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2014, 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.
+
+// This test checks for a regression found in Dart Editor: the
+// analyzer was treating [Type] as more specific than any type
+// variable (generic parameter).
+//
+// https://code.google.com/p/dart/issues/detail?id=18628
+
+class C<T> {
+  // This line is supposed to cause the warning; the other commented
+  // line just doesn't make sense without this line.
+  T t = int;
+  //    ^^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  // [cfe] A value of type 'Type' can't be assigned to a variable of type 'T'.
+}
+
+main() {
+  C<Type> c = new C<Type>();
+  print(c.t);
+}
diff --git a/tests/language/regress/regress18628_2_runtime_test.dart b/tests/language/regress/regress18628_2_runtime_test.dart
new file mode 100644
index 0000000..d604adb
--- /dev/null
+++ b/tests/language/regress/regress18628_2_runtime_test.dart
@@ -0,0 +1,23 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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.
+
+// This test checks for a regression found in Dart Editor: the
+// analyzer was treating [Type] as more specific than any type
+// variable (generic parameter).
+//
+// https://code.google.com/p/dart/issues/detail?id=18628
+
+class X<T extends Type> {}
+
+// This line is supposed to cause the warning; the other lines are
+// marked because they don't make sense when [Y] is not defined.
+
+
+main() {
+
+
+}
diff --git a/tests/language/regress/regress18628_2_test.dart b/tests/language/regress/regress18628_2_test.dart
new file mode 100644
index 0000000..622b724
--- /dev/null
+++ b/tests/language/regress/regress18628_2_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, 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.
+
+// This test checks for a regression found in Dart Editor: the
+// analyzer was treating [Type] as more specific than any type
+// variable (generic parameter).
+//
+// https://code.google.com/p/dart/issues/detail?id=18628
+
+class X<T extends Type> {}
+
+// This line is supposed to cause the warning; the other lines are
+// marked because they don't make sense when [Y] is not defined.
+class Y<U> extends X<U> {}
+//    ^
+// [cfe] Type argument 'U' doesn't conform to the bound 'Type' of the type variable 'T' on 'X' in the supertype 'X' of class 'Y'.
+//                   ^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
+main() {
+  X<Type> x = new X<Type>();
+  Y<Type> y = new Y<Type>();
+}
diff --git a/tests/language/regress/regress18713_test.dart b/tests/language/regress/regress18713_test.dart
new file mode 100644
index 0000000..01f51d8
--- /dev/null
+++ b/tests/language/regress/regress18713_test.dart
@@ -0,0 +1,35 @@
+// Copyright (c) 2016, 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";
+
+class T<X> {
+  final Type tType = X;
+  Type get getTType => X;
+}
+
+class S<Y> {
+  final Type sType = Y;
+  Type get getSType => Y;
+}
+
+class TS<A, B> = T<A> with S<B>;
+
+@pragma('dart2js:noInline')
+@pragma('dart2js:assumeDynamic')
+dyn(x) => x;
+
+main() {
+  var ts = new TS<int, String>();
+
+  Expect.equals("String", ts.sType.toString());
+  Expect.equals("int", ts.tType.toString());
+  Expect.equals("String", ts.getSType.toString());
+  Expect.equals("int", ts.getTType.toString());
+
+  Expect.equals("String", dyn(ts).sType.toString());
+  Expect.equals("int", dyn(ts).tType.toString());
+  Expect.equals("String", dyn(ts).getSType.toString());
+  Expect.equals("int", dyn(ts).getTType.toString());
+}
diff --git a/tests/language/regress/regress18865_test.dart b/tests/language/regress/regress18865_test.dart
new file mode 100644
index 0000000..8727bb3
--- /dev/null
+++ b/tests/language/regress/regress18865_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 18865.
+
+class B<T> {}
+
+class A<T> extends B {
+  static foo() => new A();
+}
+
+main() {
+  A.foo();
+}
diff --git a/tests/language/regress/regress19413_bar.dart b/tests/language/regress/regress19413_bar.dart
new file mode 100644
index 0000000..98ef508
--- /dev/null
+++ b/tests/language/regress/regress19413_bar.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2014, 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.
+
+library bar;
+
+f() {
+  print('bar.f()');
+}
diff --git a/tests/language/regress/regress19413_foo.dart b/tests/language/regress/regress19413_foo.dart
new file mode 100644
index 0000000..b7e9a19
--- /dev/null
+++ b/tests/language/regress/regress19413_foo.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2014, 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.
+
+library foo;
+
+f() {
+  print('foo.f()');
+}
diff --git a/tests/language/regress/regress19413_test.dart b/tests/language/regress/regress19413_test.dart
new file mode 100644
index 0000000..eb0e2ad
--- /dev/null
+++ b/tests/language/regress/regress19413_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 19413.
+
+import 'regress19413_foo.dart' as foo;
+import 'regress19413_bar.dart' as foo;
+
+main() {
+  foo.f(); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/regress/regress19728_test.dart b/tests/language/regress/regress19728_test.dart
new file mode 100644
index 0000000..693962a
--- /dev/null
+++ b/tests/language/regress/regress19728_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 19728.
+
+class C<T extends dynamic> {
+  T? field;
+
+  test() {
+    field = 0; /*@compile-error=unspecified*/
+    int i = field; /*@compile-error=unspecified*/
+  }
+}
+
+void main() {
+  new C().test();
+}
diff --git a/tests/language/regress/regress20074_test.dart b/tests/language/regress/regress20074_test.dart
new file mode 100644
index 0000000..77623e1
--- /dev/null
+++ b/tests/language/regress/regress20074_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 20074. Check that a parameter is not declared
+// in the same scope as its function declaration.
+
+doit() {
+  error(error) {
+    print(error);
+  }
+
+  error('foobar');
+}
+
+main() {
+  doit();
+}
diff --git a/tests/language/regress/regress20394_lib.dart b/tests/language/regress/regress20394_lib.dart
new file mode 100644
index 0000000..ab5154b
--- /dev/null
+++ b/tests/language/regress/regress20394_lib.dart
@@ -0,0 +1,6 @@
+library lib;
+
+class Super {
+  Super();
+  Super._private(arg);
+}
diff --git a/tests/language/regress/regress20394_runtime_test.dart b/tests/language/regress/regress20394_runtime_test.dart
new file mode 100644
index 0000000..80da6ba
--- /dev/null
+++ b/tests/language/regress/regress20394_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+import 'regress20394_lib.dart';
+
+class M {}
+
+class C extends Super with M {
+
+}
+
+main() {
+  new C();
+}
diff --git a/tests/language/regress/regress20394_test.dart b/tests/language/regress/regress20394_test.dart
new file mode 100644
index 0000000..daff29b
--- /dev/null
+++ b/tests/language/regress/regress20394_test.dart
@@ -0,0 +1,14 @@
+import 'regress20394_lib.dart';
+
+class M {}
+
+class C extends Super with M {
+  C() : super._private(42);
+  //    ^^^^^^^^^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.UNDEFINED_CONSTRUCTOR_IN_INITIALIZER
+  // [cfe] Superclass has no constructor named 'Super._private'.
+}
+
+main() {
+  new C();
+}
diff --git a/tests/language/regress/regress20476_test.dart b/tests/language/regress/regress20476_test.dart
new file mode 100644
index 0000000..f0202be
--- /dev/null
+++ b/tests/language/regress/regress20476_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2014, 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';
+
+foo() {
+  try {
+    try {
+      return 1;
+    } catch (e1) {} finally {
+      return 3;
+    }
+  } catch (e2) {} finally {
+    return 5;
+  }
+}
+
+main() {
+  Expect.equals(5, foo());
+}
diff --git a/tests/language/regress/regress20840_test.dart b/tests/language/regress/regress20840_test.dart
new file mode 100644
index 0000000..8fb502c
--- /dev/null
+++ b/tests/language/regress/regress20840_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 20840.
+
+class SomeClass {
+  Object? someField;
+
+  SomeClass() {
+    [1].forEach((o) => someMethod());
+    someField = new Object();
+  }
+
+  void someMethod() {
+    if (someField != null) {
+      throw "FAIL";
+    }
+  }
+}
+
+void main() {
+  new SomeClass();
+}
diff --git a/tests/language/regress/regress21016_test.dart b/tests/language/regress/regress21016_test.dart
new file mode 100644
index 0000000..a8ca2d9
--- /dev/null
+++ b/tests/language/regress/regress21016_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2014, 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 that we give up on tracing a function if one of its closurizations
+// escapes tracing.
+
+class A {
+  var _boo = 22;
+  get boo {
+    return _boo;
+    return 1;
+  }
+}
+
+class B {
+  var _bar = 42;
+  get boo {
+    return _bar;
+    return 1;
+  }
+}
+
+class Holder {
+  tearMe(x) => x.boo;
+}
+
+var list = [];
+
+main() {
+  var holder = new Holder();
+  var hide = ((X) => X)(holder.tearMe);
+  hide(new A());
+  list.add(holder.tearMe);
+  var x = list[0];
+  x(new B());
+}
diff --git a/tests/language/regress/regress21793_runtime_test.dart b/tests/language/regress/regress21793_runtime_test.dart
new file mode 100644
index 0000000..4bdd03b
--- /dev/null
+++ b/tests/language/regress/regress21793_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 21793.
+
+import 'package:expect/expect.dart';
+
+
+class A {
+  call(x) => x;
+}
+
+
+main() {
+  print(new A()(499));
+}
diff --git a/tests/language/regress/regress21793_test.dart b/tests/language/regress/regress21793_test.dart
new file mode 100644
index 0000000..d767690
--- /dev/null
+++ b/tests/language/regress/regress21793_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, 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.
+
+// Regression test for issue 21793.
+
+import 'package:expect/expect.dart';
+
+/*
+class A {
+  call(x) => x;
+}
+*/
+
+main() {
+  print(new A()(499));
+  //        ^
+  // [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+  // [cfe] Method not found: 'A'.
+}
diff --git a/tests/language/regress/regress21795_test.dart b/tests/language/regress/regress21795_test.dart
new file mode 100644
index 0000000..2ca18a3
--- /dev/null
+++ b/tests/language/regress/regress21795_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 21795.
+
+@pragma("vm:entry-point") // Prevent obfuscation
+foo(t) {
+  try {
+    if (t == 123) throw 42;
+  } finally {}
+}
+
+bar() {
+  try {
+    return 42;
+  } finally {}
+}
+
+class A {
+  test(t) {
+    try {
+      foo(t);
+    } finally {
+      if (t == 0) {
+        try {} catch (err, st) {}
+      }
+    }
+  }
+}
+
+main() {
+  var a = new A();
+  for (var i = 0; i < 10000; ++i) a.test(0);
+  try {
+    a.test(123);
+  } catch (e, s) {
+    if (s.toString().indexOf("foo") == -1) {
+      print(s);
+      throw "Expected foo in stacktrace!";
+    }
+  }
+}
diff --git a/tests/language/regress/regress21912_runtime_test.dart b/tests/language/regress/regress21912_runtime_test.dart
new file mode 100644
index 0000000..e44b17f
--- /dev/null
+++ b/tests/language/regress/regress21912_runtime_test.dart
@@ -0,0 +1,26 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 21912.
+
+class A {}
+
+class B extends A {}
+
+typedef T Function2<S, T>(S z);
+typedef B AToB(A x);
+typedef A BToA(B x);
+
+void main() {
+  {
+    Function2<Function2<A, B>, Function2<B, A>> t1;
+    Function2<AToB, BToA> t2;
+    Function2<Function2<int, double>, Function2<int, double>> left;
+
+
+  }
+}
diff --git a/tests/language/regress/regress21912_test.dart b/tests/language/regress/regress21912_test.dart
new file mode 100644
index 0000000..6ba343ca5
--- /dev/null
+++ b/tests/language/regress/regress21912_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 21912.
+
+class A {}
+
+class B extends A {}
+
+typedef T Function2<S, T>(S z);
+typedef B AToB(A x);
+typedef A BToA(B x);
+
+void main() {
+  test(
+      Function2<Function2<A, B>, Function2<B, A>> t1,
+      Function2<AToB, BToA> t2,
+      Function2<Function2<int, double>, Function2<int, double>> left) {
+    left = t1;
+    //     ^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    // [cfe] A value of type 'A Function(B) Function(B Function(A))' can't be assigned to a variable of type 'double Function(int) Function(double Function(int))'.
+    left = t2;
+    //     ^^
+    // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+    // [cfe] A value of type 'A Function(B) Function(B Function(A))' can't be assigned to a variable of type 'double Function(int) Function(double Function(int))'.
+  }
+}
diff --git a/tests/language/regress/regress21957_double_test.dart b/tests/language/regress/regress21957_double_test.dart
new file mode 100644
index 0000000..d2920a4
--- /dev/null
+++ b/tests/language/regress/regress21957_double_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2014, 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.
+
+// Check slow path for PotentialUnboxedStore.
+// VMOptions=--optimization_counter_threshold=-1
+
+main() {
+  for (int i = 0; i < 1000000; i++) {
+    new A();
+  }
+}
+
+class A {
+  var a = 1.0;
+}
diff --git a/tests/language/regress/regress21957_float32x4_test.dart b/tests/language/regress/regress21957_float32x4_test.dart
new file mode 100644
index 0000000..f364261
--- /dev/null
+++ b/tests/language/regress/regress21957_float32x4_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Check slow path for PotentialUnboxedStore.
+// VMOptions=--optimization_counter_threshold=-1
+
+import "dart:typed_data";
+
+main() {
+  for (int i = 0; i < 1000000; i++) {
+    new A();
+  }
+}
+
+class A {
+  var a = new Float32x4(1.0, 2.0, 3.0, 4.0);
+}
diff --git a/tests/language/regress/regress21957_float64x2_test.dart b/tests/language/regress/regress21957_float64x2_test.dart
new file mode 100644
index 0000000..5b51722
--- /dev/null
+++ b/tests/language/regress/regress21957_float64x2_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Check slow path for PotentialUnboxedStore.
+// VMOptions=--optimization_counter_threshold=-1
+
+import "dart:typed_data";
+
+main() {
+  for (int i = 0; i < 1000000; i++) {
+    new A();
+  }
+}
+
+class A {
+  var a = new Float64x2(1.0, 2.0);
+}
diff --git a/tests/language/regress/regress21998_1_test.dart b/tests/language/regress/regress21998_1_test.dart
new file mode 100644
index 0000000..132877e
--- /dev/null
+++ b/tests/language/regress/regress21998_1_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, 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:math' as Math;
+import 'package:expect/expect.dart';
+
+main() {
+  Expect.equals(4, new C().m());
+}
+
+class C {
+  max(a) => a;
+
+  m() {
+    return max(Math.max(2, 4));
+  }
+}
diff --git a/tests/language/regress/regress21998_2_test.dart b/tests/language/regress/regress21998_2_test.dart
new file mode 100644
index 0000000..9214d6b
--- /dev/null
+++ b/tests/language/regress/regress21998_2_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2015, 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:math' as Math;
+import 'package:expect/expect.dart';
+import 'regress21998_lib1.dart' as lib1;
+
+main() {
+  Expect.equals(4, new C().m());
+}
+
+class C {
+  max(a) => a;
+
+  m() {
+    return max(Math.max(2, lib1.max('a', 'b', 'cd').length));
+  }
+}
diff --git a/tests/language/regress/regress21998_3_test.dart b/tests/language/regress/regress21998_3_test.dart
new file mode 100644
index 0000000..ebd3782
--- /dev/null
+++ b/tests/language/regress/regress21998_3_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2015, 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:math' as Math;
+import 'package:expect/expect.dart';
+import 'regress21998_lib1.dart' as lib1;
+import 'regress21998_lib2.dart';
+
+main() {
+  Expect.equals(4, new C().m());
+}
+
+class C {
+  max(a) => a;
+
+  m() {
+    return max(
+        Math.max<num>(lib2_max(1, 2), lib1.max('a', 'b', 'cd').length));
+  }
+}
diff --git a/tests/language/regress/regress21998_4_test.dart b/tests/language/regress/regress21998_4_test.dart
new file mode 100644
index 0000000..6bc8c03
--- /dev/null
+++ b/tests/language/regress/regress21998_4_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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:math' as Math;
+import 'package:expect/expect.dart';
+import 'regress21998_lib1.dart' as lib1;
+import 'regress21998_lib2.dart';
+import 'regress21998_lib3.dart';
+
+main() {
+  Expect.equals(4, new C().m());
+}
+
+class C {
+  max(a) => a;
+
+  m() {
+    return max(Math.max<num>(
+        lib3_max(0, lib2_max(1, 2)), lib1.max('a', 'b', 'cd').length));
+  }
+}
diff --git a/tests/language/regress/regress21998_lib1.dart b/tests/language/regress/regress21998_lib1.dart
new file mode 100644
index 0000000..29750b6
--- /dev/null
+++ b/tests/language/regress/regress21998_lib1.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+library regress_21998_lib1;
+
+String max(String a, String b, String c) => '$a$b$c';
diff --git a/tests/language/regress/regress21998_lib2.dart b/tests/language/regress/regress21998_lib2.dart
new file mode 100644
index 0000000..83117f9
--- /dev/null
+++ b/tests/language/regress/regress21998_lib2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, 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.
+
+library regress_21998_lib2;
+
+import 'dart:math';
+
+lib2_max(a, b) => max<num>(a, b);
diff --git a/tests/language/regress/regress21998_lib3.dart b/tests/language/regress/regress21998_lib3.dart
new file mode 100644
index 0000000..33ea88f
--- /dev/null
+++ b/tests/language/regress/regress21998_lib3.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, 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.
+
+library regress_21998_lib3;
+
+import 'dart:math' as math;
+
+lib3_max(a, b) => math.max<num>(a, b);
diff --git a/tests/language/regress/regress22438_test.dart b/tests/language/regress/regress22438_test.dart
new file mode 100644
index 0000000..849610d
--- /dev/null
+++ b/tests/language/regress/regress22438_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+
+main() async {
+  Object error = "no error";
+  try {
+    try {
+      await new Future.error("error");
+    } on MissingType catch (e) {} /*@compile-error=unspecified*/
+  } catch (e) {
+    error = e;
+  }
+  Expect.isTrue(error is TypeError);
+}
diff --git a/tests/language/regress/regress22443_lib.dart b/tests/language/regress/regress22443_lib.dart
new file mode 100644
index 0000000..879d5f7
--- /dev/null
+++ b/tests/language/regress/regress22443_lib.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+library regress_22443;
+
+class LazyClass {}
diff --git a/tests/language/regress/regress22443_test.dart b/tests/language/regress/regress22443_test.dart
new file mode 100644
index 0000000..81a1e5d
--- /dev/null
+++ b/tests/language/regress/regress22443_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, 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 'regress22443_lib.dart' deferred as D;
+import 'package:expect/expect.dart';
+
+int fooCount = 0;
+
+foo() {
+  fooCount++;
+  return new D.LazyClass();
+}
+
+main() {
+  var caughtIt = false;
+  try {
+    foo();
+  } catch (e) {
+    caughtIt = true;
+  }
+  D.loadLibrary().then((_) {
+    foo();
+    Expect.isTrue(caughtIt);
+    Expect.equals(2, fooCount);
+  });
+}
diff --git a/tests/language/regress/regress22445_test.dart b/tests/language/regress/regress22445_test.dart
new file mode 100644
index 0000000..e0570ad
--- /dev/null
+++ b/tests/language/regress/regress22445_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+
+foo() async {
+  try {
+    print("a");
+    await new Future.value(3);
+    print("b");
+    throw "Error";
+    print("c");
+  } catch (e) {
+    print("d");
+    await new Future.error("Error2");
+  } finally {
+    print("e");
+  }
+  print("f");
+}
+
+main() async {
+  Object error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("Error2", error);
+}
diff --git a/tests/language/regress/regress22579_test.dart b/tests/language/regress/regress22579_test.dart
new file mode 100644
index 0000000..f320581
--- /dev/null
+++ b/tests/language/regress/regress22579_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+
+foo() async {
+  try {
+    await 1;
+  } catch (e) {}
+  throw "error";
+}
+
+main() async {
+  Object error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("error", error);
+}
diff --git a/tests/language/regress/regress22666_test.dart b/tests/language/regress/regress22666_test.dart
new file mode 100644
index 0000000..432ec7c
--- /dev/null
+++ b/tests/language/regress/regress22666_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2015, 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';
+
+class A extends Object with LinkedListEntry<A> {}
+
+main() => new A();
diff --git a/tests/language/regress/regress22700_test.dart b/tests/language/regress/regress22700_test.dart
new file mode 100644
index 0000000..c0a005b
--- /dev/null
+++ b/tests/language/regress/regress22700_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2015, 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";
+
+class WrapT<T> {
+  Type get type => T;
+}
+
+printAndCheck(t) {
+  print(t);
+  Expect.equals(String, t);
+}
+
+class MyClass<T> {
+  factory MyClass.works() {
+    Type t = new WrapT<T>().type;
+    printAndCheck(t);
+    return MyClass._();
+  }
+
+  factory MyClass.works2() {
+    printAndCheck(T);
+    return MyClass._();
+  }
+
+  MyClass._();
+}
+
+main() {
+  new MyClass<String>.works();
+  new MyClass<String>.works2();
+}
diff --git a/tests/language/regress/regress22719_test.dart b/tests/language/regress/regress22719_test.dart
new file mode 100644
index 0000000..13310ef
--- /dev/null
+++ b/tests/language/regress/regress22719_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2015, 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';
+
+abstract class A {}
+
+abstract class B extends Object with IterableMixin<int> {
+  Iterator<int> get iterator;
+}
+
+abstract class C extends A with IterableMixin<int> implements B {
+  final list = [1, 2, 3, 4, 5];
+  Iterator<int> get iterator => list.iterator;
+}
+
+class D extends C {}
+
+void main() {
+  var d = new D();
+  var expected = 1;
+  for (var i in d) {
+    Expect.equals(expected, i);
+    expected += 1;
+  }
+}
diff --git a/tests/language/regress/regress22728_test.dart b/tests/language/regress/regress22728_test.dart
new file mode 100644
index 0000000..b4f32c5
--- /dev/null
+++ b/tests/language/regress/regress22728_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2015, 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';
+
+bool assertsChecked() {
+  bool checked = false;
+  try {
+    assert(false);
+  } on AssertionError catch (error) {
+    checked = true;
+  }
+  return checked;
+}
+
+main() async {
+  bool fault = false;
+  try {
+    assert(await false);
+  } on AssertionError catch (error) {
+    fault = true;
+  }
+  Expect.equals(assertsChecked(), fault);
+}
diff --git a/tests/language/regress/regress22777_test.dart b/tests/language/regress/regress22777_test.dart
new file mode 100644
index 0000000..38bc24b
--- /dev/null
+++ b/tests/language/regress/regress22777_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2015, 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:async_helper/async_helper.dart";
+import "package:expect/expect.dart";
+
+var a = 0;
+
+testSync() {
+  do {
+    continue;
+  } while (throw "Error");
+  a = 100;
+}
+
+testAsync() async {
+  do {
+    continue;
+  } while (await (throw "Error"));
+  a = 100;
+}
+
+test() async {
+  try {
+    testSync();
+  } catch (e) {
+    Expect.equals(e, "Error");
+  }
+  Expect.equals(a, 0);
+
+  try {
+    await testAsync();
+  } catch (e) {
+    Expect.equals(e, "Error");
+  }
+  Expect.equals(a, 0);
+}
+
+main() {
+  asyncStart();
+  test().then((_) => asyncEnd());
+}
diff --git a/tests/language/regress/regress22780_test.dart b/tests/language/regress/regress22780_test.dart
new file mode 100644
index 0000000..34dabd6
--- /dev/null
+++ b/tests/language/regress/regress22780_test.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2015, 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.
+
+main() {
+  f() => "Oh, the joy of ${f()}"; print(f()); //# 01: runtime error
+}
diff --git a/tests/language/regress/regress22800_test.dart b/tests/language/regress/regress22800_test.dart
new file mode 100644
index 0000000..36b6978
--- /dev/null
+++ b/tests/language/regress/regress22800_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2015, 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.
+
+// Check proper exception handler finalization, even for unreachable handlers.
+
+void main() {
+  try {
+    print("Starting here");
+    throw 0;
+    try {} catch (e) {}
+  } catch (e) {
+    print("Caught in here: $e");
+  }
+  try {} catch (e) {}
+}
diff --git a/tests/language/regress/regress22822_test.dart b/tests/language/regress/regress22822_test.dart
new file mode 100644
index 0000000..ad990c7
--- /dev/null
+++ b/tests/language/regress/regress22822_test.dart
@@ -0,0 +1,27 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 22822. The assignment in the finally block
+// used to crash because it was executed at context level 1 instead of
+// context level 2.
+
+import 'package:expect/expect.dart';
+
+test(b) {
+  try {
+    for (int i = 0; i < 10; i++) {
+      // Closurizing i and b, thus the return statement
+      // executes at context level 2, and the code in
+      // the finally block runs at context level 1.
+      return () => i + b;
+    }
+  } finally {
+    b = 10;
+  }
+}
+
+main() {
+  var c = test(0);
+  Expect.equals(10, c());
+}
diff --git a/tests/language/regress/regress22858_test.dart b/tests/language/regress/regress22858_test.dart
new file mode 100644
index 0000000..d685ce2
--- /dev/null
+++ b/tests/language/regress/regress22858_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2015, 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';
+
+main() {
+  var good = "good";
+
+  f1() {
+    {
+      var bad = "bad";
+      f2() {
+        bad;
+      }
+    }
+
+    Expect.equals("good", good);
+    do {
+      Expect.equals("good", good);
+      int ugly = 0;
+      f3() {
+        ugly;
+      }
+    } while (false);
+  }
+
+  f1();
+}
diff --git a/tests/language/regress/regress22936_test.dart b/tests/language/regress/regress22936_test.dart
new file mode 100644
index 0000000..878e7c4
--- /dev/null
+++ b/tests/language/regress/regress22936_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 22936.
+
+import 'package:expect/expect.dart';
+
+bool fooCalled = false;
+
+foo() {
+  fooCalled = true;
+  return null;
+}
+
+main() {
+  final x = null;
+  try {
+    x = /*@compile-error=unspecified*/ foo();
+  } on NoSuchMethodError {}
+  Expect.isTrue(fooCalled);
+}
diff --git a/tests/language/regress/regress22976_test.dart b/tests/language/regress/regress22976_test.dart
new file mode 100644
index 0000000..63180f8
--- /dev/null
+++ b/tests/language/regress/regress22976_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 22976.
+
+class A<T> {}
+
+class B<T> implements A<T> {}
+
+class C<S, T> implements B<S>, A<T> {}
+// [error line 11, column 1, length 38]
+// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_GENERIC_INTERFACES
+//    ^
+// [cfe] 'C' can't implement both 'A<S>' and 'A<T>'
+
+main() {
+  C<int, String> c1 = new C<int, String>();
+  C<String, int> c2 = new C<String, int>();
+  A<int> a0 = c1;
+  A<int> a1 = c2;
+  //          ^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  //          ^
+  // [cfe] A value of type 'C<String, int>' can't be assigned to a variable of type 'A<int>'.
+}
diff --git a/tests/language/regress/regress23038_runtime_test.dart b/tests/language/regress/regress23038_runtime_test.dart
new file mode 100644
index 0000000..fb22db1
--- /dev/null
+++ b/tests/language/regress/regress23038_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2015, 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 C<T> {
+  const
+
+  C()
+
+  ;
+}
+
+main() {
+  const C<int>();
+}
diff --git a/tests/language/regress/regress23038_test.dart b/tests/language/regress/regress23038_test.dart
new file mode 100644
index 0000000..bf5cbd0
--- /dev/null
+++ b/tests/language/regress/regress23038_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2015, 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 C<T> {
+  const
+    factory
+  C()
+//^
+// [cfe] Cyclic definition of factory 'C'.
+    = C<C<T>>
+    //^^^^^^^
+    // [analyzer] COMPILE_TIME_ERROR.RECURSIVE_FACTORY_REDIRECT
+    // [cfe] The constructor function type 'C<C<T>> Function()' isn't a subtype of 'C<T> Function()'.
+  ;
+}
+
+main() {
+  const C<int>();
+}
diff --git a/tests/language/regress/regress23046_test.dart b/tests/language/regress/regress23046_test.dart
new file mode 100644
index 0000000..e5dcdc4
--- /dev/null
+++ b/tests/language/regress/regress23046_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2015, 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";
+
+// Make sure the logic for skipping the initial quotes in a string isn't
+// re-triggered after an interpolation expression.
+
+const String x = '$y"';
+const String y = 'foo';
+const Map m = const {x: 0, y: 1};
+
+main() {
+  Expect.equals(x, 'foo"');
+  Expect.equals(m.length, 2);
+}
diff --git a/tests/language/regress/regress23051_test.dart b/tests/language/regress/regress23051_test.dart
new file mode 100644
index 0000000..f9837de
--- /dev/null
+++ b/tests/language/regress/regress23051_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2015, 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.
+
+// Regression test for issue 23051.
+
+main() {
+  new A(); //                                //# 01: continued
+}
+
+class A { //                                 //# 01: continued
+  // Note the trailing ' in the next line.   //# 01: continued
+  get foo => bar();' //                      //# 01: syntax error
+  //                                         //# 01: continued
+  String bar( //                             //# 01: continued
diff --git a/tests/language/regress/regress23089_test.dart b/tests/language/regress/regress23089_test.dart
new file mode 100644
index 0000000..2718475
--- /dev/null
+++ b/tests/language/regress/regress23089_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2015, 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 doesn't cover http://dartbug.com/23089 anymore.
+// Generic bounds now must be fully instantiated. This means that the
+// cycle is not possible anymore.
+
+abstract class IPeer<C extends IP2PClient /*@compile-error=unspecified*/ > {}
+
+abstract class IPeerRoom<P extends IPeer, C extends IP2PClient> {}
+
+abstract class IP2PClient<R extends IPeerRoom> {}
+
+class _Peer<C extends _P2PClient> implements IPeer<C> {}
+
+class _PeerRoom<P extends _Peer, C extends _P2PClient>
+    implements IPeerRoom<P, C> {}
+
+abstract class _P2PClient<R extends _PeerRoom, P extends _Peer>
+    implements IP2PClient<R> {}
+
+void main() {}
diff --git a/tests/language/regress/regress23244_test.dart b/tests/language/regress/regress23244_test.dart
new file mode 100644
index 0000000..6a25b57
--- /dev/null
+++ b/tests/language/regress/regress23244_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2013, 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.
+
+// VMOptions=--enable-isolate-groups
+// VMOptions=--no-enable-isolate-groups
+
+// Regression test case for http://dartbug.com/23244
+import 'dart:async';
+import 'dart:isolate';
+import 'package:async_helper/async_helper.dart';
+
+enum Fisk {
+  torsk,
+}
+
+isolate1(Object port) {
+  (port as SendPort).send(Fisk.torsk);
+}
+
+isolate2(Object port) {
+  (port as SendPort).send([Fisk.torsk]);
+}
+
+isolate3(Object port) {
+  var x = new Map<int, Fisk>();
+  x[0] = Fisk.torsk;
+  x[1] = Fisk.torsk;
+  (port as SendPort).send(x);
+}
+
+main() async {
+  var port = new ReceivePort();
+  asyncStart();
+  await Isolate.spawn(isolate1, port.sendPort);
+  Completer completer1 = new Completer();
+  port.listen((message) {
+    print("Received $message");
+    port.close();
+    expectTorsk(message);
+    completer1.complete();
+  });
+  await completer1.future;
+  Completer completer2 = new Completer();
+  port = new ReceivePort();
+  await Isolate.spawn(isolate2, port.sendPort);
+  port.listen((message) {
+    print("Received $message");
+    port.close();
+    expectTorsk(message[0]);
+    completer2.complete();
+  });
+  await completer2.future;
+  port = new ReceivePort();
+  await Isolate.spawn(isolate3, port.sendPort);
+  port.listen((message) {
+    print("Received $message");
+    port.close();
+    expectTorsk(message[0]);
+    expectTorsk(message[1]);
+    asyncEnd();
+  });
+}
+
+expectTorsk(Fisk fisk) {
+  if (fisk != Fisk.torsk) {
+    throw "$fisk isn't a ${Fisk.torsk}";
+  }
+}
diff --git a/tests/language/regress/regress23408_lib.dart b/tests/language/regress/regress23408_lib.dart
new file mode 100644
index 0000000..564c2eb
--- /dev/null
+++ b/tests/language/regress/regress23408_lib.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, 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.
+
+library regress_23408_lib;
+
+import "regress23408_test.dart" as main;
+
+class K extends main.C {
+  K();
+}
diff --git a/tests/language/regress/regress23408_test.dart b/tests/language/regress/regress23408_test.dart
new file mode 100644
index 0000000..1ad8c55
--- /dev/null
+++ b/tests/language/regress/regress23408_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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.
+
+library regress_23408_test;
+
+import 'package:expect/expect.dart';
+
+import 'regress23408_lib.dart' deferred as lib;
+
+class C {
+  var v = 55;
+  C();
+  factory C.c() = lib.K;
+}
+
+void main() {
+  lib.loadLibrary().then((_) {
+    var z = new C.c();
+    Expect.equals(55, z.v);
+  });
+}
diff --git a/tests/language/regress/regress23408a_test.dart b/tests/language/regress/regress23408a_test.dart
new file mode 100644
index 0000000..b8fd7a4
--- /dev/null
+++ b/tests/language/regress/regress23408a_test.dart
@@ -0,0 +1,27 @@
+// 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.
+
+library regress_23408a_test;
+
+import 'package:expect/expect.dart';
+
+import 'regress23408_lib.dart' deferred as lib;
+
+class A<T> extends C {
+  get t => T;
+}
+
+class C {
+  C();
+  factory C.l() = A<lib.K>;
+  //                ^^^^^
+  // [analyzer] STATIC_WARNING.TYPE_ANNOTATION_DEFERRED_CLASS
+  // [cfe] unspecified
+  get t => null;
+}
+
+void main() async {
+  await lib.loadLibrary();
+  Expect.equals(lib.K, C.l().t);
+}
diff --git a/tests/language/regress/regress23498_test.dart b/tests/language/regress/regress23498_test.dart
new file mode 100644
index 0000000..b7076ae
--- /dev/null
+++ b/tests/language/regress/regress23498_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+
+foo() async {
+  try {
+    try {
+      await new Future.error('error');
+    } catch (error) {
+      print("caught once");
+      throw 'error';
+    }
+  } catch (error) {
+    print("caught twice");
+    throw 'error';
+  }
+}
+
+main() async {
+  Object error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("error", error);
+}
diff --git a/tests/language/regress/regress23500_test.dart b/tests/language/regress/regress23500_test.dart
new file mode 100644
index 0000000..6278fd6
--- /dev/null
+++ b/tests/language/regress/regress23500_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+
+foo() async {
+  try {
+    try {
+      await for (var c in new Stream.fromIterable([])) {} // //# 01: ok
+      await 0; // //# 02: ok
+    } catch (error) {}
+  } catch (error) {}
+  throw "error";
+}
+
+main() async {
+  Object error = "no error";
+  try {
+    await foo();
+  } catch (e) {
+    error = e;
+  }
+  Expect.equals("error", error);
+}
diff --git a/tests/language/regress/regress23537_test.dart b/tests/language/regress/regress23537_test.dart
new file mode 100644
index 0000000..c8c6667
--- /dev/null
+++ b/tests/language/regress/regress23537_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2015, 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';
+
+var d;
+
+test(a) {
+  while (true) {
+    try {
+      var b;
+      try {
+        for (int i = 0; i < 10; i++) {
+          // Closurizing i, a, and b, thus the return statement
+          // executes at context level 3, and the code in
+          // the finally blocks runs at context level 1 and 2.
+          return () => i + a + b;
+        }
+      } finally {
+        b = 10;
+        while (true) {
+          // Chain a new context.
+          var c = 5;
+          d = () => a + b + c;
+          break;
+        }
+      }
+    } finally {
+      a = 1;
+    }
+    break;
+  }
+}
+
+main() {
+  var c = test(0);
+  Expect.equals(11, c());
+  Expect.equals(16, d());
+}
diff --git a/tests/language/regress/regress23650_test.dart b/tests/language/regress/regress23650_test.dart
new file mode 100644
index 0000000..1684736
--- /dev/null
+++ b/tests/language/regress/regress23650_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2015, 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 that type variables in try-catch work.
+
+import "package:expect/expect.dart";
+
+class C<T> {
+  C.foo();
+  factory C() {
+    try {
+      return new C<T>.foo();
+    } finally {}
+  }
+}
+
+main() {
+  var c = new C<int>();
+  Expect.isTrue(c is C<int>);
+  Expect.isFalse(c is C<String>);
+}
diff --git a/tests/language/regress/regress23914_test.dart b/tests/language/regress/regress23914_test.dart
new file mode 100644
index 0000000..5ba0335
--- /dev/null
+++ b/tests/language/regress/regress23914_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, 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';
+
+class C extends LinkedListEntry<C> {}
+
+main() {
+  var ll = new LinkedList<C>();
+  var a = new List.unmodifiable(ll);
+}
diff --git a/tests/language/regress/regress23996_test.dart b/tests/language/regress/regress23996_test.dart
new file mode 100644
index 0000000..4401a46
--- /dev/null
+++ b/tests/language/regress/regress23996_test.dart
@@ -0,0 +1,77 @@
+// Copyright (c) 2016, 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:async_helper/async_helper.dart";
+
+/// This test verifies that an await for loop sends the correct
+/// signals to the stream it iterates over:
+/// 1) A listen event.
+/// 2) A pause event when the loop body is awaiting something,
+///    and more elements arrive on the stream.  See issue
+///    https://github.com/dart-lang/sdk/issues/23996 .
+/// 3) A resume event, when the loop is again ready to iterate.
+main() {
+  Completer listenEventReceived = new Completer();
+  Completer pauseEventReceived = new Completer();
+  Completer resumeEventReceived = new Completer();
+  StreamController controller = new StreamController(
+      onListen: () => listenEventReceived.complete(),
+      onPause: () => pauseEventReceived.complete(),
+      onResume: () => resumeEventReceived.complete());
+
+  Completer forLoopEntered = new Completer();
+
+  /// The send function puts items on the stream. It waits for a
+  /// listener, puts "first" on the stream, waits for the for loop
+  /// to start (and eventually block), puts "second" on the stream
+  /// multiple times, letting the event loop run, until the for loop
+  /// pauses the stream because it it blocked.
+  /// The for loop unblocks after the pause message is received, and
+  /// reads the stream items, sending a stream resume message when it
+  /// is ready for more.
+  /// Then the send function puts a final "third" on the stream, and
+  /// closes the stream.
+  send() async {
+    await listenEventReceived.future;
+    controller.add('first');
+    await forLoopEntered.future;
+    var timer = new Timer.periodic(new Duration(milliseconds: 10), (timer) {
+      controller.add('second');
+    });
+    await pauseEventReceived.future;
+    // pauseEventReceived.future completes when controller.stream is
+    // paused by the await-for loop below. What's specified is that
+    // await-for must pause immediately on an "await", but instead
+    // the implementations agree on not pausing until receiving the
+    // next event. For this reason, [timer] will call its callback at
+    // least once before we cancel it again.
+    timer.cancel();
+    await resumeEventReceived.future;
+    controller.add('third');
+    controller.close();
+  }
+
+  receive() async {
+    bool thirdReceived = false;
+    await for (var entry in controller.stream) {
+      if (entry == 'first') {
+        forLoopEntered.complete();
+        await pauseEventReceived.future;
+      } else if (entry == 'third') {
+        thirdReceived = true;
+      }
+    }
+    if (!thirdReceived) {
+      throw "Error in await-for loop: 'third' not received";
+    }
+  }
+
+  asyncTest(() async {
+    // We need to start both functions in parallel, and wait on them both.
+    var f = send();
+    await receive();
+    await f;
+  });
+}
diff --git a/tests/language/regress/regress24283_test.dart b/tests/language/regress/regress24283_test.dart
new file mode 100644
index 0000000..056bfd8
--- /dev/null
+++ b/tests/language/regress/regress24283_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2015, 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";
+
+main() {
+  // Smi
+  var i = 1 << 30;
+  var j = -i;
+  Expect.equals(0, i >> 37);
+  Expect.equals(-1, j >> 37);
+  // Mint
+  i = 1 << 50;
+  j = -i;
+  Expect.equals(0, i >> 67);
+  Expect.equals(-1, j >> 67);
+}
diff --git a/tests/language/regress/regress24567_test.dart b/tests/language/regress/regress24567_test.dart
new file mode 100644
index 0000000..8010da7
--- /dev/null
+++ b/tests/language/regress/regress24567_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, 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 'dart:math' as math;
+
+class Random {}
+
+typedef F(Random r);
+
+main() {
+  f(Random r) {}
+  g(math.Random r) {}
+  Expect.isTrue(f is F);
+  Expect.isFalse(g is F);
+}
diff --git a/tests/language/regress/regress24935_test.dart b/tests/language/regress/regress24935_test.dart
new file mode 100644
index 0000000..430629f
--- /dev/null
+++ b/tests/language/regress/regress24935_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2016, 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';
+
+S() => new Stream.fromIterable([1]);
+
+Future main() async {
+  L:
+  for (var s = 0; s < 10; s++) {
+    await for (var s1 in S()) {
+      await for (var s2 in S()) {
+        continue L;
+      }
+    }
+  }
+  // Regression check: make sure throwing an exception
+  // after breaking out of the innermost loop does not
+  // crash the VM. In other words, the expected test
+  // outcome is an unhandled exception.
+  throw "ball"; //# 01: runtime error
+}
diff --git a/tests/language/regress/regress25122_test.dart b/tests/language/regress/regress25122_test.dart
new file mode 100644
index 0000000..b7d4068
--- /dev/null
+++ b/tests/language/regress/regress25122_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2015, 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.
+
+main() {}
+
+class AbstractListMember<E, M extends AbstractListMember<E, M>> {}
+
+class RepoListMember<M extends RepoListMember<M>>
+    extends AbstractListMember<String, M> {}
diff --git a/tests/language/regress/regress25246_1_test.dart b/tests/language/regress/regress25246_1_test.dart
new file mode 100644
index 0000000..65101de
--- /dev/null
+++ b/tests/language/regress/regress25246_1_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, 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 'regress25246_2.dart';
+
+class ConcreteClass extends Object with MixIn {}
+
+void main() {
+  new ConcreteClass().test();
+}
diff --git a/tests/language/regress/regress25246_2.dart b/tests/language/regress/regress25246_2.dart
new file mode 100644
index 0000000..3c91e73
--- /dev/null
+++ b/tests/language/regress/regress25246_2.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2015, 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 'regress25246_3.dart';
+
+class MixIn {
+  var test3 = new Test3(() {});
+  void test() {
+    test3.test();
+  }
+}
diff --git a/tests/language/regress/regress25246_3.dart b/tests/language/regress/regress25246_3.dart
new file mode 100644
index 0000000..ce61a2e
--- /dev/null
+++ b/tests/language/regress/regress25246_3.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2015, 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 Test3 {
+  final fn;
+  Test3(this.fn);
+  void test() {
+    fn();
+  }
+}
diff --git a/tests/language/regress/regress25389_part.dart b/tests/language/regress/regress25389_part.dart
new file mode 100644
index 0000000..254c87b
--- /dev/null
+++ b/tests/language/regress/regress25389_part.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+
+part of regress_25389;
+
+abstract class ComponentState<S extends ComponentState<S>> {}
+
+abstract class AbstractListEditorState<D,
+    S extends AbstractListEditorState<D, S>> extends ComponentState<S> {}
+
+class IssueListEditorState
+    extends AbstractListEditorState<String, IssueListEditorState>
+    implements ComponentState<IssueListEditorState> {}
diff --git a/tests/language/regress/regress25389_test.dart b/tests/language/regress/regress25389_test.dart
new file mode 100644
index 0000000..8a4b882
--- /dev/null
+++ b/tests/language/regress/regress25389_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2016, 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.
+
+library regress_25389;
+
+part 'regress25389_part.dart';
+
+main() {
+  new IssueListEditorState();
+}
+
+abstract class AbstractListEditor<D, S extends AbstractListEditorState<D, S>> {}
diff --git a/tests/language/regress/regress25550_test.dart b/tests/language/regress/regress25550_test.dart
new file mode 100644
index 0000000..4a8a7c5
--- /dev/null
+++ b/tests/language/regress/regress25550_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2016, 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.
+
+typedef int Adder(int a, int b);
+
+class Mock {
+  noSuchMethod(i) => null;
+}
+
+class MockAdder extends Mock {
+  int call(int a, int b);
+}
+
+main() {
+  Adder adder = new MockAdder();
+}
diff --git a/tests/language/regress/regress25568_test.dart b/tests/language/regress/regress25568_test.dart
new file mode 100644
index 0000000..14d4986
--- /dev/null
+++ b/tests/language/regress/regress25568_test.dart
@@ -0,0 +1,24 @@
+// Copyright (c) 2016, 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.
+
+main() {
+  var c1 = new BacklogListEditorState();
+  var c2 = new BacklogsState();
+}
+
+class BacklogListEditorState
+    extends AbstractListEditorState<BacklogsState, BacklogListEditorState> {}
+
+class BacklogsState extends MutableEntityState<BacklogsState> {}
+
+abstract class AbstractListEditorState<ES extends ComponentState<ES>,
+    S extends AbstractListEditorState<ES, S>> extends ComponentState<S> {}
+
+abstract class ComponentState<S extends ComponentState<S>> {}
+
+abstract class EntityState<ES extends EntityState<ES>>
+    extends ComponentState<ES> {}
+
+abstract class MutableEntityState<S extends MutableEntityState<S>>
+    extends EntityState<S> implements ComponentState<S> {}
diff --git a/tests/language/regress/regress25609_lib1.dart b/tests/language/regress/regress25609_lib1.dart
new file mode 100644
index 0000000..1e9c886
--- /dev/null
+++ b/tests/language/regress/regress25609_lib1.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, 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.
+
+library regress_25609_lib1;
+
+import 'regress25609_lib2.dart';
+
+typedef Bar Foo(int y);
diff --git a/tests/language/regress/regress25609_lib2.dart b/tests/language/regress/regress25609_lib2.dart
new file mode 100644
index 0000000..d51c061
--- /dev/null
+++ b/tests/language/regress/regress25609_lib2.dart
@@ -0,0 +1,7 @@
+// Copyright (c) 2016, 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.
+
+library regress_25609_lib2;
+
+typedef void Bar(double x);
diff --git a/tests/language/regress/regress25609_test.dart b/tests/language/regress/regress25609_test.dart
new file mode 100644
index 0000000..e321240
--- /dev/null
+++ b/tests/language/regress/regress25609_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2016, 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 'regress25609_lib1.dart';
+
+Foo? baz() => null;
+
+main() {
+  baz();
+}
diff --git a/tests/language/regress/regress25620_test.dart b/tests/language/regress/regress25620_test.dart
new file mode 100644
index 0000000..ed47189
--- /dev/null
+++ b/tests/language/regress/regress25620_test.dart
@@ -0,0 +1,8 @@
+// Copyright (c) 2016, 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";
+
+typedef Future<T> SyncedExecutionFn<T>(Future<T> fn());
+main() {}
diff --git a/tests/language/regress/regress25935_test.dart b/tests/language/regress/regress25935_test.dart
new file mode 100644
index 0000000..5b2e4e1
--- /dev/null
+++ b/tests/language/regress/regress25935_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2016, 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.
+
+main() {
+  AddIssueSourceMember2 m = new AddIssueSourceMember2();
+}
+
+abstract class RepoListEditorState2<M extends RepoListMember2<M>,
+        S extends RepoListEditorState2<M, S>>
+    extends AbstractListEditorState2<M, S> {}
+
+abstract class AbstractListEditorState2<
+    M extends AbstractListMember2<Object, M>,
+    S extends AbstractListEditorState2<M, S>> extends ComponentState2<S> {}
+
+class AddIssueSourceMember2 extends RepoListMember2<AddIssueSourceMember2> {}
+
+class RepoListMember2<M extends RepoListMember2<M>>
+    extends AbstractListMember2<Object, M> {}
+
+abstract class AbstractListMember2<E, M extends AbstractListMember2<E, M>>
+    extends ComponentState2<M> {}
+
+abstract class ComponentState2<S extends ComponentState2<S>> {}
diff --git a/tests/language/regress/regress26133_test.dart b/tests/language/regress/regress26133_test.dart
new file mode 100644
index 0000000..7c657a1
--- /dev/null
+++ b/tests/language/regress/regress26133_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2016, 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';
+
+var x = 'a';
+
+Future<int> foo() async {
+  return x; /*@compile-error=unspecified*/
+}
+
+main() {
+  foo();
+}
diff --git a/tests/language/regress/regress26175_test.dart b/tests/language/regress/regress26175_test.dart
new file mode 100644
index 0000000..dd7ac2a
--- /dev/null
+++ b/tests/language/regress/regress26175_test.dart
@@ -0,0 +1,74 @@
+// Copyright (c) 2015, 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:expect/expect.dart";
+import "package:async_helper/async_helper.dart";
+
+// Test that local variable reads and writes are sequenced correctly with
+// respect to reads and writes in an awaited Future.  See issue 26175.
+
+// Reads are sequenced correctly with respect to writes in a Future.
+Future test1() async {
+  var x = 'a';
+  f() async => x = 'b';
+  Expect.equals('abb', '${x}${await f()}${x}');
+}
+
+// Writes are sequenced correctly with respect to writes in a Future.
+Future test2(ignore) async {
+  var x;
+  f() async => x = 'b';
+  Expect.equals('abb', '${x = 'a'}${await f()}${x}');
+}
+
+// Writes are sequenced correctly with respect to reads in a Future.
+Future test3(ignore) async {
+  var x = 'a';
+  f() async => x;
+  Expect.equals('bbb', '${x = 'b'}${await f()}${x}');
+}
+
+// Repeat the same tests for static variables.
+var cell = 'a';
+
+asyncReadCell() async => cell;
+asyncWriteCell(value) async => cell = value;
+
+Future test4(ignore) async {
+  // This test assumes that it can read the initial value of cell.
+  Expect.equals('abb', '${cell}${await asyncWriteCell('b')}${cell}');
+}
+
+Future test5(ignore) async {
+  Expect.equals('abb', '${cell = 'a'}${await asyncWriteCell('b')}${cell}');
+}
+
+Future test6(ignore) async {
+  Expect.equals('bbb', '${cell = 'b'}${await asyncReadCell()}${cell}');
+}
+
+// Test that throwing is sequenced correctly with respect to other effects.
+Future test7(ignore) async {
+  cell = 'a';
+  try {
+    Expect.equals(
+        'unreachable', '${throw 0}${await asyncWriteCell('b')}${cell}');
+  } catch (_) {
+    Expect.equals('a', cell);
+  }
+}
+
+main() {
+  asyncStart();
+  test1()
+      .then(test2)
+      .then(test3)
+      .then(test4)
+      .then(test5)
+      .then(test6)
+      .then(test7)
+      .then((_) => asyncEnd());
+}
diff --git a/tests/language/regress/regress26230_test.dart b/tests/language/regress/regress26230_test.dart
new file mode 100644
index 0000000..77792bc
--- /dev/null
+++ b/tests/language/regress/regress26230_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2016, 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 _RenderTabBar extends RenderBox
+    with
+        ContainerRenderObjectMixin<RenderBox, _TabBarParentData>,
+        RenderBoxContainerDefaultsMixin<RenderBox, _TabBarParentData> {}
+
+class RenderObject {}
+
+class RenderSector extends RenderObject {}
+
+class RenderBox extends RenderObject {}
+
+class ParentData {}
+
+class BoxParentData extends ParentData {}
+
+class SectorParentData extends ParentData {}
+
+class ContainerParentDataMixin<ChildType extends RenderObject> {}
+
+class ContainerRenderObjectMixin<ChildType extends RenderObject,
+    ParentDataType extends ContainerParentDataMixin<ChildType>> {}
+
+class SectorChildListParentData extends SectorParentData
+    with ContainerParentDataMixin<RenderSector> {}
+
+class RenderDecoratedSector extends RenderSector {}
+
+class RenderSectorWithChildren extends RenderDecoratedSector
+    with ContainerRenderObjectMixin<RenderSector, SectorChildListParentData> {}
+
+class ContainerBoxParentDataMixin<ChildType extends RenderObject>
+    extends BoxParentData with ContainerParentDataMixin<ChildType> {}
+
+class RenderBoxContainerDefaultsMixin<ChildType extends RenderBox,
+        ParentDataType extends ContainerBoxParentDataMixin<ChildType>>
+    implements ContainerRenderObjectMixin<ChildType, ParentDataType> {}
+
+class FlexParentData extends ContainerBoxParentDataMixin<RenderBox> {}
+
+class _TabBarParentData extends ContainerBoxParentDataMixin<RenderBox> {}
+
+main() {
+  new _RenderTabBar();
+}
diff --git a/tests/language/regress/regress26453_test.dart b/tests/language/regress/regress26453_test.dart
new file mode 100644
index 0000000..32d6f59
--- /dev/null
+++ b/tests/language/regress/regress26453_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2016, 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 program crashed with segfault because we when we first compile foo
+// and bar we allocate all four variables (a, b, c and d) to the context.
+// When we compile foo the second time (with optimizations) we allocate
+// only c and d to the context. This happened because parser folds away
+// "${a}" and "${b}" as constant expressions when parsing bar on its own,
+// i.e. the expressions were not parsed again and thus a and b were not
+// marked as captured.
+// This caused a mismatch between a context that bar expects and that
+// the optimized version of foo produces.
+
+foo() {
+  const a = 1;
+  const b = 2;
+  var c = 3;
+  var d = 4;
+
+  bar() {
+    if ("${a}" != "1") throw "failed";
+    if ("${b}" != "2") throw "failed";
+    if ("${c}" != "3") throw "failed";
+    if ("${d}" != "4") throw "failed";
+  }
+
+  bar();
+}
+
+main() {
+  for (var i = 0; i < 50000; i++) foo();
+}
diff --git a/tests/language/regress/regress26530_test.dart b/tests/language/regress/regress26530_test.dart
new file mode 100644
index 0000000..ab22638
--- /dev/null
+++ b/tests/language/regress/regress26530_test.dart
@@ -0,0 +1,32 @@
+// Copyright (c) 2016, 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";
+
+var trace = "";
+
+main() {
+  var x = 0;
+  try {
+    try {
+      throw x++; // 1
+    } on int catch (e) {
+      trace += "$e";
+      trace += "-$x";
+      x++; // 2
+      try {
+        x++; // 3
+        rethrow;
+      } finally {
+        trace += "-f";
+        x++; // 4
+      }
+    }
+  } catch (e) {
+    trace += "-c";
+    trace += "-$e";
+    trace += "-$x";
+  }
+  Expect.equals("0-1-f-c-0-4", trace);
+}
diff --git a/tests/language/regress/regress26543_1_test.dart b/tests/language/regress/regress26543_1_test.dart
new file mode 100644
index 0000000..39305f6
--- /dev/null
+++ b/tests/language/regress/regress26543_1_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for issue 26543
+
+class C {
+  var x;
+  C() : x = null ?? <int, int>{} {}
+}
+
+main() {
+  print(new C());
+}
diff --git a/tests/language/regress/regress26543_2_test.dart b/tests/language/regress/regress26543_2_test.dart
new file mode 100644
index 0000000..ac7b5f5
--- /dev/null
+++ b/tests/language/regress/regress26543_2_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for issue 26543
+
+class C {
+  var x, y;
+  C()
+      : x = null ?? <int, int>{},
+        y = 0 {}
+}
+
+main() {
+  print(new C());
+}
diff --git a/tests/language/regress/regress26543_3_test.dart b/tests/language/regress/regress26543_3_test.dart
new file mode 100644
index 0000000..91bbfa4
--- /dev/null
+++ b/tests/language/regress/regress26543_3_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for issue 26543
+
+class C {
+  var x, y;
+  C()
+      : x = 0,
+        y = null ?? <int, int>{} {}
+}
+
+main() {
+  print(new C());
+}
diff --git a/tests/language/regress/regress26668_test.dart b/tests/language/regress/regress26668_test.dart
new file mode 100644
index 0000000..6fc8071
--- /dev/null
+++ b/tests/language/regress/regress26668_test.dart
@@ -0,0 +1,16 @@
+// Copyright (c) 2016, 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';
+
+main() async {
+  var myClass = new CustomClass<int>();
+  await myClass.processData();
+}
+
+class CustomClass<T> {
+  Future<T?> processData() async {
+    return null;
+  }
+}
diff --git a/tests/language/regress/regress26855_runtime_test.dart b/tests/language/regress/regress26855_runtime_test.dart
new file mode 100644
index 0000000..a5cc175
--- /dev/null
+++ b/tests/language/regress/regress26855_runtime_test.dart
@@ -0,0 +1,28 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2016, 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 C {
+  C();
+  var x;
+
+
+}
+
+main() {
+
+
+
+  C c = new C();
+
+
+}
diff --git a/tests/language/regress/regress26855_test.dart b/tests/language/regress/regress26855_test.dart
new file mode 100644
index 0000000..0568e19
--- /dev/null
+++ b/tests/language/regress/regress26855_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2016, 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.
+
+void f0(this.x) {}
+//      ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+// [cfe] Field formal parameters can only be used in a constructor.
+
+void f1(int g(this.x)) {}
+//            ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+// [cfe] Field formal parameters can only be used in a constructor.
+
+void f2(int g(int this.x)) {}
+//            ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+//                ^
+// [cfe] Field formal parameters can only be used in a constructor.
+
+class C {
+  C();
+  var x;
+  void f3(int g(this.x)) {}
+  //            ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+  C.f4(int g(this.x));
+  //         ^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.FIELD_INITIALIZER_OUTSIDE_CONSTRUCTOR
+  // [cfe] Field formal parameters can only be used in a constructor.
+}
+
+main() {
+  dynamic arg = null;
+  f0(arg);
+  f1(arg);
+  f2(arg);
+  C c = new C();
+  c.f3(arg);
+  new C.f4(arg);
+}
diff --git a/tests/language/regress/regress26948_test.dart b/tests/language/regress/regress26948_test.dart
new file mode 100644
index 0000000..c37d3f7
--- /dev/null
+++ b/tests/language/regress/regress26948_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, 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.
+// VMOptions=--optimization-counter-threshold=10 --no-background-compilation
+
+import 'dart:async';
+import "package:expect/expect.dart";
+
+void check(Function f) {
+  Expect.isTrue(f());
+}
+
+Future doSync() async {
+  try {
+    await 123;
+  } finally {
+    var next = 5.0;
+    check(() => next == 5.0);
+  }
+}
+
+main() async {
+  for (int i = 0; i < 20; i++) {
+    await doSync();
+  }
+}
diff --git a/tests/language/regress/regress27164_test.dart b/tests/language/regress/regress27164_test.dart
new file mode 100644
index 0000000..a71873c
--- /dev/null
+++ b/tests/language/regress/regress27164_test.dart
@@ -0,0 +1,19 @@
+// Copyright (c) 2016, 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.
+
+// Regression test for issue 27164.
+
+import 'package:expect/expect.dart';
+
+String simpleEcho(String arg) => arg;
+
+class Echo {
+  final echo;
+  // Check that the expression simpleEcho is a compile-time constant.
+  const Echo() : echo = simpleEcho;
+}
+
+void main() {
+  Expect.equals("hello", const Echo().echo("hello"));
+}
diff --git a/tests/language/regress/regress27572_test.dart b/tests/language/regress/regress27572_test.dart
new file mode 100644
index 0000000..398fdb9
--- /dev/null
+++ b/tests/language/regress/regress27572_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2016, 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 has been modified and doesn't test http://dartbug.com/275272 anymore.
+// Static unresolved calls are not allowed anymore.
+
+import "package:expect/expect.dart";
+
+import 'dart:collection' as col;
+
+main() {
+  col.foobar(1234567); /*@compile-error=unspecified*/
+}
diff --git a/tests/language/regress/regress27617_runtime_test.dart b/tests/language/regress/regress27617_runtime_test.dart
new file mode 100644
index 0000000..e75bc21
--- /dev/null
+++ b/tests/language/regress/regress27617_runtime_test.dart
@@ -0,0 +1,18 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2016, 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 Foo {
+  final String greeting;
+  Foo._(this.greeting) {}
+
+  // Const constructor must not redirect to non-const constructor.
+
+}
+
+main() {
+
+}
diff --git a/tests/language/regress/regress27617_test.dart b/tests/language/regress/regress27617_test.dart
new file mode 100644
index 0000000..fbd06e4
--- /dev/null
+++ b/tests/language/regress/regress27617_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, 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 Foo {
+  final String greeting;
+  Foo._(this.greeting) {}
+
+  // Const constructor must not redirect to non-const constructor.
+  const Foo.hi() : this._('hi');
+  //                    ^
+  // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CONST_CONSTRUCTOR
+  // [cfe] A constant constructor can't call a non-constant constructor.
+}
+
+main() {
+  const h = const Foo.hi();
+}
diff --git a/tests/language/regress/regress27659_test.dart b/tests/language/regress/regress27659_test.dart
new file mode 100644
index 0000000..e40a886
--- /dev/null
+++ b/tests/language/regress/regress27659_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2016, 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.
+
+const String lineLength = '120';
+
+foo({lineLength: lineLength}) {
+  print(lineLength);
+}
+
+bar({lineLength: lineLength}) async {
+  print(lineLength);
+}
+
+baz([lineLength = lineLength]) {
+  print(lineLength);
+}
+
+qux([lineLength = lineLength]) async {
+  print(lineLength);
+}
+
+main() {
+  foo();
+  bar();
+  baz();
+  qux();
+}
diff --git a/tests/language/regress/regress27700_test.dart b/tests/language/regress/regress27700_test.dart
new file mode 100644
index 0000000..63ff9b9
--- /dev/null
+++ b/tests/language/regress/regress27700_test.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2017, 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.
+
+// Regression test for issue 27700.
+
+main() {
+  var x = new List.empty();
+  var z = "$x";
+}
diff --git a/tests/language/regress/regress27957_lib1.dart b/tests/language/regress/regress27957_lib1.dart
new file mode 100644
index 0000000..7a06ff3
--- /dev/null
+++ b/tests/language/regress/regress27957_lib1.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, 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.
+
+library regress_27957_lib1;
+
+class Superclass {
+  int m() => 1;
+}
diff --git a/tests/language/regress/regress27957_lib2.dart b/tests/language/regress/regress27957_lib2.dart
new file mode 100644
index 0000000..24097d0
--- /dev/null
+++ b/tests/language/regress/regress27957_lib2.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2016, 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.
+
+library regress_27957_lib2;
+
+class Superclass {
+  int m() => 2;
+}
diff --git a/tests/language/regress/regress27957_test.dart b/tests/language/regress/regress27957_test.dart
new file mode 100644
index 0000000..1c5dbcd
--- /dev/null
+++ b/tests/language/regress/regress27957_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2016, 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 'regress27957_lib1.dart' as s1;
+import 'regress27957_lib2.dart' as s2;
+
+class Mixin {}
+
+class C1 = s1.Superclass with Mixin;
+class C2 = s2.Superclass with Mixin;
+
+main() {
+  var c1 = new C1(), c2 = new C2();
+  Expect.equals(1, c1.m());
+  Expect.equals(2, c2.m());
+}
diff --git a/tests/language/regress/regress28217_test.dart b/tests/language/regress/regress28217_test.dart
new file mode 100644
index 0000000..a49876f
--- /dev/null
+++ b/tests/language/regress/regress28217_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2017, 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 non-existing redirecting constructor and
+// redirecting to a factory constructor.
+
+class B {
+  B() : this.a(); //   //# none: compile-time error
+  factory B.a() {} //  //# 01: compile-time error
+  B.a(); //            //# 02: ok
+}
+
+main() => new B();
diff --git a/tests/language/regress/regress28268_test.dart b/tests/language/regress/regress28268_test.dart
new file mode 100644
index 0000000..a2a0bd5
--- /dev/null
+++ b/tests/language/regress/regress28268_test.dart
@@ -0,0 +1,159 @@
+// 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';
+
+class E {
+  static final String a = "get a";
+  static void set a(String o) {
+    printx("set a: $o");
+  }
+
+  static const String b = "get b";
+  static void set b(String o) {
+    printx("set b: $o");
+  }
+
+  static void set c(String o) {
+    printx("set c: $o");
+  }
+
+  final String d = "get d";
+  void set d(String o) {
+    printx("set d: $o");
+  }
+
+  final String e = "get e";
+
+  static const String f = "get f";
+
+  set g(v) {
+    printx("set g: $v");
+  }
+
+  set h(v) {
+    printx("set h: $v");
+  }
+
+  foo() {
+    printx(e);
+    e = "set e"; // //# 01: compile-time error
+    printx(e);
+
+    printx(f);
+    f = "set f"; // //# 02: compile-time error
+    printx(f);
+
+    printx(g); //   //# 03: compile-time error
+    g = "set g";
+    printx(g); //   //# 04: compile-time error
+
+    printx(h); //   //# 05: compile-time error
+    h = "set h";
+    printx(h); //   //# 06: compile-time error
+  }
+}
+
+set e(v) {
+  printx("Setting top-level e: $v");
+}
+
+set f(v) {
+  printx("Setting top-level f: $v");
+}
+
+final String g = "get g";
+
+const String h = "get h";
+
+const x = 42;
+final y = 42;
+
+set x(v) {
+  printx("Setting top-level x: $v");
+}
+
+set y(v) {
+  printx("Setting top-level y: $v");
+}
+
+main() {
+  printx(E.a);
+  E.a = "set E";
+  printx(E.a);
+
+  printx(E.b);
+  E.b = "set E";
+  printx(E.b);
+
+  E.c = "set E";
+
+  E eInstance = new E();
+  printx(eInstance.d);
+  eInstance.d = "set eInstance";
+  printx(eInstance.d);
+  eInstance.foo();
+
+  printx(e); //     //# 07: compile-time error
+  e = "set e";
+  printx(e); //     //# 08: compile-time error
+
+  printx(f); //     //# 09: compile-time error
+  f = "set f";
+  printx(f); //     //# 10: compile-time error
+
+  printx(g);
+  g = "set g"; //   //# 11: compile-time error
+  printx(g);
+
+  printx(h);
+  h = "set h"; //   //# 12: compile-time error
+  printx(h);
+
+  printx(x);
+  x = "Hello world!";
+  printx(x);
+
+  printx(y);
+  y = "Hello world!";
+  printx(y);
+
+  Expect.listEquals(expected, actual);
+}
+
+List<String> actual = <String>[];
+void printx(Object x) {
+  actual.add(x.toString());
+}
+
+List<String> expected = <String>[
+  "get a",
+  "set a: set E",
+  "get a",
+  "get b",
+  "set b: set E",
+  "get b",
+  "set c: set E",
+  "get d",
+  "set d: set eInstance",
+  "get d",
+  "get e",
+  "get e",
+  "get f",
+  "get f",
+  "set g: set g",
+  "set h: set h",
+  "Setting top-level e: set e",
+  "Setting top-level f: set f",
+  "get g",
+  "get g",
+  "get h",
+  "get h",
+  "42",
+  "Setting top-level x: Hello world!",
+  "42",
+  "42",
+  "Setting top-level y: Hello world!",
+  "42",
+];
diff --git a/tests/language/regress/regress28278_lib.dart b/tests/language/regress/regress28278_lib.dart
new file mode 100644
index 0000000..0bc67f1
--- /dev/null
+++ b/tests/language/regress/regress28278_lib.dart
@@ -0,0 +1,5 @@
+// Copyright (c) 2017, 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.
+
+foo(x) => x + "Hello";
diff --git a/tests/language/regress/regress28278_test.dart b/tests/language/regress/regress28278_test.dart
new file mode 100644
index 0000000..aaeed57
--- /dev/null
+++ b/tests/language/regress/regress28278_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2017, 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.
+// VMOptions=--load-deferred-eagerly
+// VMOptions=
+
+import "package:expect/expect.dart";
+
+import "regress28278_lib.dart" deferred as def;
+
+var result = "";
+
+class D {
+  m() async {
+    await def.loadLibrary();
+    result = def.foo(result += "Here");
+  }
+}
+
+main() async {
+  var d = new D();
+  await d.m();
+  await d.m();
+  Expect.equals("HereHelloHereHello", result);
+}
diff --git a/tests/language/regress/regress28341_test.dart b/tests/language/regress/regress28341_test.dart
new file mode 100644
index 0000000..c43d594
--- /dev/null
+++ b/tests/language/regress/regress28341_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, 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";
+
+enum E { A }
+
+main() {
+  Expect.isTrue(E.values == const <E>[E.A]);
+  Expect.isTrue(E.values == const [E.A]);
+}
diff --git a/tests/language/regress/regress28498_test.dart b/tests/language/regress/regress28498_test.dart
new file mode 100644
index 0000000..664d33b
--- /dev/null
+++ b/tests/language/regress/regress28498_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+// The Kernel async transformer should not skip assert statements.
+
+import 'dart:async';
+
+import 'package:expect/expect.dart';
+import 'package:async_helper/async_helper.dart';
+
+g() async => 21;
+f() async => 42;
+
+test() async {
+  assert(await g() == await f());
+}
+
+main() {
+  bool ok = true;
+  assert(!(ok = false));
+  // !ok iff asserts are enabled.
+
+  asyncStart();
+  test().then((_) => Expect.isTrue(ok), onError: (error) {
+    // !ok implies error is AssertionError.
+    Expect.isTrue(ok || error is AssertionError);
+  }).whenComplete(asyncEnd);
+}
diff --git a/tests/language/regress/regress28610_test.dart b/tests/language/regress/regress28610_test.dart
new file mode 100644
index 0000000..adefd32d
--- /dev/null
+++ b/tests/language/regress/regress28610_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2017, 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";
+
+class A {
+  final int Function = 0;
+}
+
+main() {
+  final int Function = 0;
+  Expect.equals(Function, new A().Function);
+}
diff --git a/tests/language/regress/regress29025_test.dart b/tests/language/regress/regress29025_test.dart
new file mode 100644
index 0000000..867d738
--- /dev/null
+++ b/tests/language/regress/regress29025_test.dart
@@ -0,0 +1,28 @@
+// Copyright (c) 2017, 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.
+
+abstract class F<T> {
+  T foo(T t);
+}
+
+class B<T extends F<T>> {}
+
+class C<T extends F<C<T>>> {}
+
+class D extends B<D> implements F<D> {
+  D foo(D x) => x;
+}
+
+class E extends C<E> implements F<C<E>> {
+  C<E> foo(C<E> x) => x;
+}
+
+main() {
+  D fd = D();
+  var d = fd.foo(fd);
+  print(d);
+  E fe = E();
+  var e = fe.foo(fe);
+  print(e);
+}
diff --git a/tests/language/regress/regress29243_test.dart b/tests/language/regress/regress29243_test.dart
new file mode 100644
index 0000000..60b0cb7
--- /dev/null
+++ b/tests/language/regress/regress29243_test.dart
@@ -0,0 +1,12 @@
+// Copyright (c) 2017, 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";
+
+int Function() x = () => 42;
+int Function(int Function()) y = (int Function() x) => x();
+List<int Function()> l = <int Function()>[()=>42, x];
+main() {
+  Expect.equals(42, y(l[1]));
+}
diff --git a/tests/language/regress/regress29349_test.dart b/tests/language/regress/regress29349_test.dart
new file mode 100644
index 0000000..ea91b79
--- /dev/null
+++ b/tests/language/regress/regress29349_test.dart
@@ -0,0 +1,11 @@
+// Copyright (c) 2017, 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.
+
+List<T> get<T>(T item) => <T>[item];
+List<T> get2<T>(T item) => <T>[item];
+
+void main() {
+ print(get(1));
+ print(get2(1));
+}
diff --git a/tests/language/regress/regress29357_test.dart b/tests/language/regress/regress29357_test.dart
new file mode 100644
index 0000000..3777e3c
--- /dev/null
+++ b/tests/language/regress/regress29357_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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.
+
+abstract class A<T extends A<T>> {}
+
+abstract class B<T extends A<T>> {}
+
+class C<U> extends B<D<U>> {}
+
+class D<U> extends A<D<U>> {}
+
+main() {
+  new D();
+  new C();
+  new D<C>();
+  new C<D>();
+}
diff --git a/tests/language/regress/regress29784_runtime_test.dart b/tests/language/regress/regress29784_runtime_test.dart
new file mode 100644
index 0000000..f145ed4
--- /dev/null
+++ b/tests/language/regress/regress29784_runtime_test.dart
@@ -0,0 +1,24 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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.
+
+// VMOptions=--enable_asserts
+
+// Verify that only static members can be accessed in initializers, and this
+// applies to asserts in initializers.
+
+import 'package:expect/expect.dart';
+
+class A {
+
+
+  var a, b;
+}
+
+main() {
+
+
+}
diff --git a/tests/language/regress/regress29784_test.dart b/tests/language/regress/regress29784_test.dart
new file mode 100644
index 0000000..0df166f
--- /dev/null
+++ b/tests/language/regress/regress29784_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2017, 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.
+
+// VMOptions=--enable_asserts
+
+// Verify that only static members can be accessed in initializers, and this
+// applies to asserts in initializers.
+
+import 'package:expect/expect.dart';
+
+class A {
+  A.ok() : b = a;
+  //           ^
+  // [analyzer] COMPILE_TIME_ERROR.IMPLICIT_THIS_REFERENCE_IN_INITIALIZER
+  // [cfe] Can't access 'this' in a field initializer to read 'a'.
+  A.ko() : assert(a == null);
+  //              ^
+  // [cfe] Can't access 'this' in a field initializer to read 'a'.
+  var a, b;
+}
+
+main() {
+  new A.ok();
+  new A.ko();
+}
diff --git a/tests/language/regress/regress29949_test.dart b/tests/language/regress/regress29949_test.dart
new file mode 100644
index 0000000..8685fae
--- /dev/null
+++ b/tests/language/regress/regress29949_test.dart
@@ -0,0 +1,15 @@
+// Copyright (c) 2017, 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.
+
+abstract class S {}
+
+abstract class M<T> {}
+
+abstract class N<T> {}
+
+class C<T> extends S with M<C<T>>, N<C<T>> {}
+
+main() {
+  new C<int>();
+}
diff --git a/tests/language/regress/regress30092_test.dart b/tests/language/regress/regress30092_test.dart
new file mode 100644
index 0000000..46ff3cd
--- /dev/null
+++ b/tests/language/regress/regress30092_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2017, 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 BigInt {}
+
+main() {
+  void foo(void Function(BigInt, BigInt) f) {
+    f(new BigInt(), new BigInt());
+  }
+
+  foo((x, y) {});
+}
diff --git a/tests/language/regress/regress30121_test.dart b/tests/language/regress/regress30121_test.dart
new file mode 100644
index 0000000..2bebf96
--- /dev/null
+++ b/tests/language/regress/regress30121_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2017, 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 Mock {
+  noSuchMethod(i) => 1;
+}
+
+class Foo {
+  int call() => 1;
+}
+
+class MockFoo extends Mock implements Foo {}
+
+main() {
+  var foo = new MockFoo();
+  foo();
+}
diff --git a/tests/language/regress/regress30339_test.dart b/tests/language/regress/regress30339_test.dart
new file mode 100644
index 0000000..c3a6861
--- /dev/null
+++ b/tests/language/regress/regress30339_test.dart
@@ -0,0 +1,37 @@
+// Copyright (c) 2017, 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:expect/expect.dart';
+
+isCheckedMode() {
+  try {
+    dynamic i = 1;
+    String s = i;
+    return false;
+  } on TypeError {
+    return true;
+  }
+}
+
+dynamic x = 'a';
+
+Future<int> foo() async {
+  return x;
+}
+
+Future<int> bar() async => x;
+
+main() {
+  foo().then((_) {
+    Expect.isFalse(isCheckedMode());
+  }, onError: (e) {
+    Expect.isTrue(isCheckedMode() && (e is TypeError));
+  });
+  bar().then((_) {
+    Expect.isFalse(isCheckedMode());
+  }, onError: (e) {
+    Expect.isTrue(isCheckedMode() && (e is TypeError));
+  });
+}
diff --git a/tests/language/regress/regress30516_test.dart b/tests/language/regress/regress30516_test.dart
new file mode 100644
index 0000000..b8189cc
--- /dev/null
+++ b/tests/language/regress/regress30516_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+typedef void RecognizerCallback<T>();
+typedef void GestureTapCancelCallback();
+GestureTapCancelCallback? onTapCancel;
+T? invokeCallback<T>(String name, RecognizerCallback<T>? callback,
+    {String debugReport()?}) {}
+main() {
+  invokeCallback<void>('spontaneous onTapCancel', onTapCancel);
+}
diff --git a/tests/language/regress/regress30669_test.dart b/tests/language/regress/regress30669_test.dart
new file mode 100644
index 0000000..967ee54
--- /dev/null
+++ b/tests/language/regress/regress30669_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2017, 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';
+
+class M {
+  int compareTo(int x) => x.isEven ? 1 : -1;
+}
+
+// All of these should work the same for the purposes of calling through
+// the Comparable interface.
+
+class C extends M implements Comparable<int> {}
+
+class D extends Object with M implements Comparable<int> {}
+
+class E = Object with M implements Comparable<int>;
+
+/// Regression test for https://github.com/dart-lang/sdk/issues/30669, DDC was
+/// not attaching the "extension member" symbol to call `Comparable.compareTo` in
+/// some cases.
+main() {
+  testComparable(new C());
+  testComparable(new D());
+  testComparable(new E());
+}
+
+testComparable(Comparable<Object> c) {
+  Expect.equals(c.compareTo(42), 1, '$c');
+  Expect.equals(c.compareTo(41), -1, '$c');
+  Expect.throws(() => c.compareTo('42'));
+}
diff --git a/tests/language/regress/regress30927_test.dart b/tests/language/regress/regress30927_test.dart
new file mode 100644
index 0000000..dc3c9aa
--- /dev/null
+++ b/tests/language/regress/regress30927_test.dart
@@ -0,0 +1,25 @@
+// Copyright (c) 2017, 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';
+
+class B {
+  m(int v) => v + 42;
+}
+
+abstract class C extends B {
+  m(Object v);
+}
+
+class D extends C {
+  m(Object v) => 'hi $v!';
+}
+
+/// Regression test for https://github.com/dart-lang/sdk/issues/30927, DDC used
+/// to use the incorrect signature for D.m.
+main() {
+  dynamic d = new D();
+  // Make sure we dispatch using the type signature for D.m, not B.m
+  Expect.equals(d.m('world'), 'hi world!');
+}
diff --git a/tests/language/regress/regress31057_test.dart b/tests/language/regress/regress31057_test.dart
new file mode 100644
index 0000000..aa443ef
--- /dev/null
+++ b/tests/language/regress/regress31057_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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.
+
+// VMOptions=--reify-generic-functions
+
+import 'package:expect/expect.dart';
+
+class Foo<T> {
+  a<A>() {
+    b<B>() {
+      c<C>() => '$T $A $B $C';
+      return c;
+    }
+
+    return b;
+  }
+}
+
+main() {
+  Expect.equals('bool int double String',
+      ((new Foo<bool>().a<int>())<double>())<String>());
+}
diff --git a/tests/language/regress/regress31066_test.dart b/tests/language/regress/regress31066_test.dart
new file mode 100644
index 0000000..68a07e5
--- /dev/null
+++ b/tests/language/regress/regress31066_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2017, 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 Bar = int Function(int);
+
+int defaultBar(int value) => value + 1;
+
+class Foo {
+  final Bar bar;
+
+  const Foo._(Bar? bar) : bar = bar ?? defaultBar;
+
+  const Foo.baz({Bar? bar}) : this._(bar);
+}
+
+void main() {
+  final foo = const Foo.baz();
+  Expect.equals(2, foo.bar(1));
+}
diff --git a/tests/language/regress/regress31106_test.dart b/tests/language/regress/regress31106_test.dart
new file mode 100644
index 0000000..0c484d1
--- /dev/null
+++ b/tests/language/regress/regress31106_test.dart
@@ -0,0 +1,42 @@
+// Copyright (c) 2017, 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';
+
+void main() {
+  final schema = const UserSchema();
+  Expect.equals('users', schema.name);
+  final user = const User(first: 'firstname');
+  var map = schema._decode(user);
+  Expect.equals('firstname', map['first']);
+}
+
+class User {
+  final String first;
+
+  const User({
+    required this.first,
+  });
+}
+
+class Schema<T> {
+  final String name;
+  final Map<String, Object> Function(T) _decode;
+
+  const Schema({
+    required this.name,
+    required Map<String, Object> Function(T) decode,
+  })
+      : _decode = decode;
+}
+
+class UserSchema extends Schema<User> {
+  static Map<String, Object> _decode$(User user) {
+    return {
+      'first': user.first,
+    };
+  }
+
+  const UserSchema() : super(name: 'users', decode: _decode$);
+}
diff --git a/tests/language/regress/regress31279_test.dart b/tests/language/regress/regress31279_test.dart
new file mode 100644
index 0000000..57b0914
--- /dev/null
+++ b/tests/language/regress/regress31279_test.dart
@@ -0,0 +1,23 @@
+// Copyright (c) 2017, 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.
+
+abstract class Base {
+  void update(void Function(Iterable) updates);
+  void update2(void updates(Iterable iterable));
+}
+
+class CovariantParsingIssue implements Base {
+  void update(covariant void Function(List) updates) {}
+  void update2(covariant void updates(List list)) {}
+}
+
+void VoidParsingIssue() {
+  List<void Function(int)> functions = [(int i) => print(i + 1)];
+  functions[0](42);
+}
+
+void main() {
+  new CovariantParsingIssue();
+  VoidParsingIssue();
+}
diff --git a/tests/language/regress/regress31436_test.dart b/tests/language/regress/regress31436_test.dart
new file mode 100644
index 0000000..84abe5c
--- /dev/null
+++ b/tests/language/regress/regress31436_test.dart
@@ -0,0 +1,67 @@
+// Copyright (c) 2017, 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";
+
+void block_test() {
+  List<Object> Function() g;
+  g = () {
+    return [3];
+  };
+  assert(g is List<Object> Function());
+  assert(g is! List<int> Function());
+  g().add("hello"); // No runtime error
+  List<int> l = [3];
+  g = () {
+    return l;
+  };
+  assert(g is List<Object> Function());
+  assert(g is List<int> Function());
+  Expect.throwsTypeError(() {
+    g().add("hello"); // runtime error
+  });
+  dynamic o = l;
+  g = () {
+    return o;
+  }; // No implicit downcast on the assignment, implicit downcast on the return
+  assert(g is List<Object> Function());
+  assert(g is! List<int> Function());
+  assert(g is Object Function());
+  g(); // No runtime error;
+  o = 3;
+  Expect.throwsTypeError(() {
+    g(); // Failed runtime cast on the return type of f
+  });
+}
+
+void arrow_test() {
+  List<Object> Function() g;
+  g = () => [3];
+  assert(g is List<Object> Function());
+  assert(g is! List<int> Function());
+  g().add("hello"); // No runtime error
+  List<int> l = [3];
+  g = () => l;
+  assert(g is List<Object> Function());
+  assert(g is List<int> Function());
+  Expect.throwsTypeError(() {
+    g().add("hello"); // runtime error
+  });
+  dynamic o = l;
+  g = () =>
+      o; // No implicit downcast on the assignment, implicit downcast on the return
+  assert(g is List<Object> Function());
+  assert(g is! List<int> Function());
+  assert(g is Object Function());
+  g(); // No runtime error;
+  o = 3;
+  Expect.throwsTypeError(() {
+    g(); // Failed runtime cast on the return type of f
+  });
+}
+
+main() {
+  block_test();
+  arrow_test();
+}
diff --git a/tests/language/regress/regress31591_test.dart b/tests/language/regress/regress31591_test.dart
new file mode 100644
index 0000000..1ad5754
--- /dev/null
+++ b/tests/language/regress/regress31591_test.dart
@@ -0,0 +1,20 @@
+// Copyright (c) 2014, 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.
+
+// VMOptions=--optimization-counter-threshold=5
+
+import 'package:expect/expect.dart';
+
+typedef FunObjObj = Object? Function<T>(Object?, {Object? y});
+
+Object? funTypObj<T>(T x, {Object? y}) => y;
+
+main() {
+  for (int i = 0; i < 10; i++) {
+    Expect.throwsTypeError(() {
+      dynamic y = funTypObj;
+      final FunObjObj x2 = y;
+    });
+  }
+}
diff --git a/tests/language/regress/regress31596_covariant_declaration_test.dart b/tests/language/regress/regress31596_covariant_declaration_test.dart
new file mode 100644
index 0000000..20defe2
--- /dev/null
+++ b/tests/language/regress/regress31596_covariant_declaration_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class C {
+  void f(B x) {}
+}
+
+abstract class I {
+  void f(covariant A x);
+}
+
+class D extends C implements I {}
+//    ^
+// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
+// [cfe] unspecified
+
+main() {}
diff --git a/tests/language/regress/regress31596_override_test.dart b/tests/language/regress/regress31596_override_test.dart
new file mode 100644
index 0000000..592ae44
--- /dev/null
+++ b/tests/language/regress/regress31596_override_test.dart
@@ -0,0 +1,43 @@
+// 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.
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B x) {}
+}
+
+abstract class I1<X> {
+  void f(X x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+class D extends C implements I1<B> {}
+
+class Test extends D {
+  void f(A x) {} //# 01: ok
+  void f(covariant A x) {} //# 02: ok
+
+  void f(B x) {} //# 03: ok
+  void f(covariant B x) {} //# 04: ok
+
+  void f(I0 x) {} //# 05: ok
+  void f(covariant I0 x) {} //# 06: ok
+
+  void f(B2 x) {} //# 07: compile-time error
+  void f(covariant B2 x) {} //# 08: compile-time error
+}
+
+main() {
+  // Make sure that Test is compiled.
+  new Test();
+}
diff --git a/tests/language/regress/regress31596_runtime_test.dart b/tests/language/regress/regress31596_runtime_test.dart
new file mode 100644
index 0000000..90ed9c3
--- /dev/null
+++ b/tests/language/regress/regress31596_runtime_test.dart
@@ -0,0 +1,49 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2017, 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";
+
+class A {}
+
+class B extends A {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x, B y) {}
+}
+
+abstract class I<X> {
+  void f(X? x, B y);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// For purposes of static type checking, the interface of the class D is
+// considered to contain a method f with signature (B, B) -> void. For purposes
+// of runtime behavior, a tearoff of D.f is considered to have the reified
+// runtime type (Object, B) -> void.
+class D extends C implements I<B> {}
+
+main() {
+  var d = new D();
+  I<A> i = d;
+  A a = new A();
+  B b = new B();
+  B2? b2 = null;
+
+  i.f(b2, b); // Ok since B2 assignable to A
+  void Function(Object, B) g = d.f as dynamic; // Ok; D.f reified as (Object, B) -> void
+  Expect.throwsTypeError(() {
+    d.f(a as B, b);
+  });
+  Expect.throwsTypeError(() {
+    i.f(a, b);
+  });
+}
diff --git a/tests/language/regress/regress31596_super_runtime_1_test.dart b/tests/language/regress/regress31596_super_runtime_1_test.dart
new file mode 100644
index 0000000..f43e9e8
--- /dev/null
+++ b/tests/language/regress/regress31596_super_runtime_1_test.dart
@@ -0,0 +1,63 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+import "package:expect/expect.dart";
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// Super calls in a derived class resolve directly to C.f, and are type checked
+// accordingly at compile time.
+class D extends C implements I<B> {}
+
+class E extends D {
+  void test() {
+    I0? i0 = null;
+    B2? b2 = null;
+
+    // ok since I0 is assignable to B
+    super.f(i0 as B?);
+
+    // not ok since B2 is not assignable to B
+
+
+    var superF = super.f; // Inferred static type: void Function(B)
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    // Should pass since superF's runtime type is void Function(Object)
+
+
+
+
+  }
+}
+
+main() {
+  new E().test();
+}
diff --git a/tests/language/regress/regress31596_super_runtime_2_test.dart b/tests/language/regress/regress31596_super_runtime_2_test.dart
new file mode 100644
index 0000000..6dfe63a
--- /dev/null
+++ b/tests/language/regress/regress31596_super_runtime_2_test.dart
@@ -0,0 +1,63 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+import "package:expect/expect.dart";
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// Super calls in a derived class resolve directly to C.f, and are type checked
+// accordingly at compile time.
+class D extends C implements I<B> {}
+
+class E extends D {
+  void test() {
+    I0? i0 = null;
+    B2? b2 = null;
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    var superF = super.f; // Inferred static type: void Function(B)
+
+    // ok since I0 is assignable to B
+    superF(i0 as B?);
+
+    // not ok since B2 is not assignable to B
+
+
+    // Should pass since superF's runtime type is void Function(Object)
+
+
+
+
+  }
+}
+
+main() {
+  new E().test();
+}
diff --git a/tests/language/regress/regress31596_super_runtime_3_test.dart b/tests/language/regress/regress31596_super_runtime_3_test.dart
new file mode 100644
index 0000000..9a593c5
--- /dev/null
+++ b/tests/language/regress/regress31596_super_runtime_3_test.dart
@@ -0,0 +1,63 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+import "package:expect/expect.dart";
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// Super calls in a derived class resolve directly to C.f, and are type checked
+// accordingly at compile time.
+class D extends C implements I<B> {}
+
+class E extends D {
+  void test() {
+    I0? i0 = null;
+    B2? b2 = null;
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    var superF = super.f; // Inferred static type: void Function(B)
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    // Should pass since superF's runtime type is void Function(Object)
+    Expect.isTrue(superF is void Function(B));
+    Expect.isTrue(superF is void Function(I0));
+    Expect.isTrue(superF is void Function(A));
+    Expect.isTrue(superF is void Function(Object));
+  }
+}
+
+main() {
+  new E().test();
+}
diff --git a/tests/language/regress/regress31596_super_runtime_test.dart b/tests/language/regress/regress31596_super_runtime_test.dart
new file mode 100644
index 0000000..37e466d
--- /dev/null
+++ b/tests/language/regress/regress31596_super_runtime_test.dart
@@ -0,0 +1,63 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+import "package:expect/expect.dart";
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// Super calls in a derived class resolve directly to C.f, and are type checked
+// accordingly at compile time.
+class D extends C implements I<B> {}
+
+class E extends D {
+  void test() {
+    I0? i0 = null;
+    B2? b2 = null;
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    var superF = super.f; // Inferred static type: void Function(B)
+
+    // ok since I0 is assignable to B
+
+
+    // not ok since B2 is not assignable to B
+
+
+    // Should pass since superF's runtime type is void Function(Object)
+
+
+
+
+  }
+}
+
+main() {
+  new E().test();
+}
diff --git a/tests/language/regress/regress31596_super_test.dart b/tests/language/regress/regress31596_super_test.dart
new file mode 100644
index 0000000..636ef98
--- /dev/null
+++ b/tests/language/regress/regress31596_super_test.dart
@@ -0,0 +1,66 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class I0 {}
+
+class A {}
+
+class B extends A implements I0 {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// Super calls in a derived class resolve directly to C.f, and are type checked
+// accordingly at compile time.
+class D extends C implements I<B> {}
+
+class E extends D {
+  void test() {
+    I0? i0 = null;
+    B2? b2 = null;
+
+    // ok since I0 is assignable to B
+    super.f(i0 as B?);
+
+    // not ok since B2 is not assignable to B
+    super.f(b2);
+    //      ^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'B2?' can't be assigned to the parameter type 'B?'.
+
+    var superF = super.f; // Inferred static type: void Function(B)
+
+    // ok since I0 is assignable to B
+    superF(i0 as B?);
+
+    // not ok since B2 is not assignable to B
+    superF(b2);
+    //     ^^
+    // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+    // [cfe] The argument type 'B2?' can't be assigned to the parameter type 'B?'.
+
+    // Should pass since superF's runtime type is void Function(Object)
+    Expect.isTrue(superF is void Function(B));
+    Expect.isTrue(superF is void Function(I0));
+    Expect.isTrue(superF is void Function(A));
+    Expect.isTrue(superF is void Function(Object));
+  }
+}
+
+main() {
+  new E().test();
+}
diff --git a/tests/language/regress/regress31596_tearoff_test.dart b/tests/language/regress/regress31596_tearoff_test.dart
new file mode 100644
index 0000000..2dc9574
--- /dev/null
+++ b/tests/language/regress/regress31596_tearoff_test.dart
@@ -0,0 +1,46 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {}
+
+class B extends A {}
+
+class C {
+  void f(B? x) {}
+}
+
+abstract class I<X> {
+  void f(X? x);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// For purposes of static type checking, the interface of the class D is
+// considered to contain a method f with signature (B) -> void.  For purposes of
+// runtime behavior, a tearoff of D.f is considered to have the reified runtime
+// type (Object) -> void.
+class D extends C implements I<B> {}
+
+main() {
+  var d = new D();
+  A? aNull = null;
+  A a = new A();
+
+  // Since the compile-time type of D.f is (B?) -> void, it is assignable to (A)
+  // -> void.  Since the runtime type is (Object?) -> void, the assignment is
+  // allowed at runtime as well.
+  void Function(A?) g = d.f as dynamic;
+
+  // However, the tear-off performs a runtime check of its argument, so it
+  // accepts a value of `null`, but it does not accept a value whose runtime
+  // type is A.
+  g(aNull);
+  Expect.throwsTypeError(() {
+    g(a);
+  });
+}
diff --git a/tests/language/regress/regress31596_test.dart b/tests/language/regress/regress31596_test.dart
new file mode 100644
index 0000000..44b8c8c
--- /dev/null
+++ b/tests/language/regress/regress31596_test.dart
@@ -0,0 +1,49 @@
+// Copyright (c) 2017, 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";
+
+class A {}
+
+class B extends A {}
+
+class B2 extends A {}
+
+class C {
+  void f(B? x, B y) {}
+}
+
+abstract class I<X> {
+  void f(X? x, B y);
+}
+
+// This class contains a forwarding stub for f to allow it to satisfy the
+// interface I<B>, while still ensuring that the x argument is type checked
+// before C.f is executed.
+//
+// For purposes of static type checking, the interface of the class D is
+// considered to contain a method f with signature (B, B) -> void. For purposes
+// of runtime behavior, a tearoff of D.f is considered to have the reified
+// runtime type (Object, B) -> void.
+class D extends C implements I<B> {}
+
+main() {
+  var d = new D();
+  I<A> i = d;
+  A a = new A();
+  B b = new B();
+  B2? b2 = null;
+  d.f(b2, b);
+  //  ^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'B2?' can't be assigned to the parameter type 'B?'.
+  i.f(b2, b); // Ok since B2 assignable to A
+  void Function(Object, B) g = d.f as dynamic; // Ok; D.f reified as (Object, B) -> void
+  Expect.throwsTypeError(() {
+    d.f(a as B, b);
+  });
+  Expect.throwsTypeError(() {
+    i.f(a, b);
+  });
+}
diff --git a/tests/language/regress/regress32012_test.dart b/tests/language/regress/regress32012_test.dart
new file mode 100644
index 0000000..65f76d3
--- /dev/null
+++ b/tests/language/regress/regress32012_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class C {
+  int x = -1;
+
+  int bar() {
+    return 19;
+  }
+}
+
+main() {
+  B foo<A extends B, B extends C>(A a) {
+    int bar<Q>(B b) {
+      return 23 + b.bar();
+    }
+
+    a.x = bar(a);
+    return a;
+  }
+
+  var x = <A extends B, B>(A a) {
+    return a;
+  };
+
+  Expect.equals(x(foo(new C())).x, 42);
+}
diff --git a/tests/language/regress/regress32267_test.dart b/tests/language/regress/regress32267_test.dart
new file mode 100644
index 0000000..64ed4f3
--- /dev/null
+++ b/tests/language/regress/regress32267_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// There was a bug in the Kernel mixin transformation: it copied factory
+// constructors from the mixin into the mixin application class.  This could be
+// observed as an unbound type parameter which led to a crash.
+
+class State<T> {}
+
+class A {}
+
+abstract class Mixin<T> {
+  factory Mixin._() => throw "uncalled";
+}
+
+class AState extends State<A> {}
+
+class AStateImpl extends AState with Mixin {}
+
+void main() {
+  new AStateImpl();
+}
diff --git a/tests/language/regress/regress32305_test.dart b/tests/language/regress/regress32305_test.dart
new file mode 100644
index 0000000..5943764
--- /dev/null
+++ b/tests/language/regress/regress32305_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+void main() {
+  int Function(int) f;
+
+  List<num> l = [];
+  /*@compile-error=unspecified*/ var a = l.map(f);
+}
diff --git a/tests/language/regress/regress32353_2_test.dart b/tests/language/regress/regress32353_2_test.dart
new file mode 100644
index 0000000..19aff61
--- /dev/null
+++ b/tests/language/regress/regress32353_2_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// The following compile-time error is expected:
+//
+// Error: 'D' can't implement both '#lib1::B<#lib1::D::X, #lib1::D::Y>' and
+// '#lib1::B<#lib1::D::X, #lib1::A>'
+// class D<X, Y> extends B<X, Y> with C<X> {}
+//       ~
+
+class A {}
+
+class B<X, Y> {}
+
+mixin C<X> on B<X, A> {}
+
+class /*@compile-error=unspecified*/ D<X, Y> extends B<X, Y> with C {}
+
+main() {}
diff --git a/tests/language/regress/regress32353_test.dart b/tests/language/regress/regress32353_test.dart
new file mode 100644
index 0000000..080d46d
--- /dev/null
+++ b/tests/language/regress/regress32353_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class io_FileSystemEntity {}
+
+class io_Directory extends io_FileSystemEntity {}
+
+class _LocalDirectory
+    extends _LocalFileSystemEntity<_LocalDirectory, io_Directory>
+    with ForwardingDirectory, DirectoryAddOnsMixin {
+  noSuchMethod(invocation) => null;
+}
+
+abstract class _LocalFileSystemEntity<T extends FileSystemEntity,
+    D extends io_FileSystemEntity> extends ForwardingFileSystemEntity<T, D> {}
+
+abstract class FileSystemEntity implements io_FileSystemEntity {}
+
+abstract class ForwardingFileSystemEntity<T extends FileSystemEntity,
+    D extends io_FileSystemEntity> implements FileSystemEntity {}
+
+mixin ForwardingDirectory<T extends Directory>
+    on ForwardingFileSystemEntity<T, io_Directory> implements Directory {
+  get t => T;
+}
+
+abstract class Directory implements FileSystemEntity, io_Directory {}
+
+abstract class DirectoryAddOnsMixin implements Directory {}
+
+main() {
+  var x = new _LocalDirectory();
+  Expect.equals(x.t, _LocalDirectory);
+}
diff --git a/tests/language/regress/regress32372_test.dart b/tests/language/regress/regress32372_test.dart
new file mode 100644
index 0000000..2ce2b42
--- /dev/null
+++ b/tests/language/regress/regress32372_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A extends Object with B<String>, C {}
+
+class B<T> {}
+
+mixin C<T> on B<T> {
+  get t => T;
+}
+
+main() {
+  var x = new A();
+  Expect.equals(x.t, String);
+}
diff --git a/tests/language/regress/regress32425_test.dart b/tests/language/regress/regress32425_test.dart
new file mode 100644
index 0000000..fe19937
--- /dev/null
+++ b/tests/language/regress/regress32425_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+import 'package:expect/expect.dart';
+
+class A<T> {}
+
+final map = {};
+
+class B<T> {
+  void foo() {
+    Expect.equals(map[new A<T>().runtimeType], 42);
+  }
+}
+
+class C<T, U> {
+  void build() {
+    new B<T>().foo();
+    new B<U>().foo();
+    Expect.equals(new B<T>().runtimeType, new B<U>().runtimeType);
+  }
+}
+
+void main() {
+  map[new A<String>().runtimeType] = 42;
+  new C<String, String>().build();
+}
diff --git a/tests/language/regress/regress32660_test.dart b/tests/language/regress/regress32660_test.dart
new file mode 100644
index 0000000..9ca6c0e
--- /dev/null
+++ b/tests/language/regress/regress32660_test.dart
@@ -0,0 +1,78 @@
+// 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.
+
+// noSuchMethod does not overwrite actual implementations, so if an
+// implemetation of a member exists that doesn't fulfill the interface it's
+// an error.
+// On the other hand, if no implementation exists,
+// noSuchMethod will take its place and everything is okay.
+
+class B {
+  foo(int x, // force formatter to not combine these lines.
+          {int? y} //# 02: compile-time error
+          ) =>
+      x;
+}
+
+class C extends B {
+  foo(int x, // force formatter to not combine these lines.
+      {int? y} //# 01: compile-time error
+      );
+  bar();
+
+  noSuchMethod(i) {
+    print("No such method!");
+    return 42;
+  }
+}
+
+abstract class D {
+  foo(int x, // force formatter to not combine these lines.
+      {int? y} //# 03: ok
+      );
+}
+
+abstract class E {
+  foo(int x, // force formatter to not combine these lines.
+      {int? y} //# 04: ok
+      );
+}
+
+class F extends D implements E {
+  noSuchMethod(i) {
+    print("No such method!");
+    return 42;
+  }
+}
+
+class G {
+  foo(int x, // force formatter to not combine these lines.
+          {int? y} //# 05: ok
+          ) =>
+      x;
+}
+
+class H {
+  foo(int x, // force formatter to not combine these lines.
+          {int? y} //# 06: compile-time error
+          ) =>
+      x;
+}
+
+class I extends G implements H {
+  noSuchMethod(i) {
+    print("No such method: $i!");
+    return 42;
+  }
+}
+
+main() {
+  var c = new C();
+  c.foo(123);
+  c.bar();
+  var f = new F();
+  f.foo(42);
+  var i = new I();
+  i.foo(42);
+}
diff --git a/tests/language/regress/regress33009_lib.dart b/tests/language/regress/regress33009_lib.dart
new file mode 100644
index 0000000..272b948
--- /dev/null
+++ b/tests/language/regress/regress33009_lib.dart
@@ -0,0 +1,8 @@
+// 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.
+
+class I<T> {
+  T? get foo => _foo;
+  T? _foo = null;
+}
diff --git a/tests/language/regress/regress33009_test.dart b/tests/language/regress/regress33009_test.dart
new file mode 100644
index 0000000..f951245
--- /dev/null
+++ b/tests/language/regress/regress33009_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+import 'regress33009_lib.dart';
+
+class A implements I<dynamic> {
+  dynamic get foo => 1;
+}
+
+main() {}
diff --git a/tests/language/regress/regress33235_01_runtime_test.dart b/tests/language/regress/regress33235_01_runtime_test.dart
new file mode 100644
index 0000000..7ca47d7
--- /dev/null
+++ b/tests/language/regress/regress33235_01_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+
+
+  static int get n {
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_01_test.dart b/tests/language/regress/regress33235_01_test.dart
new file mode 100644
index 0000000..2936782
--- /dev/null
+++ b/tests/language/regress/regress33235_01_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  C.n() {}
+//^
+// [cfe] Conflicts with member 'n'.
+//  ^
+// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD
+
+  static int get n {
+  //             ^
+  // [cfe] Conflicts with constructor 'C.n'.
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_02_runtime_test.dart b/tests/language/regress/regress33235_02_runtime_test.dart
new file mode 100644
index 0000000..8694344
--- /dev/null
+++ b/tests/language/regress/regress33235_02_runtime_test.dart
@@ -0,0 +1,22 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+
+
+  static int n() {
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_02_test.dart b/tests/language/regress/regress33235_02_test.dart
new file mode 100644
index 0000000..5d9156b
--- /dev/null
+++ b/tests/language/regress/regress33235_02_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  C.n() {}
+//^
+// [cfe] Conflicts with member 'n'.
+//  ^
+// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_CONSTRUCTOR_AND_STATIC_METHOD
+
+  static int n() {
+  //         ^
+  // [cfe] Conflicts with constructor 'C.n'.
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_03_runtime_test.dart b/tests/language/regress/regress33235_03_runtime_test.dart
new file mode 100644
index 0000000..01801f6
--- /dev/null
+++ b/tests/language/regress/regress33235_03_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+
+
+  static set n(int x) {}
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_03_test.dart b/tests/language/regress/regress33235_03_test.dart
new file mode 100644
index 0000000..c47118d
--- /dev/null
+++ b/tests/language/regress/regress33235_03_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  C.n() {}
+//^
+// [cfe] Conflicts with setter 'n'.
+//  ^
+// [analyzer] COMPILE_TIME_ERROR.CONFLICTING_CONSTRUCTOR_AND_STATIC_FIELD
+
+  static set n(int x) {}
+  //         ^
+  // [cfe] Conflicts with constructor 'n'.
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_04_runtime_test.dart b/tests/language/regress/regress33235_04_runtime_test.dart
new file mode 100644
index 0000000..56e2636
--- /dev/null
+++ b/tests/language/regress/regress33235_04_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+
+
+  static int n() => 42;
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_04_test.dart b/tests/language/regress/regress33235_04_test.dart
new file mode 100644
index 0000000..2214c0a
--- /dev/null
+++ b/tests/language/regress/regress33235_04_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  static int get n => 42;
+
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_05_runtime_test.dart b/tests/language/regress/regress33235_05_runtime_test.dart
new file mode 100644
index 0000000..d2d1f9d
--- /dev/null
+++ b/tests/language/regress/regress33235_05_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int get n => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_05_test.dart b/tests/language/regress/regress33235_05_test.dart
new file mode 100644
index 0000000..fa22f82
--- /dev/null
+++ b/tests/language/regress/regress33235_05_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 43;
+}
+
+class B extends A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+
+  int get n => 43;
+  //      ^
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_06_runtime_test.dart b/tests/language/regress/regress33235_06_runtime_test.dart
new file mode 100644
index 0000000..4d9123d
--- /dev/null
+++ b/tests/language/regress/regress33235_06_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int n() => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_06_test.dart b/tests/language/regress/regress33235_06_test.dart
new file mode 100644
index 0000000..3e36251
--- /dev/null
+++ b/tests/language/regress/regress33235_06_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+
+  int n() => 43;
+  //  ^
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_07_runtime_test.dart b/tests/language/regress/regress33235_07_runtime_test.dart
new file mode 100644
index 0000000..1100c43
--- /dev/null
+++ b/tests/language/regress/regress33235_07_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_07_test.dart b/tests/language/regress/regress33235_07_test.dart
new file mode 100644
index 0000000..9912e7c
--- /dev/null
+++ b/tests/language/regress/regress33235_07_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int get n => 42;
+  //             ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] This static member conflicts with an instance member.
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_08_runtime_test.dart b/tests/language/regress/regress33235_08_runtime_test.dart
new file mode 100644
index 0000000..d2d1f9d
--- /dev/null
+++ b/tests/language/regress/regress33235_08_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int get n => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_08_test.dart b/tests/language/regress/regress33235_08_test.dart
new file mode 100644
index 0000000..26aa457
--- /dev/null
+++ b/tests/language/regress/regress33235_08_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 43;
+}
+
+class B extends A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+
+  int get n => 43;
+  //      ^
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_09_runtime_test.dart b/tests/language/regress/regress33235_09_runtime_test.dart
new file mode 100644
index 0000000..4d9123d
--- /dev/null
+++ b/tests/language/regress/regress33235_09_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int n() => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_09_test.dart b/tests/language/regress/regress33235_09_test.dart
new file mode 100644
index 0000000..4e17aa0
--- /dev/null
+++ b/tests/language/regress/regress33235_09_test.dart
@@ -0,0 +1,41 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+
+  int n() => 43;
+  //  ^
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_10_runtime_test.dart b/tests/language/regress/regress33235_10_runtime_test.dart
new file mode 100644
index 0000000..1100c43
--- /dev/null
+++ b/tests/language/regress/regress33235_10_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_10_test.dart b/tests/language/regress/regress33235_10_test.dart
new file mode 100644
index 0000000..cdb84e5
--- /dev/null
+++ b/tests/language/regress/regress33235_10_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] This static member conflicts with an instance member.
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_11_runtime_test.dart b/tests/language/regress/regress33235_11_runtime_test.dart
new file mode 100644
index 0000000..56e2636
--- /dev/null
+++ b/tests/language/regress/regress33235_11_runtime_test.dart
@@ -0,0 +1,20 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+
+
+  static int n() => 42;
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_11_test.dart b/tests/language/regress/regress33235_11_test.dart
new file mode 100644
index 0000000..74710f4
--- /dev/null
+++ b/tests/language/regress/regress33235_11_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  static void set n(int i) {}
+  //              ^
+  // [cfe] Conflicts with member 'n'.
+
+  static int n() => 42;
+  //         ^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] Conflicts with setter 'n'.
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_12_runtime_test.dart b/tests/language/regress/regress33235_12_runtime_test.dart
new file mode 100644
index 0000000..777a912
--- /dev/null
+++ b/tests/language/regress/regress33235_12_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 42;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int get n => 42;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_12_test.dart b/tests/language/regress/regress33235_12_test.dart
new file mode 100644
index 0000000..c867285
--- /dev/null
+++ b/tests/language/regress/regress33235_12_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n => 42;
+}
+
+class B extends A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] This static member conflicts with an instance member.
+
+  int get n => 42;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_13_runtime_test.dart b/tests/language/regress/regress33235_13_runtime_test.dart
new file mode 100644
index 0000000..d5bd071
--- /dev/null
+++ b/tests/language/regress/regress33235_13_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 42;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int n() => 42;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_13_test.dart b/tests/language/regress/regress33235_13_test.dart
new file mode 100644
index 0000000..9369c01
--- /dev/null
+++ b/tests/language/regress/regress33235_13_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 42;
+}
+
+class B extends A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] This static member conflicts with an instance member.
+
+  int n() => 42;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_14_runtime_test.dart b/tests/language/regress/regress33235_14_runtime_test.dart
new file mode 100644
index 0000000..587dece
--- /dev/null
+++ b/tests/language/regress/regress33235_14_runtime_test.dart
@@ -0,0 +1,33 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+class A {
+  void set n(int x) {}
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  void set n(int x) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_14_test.dart b/tests/language/regress/regress33235_14_test.dart
new file mode 100644
index 0000000..0e9595e
--- /dev/null
+++ b/tests/language/regress/regress33235_14_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+class A {
+  void set n(int x) {}
+}
+
+class B extends A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  static void set n(int i) {}
+  //              ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_STATIC_AND_INSTANCE
+
+  void set n(int x) {}
+  //       ^
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_15_runtime_test.dart b/tests/language/regress/regress33235_15_runtime_test.dart
new file mode 100644
index 0000000..4d9123d
--- /dev/null
+++ b/tests/language/regress/regress33235_15_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int n() => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_15_test.dart b/tests/language/regress/regress33235_15_test.dart
new file mode 100644
index 0000000..0e4eb85
--- /dev/null
+++ b/tests/language/regress/regress33235_15_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+  int get n => 42;
+  //      ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  int get n => 42;
+  //      ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  int get n => 42;
+
+  int n() => 43;
+  //  ^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_16_runtime_test.dart b/tests/language/regress/regress33235_16_runtime_test.dart
new file mode 100644
index 0000000..4d9123d
--- /dev/null
+++ b/tests/language/regress/regress33235_16_runtime_test.dart
@@ -0,0 +1,34 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+
+}
+
+abstract class B2 implements A {
+
+}
+
+class C {
+
+
+  int n() => 43;
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_16_test.dart b/tests/language/regress/regress33235_16_test.dart
new file mode 100644
index 0000000..cd51ee4
--- /dev/null
+++ b/tests/language/regress/regress33235_16_test.dart
@@ -0,0 +1,40 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() => 43;
+}
+
+class B extends A {
+  void set n(int i) {}
+  //       ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+abstract class B2 implements A {
+  void set n(int i) {}
+  //       ^
+  // [analyzer] COMPILE_TIME_ERROR.CONFLICTING_FIELD_AND_METHOD
+  // [cfe] Can't declare a member that conflicts with an inherited one.
+}
+
+class C {
+  void set n(int i) {}
+
+  int n() => 43;
+  //  ^
+  // [analyzer] COMPILE_TIME_ERROR.DUPLICATE_DEFINITION
+  // [cfe] 'n' is already declared in this scope.
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_17_test.dart b/tests/language/regress/regress33235_17_test.dart
new file mode 100644
index 0000000..95ae7d7
--- /dev/null
+++ b/tests/language/regress/regress33235_17_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class C {
+  static void set n(int i) {}
+
+  static int get n {
+    return 43;
+  }
+}
+
+main() {
+  print(C);
+}
diff --git a/tests/language/regress/regress33235_18_test.dart b/tests/language/regress/regress33235_18_test.dart
new file mode 100644
index 0000000..ec72cb1
--- /dev/null
+++ b/tests/language/regress/regress33235_18_test.dart
@@ -0,0 +1,37 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+  int get n {
+    return 42;
+  }
+}
+
+abstract class B2 implements A {
+  int get n {
+    return 42;
+  }
+}
+
+class C {
+  int get n {
+    return 42;
+  }
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_19_test.dart b/tests/language/regress/regress33235_19_test.dart
new file mode 100644
index 0000000..999d661
--- /dev/null
+++ b/tests/language/regress/regress33235_19_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int n() {
+    return 42;
+  }
+}
+
+class B extends A {
+  B.n() {}
+}
+
+abstract class B2 implements A {
+  B2.n() {}
+}
+
+class C {
+  C.n() {}
+
+  int n() {
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_20_test.dart b/tests/language/regress/regress33235_20_test.dart
new file mode 100644
index 0000000..d312026
--- /dev/null
+++ b/tests/language/regress/regress33235_20_test.dart
@@ -0,0 +1,35 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  int get n {
+    return 42;
+  }
+}
+
+class B extends A {
+  B.n() {}
+}
+
+abstract class B2 implements A {
+  B2.n() {}
+}
+
+class C {
+  C.n() {}
+
+  int get n {
+    return 42;
+  }
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33235_21_test.dart b/tests/language/regress/regress33235_21_test.dart
new file mode 100644
index 0000000..b013bce
--- /dev/null
+++ b/tests/language/regress/regress33235_21_test.dart
@@ -0,0 +1,31 @@
+// 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.
+
+// Test for complience with tables at
+// https://github.com/dart-lang/sdk/issues/33235#issue-326617285
+// Files 01 to 16 should be compile time errors, files 17 to 21 should not.
+
+class A {
+  void set n(int i) {}
+}
+
+class B extends A {
+  B.n() {}
+}
+
+abstract class B2 implements A {
+  B2.n() {}
+}
+
+class C {
+  C.n() {}
+
+  void set n(int i) {}
+}
+
+main() {
+  print(C);
+  print(B);
+  print(B2);
+}
diff --git a/tests/language/regress/regress33392_test.dart b/tests/language/regress/regress33392_test.dart
new file mode 100644
index 0000000..18e2b73
--- /dev/null
+++ b/tests/language/regress/regress33392_test.dart
@@ -0,0 +1,16 @@
+// 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.
+
+import 'dart:async';
+import 'package:expect/expect.dart';
+
+class B extends A<B> {}
+
+class A<T> {
+  int x(FutureOr<T> v) => 42;
+}
+
+void main() {
+  Expect.equals(new B().x(new B()), 42);
+}
diff --git a/tests/language/regress/regress33479_runtime_test.dart b/tests/language/regress/regress33479_runtime_test.dart
new file mode 100644
index 0000000..c6f47a2
--- /dev/null
+++ b/tests/language/regress/regress33479_runtime_test.dart
@@ -0,0 +1,12 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+class Hest<TypeX extends Fisk> {}
+
+typedef Fisk = void Function // don't merge lines
+
+        ();
+
+main() {
+  Hest hest = new Hest();
+}
diff --git a/tests/language/regress/regress33479_test.dart b/tests/language/regress/regress33479_test.dart
new file mode 100644
index 0000000..0ede9fb
--- /dev/null
+++ b/tests/language/regress/regress33479_test.dart
@@ -0,0 +1,28 @@
+class Hest<TypeX extends Fisk> {}
+//                       ^^^^
+// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND
+
+typedef Fisk = void Function // don't merge lines
+// [error line 5, column 1, length 462]
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+//      ^
+// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
+    <TypeY extends Hest>
+    //             ^^^^
+    // [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
+        ();
+
+main() {
+  Hest hest = new Hest();
+//^^^^
+// [analyzer] COMPILE_TIME_ERROR.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT
+//     ^
+// [cfe] A generic function type can't be used as a type argument.
+//            ^^^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+//                ^^^^
+// [analyzer] COMPILE_TIME_ERROR.COULD_NOT_INFER
+// [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
+//                ^^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+}
diff --git a/tests/language/regress/regress34034_test.dart b/tests/language/regress/regress34034_test.dart
new file mode 100644
index 0000000..6dd5f71
--- /dev/null
+++ b/tests/language/regress/regress34034_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+dynamic bar(int Function(int) f) => f;
+T foo<T>(T a) => a;
+
+void main() {
+  final closure = bar(foo);
+  String s = closure.toString();
+  print(s);
+  Expect.isTrue(s.contains("(int) => int") || s.contains("with <int>"));
+}
diff --git a/tests/language/regress/regress34091.dart b/tests/language/regress/regress34091.dart
new file mode 100644
index 0000000..5756024
--- /dev/null
+++ b/tests/language/regress/regress34091.dart
@@ -0,0 +1,42 @@
+// 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.
+
+// Tests that stack traces from data URIs don't contain the entire URI, and
+// instead just have the substitute file name: <data:application/dart>
+
+import "dart:isolate";
+import "package:expect/expect.dart";
+import 'dart:async';
+
+void main() {
+  // This data URI encodes:
+  /*
+    import "dart:isolate";
+    void main(_, p){
+      try {
+        throw("Hello World");
+      } catch (e, s) {
+        p.send("$e\n$s");
+      }
+    }
+  */
+  final uri = Uri.parse(
+      "data:application/dart;charset=utf8,import%20%22dart%3Aisolate%22%3Bvoi" +
+          "d%20main(_%2Cp)%7Btry%7Bthrow(%22Hello%20World%22)%3B%7Dcatch(e%2C" +
+          "%20s)%7Bp.send(%22%24e%5Cn%24s%22)%3B%7D%7D");
+  ReceivePort port = new ReceivePort();
+  Isolate.spawnUri(uri, [], port.sendPort);
+  port.listen((trace) {
+    // Test that the trace contains the exception message.
+    Expect.isTrue(trace.contains("Hello World"));
+
+    // Test that the trace contains data URI substitute.
+    Expect.isTrue(trace.contains("<data:application/dart>"));
+
+    // Test that the trace doesn't contain any leftover URL encoded junk.
+    Expect.isFalse(trace.contains("%20"));
+
+    port.close();
+  });
+}
diff --git a/tests/language/regress/regress34147_test.dart b/tests/language/regress/regress34147_test.dart
new file mode 100644
index 0000000..20ab478
--- /dev/null
+++ b/tests/language/regress/regress34147_test.dart
@@ -0,0 +1,80 @@
+// 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';
+
+void main() {
+  conditionalTest();
+  orTest();
+  andTest();
+  ifTest();
+  forTest();
+  whileTest();
+  doTest();
+  notTest();
+}
+
+void expectError(Function() callback) {
+  if (isWeakMode) {
+    Expect.throwsAssertionError(callback);
+  } else {
+    Expect.throwsTypeError(callback);
+  }
+}
+
+void conditionalTest() {
+  dynamic x = null;
+  expectError(() => x ? 1 : 0);
+}
+
+void orTest() {
+  dynamic x = null;
+  expectError(() => x || x);
+  expectError(() => x || false);
+  expectError(() => x || true);
+  expectError(() => false || x);
+  Expect.isTrue(true || x);
+}
+
+void andTest() {
+  dynamic x = null;
+  expectError(() => x && x);
+  expectError(() => x && false);
+  expectError(() => x && true);
+  Expect.isFalse(false && x);
+  expectError(() => true && x);
+}
+
+void ifTest() {
+  dynamic x = null;
+  expectError(() {
+    if (x) {}
+  });
+}
+
+void forTest() {
+  dynamic x = null;
+  expectError(() {
+    for (; x;) {}
+  });
+}
+
+void whileTest() {
+  dynamic x = null;
+  expectError(() {
+    while (x) {}
+  });
+}
+
+void doTest() {
+  dynamic x = null;
+  expectError(() {
+    do {} while (x);
+  });
+}
+
+void notTest() {
+  dynamic x = null;
+  expectError(() => !x);
+}
diff --git a/tests/language/regress/regress34225_test.dart b/tests/language/regress/regress34225_test.dart
new file mode 100644
index 0000000..0117672
--- /dev/null
+++ b/tests/language/regress/regress34225_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+class C {
+  static set C(v) {} //# 01: compile-time error
+  set C(v) {} //# 02: compile-time error
+}
+
+main() {
+  new C();
+}
diff --git a/tests/language/regress/regress34235_runtime_test.dart b/tests/language/regress/regress34235_runtime_test.dart
new file mode 100644
index 0000000..9cedc8e
--- /dev/null
+++ b/tests/language/regress/regress34235_runtime_test.dart
@@ -0,0 +1,29 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Base {
+  void foo() {}
+}
+
+class M1 {
+  void foo(
+      // Prevent formatter from joining the line below to the one above
+
+      ) {}
+}
+
+class BaseWithM1 = Base with M1;
+
+class M2 {
+  void foo() {}
+}
+
+class Derived extends BaseWithM1 with M2 {}
+
+main() {
+  new Derived().foo();
+}
diff --git a/tests/language/regress/regress34235_test.dart b/tests/language/regress/regress34235_test.dart
new file mode 100644
index 0000000..7451dc5
--- /dev/null
+++ b/tests/language/regress/regress34235_test.dart
@@ -0,0 +1,30 @@
+// 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.
+
+class Base {
+  void foo() {}
+}
+
+class M1 {
+  void foo(
+      // Prevent formatter from joining the line below to the one above
+      {x}
+      ) {}
+}
+
+class BaseWithM1 = Base with M1;
+
+class M2 {
+  void foo() {}
+}
+
+class Derived extends BaseWithM1 with M2 {}
+//    ^^^^^^^
+// [cfe] Applying the mixin 'M2' to 'BaseWithM1' introduces an erroneous override of 'foo'.
+//                                    ^^
+// [analyzer] COMPILE_TIME_ERROR.INVALID_OVERRIDE
+
+main() {
+  new Derived().foo();
+}
diff --git a/tests/language/regress/regress34392_test.dart b/tests/language/regress/regress34392_test.dart
new file mode 100644
index 0000000..286d8e1
--- /dev/null
+++ b/tests/language/regress/regress34392_test.dart
@@ -0,0 +1,19 @@
+// 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.
+
+abstract class I {
+  foo([a]);
+}
+
+abstract class A {
+  foo() {}
+}
+
+abstract class B extends A implements I {}
+
+class C extends B {
+  foo([a]) {}
+}
+
+void main() {}
diff --git a/tests/language/regress/regress34404_flutter_modified_test.dart b/tests/language/regress/regress34404_flutter_modified_test.dart
new file mode 100644
index 0000000..b78202a
--- /dev/null
+++ b/tests/language/regress/regress34404_flutter_modified_test.dart
@@ -0,0 +1,33 @@
+// 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.
+
+// This test case is a reduction of some Flutter code, modified to use the new
+// mixin syntax.  We wish to verify that the class _DismissibleState doesn't
+// have any type inference errors.
+
+class _DismissibleState extends State<Dismissible>
+    with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {}
+
+abstract class State<T extends StatefulWidget> extends Diagnosticable {}
+
+abstract class StatefulWidget extends Widget {}
+
+abstract class Widget extends DiagnosticableTree {}
+
+abstract class DiagnosticableTree extends Diagnosticable {}
+
+abstract class Diagnosticable {}
+
+class Dismissible extends StatefulWidget {}
+
+mixin TickerProviderStateMixin<T extends StatefulWidget> on State<T>
+    implements TickerProvider {}
+
+abstract class TickerProvider {}
+
+mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {}
+
+main() {
+  new _DismissibleState();
+}
diff --git a/tests/language/regress/regress34404_flutter_test.dart b/tests/language/regress/regress34404_flutter_test.dart
new file mode 100644
index 0000000..2e71697
--- /dev/null
+++ b/tests/language/regress/regress34404_flutter_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+// This test case is a reduction of some Flutter code.  We wish to verify that
+// the class _DismissibleState doesn't have any type inference errors.
+
+class _DismissibleState extends State<Dismissible>
+    with TickerProviderStateMixin, AutomaticKeepAliveClientMixin {}
+
+abstract class State<T extends StatefulWidget> extends Diagnosticable {}
+
+abstract class StatefulWidget extends Widget {}
+
+abstract class Widget extends DiagnosticableTree {}
+
+abstract class DiagnosticableTree extends Diagnosticable {}
+
+abstract class Diagnosticable {}
+
+class Dismissible extends StatefulWidget {}
+
+mixin TickerProviderStateMixin<T extends StatefulWidget> on State<T>
+    implements TickerProvider {}
+
+abstract class TickerProvider {}
+
+mixin AutomaticKeepAliveClientMixin<T extends StatefulWidget> on State<T> {}
+
+main() {
+  new _DismissibleState();
+}
diff --git a/tests/language/regress/regress34482_test.dart b/tests/language/regress/regress34482_test.dart
new file mode 100644
index 0000000..80b6337
--- /dev/null
+++ b/tests/language/regress/regress34482_test.dart
@@ -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.
+
+import 'dart:async';
+
+main() {
+  Future f = new Future(() => 12345);
+  Future<FutureOr> f1 = f;
+
+  FutureOr fo = f;
+  f1 = fo as Future<FutureOr>;
+}
diff --git a/tests/language/regress/regress34488_runtime_test.dart b/tests/language/regress/regress34488_runtime_test.dart
new file mode 100644
index 0000000..03485de
--- /dev/null
+++ b/tests/language/regress/regress34488_runtime_test.dart
@@ -0,0 +1,35 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+abstract class Base {
+  void f(int i);
+  void g([int i]);
+  void h({int i});
+}
+
+abstract class Mixin implements Base {}
+
+class Derived extends Object with Mixin {
+  // Type `(int) -> void` should be inherited from `Base`
+  f(i) {}
+
+  // Type `([int]) -> void` should be inherited from `Base`
+  g([i = -1]) {}
+
+  // Type `({h: int}) -> void` should be inherited from `Base`
+  h({i = -1}) {}
+}
+
+main() {
+  var d = new Derived();
+
+
+
+
+
+
+}
diff --git a/tests/language/regress/regress34488_test.dart b/tests/language/regress/regress34488_test.dart
new file mode 100644
index 0000000..ca3ac7b
--- /dev/null
+++ b/tests/language/regress/regress34488_test.dart
@@ -0,0 +1,51 @@
+// 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.
+
+abstract class Base {
+  void f(int i);
+  void g([int i]);
+  void h({int i});
+}
+
+abstract class Mixin implements Base {}
+
+class Derived extends Object with Mixin {
+  // Type `(int) -> void` should be inherited from `Base`
+  f(i) {}
+
+  // Type `([int]) -> void` should be inherited from `Base`
+  g([i = -1]) {}
+
+  // Type `({h: int}) -> void` should be inherited from `Base`
+  h({i = -1}) {}
+}
+
+main() {
+  var d = new Derived();
+  d.f('bad');
+  //  ^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
+  d.g('bad');
+  //  ^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
+  d.h(i: 'bad');
+  //  ^^^^^^^^
+  // [analyzer] STATIC_WARNING.ARGUMENT_TYPE_NOT_ASSIGNABLE
+  //     ^
+  // [cfe] The argument type 'String' can't be assigned to the parameter type 'int'.
+  Object x = d.f(1);
+  //           ^
+  // [analyzer] STATIC_WARNING.USE_OF_VOID_RESULT
+  // [cfe] This expression has type 'void' and can't be used.
+  Object y = d.g(1);
+  //           ^
+  // [analyzer] STATIC_WARNING.USE_OF_VOID_RESULT
+  // [cfe] This expression has type 'void' and can't be used.
+  Object z = d.h(i: 1);
+  //           ^
+  // [analyzer] STATIC_WARNING.USE_OF_VOID_RESULT
+  // [cfe] This expression has type 'void' and can't be used.
+}
diff --git a/tests/language/regress/regress34489_runtime_test.dart b/tests/language/regress/regress34489_runtime_test.dart
new file mode 100644
index 0000000..8cadeed
--- /dev/null
+++ b/tests/language/regress/regress34489_runtime_test.dart
@@ -0,0 +1,14 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class C<T> {
+  var field = T;
+}
+
+main() {
+
+}
diff --git a/tests/language/regress/regress34489_test.dart b/tests/language/regress/regress34489_test.dart
new file mode 100644
index 0000000..a29cab8
--- /dev/null
+++ b/tests/language/regress/regress34489_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+class C<T> {
+  var field = T;
+}
+
+main() {
+  new C().field = 'bad';
+  //              ^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.INVALID_ASSIGNMENT
+  // [cfe] A value of type 'String' can't be assigned to a variable of type 'Type'.
+}
diff --git a/tests/language/regress/regress34495_runtime_test.dart b/tests/language/regress/regress34495_runtime_test.dart
new file mode 100644
index 0000000..f31c56d
--- /dev/null
+++ b/tests/language/regress/regress34495_runtime_test.dart
@@ -0,0 +1,10 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+
+
+main() {}
diff --git a/tests/language/regress/regress34495_test.dart b/tests/language/regress/regress34495_test.dart
new file mode 100644
index 0000000..cce9bfe
--- /dev/null
+++ b/tests/language/regress/regress34495_test.dart
@@ -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.
+
+final foo = A<B>.foo();
+//          ^
+// [analyzer] STATIC_WARNING.NEW_WITH_NON_TYPE
+// [cfe] Method not found: 'A'.
+//            ^
+// [analyzer] STATIC_TYPE_WARNING.NON_TYPE_AS_TYPE_ARGUMENT
+// [cfe] 'B' isn't a type.
+
+main() {}
diff --git a/tests/language/regress/regress34498_test.dart b/tests/language/regress/regress34498_test.dart
new file mode 100644
index 0000000..e5b3f45
--- /dev/null
+++ b/tests/language/regress/regress34498_test.dart
@@ -0,0 +1,14 @@
+// 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.
+
+import 'dart:core';
+import 'dart:core' as core;
+
+class A {
+  /*@compile-error=unspecified*/ core.List get core => throw "uncalled";
+}
+
+main() {
+  new A().core;
+}
diff --git a/tests/language/regress/regress34514_test.dart b/tests/language/regress/regress34514_test.dart
new file mode 100644
index 0000000..063c500
--- /dev/null
+++ b/tests/language/regress/regress34514_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+// Inferred type should be `int`
+var x = (() => 1)();
+
+main() {
+  /*@compile-error=unspecified*/ x = 'bad'; // `String` not assignable to `int`
+}
diff --git a/tests/language/regress/regress34532_test.dart b/tests/language/regress/regress34532_test.dart
new file mode 100644
index 0000000..da30e3b
--- /dev/null
+++ b/tests/language/regress/regress34532_test.dart
@@ -0,0 +1,12 @@
+// 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.
+
+class Foo<T> {}
+
+class Bar<T extends Foo<T>> {}
+
+// Should be error here, because Bar completes to Bar<Foo>
+class Baz extends /*@compile-error=unspecified*/ Bar {}
+
+void main() {}
diff --git a/tests/language/regress/regress34635_test.dart b/tests/language/regress/regress34635_test.dart
new file mode 100644
index 0000000..6d1c6c8
--- /dev/null
+++ b/tests/language/regress/regress34635_test.dart
@@ -0,0 +1,9 @@
+// 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.
+
+class /*@compile-error=unspecified*/ A<X extends C> {}
+
+class /*@compile-error=unspecified*/ C<X extends C> {}
+
+main() {}
diff --git a/tests/language/regress/regress34636_test.dart b/tests/language/regress/regress34636_test.dart
new file mode 100644
index 0000000..242eea0
--- /dev/null
+++ b/tests/language/regress/regress34636_test.dart
@@ -0,0 +1,11 @@
+// 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.
+
+class /*@compile-error=unspecified*/ A<X extends B> {}
+
+class /*@compile-error=unspecified*/ B<X extends C> {}
+
+class /*@compile-error=unspecified*/ C<X extends A<B>> {}
+
+main() {}
diff --git a/tests/language/regress/regress34870_test.dart b/tests/language/regress/regress34870_test.dart
new file mode 100644
index 0000000..750048d
--- /dev/null
+++ b/tests/language/regress/regress34870_test.dart
@@ -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.
+
+// Regression test: superclass is not shadowed by class members.
+
+class A extends B {
+  B() {}
+}
+
+class B {}
+
+main() {}
diff --git a/tests/language/regress/regress34877_test.dart b/tests/language/regress/regress34877_test.dart
new file mode 100644
index 0000000..08ce3d4
--- /dev/null
+++ b/tests/language/regress/regress34877_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+// Regression test: ensure that async for loops remain async for loops when
+// mixed in.
+
+import 'dart:async';
+
+abstract class _Mixin {
+  Future<int> stuff(Stream<int> values) async {
+    var total = 0;
+    await for (var value in values) {
+      total += value;
+    }
+    return total;
+  }
+}
+
+class Implementation extends Object with _Mixin {}
+
+void main() async {
+  print(await Implementation().stuff(Stream.fromIterable([1, 2, 3])));
+}
diff --git a/tests/language/regress/regress34896_test.dart b/tests/language/regress/regress34896_test.dart
new file mode 100644
index 0000000..d0073b2
--- /dev/null
+++ b/tests/language/regress/regress34896_test.dart
@@ -0,0 +1,20 @@
+// 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.
+
+// Regression test: verify super-signatures of super-invoked methods of a
+// mixin against the superclass, not signatures in the mixin.
+
+class A<T> {
+  void remove(T x) {}
+}
+
+mixin M<U> on A<U> {
+  void remove(Object? x) {
+    super.remove(x as U);
+  }
+}
+
+class X<T> = A<T> with M<T>;
+
+main() {}
diff --git a/tests/language/regress/regress34907_test.dart b/tests/language/regress/regress34907_test.dart
new file mode 100644
index 0000000..42117ec
--- /dev/null
+++ b/tests/language/regress/regress34907_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class C<T> {}
+
+mixin M<T> on C<T> {}
+
+M<T> f<T>() {
+  Expect.equals(T, int);
+  // Don't have a value of M<T> to return, so throw and catch below.
+  throw "no value";
+}
+
+main() {
+  try {
+    C<int> c = f();
+  } catch (error) {
+    Expect.equals("no value", error);
+  }
+}
diff --git a/tests/language/regress/regress35043_runtime_test.dart b/tests/language/regress/regress35043_runtime_test.dart
new file mode 100644
index 0000000..f31c56d
--- /dev/null
+++ b/tests/language/regress/regress35043_runtime_test.dart
@@ -0,0 +1,10 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+
+
+main() {}
diff --git a/tests/language/regress/regress35043_test.dart b/tests/language/regress/regress35043_test.dart
new file mode 100644
index 0000000..884f707
--- /dev/null
+++ b/tests/language/regress/regress35043_test.dart
@@ -0,0 +1,10 @@
+// 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.
+
+final foo = Map<int>();
+//          ^^^^^^^^
+// [analyzer] STATIC_TYPE_WARNING.WRONG_NUMBER_OF_TYPE_ARGUMENTS
+// [cfe] Expected 2 type arguments.
+
+main() {}
diff --git a/tests/language/regress/regress35090_test.dart b/tests/language/regress/regress35090_test.dart
new file mode 100644
index 0000000..3e3c564
--- /dev/null
+++ b/tests/language/regress/regress35090_test.dart
@@ -0,0 +1,32 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+class A {
+  int get g => 0;
+}
+
+class C implements A {
+  noSuchMethod(Invocation i) {
+    return 1;
+  }
+}
+
+mixin M on A {
+  int test() {
+    return super.g;
+  }
+
+  noSuchMethod(Invocation i) {
+    return 2;
+  }
+}
+
+class MA extends C with M {}
+
+main() {
+  Expect.equals(new MA().g, 2);
+  Expect.equals(new MA().test(), 2);
+}
diff --git a/tests/language/regress/regress35258_runtime_test.dart b/tests/language/regress/regress35258_runtime_test.dart
new file mode 100644
index 0000000..480fd21
--- /dev/null
+++ b/tests/language/regress/regress35258_runtime_test.dart
@@ -0,0 +1,17 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+main() {
+  new C(42);
+}
+
+class C {
+  final d;
+
+
+  C(this.d) {}
+}
diff --git a/tests/language/regress/regress35258_test.dart b/tests/language/regress/regress35258_test.dart
new file mode 100644
index 0000000..f28bada
--- /dev/null
+++ b/tests/language/regress/regress35258_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+main() {
+  new C(42);
+  //  ^
+  // [cfe] Can't use 'C' because it is declared more than once.
+  //   ^^^^
+  // [analyzer] COMPILE_TIME_ERROR.EXTRA_POSITIONAL_ARGUMENTS
+}
+
+class C {
+  final d;
+  //    ^
+  // [cfe] Final field 'd' is not initialized.
+
+  C() {}
+//^
+// [analyzer] STATIC_WARNING.FINAL_NOT_INITIALIZED_CONSTRUCTOR
+  C(this.d) {}
+//^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
+// [cfe] 'C' is already declared in this scope.
+}
diff --git a/tests/language/regress/regress35259_runtime_test.dart b/tests/language/regress/regress35259_runtime_test.dart
new file mode 100644
index 0000000..cabe50a
--- /dev/null
+++ b/tests/language/regress/regress35259_runtime_test.dart
@@ -0,0 +1,15 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Supertype {
+
+
+}
+
+main() {
+  print(new Supertype());
+}
diff --git a/tests/language/regress/regress35259_test.dart b/tests/language/regress/regress35259_test.dart
new file mode 100644
index 0000000..eb9b24c
--- /dev/null
+++ b/tests/language/regress/regress35259_test.dart
@@ -0,0 +1,28 @@
+// 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.
+
+class Supertype {
+  factory Supertype() = Unresolved;
+  //                    ^^^^^^^^^^
+  // [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CLASS
+  // [cfe] Couldn't find constructor 'Unresolved'.
+  //                    ^
+  // [cfe] Redirection constructor target not found: 'Unresolved'
+  factory Supertype() = Unresolved;
+//        ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
+//        ^
+// [cfe] 'Supertype' is already declared in this scope.
+//                      ^^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CLASS
+// [cfe] Couldn't find constructor 'Unresolved'.
+//                      ^
+// [cfe] Redirection constructor target not found: 'Unresolved'
+}
+
+main() {
+  print(new Supertype());
+  //        ^
+  // [cfe] Can't use 'Supertype' because it is declared more than once.
+}
diff --git a/tests/language/regress/regress35260_runtime_test.dart b/tests/language/regress/regress35260_runtime_test.dart
new file mode 100644
index 0000000..b8ce1a7
--- /dev/null
+++ b/tests/language/regress/regress35260_runtime_test.dart
@@ -0,0 +1,19 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class Supertype {
+  factory Supertype() = X;
+
+}
+
+class X implements Supertype {
+  X();
+}
+
+main() {
+  X x = new Supertype() as X;
+}
diff --git a/tests/language/regress/regress35260_test.dart b/tests/language/regress/regress35260_test.dart
new file mode 100644
index 0000000..e2d5622
--- /dev/null
+++ b/tests/language/regress/regress35260_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+class Supertype {
+  factory Supertype() = X;
+  factory Supertype() = X;
+//        ^^^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
+//        ^
+// [cfe] 'Supertype' is already declared in this scope.
+}
+
+class X implements Supertype {
+  X();
+}
+
+main() {
+  X x = new Supertype() as X;
+  //        ^
+  // [cfe] Can't use 'Supertype' because it is declared more than once.
+}
diff --git a/tests/language/regress/regress35266_runtime_test.dart b/tests/language/regress/regress35266_runtime_test.dart
new file mode 100644
index 0000000..00ff9ca
--- /dev/null
+++ b/tests/language/regress/regress35266_runtime_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+class B<T> extends C<T> {
+  B();
+  factory B.foo() = B<T>;
+
+}
+
+class C<K> {
+  C();
+  factory C.bar() = B<K>.foo;
+}
+
+main() {
+  new C.bar();
+}
diff --git a/tests/language/regress/regress35266_test.dart b/tests/language/regress/regress35266_test.dart
new file mode 100644
index 0000000..713c328
--- /dev/null
+++ b/tests/language/regress/regress35266_test.dart
@@ -0,0 +1,24 @@
+// 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.
+
+class B<T> extends C<T> {
+  B();
+  factory B.foo() = B<T>;
+  factory B.foo() = B<T>;
+//        ^^^^^
+// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
+//        ^
+// [cfe] 'B.foo' is already declared in this scope.
+}
+
+class C<K> {
+  C();
+  factory C.bar() = B<K>.foo;
+  //                ^
+  // [cfe] Can't use 'B.foo' because it is declared more than once.
+}
+
+main() {
+  new C.bar();
+}
diff --git a/tests/language/regress/regress35542_test.dart b/tests/language/regress/regress35542_test.dart
new file mode 100644
index 0000000..9b4a217
--- /dev/null
+++ b/tests/language/regress/regress35542_test.dart
@@ -0,0 +1,33 @@
+// 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 'dart:async';
+import 'package:expect/expect.dart';
+
+FutureOr<dynamic> x = 'abc';
+dynamic y = 'abc';
+
+void smi() {
+  x = 42;
+  y = 42;
+}
+
+void mint() {
+  x = 0x7fffffff00000000;
+  y = 0x7fffffff00000000;
+}
+
+void dbl() {
+  x = 1.0;
+  y = 1.0;
+}
+
+void main() {
+  smi();
+  Expect.isTrue(identical(x, y));
+  mint();
+  Expect.isTrue(identical(x, y));
+  dbl();
+  Expect.isTrue(identical(x, y));
+}
diff --git a/tests/language/regress/regress36084_test.dart b/tests/language/regress/regress36084_test.dart
new file mode 100644
index 0000000..942e943
--- /dev/null
+++ b/tests/language/regress/regress36084_test.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.
+
+import "package:expect/expect.dart";
+
+class A {
+  void call(int a, [int b = -1]) {}
+}
+
+class A1 {
+  void call(int a, [int b = -1]) {}
+  int noSuchMethod(Invocation invocation) {
+    return 42;
+  }
+}
+
+class A2 {
+  // Same as A1 but without a call method.
+  int noSuchMethod(Invocation invocation) {
+    return 42;
+  }
+}
+
+class B {
+  dynamic foo;
+  dynamic get bar => foo;
+}
+
+class B1 {
+  dynamic foo;
+  dynamic get bar => foo;
+
+  noSuchMethod(Invocation invocation) {
+    Expect.fail('B1.noSuchMethod should not be called.');
+  }
+}
+
+main() {
+  B b = new B();
+  b.foo = new A();
+  Expect.throwsNoSuchMethodError(() => b.foo(1, 2, 3));
+  Expect.throwsNoSuchMethodError(() => b.bar(1, 2, 3));
+  b.foo = new A1();
+  Expect.equals(42, b.foo(1, 2, 3));
+  Expect.equals(42, b.bar(1, 2, 3));
+  b.foo = new A2();
+  Expect.equals(42, b.foo(1, 2, 3));
+  Expect.equals(42, b.bar(1, 2, 3));
+
+  // Same test but with B1, which has its own `noSuchMethod()` handler.
+  B1 b1 = new B1();
+  b1.foo = new A();
+  Expect.throwsNoSuchMethodError(() => b1.foo(1, 2, 3));
+  Expect.throwsNoSuchMethodError(() => b1.bar(1, 2, 3));
+  b1.foo = new A1();
+  Expect.equals(42, b1.foo(1, 2, 3));
+  Expect.equals(42, b1.bar(1, 2, 3));
+  b1.foo = new A2();
+  Expect.equals(42, b1.foo(1, 2, 3));
+  Expect.equals(42, b1.bar(1, 2, 3));
+}
diff --git a/tests/language/regress/regress3806_test.dart b/tests/language/regress/regress3806_test.dart
new file mode 100644
index 0000000..16cfa13
--- /dev/null
+++ b/tests/language/regress/regress3806_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+// Dart2js produced a statement in an expression context for this test.
+
+class A {
+  dynamic foo = "foo";
+  bar(x) {
+    if (foo == 3) return;
+    var t = x;
+    if (x == 0) t = foo;
+    foo = t;
+  }
+
+  toto(x) => x;
+  titi() {
+    foo = 0;
+    for (int i = 0; i < 3; i++) bar(i);
+  }
+}
+
+main() => new A().titi();
diff --git a/tests/language/regress/regress38816_test.dart b/tests/language/regress/regress38816_test.dart
new file mode 100644
index 0000000..840e082
--- /dev/null
+++ b/tests/language/regress/regress38816_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";
+
+void foo<T extends num>(T x) {}
+void bar<T extends num>(num x) {}
+
+typedef F = Function<T extends num>(T x);
+
+void main() {
+  Expect.isTrue(foo is F);
+  Expect.isTrue(bar is F);
+}
diff --git a/tests/language/regress/regress40066_test.dart b/tests/language/regress/regress40066_test.dart
new file mode 100644
index 0000000..caa08a4
--- /dev/null
+++ b/tests/language/regress/regress40066_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.
+
+import "package:expect/expect.dart";
+
+class A<T> {
+  foo(T x) {
+    print('T = $T');
+    print('x.runtimeType = ${x.runtimeType}');
+    print('x is T = ${x is T}');
+  }
+}
+
+typedef IntFunc = void Function(int);
+typedef StringFunc = void Function(String);
+
+void main() {
+  void inner<S>(S y) {}
+
+  IntFunc innerOfInt = inner;
+  A a = new A<IntFunc>();
+  a.foo(innerOfInt);
+
+  StringFunc innerOfString = inner;
+  Expect.throwsTypeError(() {
+    a.foo(innerOfString);
+  });
+}
diff --git a/tests/language/regress/regress4157508_test.dart b/tests/language/regress/regress4157508_test.dart
new file mode 100644
index 0000000..af08c9d
--- /dev/null
+++ b/tests/language/regress/regress4157508_test.dart
@@ -0,0 +1,17 @@
+// 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.
+
+class Issue4157508Test {
+  Issue4157508Test(var v) {
+    var d = new DateTime.fromMillisecondsSinceEpoch(v, isUtc: true);
+  }
+
+  static void testMain() {
+    var d = new Issue4157508Test(0);
+  }
+}
+
+main() {
+  Issue4157508Test.testMain();
+}
diff --git a/tests/language/regress/regress4295001_test.dart b/tests/language/regress/regress4295001_test.dart
new file mode 100644
index 0000000..5e42348
--- /dev/null
+++ b/tests/language/regress/regress4295001_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+class Issue4295001Test {
+  String foo;
+  Issue4295001Test(String s) : this.foo = s {
+    var f = () => s;
+  }
+
+  static void testMain() {
+    var d = new Issue4295001Test("Hello");
+  }
+}
+
+main() {
+  Issue4295001Test.testMain();
+}
diff --git a/tests/language/regress/regress4515170_test.dart b/tests/language/regress/regress4515170_test.dart
new file mode 100644
index 0000000..b187204
--- /dev/null
+++ b/tests/language/regress/regress4515170_test.dart
@@ -0,0 +1,16 @@
+// 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 "package:expect/expect.dart";
+
+class Issue4515170Test {
+  static const VAL = 3;
+  static int defaultVal([int a = VAL]) {
+    return a;
+  }
+}
+
+main() {
+  Expect.equals(3, Issue4515170Test.defaultVal());
+}
diff --git a/tests/language/regress/regress6725_part.dart b/tests/language/regress/regress6725_part.dart
new file mode 100644
index 0000000..8687837
--- /dev/null
+++ b/tests/language/regress/regress6725_part.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for a crash in dart2js.
+
+part of crash_6725;
+
+class Fisk {
+  it1(x) {
+    // "key" is unresolved and caused a crash in dart2js.
+    // This is the original example the user reported.
+    for (key in x) {
+      print(key);
+    }
+  }
+
+  it2(x) {
+    // "length" is "intercepted" and handled differently from other
+    // names when an instance of list is observed.
+    for (length in x) {
+      print(length);
+    }
+  }
+
+  it3(x) {
+    // We're pretty sure that there's no "fisk" that is "intercepted".
+    for (fisk in x) {
+      print(fisk);
+    }
+  }
+}
+
+class SubFisk extends Fisk {
+  var key;
+  var length;
+  var fisk;
+}
+
+test() {
+  Fisk f = new SubFisk();
+  var m = (x) {
+    for (undeclared in x) {
+      print(undeclared);
+    }
+  };
+  if (new DateTime.now().millisecondsSinceEpoch == 42) {
+    f = null;
+    m = (x) {};
+  }
+
+  f.it1([87, 42]);
+  if (f.key != 42) {
+    throw 'f.key != 42 (${f.key})';
+  }
+
+  f.it2([87, 42]);
+  if (f.length != 42) {
+    throw 'f.length != 42 (${f.length})';
+  }
+
+  f.it3([87, 42]);
+  if (f.fisk != 42) {
+    throw 'f.fisk != 42 (${f.fisk})';
+  }
+
+  try {
+    m([87, 42]);
+    throw 'NoSuchMethodError expected';
+  } on NoSuchMethodError {
+    // Expected.
+  }
+}
diff --git a/tests/language/regress/regress6725_runtime_test.dart b/tests/language/regress/regress6725_runtime_test.dart
new file mode 100644
index 0000000..6b07ac0
--- /dev/null
+++ b/tests/language/regress/regress6725_runtime_test.dart
@@ -0,0 +1,16 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2013, 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.
+
+// Regression test for a crash in dart2js.
+
+library crash_6725;
+
+
+
+main() {
+
+}
diff --git a/tests/language/regress/regress6725_test.dart b/tests/language/regress/regress6725_test.dart
new file mode 100644
index 0000000..96df166
--- /dev/null
+++ b/tests/language/regress/regress6725_test.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for a crash in dart2js.
+
+library crash_6725;
+
+part 'regress6725_part.dart'; //# 01: compile-time error
+
+main() {
+  test(); //# 01: continued
+}
diff --git a/tests/language/regress/regress7513_test.dart b/tests/language/regress/regress7513_test.dart
new file mode 100644
index 0000000..5df021b
--- /dev/null
+++ b/tests/language/regress/regress7513_test.dart
@@ -0,0 +1,22 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Regression test for issue 7513.
+
+foo(a, b) {
+  b[0] = 0.1;
+  return a * b[0];
+}
+
+main() {
+  var a = 0.1;
+  var b = [0.1];
+  for (var i = 0; i < 20; i++) {
+    foo(a, b);
+  }
+  Expect.approxEquals(0.01, foo(a, b));
+}
diff --git a/tests/language/regress/regress7525_test.dart b/tests/language/regress/regress7525_test.dart
new file mode 100644
index 0000000..c7fe377
--- /dev/null
+++ b/tests/language/regress/regress7525_test.dart
@@ -0,0 +1,22 @@
+// 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.
+// VMOptions=--optimization-counter-threshold=10 --no-use-osr --no-background-compilation
+
+import "package:expect/expect.dart";
+
+// Regression test for issue 7525.
+
+foo() {
+  var ol = <int>[2];
+  (ol as List<int>)[0];
+  int x = (ol as List<int>)[0];
+  return x;
+}
+
+main() {
+  for (int i = 0; i < 20; i++) {
+    foo();
+  }
+  Expect.equals(2, foo());
+}
diff --git a/tests/language/regress/regress9602_other.dart b/tests/language/regress/regress9602_other.dart
new file mode 100644
index 0000000..a189b77
--- /dev/null
+++ b/tests/language/regress/regress9602_other.dart
@@ -0,0 +1,10 @@
+// Copyright (c) 2013, 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.
+
+// Regression test case for http://dartbug.com/9602
+library issue9602_other;
+
+class M {
+  var _field;
+}
diff --git a/tests/language/regress/regress9602_test.dart b/tests/language/regress/regress9602_test.dart
new file mode 100644
index 0000000..8900388
--- /dev/null
+++ b/tests/language/regress/regress9602_test.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2013, 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.
+
+// Regression test case for http://dartbug.com/9602
+library issue9602;
+
+import 'regress9602_other.dart';
+
+class C extends Object with M {}
+
+main() {
+  new C();
+}
diff --git a/tests/language/regress/regress9664_test.dart b/tests/language/regress/regress9664_test.dart
new file mode 100644
index 0000000..b8b3c2d
--- /dev/null
+++ b/tests/language/regress/regress9664_test.dart
@@ -0,0 +1,9 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for http://dartbug.com/9664
+
+main() {
+  while (true ? true : true) break;
+}
diff --git a/tests/language/regress/regress9687_test.dart b/tests/language/regress/regress9687_test.dart
new file mode 100644
index 0000000..15d7eca
--- /dev/null
+++ b/tests/language/regress/regress9687_test.dart
@@ -0,0 +1,54 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js code generation in checked mode. See
+// last part of https://code.google.com/p/dart/issues/detail?id=9687.
+
+import "package:expect/expect.dart";
+
+class A {
+  final finalField;
+  final otherFinalField;
+
+  A()
+      : finalField = 42,
+        otherFinalField = 54;
+
+  expectFinalField(arg1, arg2) {
+    Expect.equals(arg1, arg2);
+    Expect.equals(finalField, arg1);
+    return 0;
+  }
+
+  expectOtherFinalField(_, arg1, arg2) {
+    Expect.equals(arg1, arg2);
+    Expect.equals(otherFinalField, arg1);
+  }
+}
+
+var array = [new A()];
+
+main() {
+  // [untypedReceiver] is made so that the compiler does not know
+  // what it is.
+  var untypedReceiver = array[0];
+
+  // [typedReceiver] is made so that the compiler knows what it is.
+  var typedReceiver = new A();
+
+  // Using [: finalField :] twice will make the compiler want to
+  // allocate one temporary for it.
+  var a = untypedReceiver.expectFinalField(
+      typedReceiver.finalField, typedReceiver.finalField);
+
+  // Having a check instruction in between two allocations of
+  // temporary variables used to trigger a bug in the compiler.
+  int b = a;
+
+  // Using [: otherFinalField :] twice will make the compiler want to
+  // allocate one temporary for it. The compiler used to assign the
+  // same temporary for [: otherFinalField :] and [: finalField :].
+  untypedReceiver.expectOtherFinalField(
+      b, typedReceiver.otherFinalField, typedReceiver.otherFinalField);
+}
diff --git a/tests/language/regress/regress9939_test.dart b/tests/language/regress/regress9939_test.dart
new file mode 100644
index 0000000..1a3c705
--- /dev/null
+++ b/tests/language/regress/regress9939_test.dart
@@ -0,0 +1,43 @@
+// Copyright (c) 2013, 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.
+
+// dart2js was generating incorrect code for the [A] constructor, by
+// using a temporary variable for two instructions, even though they
+// are both live at the same time.
+
+import "package:expect/expect.dart";
+
+var globalVar = [1, 2];
+
+class A {
+  final field1;
+  final field2;
+  var field3;
+
+  A(this.field1, this.field2) {
+    bool entered = false;
+    // We use [field1] twice to ensure it will have a temporary.
+    for (var a in field1) {
+      try {
+        entered = true;
+        // We use [field2] twice to ensure it will have a temporary.
+        print(field2);
+        print(field2);
+      } catch (e) {
+        // Because the catch is aborting, the SSA graph we used to
+        // generate thought that the whole try/catch was aborting, and
+        // therefore it could not reach the code after the loop.
+        throw e;
+      }
+    }
+    Expect.isTrue(entered);
+    // dart2js used to overwrite the temporary for [field1] with
+    // [field2].
+    Expect.equals(globalVar, field1);
+  }
+}
+
+main() {
+  new A(globalVar, null);
+}
diff --git a/tests/language/regress/regress9949_test.dart b/tests/language/regress/regress9949_test.dart
new file mode 100644
index 0000000..38ff6ed
--- /dev/null
+++ b/tests/language/regress/regress9949_test.dart
@@ -0,0 +1,18 @@
+// Copyright (c) 2013, 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.
+
+// Regression test for dart2js that used to crash in the presence of a
+// super constructor declared external.
+
+import "package:expect/expect.dart";
+import 'dart:collection';
+
+class Crash extends Expando<String> {
+  Crash() : super();
+}
+
+void main() {
+  Crash expando = new Crash();
+  Expect.isTrue(expando is Expando);
+}
diff --git a/tests/language/resolution/resolution_test.dart b/tests/language/resolution/resolution_test.dart
new file mode 100644
index 0000000..e9c1dc7
--- /dev/null
+++ b/tests/language/resolution/resolution_test.dart
@@ -0,0 +1,23 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+int get foo => 499;
+
+class CompileError {
+  var x;
+
+  // Dart2js tried to resolve factories twice. The second time during building
+  // when it was not allowed to do so.
+  factory CompileError() {
+    return new CompileError.internal(foo);
+  }
+
+  CompileError.internal(this.x);
+}
+
+void main() {
+  Expect.equals(499, new CompileError().x);
+}
diff --git a/tests/language/resolution/resolve_test.dart b/tests/language/resolution/resolve_test.dart
new file mode 100644
index 0000000..6cc392c
--- /dev/null
+++ b/tests/language/resolution/resolve_test.dart
@@ -0,0 +1,37 @@
+// 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.
+// Dart test for testing resolving of dynamic and static calls.
+
+import "package:expect/expect.dart";
+
+class A {
+  static staticCall() {
+    return 4;
+  }
+
+  dynamicCall() {
+    return 5;
+  }
+
+  ovrDynamicCall() {
+    return 6;
+  }
+}
+
+class B extends A {
+  ovrDynamicCall() {
+    return -6;
+  }
+}
+
+class ResolveTest {
+  static testMain() {
+    var b = new B();
+    Expect.equals(3, (b.dynamicCall() + A.staticCall() + b.ovrDynamicCall()));
+  }
+}
+
+main() {
+  ResolveTest.testMain();
+}
diff --git a/tests/language/resolution/unqual_name_test.dart b/tests/language/resolution/unqual_name_test.dart
new file mode 100644
index 0000000..d4c8d48
--- /dev/null
+++ b/tests/language/resolution/unqual_name_test.dart
@@ -0,0 +1,40 @@
+// 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.
+// Dart test program to check that we can resolve unqualified identifiers
+
+import "package:expect/expect.dart";
+
+class B {
+  B(x, y) : b = y {}
+  var b;
+
+  get_b() {
+    // Resolving unqualified instance method.
+    return really_really_get_it();
+  }
+
+  really_really_get_it() {
+    return 5;
+  }
+}
+
+class UnqualNameTest {
+  static eleven() {
+    return 11;
+  }
+
+  static testMain() {
+    var o = new B(3, 5);
+    Expect.equals(11, eleven()); // Unqualified static method call.
+    Expect.equals(5, o.get_b());
+
+    // Check whether we handle variable initializers correctly.
+    var a = 1, x, b = a + 3;
+    Expect.equals(5, a + b);
+  }
+}
+
+main() {
+  UnqualNameTest.testMain();
+}
diff --git a/tests/language/return/in_loop_test.dart b/tests/language/return/in_loop_test.dart
new file mode 100644
index 0000000..ebf100d
--- /dev/null
+++ b/tests/language/return/in_loop_test.dart
@@ -0,0 +1,25 @@
+// 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.
+// Test for a dart2js bug where the live environment was not computed
+// right.
+
+import "package:expect/expect.dart";
+
+class A {
+  foo() {
+    var x = 0;
+    while (true) {
+      if (true) {
+        return 42;
+      } else {}
+      x = bar();
+    }
+  }
+
+  bar() => 1;
+}
+
+main() {
+  Expect.equals(42, new A().foo());
+}
diff --git a/tests/language/return/skip_expression_test.dart b/tests/language/return/skip_expression_test.dart
new file mode 100644
index 0000000..a035fda
--- /dev/null
+++ b/tests/language/return/skip_expression_test.dart
@@ -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.
+
+import "package:expect/expect.dart";
+
+class OneArg<A> {
+  OneArg<A> get foo => new OneArg<A>();
+  OneArg<A> get bar {
+    return new OneArg<A>();
+  }
+}
+
+class TwoArgs<A, B> {
+  TwoArgs<A, B> get foo => new TwoArgs<A, B>();
+  TwoArgs<A, B> get bar {
+    return new TwoArgs<A, B>();
+  }
+}
+
+void main() {
+  Expect.isTrue(new OneArg<String>().foo is OneArg);
+  Expect.isTrue(new OneArg<String>().bar is OneArg);
+  Expect.isTrue(new TwoArgs<String, int>().foo is TwoArgs);
+  Expect.isTrue(new TwoArgs<String, int>().bar is TwoArgs);
+
+  // TODO(karlklose): Please remove the return when dart2js can handle
+  // the type tests after it.
+  return;
+  Expect.isTrue(new OneArg<String>().foo is OneArg<String>);
+  Expect.isTrue(new OneArg<String>().bar is OneArg<String>);
+  Expect.isTrue(new TwoArgs<String, int>().foo is TwoArgs<String, int>);
+  Expect.isTrue(new TwoArgs<String, int>().bar is TwoArgs<String, int>);
+}
diff --git a/tests/language/return/this_type_test.dart b/tests/language/return/this_type_test.dart
new file mode 100644
index 0000000..8187b76
--- /dev/null
+++ b/tests/language/return/this_type_test.dart
@@ -0,0 +1,17 @@
+// Copyright (c) 2013, 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.
+
+// Make sure the engine does not infer the wrong type for [:A.foo:].
+
+import "package:expect/expect.dart";
+
+class A {
+  foo() => this;
+}
+
+class B extends A {}
+
+main() {
+  Expect.isTrue(new B().foo() is B);
+}
diff --git a/tests/language/return/type_test.dart b/tests/language/return/type_test.dart
new file mode 100644
index 0000000..99060b5
--- /dev/null
+++ b/tests/language/return/type_test.dart
@@ -0,0 +1,15 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+int returnString1() => 's';  /*@compile-error=unspecified*/
+void returnNull() => null;
+void returnString2() => 's';  /*@compile-error=unspecified*/
+
+main() {
+  returnString1();
+  returnNull();
+  returnString2();
+}
diff --git a/tests/language/rewrite/assign_test.dart b/tests/language/rewrite/assign_test.dart
new file mode 100644
index 0000000..2a51f68
--- /dev/null
+++ b/tests/language/rewrite/assign_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2014, 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";
+
+bar(x, y) {}
+
+foo(b) {
+  var x, y;
+  if (b) {
+    x = 1;
+    y = 2;
+  } else {
+    x = 2;
+    y = 1;
+  }
+  bar(x, y);
+  bar(x, y);
+  return x;
+}
+
+main() {
+  Expect.equals(1, foo(true));
+  Expect.equals(2, foo(false));
+}
diff --git a/tests/language/rewrite/compound_assign_test.dart b/tests/language/rewrite/compound_assign_test.dart
new file mode 100644
index 0000000..ba4c1ef
--- /dev/null
+++ b/tests/language/rewrite/compound_assign_test.dart
@@ -0,0 +1,131 @@
+// Copyright (c) 2014, 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";
+
+var global = 0;
+
+class Foo {
+  var field = 0;
+  static var staticField = 0;
+}
+
+field_compound1(obj) {
+  return obj.field = obj.field + 5;
+}
+
+field_compound2(obj) {
+  return obj.field = obj.field + 1;
+}
+
+field_compound3(obj) {
+  return obj.field = obj.field - 1;
+}
+
+field_compound4(obj) {
+  return obj.field = obj.field * 1;
+}
+
+static_compound1() {
+  return Foo.staticField = Foo.staticField + 5;
+}
+
+static_compound2() {
+  return Foo.staticField = Foo.staticField + 1;
+}
+
+static_compound3() {
+  return Foo.staticField = Foo.staticField - 1;
+}
+
+static_compound4() {
+  return Foo.staticField = Foo.staticField * 1;
+}
+
+global_compound1() {
+  return global = global + 5;
+}
+
+global_compound2() {
+  return global = global + 1;
+}
+
+global_compound3() {
+  return global = global - 1;
+}
+
+global_compound4() {
+  return global = global * 1;
+}
+
+local_compound1(x) {
+  x = x + 5;
+  if (x > 0) {
+    return x;
+  }
+  return -x;
+}
+
+local_compound2(x) {
+  x = x + 1;
+  if (x > 0) {
+    return x;
+  }
+  return -x;
+}
+
+local_compound3(x) {
+  x = x - 1;
+  if (x > 0) {
+    return x;
+  }
+  return -x;
+}
+
+local_compound4(x) {
+  x = x * 1;
+  if (x > 0) {
+    return x;
+  }
+  return -x;
+}
+
+main() {
+  var obj = new Foo();
+  Expect.equals(5, field_compound1(obj));
+  Expect.equals(5, obj.field);
+  Expect.equals(6, field_compound2(obj));
+  Expect.equals(6, obj.field);
+  Expect.equals(5, field_compound3(obj));
+  Expect.equals(5, obj.field);
+  Expect.equals(5, field_compound4(obj));
+  Expect.equals(5, obj.field);
+
+  Expect.equals(5, static_compound1());
+  Expect.equals(5, Foo.staticField);
+  Expect.equals(6, static_compound2());
+  Expect.equals(6, Foo.staticField);
+  Expect.equals(5, static_compound3());
+  Expect.equals(5, Foo.staticField);
+  Expect.equals(5, static_compound4());
+  Expect.equals(5, Foo.staticField);
+
+  Expect.equals(5, global_compound1());
+  Expect.equals(5, global);
+  Expect.equals(6, global_compound2());
+  Expect.equals(6, global);
+  Expect.equals(5, global_compound3());
+  Expect.equals(5, global);
+  Expect.equals(5, global_compound4());
+  Expect.equals(5, global);
+
+  Expect.equals(8, local_compound1(3));
+  Expect.equals(3, local_compound1(-8));
+  Expect.equals(4, local_compound2(3));
+  Expect.equals(7, local_compound2(-8));
+  Expect.equals(2, local_compound3(3));
+  Expect.equals(9, local_compound3(-8));
+  Expect.equals(3, local_compound4(3));
+  Expect.equals(8, local_compound4(-8));
+}
diff --git a/tests/language/rewrite/conditional_test.dart b/tests/language/rewrite/conditional_test.dart
new file mode 100644
index 0000000..4e98475
--- /dev/null
+++ b/tests/language/rewrite/conditional_test.dart
@@ -0,0 +1,99 @@
+// Copyright (c) 2014, 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';
+
+var global = 0;
+
+bar() {
+  global += 1;
+}
+
+baz() {
+  global += 100;
+}
+
+foo(x, y, z) {
+  if ((x ? false : true) ? y : z) {
+    bar();
+    bar();
+  } else {
+    baz();
+    baz();
+  }
+}
+
+foo2(x, y, z) {
+  return (x ? false : true) ? y : z;
+}
+
+foo3(x, y, z) {
+  if (x ? (z ? false : true) : (y ? false : true)) {
+    baz();
+    baz();
+  } else {
+    bar();
+    bar();
+  }
+}
+
+main() {
+  foo(true, true, true);
+  Expect.equals(2, global);
+
+  foo(true, true, false);
+  Expect.equals(202, global);
+
+  foo(true, false, true);
+  Expect.equals(204, global);
+
+  foo(true, false, false);
+  Expect.equals(404, global);
+
+  foo(false, true, true);
+  Expect.equals(406, global);
+
+  foo(false, true, false);
+  Expect.equals(408, global);
+
+  foo(false, false, true);
+  Expect.equals(608, global);
+
+  foo(false, false, false);
+  Expect.equals(808, global);
+
+  Expect.equals(true, foo2(true, true, true));
+  Expect.equals(false, foo2(true, true, false));
+  Expect.equals(true, foo2(true, false, true));
+  Expect.equals(false, foo2(true, false, false));
+  Expect.equals(true, foo2(false, true, true));
+  Expect.equals(true, foo2(false, true, false));
+  Expect.equals(false, foo2(false, false, true));
+  Expect.equals(false, foo2(false, false, false));
+
+  global = 0;
+  foo3(true, true, true);
+  Expect.equals(2, global);
+
+  foo3(true, true, false);
+  Expect.equals(202, global);
+
+  foo3(true, false, true);
+  Expect.equals(204, global);
+
+  foo3(true, false, false);
+  Expect.equals(404, global);
+
+  foo3(false, true, true);
+  Expect.equals(406, global);
+
+  foo3(false, true, false);
+  Expect.equals(408, global);
+
+  foo3(false, false, true);
+  Expect.equals(608, global);
+
+  foo3(false, false, false);
+  Expect.equals(808, global);
+}
diff --git a/tests/language/rewrite/for_update_order_test.dart b/tests/language/rewrite/for_update_order_test.dart
new file mode 100644
index 0000000..ebdbbb1
--- /dev/null
+++ b/tests/language/rewrite/for_update_order_test.dart
@@ -0,0 +1,33 @@
+// Copyright (c) 2014, 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";
+
+var counter = 0;
+var global = 0;
+
+test() {
+  ++counter;
+  return counter <= 2;
+}
+
+first() {
+  global = global + 1;
+}
+
+second() {
+  global = global * 2;
+}
+
+foo() {
+  while (test()) {
+    first();
+    second();
+  }
+}
+
+main() {
+  foo();
+  Expect.equals(6, global);
+}
diff --git a/tests/language/rewrite/if_empty_then_test.dart b/tests/language/rewrite/if_empty_then_test.dart
new file mode 100644
index 0000000..908b496
--- /dev/null
+++ b/tests/language/rewrite/if_empty_then_test.dart
@@ -0,0 +1,50 @@
+// Copyright (c) 2014, 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";
+
+var global = 0;
+
+effect() {
+  global = 1;
+}
+
+baz(b) {
+  return b;
+}
+
+foo(b) {
+  if (b) {
+    // do nothing
+  } else {
+    effect();
+  }
+  return baz(b);
+}
+
+foo2(b) {
+  if (b) {
+    // do nothing (but implicit return may get inlined up here)
+  } else {
+    effect();
+  }
+}
+
+main() {
+  global = 0;
+  Expect.equals(true, foo(true));
+  Expect.equals(0, global);
+
+  global = 0;
+  Expect.equals(false, foo(false));
+  Expect.equals(1, global);
+
+  global = 0;
+  foo2(true);
+  Expect.equals(0, global);
+
+  global = 0;
+  foo2(false);
+  Expect.equals(1, global);
+}
diff --git a/tests/language/rewrite/if_return_test.dart b/tests/language/rewrite/if_return_test.dart
new file mode 100644
index 0000000..3c57605
--- /dev/null
+++ b/tests/language/rewrite/if_return_test.dart
@@ -0,0 +1,47 @@
+// Copyright (c) 2014, 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";
+
+var global = 0;
+
+bar() {
+  global = 1;
+}
+
+baz() {
+  global = 2;
+}
+
+return_const(b) {
+  if (b) {
+    bar();
+    return 1;
+  } else {
+    baz();
+    return 1;
+  }
+}
+
+return_var(b, x) {
+  if (b) {
+    bar();
+    return x;
+  } else {
+    baz();
+    return x;
+  }
+}
+
+main() {
+  return_const(true);
+  Expect.equals(1, global);
+  return_const(false);
+  Expect.equals(2, global);
+
+  Expect.equals(4, return_var(true, 4));
+  Expect.equals(1, global);
+  Expect.equals(5, return_var(false, 5));
+  Expect.equals(2, global);
+}
diff --git a/tests/language/rewrite/if_swap_test.dart b/tests/language/rewrite/if_swap_test.dart
new file mode 100644
index 0000000..fbde492
--- /dev/null
+++ b/tests/language/rewrite/if_swap_test.dart
@@ -0,0 +1,34 @@
+// Copyright (c) 2014, 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";
+
+var global = 0;
+
+bar() {
+  global += 1;
+}
+
+baz() {
+  global += 100;
+}
+
+foo(b) {
+  var old_backend_was_used;
+  if (b ? false : true) {
+    bar();
+    bar();
+  } else {
+    baz();
+    baz();
+  }
+}
+
+main() {
+  foo(true);
+  Expect.equals(200, global);
+
+  foo(false);
+  Expect.equals(202, global);
+}
diff --git a/tests/language/rewrite/implicit_this_runtime_test.dart b/tests/language/rewrite/implicit_this_runtime_test.dart
new file mode 100644
index 0000000..7fd2b78
--- /dev/null
+++ b/tests/language/rewrite/implicit_this_runtime_test.dart
@@ -0,0 +1,111 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// Copyright (c) 2014, 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";
+
+String toplevel = 'A';
+
+class Foo {
+  String x = 'x';
+
+  easy(z) {
+
+  }
+
+  // Shadow the 'y' field in various ways
+  shadow_y_parameter(y) {
+
+  }
+
+  shadow_y_local(z) {
+    var y = z;
+
+  }
+
+  shadow_y_capturedLocal(z) {
+    var y = z;
+    foo() {
+
+    }
+    return foo();
+  }
+
+  shadow_y_closureParam(z) {
+    foo(y) {
+
+    }
+    return foo(z);
+  }
+
+  shadow_y_localInsideClosure(z) {
+    foo() {
+      var y = z;
+
+    }
+
+    return foo();
+  }
+
+  // Shadow the 'x' field in various ways
+  shadow_x_parameter(x) {
+
+  }
+
+  shadow_x_local(z) {
+    var x = z;
+
+  }
+
+  shadow_x_capturedLocal(z) {
+    var x = z;
+    foo() {
+
+    }
+    return foo();
+  }
+
+  shadow_x_closureParam(z) {
+    foo(x) {
+
+    }
+    return foo(z);
+  }
+
+  shadow_x_localInsideClosure(z) {
+    foo() {
+      var x = z;
+
+    }
+
+    return foo();
+  }
+
+  shadow_x_toplevel() {
+
+  }
+}
+
+class Sub extends Foo {
+  String y = 'y';
+  String toplevel = 'B';
+}
+
+main() {
+
+
+
+
+
+
+
+
+
+
+
+
+
+}
diff --git a/tests/language/rewrite/implicit_this_test.dart b/tests/language/rewrite/implicit_this_test.dart
new file mode 100644
index 0000000..e0e4c41
--- /dev/null
+++ b/tests/language/rewrite/implicit_this_test.dart
@@ -0,0 +1,147 @@
+// Copyright (c) 2014, 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";
+
+String toplevel = 'A';
+
+class Foo {
+  String x = 'x';
+
+  easy(z) {
+        return x + y + z;
+        //         ^
+        // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+  }
+
+  // Shadow the 'y' field in various ways
+  shadow_y_parameter(y) {
+        return x + this.y + y;
+        //              ^
+        // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+  }
+
+  shadow_y_local(z) {
+    var y = z;
+        return x + this.y + y;
+        //              ^
+        // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+  }
+
+  shadow_y_capturedLocal(z) {
+    var y = z;
+    foo() {
+            return x + this.y + y;
+            //              ^
+            // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+    return foo();
+  }
+
+  shadow_y_closureParam(z) {
+    foo(y) {
+            return x + this.y + y;
+            //              ^
+            // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+    return foo(z);
+  }
+
+  shadow_y_localInsideClosure(z) {
+    foo() {
+      var y = z;
+            return x + this.y + y;
+            //              ^
+            // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+
+    return foo();
+  }
+
+  // Shadow the 'x' field in various ways
+  shadow_x_parameter(x) {
+        return this.x + y + x;
+        //              ^
+        // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+  }
+
+  shadow_x_local(z) {
+    var x = z;
+        return this.x + y + x;
+        //              ^
+        // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+  }
+
+  shadow_x_capturedLocal(z) {
+    var x = z;
+    foo() {
+            return this.x + y + x;
+            //              ^
+            // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+    return foo();
+  }
+
+  shadow_x_closureParam(z) {
+    foo(x) {
+            return this.x + y + x;
+            //              ^
+            // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+    return foo(z);
+  }
+
+  shadow_x_localInsideClosure(z) {
+    foo() {
+      var x = z;
+            return this.x + y + x;
+            //              ^
+            // [analyzer] STATIC_WARNING.UNDEFINED_IDENTIFIER
+            // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+    }
+
+    return foo();
+  }
+
+  shadow_x_toplevel() {
+        return x + this.y + toplevel + this.toplevel;
+        //              ^
+        // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+        // [cfe] The getter 'y' isn't defined for the class 'Foo'.
+        //                                  ^^^^^^^^
+        // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+        // [cfe] The getter 'toplevel' isn't defined for the class 'Foo'.
+  }
+}
+
+class Sub extends Foo {
+  String y = 'y';
+  String toplevel = 'B';
+}
+
+main() {
+    Expect.equals('xyz', new Sub().easy('z'));
+    Expect.equals('xyz', new Sub().shadow_y_parameter('z'));
+    Expect.equals('xyz', new Sub().shadow_y_local('z'));
+    Expect.equals('xyz', new Sub().shadow_y_capturedLocal('z'));
+    Expect.equals('xyz', new Sub().shadow_y_closureParam('z'));
+    Expect.equals('xyz', new Sub().shadow_y_localInsideClosure('z'));
+    Expect.equals('xyz', new Sub().shadow_x_parameter('z'));
+    Expect.equals('xyz', new Sub().shadow_x_local('z'));
+    Expect.equals('xyz', new Sub().shadow_x_capturedLocal('z'));
+    Expect.equals('xyz', new Sub().shadow_x_closureParam('z'));
+    Expect.equals('xyz', new Sub().shadow_x_localInsideClosure('z'));
+
+    Expect.equals('xyAB', new Sub().shadow_x_toplevel());
+}
diff --git a/tests/language/rewrite/logical_test.dart b/tests/language/rewrite/logical_test.dart
new file mode 100644
index 0000000..4fc4060
--- /dev/null
+++ b/tests/language/rewrite/logical_test.dart
@@ -0,0 +1,312 @@
+// Copyright (c) 2014, 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';
+
+cneg_and(x, y) {
+  if ((x && y) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_and_not(x, y) {
+  if ((x && (y ? false : true)) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_not_and(x, y) {
+  if (((x ? false : true) && y) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_not_and_not(x, y) {
+  if (((x ? false : true) && (y ? false : true)) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_or(x, y) {
+  if ((x || y) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_or_not(x, y) {
+  if ((x || (y ? false : true)) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_not_or(x, y) {
+  if (((x ? false : true) || y) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+cneg_not_or_not(x, y) {
+  if (((x ? false : true) || (y ? false : true)) ? false : true) {
+    return 0;
+  } else {
+    return 1;
+  }
+}
+
+value_tobool(x) {
+  return x ? true : false;
+}
+
+value_negate(x) {
+  return x ? false : true;
+}
+
+value_and(x, y) {
+  return x ? y ? true : false : false;
+}
+
+value_or(x, y) {
+  return x ? true : y ? true : false;
+}
+
+value_and_not(x, y) {
+  return x ? y ? false : true : false;
+}
+
+value_not_and(x, y) {
+  return x ? false : y ? true : false;
+}
+
+value_not_and_not(x, y) {
+  return x ? false : y ? false : true;
+}
+
+value_or_not(x, y) {
+  return x ? true : y ? false : true;
+}
+
+value_not_or(x, y) {
+  return x ? y ? true : false : true;
+}
+
+value_not_or_not(x, y) {
+  return x ? y ? false : true : true;
+}
+
+if_negate(x) {
+  if (x ? false : true) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_and(x, y) {
+  if (x ? y ? true : false : false) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_or(x, y) {
+  if (x ? true : y) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_and_not(x, y) {
+  if (x ? y ? false : true : false) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_not_and(x, y) {
+  if (x ? false : y) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_not_and_not(x, y) {
+  if (x ? false : y ? false : true) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_or_not(x, y) {
+  if (x ? true : y ? false : true) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_not_or(x, y) {
+  if (x ? y : true) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+if_not_or_not(x, y) {
+  if (x ? y ? false : true : true) {
+    return 1;
+  } else {
+    return 0;
+  }
+}
+
+main() {
+  Expect.equals(1, cneg_and(true, true));
+  Expect.equals(0, cneg_and(true, false));
+  Expect.equals(0, cneg_and(false, true));
+  Expect.equals(0, cneg_and(false, false));
+
+  Expect.equals(0, cneg_and_not(true, true));
+  Expect.equals(1, cneg_and_not(true, false));
+  Expect.equals(0, cneg_and_not(false, true));
+  Expect.equals(0, cneg_and_not(false, false));
+
+  Expect.equals(0, cneg_not_and(true, true));
+  Expect.equals(0, cneg_not_and(true, false));
+  Expect.equals(1, cneg_not_and(false, true));
+  Expect.equals(0, cneg_not_and(false, false));
+
+  Expect.equals(0, cneg_not_and_not(true, true));
+  Expect.equals(0, cneg_not_and_not(true, false));
+  Expect.equals(0, cneg_not_and_not(false, true));
+  Expect.equals(1, cneg_not_and_not(false, false));
+
+  Expect.equals(1, cneg_or(true, true));
+  Expect.equals(1, cneg_or(true, false));
+  Expect.equals(1, cneg_or(false, true));
+  Expect.equals(0, cneg_or(false, false));
+
+  Expect.equals(1, cneg_or_not(true, true));
+  Expect.equals(1, cneg_or_not(true, false));
+  Expect.equals(0, cneg_or_not(false, true));
+  Expect.equals(1, cneg_or_not(false, false));
+
+  Expect.equals(1, cneg_not_or(true, true));
+  Expect.equals(0, cneg_not_or(true, false));
+  Expect.equals(1, cneg_not_or(false, true));
+  Expect.equals(1, cneg_not_or(false, false));
+
+  Expect.equals(0, cneg_not_or_not(true, true));
+  Expect.equals(1, cneg_not_or_not(true, false));
+  Expect.equals(1, cneg_not_or_not(false, true));
+  Expect.equals(1, cneg_not_or_not(false, false));
+
+  Expect.equals(true, value_tobool(true));
+  Expect.equals(false, value_tobool(false));
+
+  Expect.equals(false, value_negate(true));
+  Expect.equals(true, value_negate(false));
+
+  Expect.equals(true, value_and(true, true));
+  Expect.equals(false, value_and(true, false));
+  Expect.equals(false, value_and(false, true));
+  Expect.equals(false, value_and(false, false));
+
+  Expect.equals(false, value_and_not(true, true));
+  Expect.equals(true, value_and_not(true, false));
+  Expect.equals(false, value_and_not(false, true));
+  Expect.equals(false, value_and_not(false, false));
+
+  Expect.equals(false, value_not_and(true, true));
+  Expect.equals(false, value_not_and(true, false));
+  Expect.equals(true, value_not_and(false, true));
+  Expect.equals(false, value_not_and(false, false));
+
+  Expect.equals(false, value_not_and_not(true, true));
+  Expect.equals(false, value_not_and_not(true, false));
+  Expect.equals(false, value_not_and_not(false, true));
+  Expect.equals(true, value_not_and_not(false, false));
+
+  Expect.equals(true, value_or(true, true));
+  Expect.equals(true, value_or(true, false));
+  Expect.equals(true, value_or(false, true));
+  Expect.equals(false, value_or(false, false));
+
+  Expect.equals(true, value_or_not(true, true));
+  Expect.equals(true, value_or_not(true, false));
+  Expect.equals(false, value_or_not(false, true));
+  Expect.equals(true, value_or_not(false, false));
+
+  Expect.equals(true, value_not_or(true, true));
+  Expect.equals(false, value_not_or(true, false));
+  Expect.equals(true, value_not_or(false, true));
+  Expect.equals(true, value_not_or(false, false));
+
+  Expect.equals(false, value_not_or_not(true, true));
+  Expect.equals(true, value_not_or_not(true, false));
+  Expect.equals(true, value_not_or_not(false, true));
+  Expect.equals(true, value_not_or_not(false, false));
+
+  Expect.equals(0, if_negate(true));
+  Expect.equals(1, if_negate(false));
+
+  Expect.equals(1, if_and(true, true));
+  Expect.equals(0, if_and(true, false));
+  Expect.equals(0, if_and(false, true));
+  Expect.equals(0, if_and(false, false));
+
+  Expect.equals(0, if_and_not(true, true));
+  Expect.equals(1, if_and_not(true, false));
+  Expect.equals(0, if_and_not(false, true));
+  Expect.equals(0, if_and_not(false, false));
+
+  Expect.equals(0, if_not_and(true, true));
+  Expect.equals(0, if_not_and(true, false));
+  Expect.equals(1, if_not_and(false, true));
+  Expect.equals(0, if_not_and(false, false));
+
+  Expect.equals(0, if_not_and_not(true, true));
+  Expect.equals(0, if_not_and_not(true, false));
+  Expect.equals(0, if_not_and_not(false, true));
+  Expect.equals(1, if_not_and_not(false, false));
+
+  Expect.equals(1, if_or(true, true));
+  Expect.equals(1, if_or(true, false));
+  Expect.equals(1, if_or(false, true));
+  Expect.equals(0, if_or(false, false));
+
+  Expect.equals(1, if_or_not(true, true));
+  Expect.equals(1, if_or_not(true, false));
+  Expect.equals(0, if_or_not(false, true));
+  Expect.equals(1, if_or_not(false, false));
+
+  Expect.equals(1, if_not_or(true, true));
+  Expect.equals(0, if_not_or(true, false));
+  Expect.equals(1, if_not_or(false, true));
+  Expect.equals(1, if_not_or(false, false));
+
+  Expect.equals(0, if_not_or_not(true, true));
+  Expect.equals(1, if_not_or_not(true, false));
+  Expect.equals(1, if_not_or_not(false, true));
+  Expect.equals(1, if_not_or_not(false, false));
+}
diff --git a/tests/language/rewrite/nested_if1_test.dart b/tests/language/rewrite/nested_if1_test.dart
new file mode 100644
index 0000000..d86cc55
--- /dev/null
+++ b/tests/language/rewrite/nested_if1_test.dart
@@ -0,0 +1,73 @@
+// Copyright (c) 2014, 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';
+
+var global;
+
+setGlobal(v) {
+  global = v;
+}
+
+check_true_true(x, y, v) {
+  if (x) {
+    if (y) {
+      setGlobal(v);
+    }
+  }
+}
+
+check_false_true(x, y, v) {
+  if (x) {} else {
+    if (y) {
+      setGlobal(v);
+    }
+  }
+}
+
+check_true_false(x, y, v) {
+  if (x) {
+    if (y) {} else {
+      setGlobal(v);
+    }
+  }
+}
+
+check_false_false(x, y, v) {
+  if (x) {} else {
+    if (y) {} else {
+      setGlobal(v);
+    }
+  }
+}
+
+main() {
+  check_true_true(true, true, 4);
+  check_true_true(false, false, 1);
+  check_true_true(false, true, 2);
+  check_true_true(true, false, 3);
+
+  Expect.equals(4, global);
+
+  check_true_false(false, false, 1);
+  check_true_false(false, true, 2);
+  check_true_false(true, false, 3);
+  check_true_false(true, true, 4);
+
+  Expect.equals(3, global);
+
+  check_false_true(false, false, 1);
+  check_false_true(false, true, 2);
+  check_false_true(true, false, 3);
+  check_false_true(true, true, 4);
+
+  Expect.equals(2, global);
+
+  check_false_false(false, false, 1);
+  check_false_false(false, true, 2);
+  check_false_false(true, false, 3);
+  check_false_false(true, true, 4);
+
+  Expect.equals(1, global);
+}
diff --git a/tests/language/rewrite/nested_if2_test.dart b/tests/language/rewrite/nested_if2_test.dart
new file mode 100644
index 0000000..2a71680
--- /dev/null
+++ b/tests/language/rewrite/nested_if2_test.dart
@@ -0,0 +1,63 @@
+// Copyright (c) 2014, 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';
+
+check_true_true(x, y) {
+  if (x) {
+    if (y) {
+      return true;
+    }
+  }
+  return false;
+}
+
+check_false_true(x, y) {
+  if (x) {} else {
+    if (y) {
+      return true;
+    }
+  }
+  return false;
+}
+
+check_true_false(x, y) {
+  if (x) {
+    if (y) {} else {
+      return true;
+    }
+  }
+  return false;
+}
+
+check_false_false(x, y) {
+  if (x) {} else {
+    if (y) {} else {
+      return true;
+    }
+  }
+  return false;
+}
+
+main() {
+  Expect.equals(true, check_true_true(true, true));
+  Expect.equals(false, check_true_true(true, false));
+  Expect.equals(false, check_true_true(false, true));
+  Expect.equals(false, check_true_true(false, false));
+
+  Expect.equals(false, check_true_false(true, true));
+  Expect.equals(true, check_true_false(true, false));
+  Expect.equals(false, check_true_false(false, true));
+  Expect.equals(false, check_true_false(false, false));
+
+  Expect.equals(false, check_false_true(true, true));
+  Expect.equals(false, check_false_true(true, false));
+  Expect.equals(true, check_false_true(false, true));
+  Expect.equals(false, check_false_true(false, false));
+
+  Expect.equals(false, check_false_false(true, true));
+  Expect.equals(false, check_false_false(true, false));
+  Expect.equals(false, check_false_false(false, true));
+  Expect.equals(true, check_false_false(false, false));
+}
diff --git a/tests/language/rewrite/nested_if3_test.dart b/tests/language/rewrite/nested_if3_test.dart
new file mode 100644
index 0000000..b985df8
--- /dev/null
+++ b/tests/language/rewrite/nested_if3_test.dart
@@ -0,0 +1,69 @@
+// Copyright (c) 2014, 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';
+
+baz() {}
+
+check_true_true(x, y) {
+  if (x) {
+    if (y) {
+      return true;
+    }
+  }
+  baz();
+  return false;
+}
+
+check_false_true(x, y) {
+  if (x) {} else {
+    if (y) {
+      return true;
+    }
+  }
+  baz();
+  return false;
+}
+
+check_true_false(x, y) {
+  if (x) {
+    if (y) {} else {
+      return true;
+    }
+  }
+  baz();
+  return false;
+}
+
+check_false_false(x, y) {
+  if (x) {} else {
+    if (y) {} else {
+      return true;
+    }
+  }
+  baz();
+  return false;
+}
+
+main() {
+  Expect.equals(true, check_true_true(true, true));
+  Expect.equals(false, check_true_true(true, false));
+  Expect.equals(false, check_true_true(false, true));
+  Expect.equals(false, check_true_true(false, false));
+
+  Expect.equals(false, check_true_false(true, true));
+  Expect.equals(true, check_true_false(true, false));
+  Expect.equals(false, check_true_false(false, true));
+  Expect.equals(false, check_true_false(false, false));
+
+  Expect.equals(false, check_false_true(true, true));
+  Expect.equals(false, check_false_true(true, false));
+  Expect.equals(true, check_false_true(false, true));
+  Expect.equals(false, check_false_true(false, false));
+
+  Expect.equals(false, check_false_false(true, true));
+  Expect.equals(false, check_false_false(true, false));
+  Expect.equals(false, check_false_false(false, true));
+  Expect.equals(true, check_false_false(false, false));
+}
diff --git a/tests/language/rewrite/swap_test.dart b/tests/language/rewrite/swap_test.dart
new file mode 100644
index 0000000..5c6d115
--- /dev/null
+++ b/tests/language/rewrite/swap_test.dart
@@ -0,0 +1,90 @@
+// Copyright (c) 2014, 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";
+
+swap1(x, y, b) {
+  if (b) {
+    var t = x;
+    x = y;
+    y = t;
+  }
+  Expect.equals(2, x);
+  Expect.equals(1, y);
+}
+
+swap2(x, y, z, w, b) {
+  if (b) {
+    var t = x;
+    x = y;
+    y = t;
+
+    var q = z;
+    z = w;
+    w = q;
+  }
+  Expect.equals(2, x);
+  Expect.equals(1, y);
+  Expect.equals(4, z);
+  Expect.equals(3, w);
+}
+
+swap3(x, y, z, b) {
+  if (b) {
+    var t = x;
+    x = y;
+    y = z;
+    z = t;
+  }
+  Expect.equals(2, x);
+  Expect.equals(3, y);
+  Expect.equals(1, z);
+}
+
+swap4(x, y, z, b) {
+  if (b) {
+    var t = x;
+    x = y;
+    y = z; // swap cycle involves unused variable 'y'
+    z = t;
+  }
+  Expect.equals(2, x);
+  Expect.equals(1, z);
+}
+
+swap5(x, y, z, w, b, b2) {
+  if (b) {
+    var t = x;
+    x = y;
+    y = t;
+  }
+  if (b2) {
+    var q = z;
+    z = w;
+    w = q;
+  }
+  Expect.equals(2, x);
+  Expect.equals(1, y);
+  Expect.equals(4, z);
+  Expect.equals(3, w);
+}
+
+main() {
+  swap1(1, 2, true);
+  swap1(2, 1, false);
+
+  swap2(1, 2, 3, 4, true);
+  swap2(2, 1, 4, 3, false);
+
+  swap3(1, 2, 3, true);
+  swap3(2, 3, 1, false);
+
+  swap4(1, 2, 3, true);
+  swap4(2, 3, 1, false);
+
+  swap5(1, 2, 3, 4, true, true);
+  swap5(1, 2, 4, 3, true, false);
+  swap5(2, 1, 3, 4, false, true);
+  swap5(2, 1, 4, 3, false, false);
+}
diff --git a/tests/language/rewrite/variable_initializer_test.dart b/tests/language/rewrite/variable_initializer_test.dart
new file mode 100644
index 0000000..75de2d0
--- /dev/null
+++ b/tests/language/rewrite/variable_initializer_test.dart
@@ -0,0 +1,40 @@
+// Copyright (c) 2014, 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";
+
+class Foo {
+  var field = 0;
+}
+
+bar(x, y) {
+  return x * 100 + y;
+}
+
+foo(z) {
+  var x = 0, y = x;
+  if (z > 0) {
+    x = 10;
+  }
+  if (z > 10) {
+    y = 20;
+  }
+  return bar(x, y);
+}
+
+baz(z) {
+  var f = new Foo()
+    ..field = 10
+    ..field = z;
+  return f;
+}
+
+main() {
+  Expect.equals(0, foo(0));
+  Expect.equals(1000, foo(5));
+  Expect.equals(1020, foo(15));
+
+  Expect.equals(20, baz(20).field);
+  Expect.equals(30, baz(30).field);
+}
diff --git a/tests/language/rewrite/while_many_exits_test.dart b/tests/language/rewrite/while_many_exits_test.dart
new file mode 100644
index 0000000..f3aa523
--- /dev/null
+++ b/tests/language/rewrite/while_many_exits_test.dart
@@ -0,0 +1,48 @@
+// Copyright (c) 2014, 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";
+
+var baz_clicks = 0;
+
+baz() {
+  return ++baz_clicks;
+}
+
+var global = 0;
+
+increment_global() {
+  ++global;
+  return global <= 10;
+}
+
+foo(x, y) {
+  var n = 0;
+  while (true) {
+    baz();
+    if (n >= x) {
+      return n;
+    }
+    baz();
+    if (n >= y) {
+      return n;
+    }
+    n = n + 1;
+  }
+}
+
+bar() {
+  while (increment_global()) {
+    baz();
+  }
+  return baz();
+}
+
+main() {
+  Expect.equals(10, foo(10, 20));
+  Expect.equals(10, foo(20, 10));
+
+  baz_clicks = 0;
+  Expect.equals(11, bar());
+}
diff --git a/tests/language/rewrite/while_test.dart b/tests/language/rewrite/while_test.dart
new file mode 100644
index 0000000..c773ee0
--- /dev/null
+++ b/tests/language/rewrite/while_test.dart
@@ -0,0 +1,85 @@
+// Copyright (c) 2014, 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";
+
+baz() {}
+
+loop1(x) {
+  var n = 0;
+  while (n < x) {
+    n = n + 1;
+  }
+  return n;
+}
+
+loop2(x) {
+  var n = 0;
+  if (x < 100) {
+    while (n < x) {
+      n = n + 1;
+    }
+  }
+  baz();
+  return n;
+}
+
+loop3(x) {
+  var n = 0;
+  if (x < 100) {
+    while (n < x) {
+      n = n + 1;
+      baz();
+    }
+  }
+  baz();
+  return n;
+}
+
+loop4(x) {
+  var n = 0;
+  if (x < 100) {
+    while (n < x) {
+      baz();
+      n = n + 1;
+    }
+  }
+  baz();
+  return n;
+}
+
+f1(b) {
+  while (b) return 1;
+
+  return 2;
+}
+
+f2(b) {
+  while (b) {
+    return 1;
+  }
+  return 2;
+}
+
+main() {
+  Expect.equals(0, loop1(-10));
+  Expect.equals(10, loop1(10));
+
+  Expect.equals(0, loop2(-10));
+  Expect.equals(10, loop2(10));
+  Expect.equals(0, loop2(200));
+
+  Expect.equals(0, loop3(-10));
+  Expect.equals(10, loop3(10));
+  Expect.equals(0, loop3(200));
+
+  Expect.equals(0, loop4(-10));
+  Expect.equals(10, loop4(10));
+  Expect.equals(0, loop4(200));
+
+  Expect.equals(1, f1(true));
+  Expect.equals(2, f1(false));
+  Expect.equals(1, f2(true));
+  Expect.equals(2, f2(false));
+}
diff --git a/tests/language/script/lib.dart b/tests/language/script/lib.dart
new file mode 100644
index 0000000..eafca26
--- /dev/null
+++ b/tests/language/script/lib.dart
@@ -0,0 +1,9 @@
+// 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.
+
+// A perfectly legal dart library for use with script and library tests.
+
+library ScriptLib;
+
+const int scriptLib = 1;
diff --git a/tests/language/script/script1_lib.dart b/tests/language/script/script1_lib.dart
new file mode 100644
index 0000000..525b2ca
--- /dev/null
+++ b/tests/language/script/script1_lib.dart
@@ -0,0 +1,5 @@
+// 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.
+
+int ok = 1;
diff --git a/tests/language/script/script1_part.dart b/tests/language/script/script1_part.dart
new file mode 100644
index 0000000..15bd30d
--- /dev/null
+++ b/tests/language/script/script1_part.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.
+
+part of "script1_test.dart";
+
+const int scriptPart = 1;
diff --git a/tests/language/script/script1_test.dart b/tests/language/script/script1_test.dart
new file mode 100644
index 0000000..8d714e9
--- /dev/null
+++ b/tests/language/script/script1_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.
+
+/// Wrong order of import and part directives.
+
+part "script1_part.dart";
+import "script1_lib.dart";
+// [error line 8, column 1, length 6]
+// [analyzer] SYNTACTIC_ERROR.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
+// [cfe] Import directives must precede part directives.
+
+main() {
+  print("Should not reach here.");
+}
diff --git a/tests/language/script/script2_part.dart b/tests/language/script/script2_part.dart
new file mode 100644
index 0000000..e48f121
--- /dev/null
+++ b/tests/language/script/script2_part.dart
@@ -0,0 +1,10 @@
+// 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.
+
+library Script2Part;
+import "lib.dart";
+
+part of "script2_test.dart";
+
+const int scriptPart = 1;
diff --git a/tests/language/script/script2_test.dart b/tests/language/script/script2_test.dart
new file mode 100644
index 0000000..7ab8397
--- /dev/null
+++ b/tests/language/script/script2_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.
+
+/// Part file has library and import directives.
+
+/*@compile-error=unspecified*/
+// TODO(rnystrom): Using the above tag instead of making this a static error
+// test because the error is reported in the part file and not in this file.
+// Static error tests only support errors reported in the main test file itself.
+part "script2_part.dart";
+
+main() {
+  print("Should not reach here.");
+}
diff --git a/tests/language/script/source.dart b/tests/language/script/source.dart
new file mode 100644
index 0000000..44f0d34
--- /dev/null
+++ b/tests/language/script/source.dart
@@ -0,0 +1,7 @@
+// 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.
+
+// A perfectly legal dart source file for use with script and library tests.
+
+const int script_source = 1;
diff --git a/tests/language/set_literals/const_set_literal_test.dart b/tests/language/set_literals/const_set_literal_test.dart
new file mode 100644
index 0000000..0e7c57d
--- /dev/null
+++ b/tests/language/set_literals/const_set_literal_test.dart
@@ -0,0 +1,128 @@
+// 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.
+
+import 'dart:async';
+
+import "package:expect/expect.dart";
+
+void main() {
+  test();
+}
+
+void test() {
+  checkSet<T>(Object o, List elements) {
+    Expect.type<Set<T>>(o);
+    Set<T> set = o as Set<T>;
+    Expect.listEquals(elements, set.toList());
+    Expect.throws<Error>(set.clear);
+  }
+
+  // Various context types for literals.
+  Object setContext<T>(Set<T> object) => object;
+  Object iterableContext<T>(Iterable<T> object) => object;
+  Object foSetContext<T>(FutureOr<Set<T>> object) => object;
+  Object foIterableContext<T>(FutureOr<Set<T>> object) => object;
+
+  // Empty literal, no type arguments.
+  // No context.
+  Expect.type<Map<dynamic, dynamic>>(const {});
+  // Set context with no inferred type argument.
+  checkSet<dynamic>(setContext(const {}), []);
+  checkSet<dynamic>(iterableContext(const {}), []);
+  checkSet<dynamic>(foSetContext(const {}), []);
+  checkSet<dynamic>(foIterableContext(const {}), []);
+  // Specific set context.
+  checkSet<int>(setContext<int>(const {}), []);
+  checkSet<int>(iterableContext<int>(const {}), []);
+  checkSet<int>(foSetContext<int>(const {}), []);
+  checkSet<int>(foIterableContext<int>(const {}), []);
+
+  // Non-empty set literal, no type argument.
+  // No context.
+  checkSet<int>(const {1}, [1]);
+  checkSet<int>(const {3, 1, 2, 4}, [3, 1, 2, 4]);
+  // Set context with no inferred type argument.
+  checkSet<int>(setContext(const {1}), [1]);
+  checkSet<int>(iterableContext(const {1}), [1]);
+  checkSet<int>(foSetContext(const {1}), [1]);
+  checkSet<int>(foIterableContext(const {1}), [1]);
+  checkSet<int>(setContext(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+  checkSet<int>(iterableContext(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+  checkSet<int>(foSetContext(const {1}), [1]);
+  checkSet<int>(foIterableContext(const {1}), [1]);
+  // Specific set context.
+  checkSet<num>(setContext<num>(const {1}), [1]);
+  checkSet<num>(iterableContext<num>(const {1}), [1]);
+  checkSet<num>(foSetContext<num>(const {1}), [1]);
+  checkSet<num>(foIterableContext<num>(const {1}), [1]);
+  checkSet<num>(setContext<num>(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+  checkSet<num>(iterableContext<num>(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+  checkSet<num>(foSetContext<num>(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+  checkSet<num>(foIterableContext<num>(const {3, 1, 2, 4}), [3, 1, 2, 4]);
+
+  // Non-empty set literal with type argument.
+  checkSet<num>(const <num>{1}, [1]);
+  checkSet<num>(const <num>{3, 1, 2, 4}, [3, 1, 2, 4]);
+
+  // Integers, String and symbols work, even if they override ==.
+  checkSet<String>(const {"foo", "bar"}, ["foo", "bar"]);
+  checkSet<Symbol>(const {#foo, #bar}, [#foo, #bar]);
+  checkSet<Symbol>(const {#_foo, #_bar}, [#_foo, #_bar]);
+  const object = Object();
+  checkSet<Object>(const {#foo, 1, "string", object, true},
+      [#foo, 1, "string", object, true]);
+
+  // Nested constant literals.
+  const Object o = {{2}};
+  Expect.type<Set<Set<int>>>(o);
+  Set<Set<int>> set = o as Set<Set<int>>;
+  Expect.equals(1, set.length);
+  Expect.equals(1, set.first.length);
+  Expect.equals(2, set.first.first);
+
+  const Object o2 = {{2}, <int>{}};
+  Expect.type<Set<Set<int>>>(o);
+  set = o2 as Set<Set<int>>;
+  Expect.equals(2, set.length);
+  Expect.equals(1, set.first.length);
+  Expect.equals(2, set.first.first);
+
+  const Set<Set<int>> o3 = {{}};
+  Expect.equals(1, o3.length);
+  Expect.equals(0, o3.first.length);
+
+  const o4 = {{}};
+  Expect.type<Set<Map<dynamic, dynamic>>>(o4);
+  Expect.equals(1, o4.length);
+  Expect.equals(0, o4.first.length);
+
+  const o5 = {{1}, {}};  // Set<Object>
+  Expect.type<Set<Object>>(o5);
+  Expect.notType<Set<Set<Object>>>(o5);
+
+  // User defined constant class.
+  const o6 = {
+    Something(1, "a"),
+    Something(2, "a"),
+    Something(1, "b"),
+    Something(2, "b"),
+  };
+  Expect.equals("1:a,2:a,1:b,2:b", o6.toList().join(","));
+
+  // Canonicalization of constant sets takes ordering into account,
+  // that is, o7 and o8 cannot be the same object.
+  const o7 = {1, 2, 3};
+  const o8 = {3, 2, 1};
+  Expect.notIdentical(o7, o8);
+  // But o7 and o9 must be identical.
+  const o9 = {1, 2, 3};
+  Expect.identical(o7, o9);
+}
+
+class Something {
+  final int id;
+  final String name;
+  const Something(this.id, this.name);
+  String toString() => "$id:$name";
+}
diff --git a/tests/language/set_literals/in_annotations_test.dart b/tests/language/set_literals/in_annotations_test.dart
new file mode 100644
index 0000000..d59dfa9
--- /dev/null
+++ b/tests/language/set_literals/in_annotations_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.
+
+@Meta({})
+import 'dart:core';
+
+@Meta({})
+void f(@Meta({}) int foo) {}
+
+@Meta({})
+class A<@Meta({}) T> {
+  @Meta({})
+  String? x, y;
+
+  @Meta({})
+  A();
+
+  @Meta({})
+  void m() {
+    @Meta({})
+    int z;
+  }
+}
+
+@Meta({})
+enum E {
+  @Meta({})
+  v
+}
+
+class Meta {
+  final Set<int> value;
+
+  const Meta(this.value);
+}
+
+main() {}
diff --git a/tests/language/set_literals/in_initializer_test.dart b/tests/language/set_literals/in_initializer_test.dart
new file mode 100644
index 0000000..f58ba1e
--- /dev/null
+++ b/tests/language/set_literals/in_initializer_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.
+
+class Bag {
+  final Set<Object> things;
+  Bag({Set<Object>? things}) : this.things = things ?? <Object>{};
+  Bag.full({Set<Object> this.things = const {"cat"}});
+}
+
+main() {
+  new Bag();
+  new Bag(things: {});
+  new Bag.full();
+  new Bag.full(things: {});
+}
diff --git a/tests/language/set_literals/invalid_set_literal_test.dart b/tests/language/set_literals/invalid_set_literal_test.dart
new file mode 100644
index 0000000..3030d53
--- /dev/null
+++ b/tests/language/set_literals/invalid_set_literal_test.dart
@@ -0,0 +1,88 @@
+// 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.
+
+import "dart:collection" show HashSet, LinkedHashSet;
+
+import "package:expect/expect.dart";
+
+const Object d = 3.5;
+
+void main() {
+   var o //
+      = <int>{1: 1} //# 01: compile-time error
+      = <int, int, int>{} //# 02: compile-time error
+      = <int, int, int>{1} //# 03: compile-time error
+      = <int, int>{1} //# 04: compile-time error
+      = const <int, int, int>{} //# 05: compile-time error
+      = const <int, int, int>{1} //# 06: compile-time error
+      = const <int, int>{1} //# 07: compile-time error
+      = const {Duration(seconds: 0)} // Overrides ==. //# 08: compile-time error
+      = const {4.2} // Overrides ==. //# 09: compile-time error
+      = const {d} // Overrides ==. //# 10: compile-time error
+      = {,} //# 11: syntax error
+      = {1,,} //# 12: syntax error
+      = {1,,1} //# 13: syntax error
+      ;
+  Expect.isNull(o); // Should be unreachable with a value.
+
+  Set<int>? s //
+      = {"not int"} //# 14: compile-time error
+      = {4.2} //# 15: compile-time error
+      = {1: 1} //# 16: compile-time error
+      = {{}} //# 17: compile-time error
+      ;
+  Expect.isNull(s);
+
+  Set<Set<Object>>? ss //
+      = {{1: 1}} //# 19: compile-time error
+      = {<int, int>{}} //# 20: compile-time error
+      = {<int>{1: 1}} //# 21: compile-time error
+      = const {ss} //# 22: compile-time error
+      ;
+  Expect.isNull(ss);
+
+  HashSet<int>? hs //
+      = {} // Exact type is LinkedHashSet //# 23: compile-time error
+      ;
+  Expect.isNull(hs);
+
+  <T>(x) {
+    // Type constants are allowed, type variables are not.
+    var o //
+        = const {T} //# 26: compile-time error
+        = const {x} //# 27: compile-time error
+        ;
+    Expect.isNull(o);
+  }<int>(42);
+
+  <T extends Set<num>>() {
+    // Regression test for http://dartbug.com/35300.
+    // The `Set<Null>` type is not assignable to `T extends Set<num>`,
+    // so we don't make this a set. You can't assign a map to `T`.
+    T o //
+    = {}; //# 28: compile-time error
+    ;
+  }();
+
+  // Constant sets must not contain equal elements.
+  const cs = {
+    1,
+    "s",
+    #foo,
+    int,
+    C(1),
+    {1},
+    1, //# 29: compile-time error
+    "s", //# 30: compile-time error
+    #foo, //# 31: compile-time error
+    int, //# 32: compile-time error
+    C(1), //# 33: compile-time error
+    {1}, //# 34: compile-time error
+  };
+}
+
+class C {
+  final Object id;
+  const C(this.id);
+}
diff --git a/tests/language/set_literals/set_literal_test.dart b/tests/language/set_literals/set_literal_test.dart
new file mode 100644
index 0000000..ee2d27c
--- /dev/null
+++ b/tests/language/set_literals/set_literal_test.dart
@@ -0,0 +1,131 @@
+// 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.
+
+import 'dart:async';
+import "dart:collection" show LinkedHashSet;
+
+import "package:expect/expect.dart";
+
+void main() {
+  test();
+}
+
+void test() {
+  checkSet<T>(Object o, List elements) {
+    Expect.type<LinkedHashSet<T>>(o);
+    Set<T> set = o as Set<T>;
+    Expect.listEquals(elements, set.toList());
+  }
+
+  Object setContext<T>(Set<T> object) => object;
+  Object iterableContext<T>(Iterable<T> object) => object;
+  Object foSetContext<T>(FutureOr<Set<T>> object) => object;
+  Object foIterableContext<T>(FutureOr<Iterable<T>> object) => object;
+
+  // Empty literal, no type arguments.
+  // No context.
+  Expect.type<Map<dynamic, dynamic>>({});
+  // Set context with no inferred type argument.
+  checkSet<dynamic>(setContext({}), []);
+  checkSet<dynamic>(iterableContext({}), []);
+  checkSet<dynamic>(foSetContext({}), []);
+  checkSet<dynamic>(foIterableContext({}), []);
+  // Specific set context.
+  checkSet<int>(setContext<int>({}), []);
+  checkSet<int>(iterableContext<int>({}), []);
+  checkSet<int>(foSetContext<int>({}), []);
+  checkSet<int>(foIterableContext<int>({}), []);
+
+  // Non-empty set literal, no type argument.
+  // No context.
+  checkSet<int>({1}, [1]);
+  checkSet<int>({3, 1, 2, 4, 1, 4}, [3, 1, 2, 4]);
+  // Set context with no inferred type argument.
+  checkSet<int>(setContext({1}), [1]);
+  checkSet<int>(iterableContext({1}), [1]);
+  checkSet<int>(foSetContext({1}), [1]);
+  checkSet<int>(foIterableContext({1}), [1]);
+  checkSet<int>(setContext({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<int>(iterableContext({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<int>(foSetContext({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<int>(foIterableContext({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  // Specific set context.
+  checkSet<num>(setContext<num>({1}), [1]);
+  checkSet<num>(iterableContext<num>({1}), [1]);
+  checkSet<num>(foSetContext<num>({1}), [1]);
+  checkSet<num>(foIterableContext<num>({1}), [1]);
+  checkSet<num>(setContext<num>({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<num>(iterableContext<num>({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<num>(foSetContext<num>({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+  checkSet<num>(foIterableContext<num>({3, 1, 2, 4, 1, 4}), [3, 1, 2, 4]);
+
+  // Non-empty set literal with type argument.
+  checkSet<num>(<num>{1}, [1]);
+  checkSet<num>(<num>{3, 1, 2, 4, 1, 4}, [3, 1, 2, 4]);
+
+  // Iteration order. Values are evaluated in first-added order.
+  var e1a = Equality(1, "a");
+  var e1b = Equality(1, "b");
+  var e2a = Equality(2, "a");
+  var e2b = Equality(2, "b");
+  var es = {e1a, e2b, e1b, e2a};
+  checkSet<Equality>(es, [e1a, e2b]);
+  Expect.equals("1:a,2:b", es.join(","));
+
+  // Evaluation order. All elements are evaluated, left to right.
+  var entries = <int>[];
+  T log<T>(T value, int entry) {
+    entries.add(entry);
+    return value;
+  }
+  checkSet<Equality>(
+      {log(e1a, 1), log(e2b, 2), log(e1b, 3), log(e2a, 4)}, [e1a, e2b]);
+  Expect.listEquals([1, 2, 3, 4], entries);
+
+  // Nested literals.
+  Object o = {{2}};
+  Expect.type<LinkedHashSet<Set<int>>>(o);
+  Expect.type<LinkedHashSet<int>>((o as Set).first);
+  Set<Set<int>> set = o as Set<Set<int>>;
+  Expect.equals(1, set.length);
+  Expect.equals(1, set.first.length);
+  Expect.equals(2, set.first.first);
+
+  o = {{2}, <int>{}};
+  Expect.type<LinkedHashSet<Set<int>>>(o);
+  Expect.type<LinkedHashSet<int>>((o as Set).first);
+  set = o as Set<Set<int>>;
+  Expect.equals(2, set.length);
+  Expect.equals(1, set.first.length);
+  Expect.equals(2, set.first.first);
+
+  var set2 = {{}};
+  Expect.type<Set<Map<dynamic, dynamic>>>(set2);
+  Expect.equals(1, set2.length);
+  Expect.equals(0, set2.first.length);
+
+  var set3 = {{1}, {}};  // Set<Object>
+  Expect.type<Set<Object>>(set3);
+  Expect.notType<Set<Set<Object>>>(set3);
+
+  // Trailing comma.
+  Iterable<Object> i;
+  i = {1,};
+  Expect.type<Set<Object>>(i);
+  Expect.equals(1, i.length);
+
+  Object o2 = {1, 2, 3,};
+  Expect.type<Set<int>>(o2);
+  Set<Object> set4 = o2 as Set<Object>;
+  Expect.equals(3, set4.length);
+}
+
+class Equality {
+  final int id;
+  final String name;
+  const Equality(this.id, this.name);
+  int get hashCode => id;
+  bool operator==(Object other) => other is Equality && id == other.id;
+  String toString() => "$id:$name";
+}
diff --git a/tests/language/setter/checked2_test.dart b/tests/language/setter/checked2_test.dart
new file mode 100644
index 0000000..ff6a814
--- /dev/null
+++ b/tests/language/setter/checked2_test.dart
@@ -0,0 +1,21 @@
+// Copyright (c) 2013, 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 that implicit setters do a type check generic types.
+import "package:expect/expect.dart";
+
+class A {
+  late C<int> c;
+}
+
+class B extends A {}
+
+class C<T> {}
+
+var array = <dynamic>[new B()];
+
+main() {
+  array[0].c = new C<int>();
+  Expect.throwsTypeError(() => array[0].c = new C<bool>());
+}
diff --git a/tests/language/setter/checked3_test.dart b/tests/language/setter/checked3_test.dart
new file mode 100644
index 0000000..e5b7a13
--- /dev/null
+++ b/tests/language/setter/checked3_test.dart
@@ -0,0 +1,31 @@
+// Copyright (c) 2013, 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";
+
+class A<T> {
+  late T field;
+}
+
+class B<T> {
+  T field = 42 as dynamic;
+}
+
+main() {
+  var a = new A<String>();
+  dynamic s = "string";
+
+  // This assignment is OK.
+  a.field = s;
+
+  dynamic i = 42;
+  Expect.throwsTypeError(() => a.field = i);
+
+  // Throws because the field initializer fails the implicit cast.
+  Expect.throwsTypeError(() => new B<String>());
+
+  // Throws because the assigned value fails the implicit cast.
+  var b = new B<int>();
+  Expect.throwsTypeError(() => b.field = s);
+}
diff --git a/tests/language/setter/checked_setter_test.dart b/tests/language/setter/checked_setter_test.dart
new file mode 100644
index 0000000..82d1eb1
--- /dev/null
+++ b/tests/language/setter/checked_setter_test.dart
@@ -0,0 +1,22 @@
+// Copyright (c) 2013, 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 that implicit setters do a runtime type check.
+
+import "package:expect/expect.dart";
+
+class A {
+  late C c;
+}
+
+class B extends A {}
+
+class C {}
+
+var array = <dynamic>[new B()];
+
+main() {
+  array[0].c = new C();
+  Expect.throwsTypeError(() => array[0].c = new B());
+}
diff --git a/tests/language/setter/declaration_test.dart b/tests/language/setter/declaration_test.dart
new file mode 100644
index 0000000..cc5e6a7
--- /dev/null
+++ b/tests/language/setter/declaration_test.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.
+
+/// Test that a setter has a single argument.
+
+set tooFew() {}
+//  ^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
+//        ^
+// [cfe] A setter should have exactly one formal parameter.
+
+set tooMany(var value, var extra) {}
+//  ^^^^^^^
+// [analyzer] COMPILE_TIME_ERROR.WRONG_NUMBER_OF_PARAMETERS_FOR_SETTER
+//         ^
+// [cfe] A setter should have exactly one formal parameter.
+
+main() {
+  tooFew = 1;
+  tooMany = 2;
+}
diff --git a/tests/language/setter/no_getter_call_runtime_test.dart b/tests/language/setter/no_getter_call_runtime_test.dart
new file mode 100644
index 0000000..d243de3
--- /dev/null
+++ b/tests/language/setter/no_getter_call_runtime_test.dart
@@ -0,0 +1,29 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+import "package:expect/expect.dart";
+
+var topLevelClosure;
+
+
+get topLevel => topLevelClosure;
+
+set topLevel(var value) {}
+
+initialize() {
+  print("initializing");
+  topLevelClosure = (x) => x * 2;
+}
+
+main() {
+  initialize();
+  var x = topLevelClosure(2);
+  Expect.equals(4, x);
+
+  x = topLevel(3);
+  Expect.equals(6, x);
+}
diff --git a/tests/language/setter/no_getter_call_test.dart b/tests/language/setter/no_getter_call_test.dart
new file mode 100644
index 0000000..77b06dc
--- /dev/null
+++ b/tests/language/setter/no_getter_call_test.dart
@@ -0,0 +1,29 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+var topLevelClosure;
+
+/*
+get topLevel => topLevelClosure;
+*/
+set topLevel(var value) {}
+
+initialize() {
+  print("initializing");
+  topLevelClosure = (x) => x * 2;
+}
+
+main() {
+  initialize();
+  var x = topLevelClosure(2);
+  Expect.equals(4, x);
+
+  x = topLevel(3);
+  //  ^^^^^^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_FUNCTION
+  // [cfe] Getter not found: 'topLevel'.
+  Expect.equals(6, x);
+}
diff --git a/tests/language/setter/no_getter_test.dart b/tests/language/setter/no_getter_test.dart
new file mode 100644
index 0000000..f2ea3e3
--- /dev/null
+++ b/tests/language/setter/no_getter_test.dart
@@ -0,0 +1,22 @@
+// 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.
+
+set topLevel(var value) {}
+
+class Example {
+  set foo(var value) {}
+}
+
+main() {
+  print(topLevel++);
+  //    ^
+  // [analyzer] unspecified
+  // [cfe] Getter not found: 'topLevel'.
+
+  Example ex = new Example();
+  print(ex.foo++);
+  //       ^^^
+  // [analyzer] STATIC_TYPE_WARNING.UNDEFINED_GETTER
+  // [cfe] The getter 'foo' isn't defined for the class 'Example'.
+}
diff --git a/tests/language/setter/override2_test.dart b/tests/language/setter/override2_test.dart
new file mode 100644
index 0000000..80902b7
--- /dev/null
+++ b/tests/language/setter/override2_test.dart
@@ -0,0 +1,30 @@
+// Copyright (c) 2013, 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 that we do not report a compile-time error when an instance setter named
+// foo= is declared in a class inheriting an instance method, field, or getter
+// named foo, or an instance setter named foo=.
+
+import "package:expect/expect.dart";
+import "package:meta/meta.dart" show virtual;
+
+class A {
+  var foo = 42; // //# 00: ok
+  get foo => 42; // //# 01: ok
+  foo() => 42; // //# 02: compile-time error
+  set foo(value) {} // //# 03: ok
+}
+
+class B extends A {
+  var foo_;
+  set foo(value) {
+    foo_ = value;
+  }
+}
+
+main() {
+  var b = new B();
+  b.foo = 42;
+  Expect.equals(42, b.foo_);
+}
diff --git a/tests/language/setter/override3_test.dart b/tests/language/setter/override3_test.dart
new file mode 100644
index 0000000..bb00cf6
--- /dev/null
+++ b/tests/language/setter/override3_test.dart
@@ -0,0 +1,26 @@
+// Copyright (c) 2016, 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.
+
+// Tests that a setter in a subclass does not shadow the getter in the
+// superclass.
+import "package:expect/expect.dart";
+
+class A {
+  int _x = 42;
+  int get x => _x;
+}
+
+class B extends A {
+  void set x(int val) {
+    _x = val;
+  }
+}
+
+void main() {
+  var b = new B();
+  Expect.equals(42, b.x);
+
+  b.x = 21;
+  Expect.equals(21, b.x);
+}
diff --git a/tests/language/setter/override_test.dart b/tests/language/setter/override_test.dart
new file mode 100644
index 0000000..88d7402
--- /dev/null
+++ b/tests/language/setter/override_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2013, 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 that we do not report a compile-time error when a static setter named
+// foo= is declared in a class inheriting an instance method or getter named
+// foo, and that we do report an error if an instance setter named foo= or
+// instance field name foo is inherited.
+
+import "package:expect/expect.dart";
+
+class A {
+  var foo = 42; // //# 00: compile-time error
+  get foo => 42; // //# 01: compile-time error
+  foo() => 42; // //# 02: compile-time error
+  set foo(value) {} // //# 03: compile-time error
+}
+
+class B extends A {
+  static var foo_;
+  static set foo(value) {
+    foo_ = value;
+  }
+}
+
+main() {
+  B.foo = 42;
+  Expect.equals(42, B.foo_);
+}
diff --git a/tests/language/setter/setter0_test.dart b/tests/language/setter/setter0_test.dart
new file mode 100644
index 0000000..5817172
--- /dev/null
+++ b/tests/language/setter/setter0_test.dart
@@ -0,0 +1,57 @@
+// 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.
+// Dart test program for testing setting/getting of fields when
+// only getter/setter methods are specified.
+
+import "package:expect/expect.dart";
+
+class First {
+  First(int val) : a_ = val {}
+  int a_;
+}
+
+class Second extends First {
+  static int c = -1;
+
+  Second(int val) : super(val) {}
+
+  static void testStaticMethod() {
+    int i;
+    Second.static_a = 20;
+    i = Second.c;
+  }
+
+  void set instance_a(int value) {
+    a_ = a_ + value;
+  }
+
+  int get instance_a {
+    return a_;
+  }
+
+  static void set static_a(int value) {
+    Second.c = value;
+  }
+
+  static int get static_d {
+    return Second.c;
+  }
+}
+
+class Setter0Test {
+  static testMain() {
+    Second obj = new Second(10);
+    Expect.equals(10, obj.instance_a);
+    obj.instance_a = 20;
+    Expect.equals(30, obj.instance_a);
+
+    Second.testStaticMethod();
+    Expect.equals(20, Second.c);
+    Expect.equals(20, Second.static_d);
+  }
+}
+
+main() {
+  Setter0Test.testMain();
+}
diff --git a/tests/language/setter/setter1_test.dart b/tests/language/setter/setter1_test.dart
new file mode 100644
index 0000000..d9aada3
--- /dev/null
+++ b/tests/language/setter/setter1_test.dart
@@ -0,0 +1,100 @@
+// 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.
+// Dart test program for testing setting/getting of fields when
+// only getter/setter methods are specified.
+
+import "package:expect/expect.dart";
+
+class First {
+  First(int val) : a_ = val {}
+
+  void testMethod() {
+    a = 20;
+  }
+
+  static void testStaticMethod() {
+    b = 20;
+  }
+
+  int get a {
+    return a_;
+  }
+
+  void set a(int val) {
+    a_ = a_ + val;
+  }
+
+  static int get b {
+    return b_;
+  }
+
+  static void set b(int val) {
+    b_ = val;
+  }
+
+  int a_;
+  static int b_ = -1;
+}
+
+class Second {
+  static int c = -1;
+  int a_;
+
+  Second(int value) : a_ = value {}
+
+  void testMethod() {
+    a = 20;
+  }
+
+  static void testStaticMethod() {
+    int i;
+    b = 20;
+    i = d;
+    // TODO(asiva): Turn these on once we have error handling.
+    // i = b; // Should be an error.
+    // d = 40; // Should be an error.
+  }
+
+  int get a {
+    return a_;
+  }
+
+  void set a(int value) {
+    a_ = a_ + value;
+  }
+
+  static void set b(int value) {
+    Second.c = value;
+  }
+
+  static int get d {
+    return Second.c;
+  }
+}
+
+class Setter1Test {
+  static testMain() {
+    First obj1 = new First(10);
+    Expect.equals(10, obj1.a);
+    obj1.testMethod();
+    Expect.equals(30, obj1.a);
+    First.b = 10;
+    Expect.equals(10, First.b);
+    First.testStaticMethod();
+    Expect.equals(20, First.b);
+
+    Second obj = new Second(10);
+    Expect.equals(10, obj.a);
+    obj.testMethod();
+    Expect.equals(30, obj.a);
+
+    Second.testStaticMethod();
+    Expect.equals(20, Second.c);
+    Expect.equals(20, Second.d);
+  }
+}
+
+main() {
+  Setter1Test.testMain();
+}
diff --git a/tests/language/setter/setter2_test.dart b/tests/language/setter/setter2_test.dart
new file mode 100644
index 0000000..9c42bff
--- /dev/null
+++ b/tests/language/setter/setter2_test.dart
@@ -0,0 +1,44 @@
+// 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.
+// Dart test program for testing use of 'this' in an instance method.
+
+import "package:expect/expect.dart";
+
+class Nested {
+  Nested(int val) : a = val {}
+  int a;
+  int foo(int i) {
+    return i;
+  }
+}
+
+class Second {
+  int a = -1;
+  static Nested obj = new Nested(-1);
+
+  Second(int val) {}
+
+  void bar(int value) {
+    a = value;
+    Second.obj.a = Second.obj.foo(this.a);
+    this.a = 100;
+    Expect.equals(100, a);
+  }
+}
+
+class Setter2Test {
+  static testMain() {
+    Second obj = new Second(10);
+    Second.obj = new Nested(10);
+    Second.obj.a = 10;
+    Expect.equals(10, Second.obj.a);
+    Expect.equals(10, Second.obj.foo(10));
+    obj.bar(20);
+    Expect.equals(20, Second.obj.a);
+  }
+}
+
+main() {
+  Setter2Test.testMain();
+}
diff --git a/tests/language/setter/setter3_runtime_test.dart b/tests/language/setter/setter3_runtime_test.dart
new file mode 100644
index 0000000..42d3d74
--- /dev/null
+++ b/tests/language/setter/setter3_runtime_test.dart
@@ -0,0 +1,21 @@
+// TODO(multitest): This was automatically migrated from a multitest and may
+// contain strange or dead code.
+
+// 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.
+
+// Test that setters cannot have defined, non-void return types.
+// Note: The language specification specifies the absence of a type means
+// it is dynamic, however you cannot specify dynamic.
+
+class A {
+  set foo(x) {}
+  void set bar(x) {}
+
+
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/setter/setter3_test.dart b/tests/language/setter/setter3_test.dart
new file mode 100644
index 0000000..bd71750
--- /dev/null
+++ b/tests/language/setter/setter3_test.dart
@@ -0,0 +1,25 @@
+// 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.
+
+// Test that setters cannot have defined, non-void return types.
+// Note: The language specification specifies the absence of a type means
+// it is dynamic, however you cannot specify dynamic.
+
+class A {
+  set foo(x) {}
+  void set bar(x) {}
+  dynamic set baz(x) {}
+//^^^^^^^
+// [analyzer] STATIC_WARNING.NON_VOID_RETURN_FOR_SETTER
+  bool set bob(x) {}
+//^^^^
+// [analyzer] STATIC_WARNING.NON_VOID_RETURN_FOR_SETTER
+//         ^^^
+// [analyzer] COMPILE_TIME_ERROR.BODY_MIGHT_COMPLETE_NORMALLY
+// [cfe] A non-null value must be returned since the return type 'bool' doesn't allow null.
+}
+
+main() {
+  new A();
+}
diff --git a/tests/language/setter/setter4_test.dart b/tests/language/setter/setter4_test.dart
new file mode 100644
index 0000000..182cd86
--- /dev/null
+++ b/tests/language/setter/setter4_test.dart
@@ -0,0 +1,18 @@
+// 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.
+// Dart test to catch error reporting bugs in class fields declarations.
+// Should be an error because we have a setter overriding a function name.
+
+class A {
+  int a() {
+    return 1;
+  }
+
+  void set a(var val) {
+    /*@compile-error=unspecified*/
+    int i = val;
+  }
+}
+
+main() {}
diff --git a/tests/language_2/mixin/illegal_super_use_test.dart b/tests/language_2/mixin/illegal_super_use_test.dart
index 4796185..89c3a76 100644
--- a/tests/language_2/mixin/illegal_super_use_test.dart
+++ b/tests/language_2/mixin/illegal_super_use_test.dart
@@ -76,14 +76,8 @@
 
 class C = Object with M;
 class D = Object with P0;
-//                    ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 class E = Object with M, P1;
-//                       ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 class F = Object with P2, M;
-//                    ^^
-// [analyzer] COMPILE_TIME_ERROR.MIXIN_REFERENCES_SUPER
 
 main() {
   var p1 = new P1();
diff --git a/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.dart b/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.dart
new file mode 100644
index 0000000..58d2081
--- /dev/null
+++ b/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_helper.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 "mixin_constructor_parameter_forwarding_test.dart";
+
+// A private class that the mixin application cannot access syntactically,
+// yet it needs an instance of it for the default value.
+class _Private {
+  const _Private();
+}
+
+class B2<T> implements B<T> {
+  final T x;
+  final Object y;
+  const B2(T x, [Object y = const _Private()])
+      : x = x,
+        y = y;
+}
+
+// Leaking the constant value in a non-constant way which cannot be used
+// for the default value of the mixin application.
+Object get privateValue => const _Private();
diff --git a/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart b/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart
new file mode 100644
index 0000000..0aba8b9
--- /dev/null
+++ b/tests/language_2/mixin_constructor_forwarding/mixin_constructor_parameter_forwarding_test.dart
@@ -0,0 +1,77 @@
+// 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.
+
+// Tests that mixin application forwarding constructors correctly forward
+// optional parameter default values.
+
+import "package:expect/expect.dart";
+
+import "mixin_constructor_parameter_forwarding_helper.dart"
+    show B2, privateValue;
+
+class B<T> {
+  final T x;
+  final Object y;
+  const B(T x, [Object y = 0])
+      : x = x,
+        y = y;
+  const B.b1(T x, {Object y = 0})
+      : x = x,
+        y = y;
+  const B.b2(T x, [Object y = const <int>[0]])
+      : x = x,
+        y = y;
+}
+
+mixin M1 on B<int> {
+  void check(int x, Object y) {
+    Expect.identical(x, this.x);
+    Expect.identical(y, this.y);
+  }
+}
+
+mixin M2<T> on B<T> {
+  void check(T x, Object y) {
+    Expect.identical(x, this.x);
+    Expect.identical(y, this.y);
+  }
+}
+
+class A1 = B<int> with M1;
+class A2 = B<int> with M2<int>;
+class P1 = B2<int> with M2<int>;
+
+main() {
+  A1(1, 2).check(1, 2);
+  A1.b1(1, y: 2).check(1, 2);
+  A1.b2(1, 2).check(1, 2);
+  A2(1, 2).check(1, 2);
+  A2.b1(1, y: 2).check(1, 2);
+  A2.b2(1, 2).check(1, 2);
+  P1(1, 2).check(1, 2);
+
+  A1(1).check(1, 0);
+  A1.b1(1).check(1, 0);
+  A1.b2(1).check(1, const <int>[0]);
+  A2(1).check(1, 0);
+  A2.b1(1).check(1, 0);
+  A2.b2(1).check(1, const <int>[0]);
+  P1(1).check(1, privateValue);
+
+  const A1(1, 2).check(1, 2);
+  const A1.b1(1, y: 2).check(1, 2);
+  const A1.b2(1, 2).check(1, 2);
+  const A2(1, 2).check(1, 2);
+  const A2.b1(1, y: 2).check(1, 2);
+  const A2.b2(1, 2).check(1, 2);
+  const P1(1, 2).check(1, 2);
+
+  const A1(1).check(1, 0);
+  const A1.b1(1).check(1, 0);
+  const A1.b2(1).check(1, const <int>[0]);
+  const A2(1).check(1, 0);
+  const A2.b1(1).check(1, 0);
+  const A2.b2(1).check(1, const <int>[0]);
+  const P1(1).check(1, privateValue);
+}
diff --git a/tests/language_2/unsorted/black_listed_test.dart b/tests/language_2/unsorted/black_listed_test.dart
deleted file mode 100644
index 431872b..0000000
--- a/tests/language_2/unsorted/black_listed_test.dart
+++ /dev/null
@@ -1,79 +0,0 @@
-// 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.
-// Dart test checking that static/instance field shadowing do not conflict.
-
-// Test that certain interfaces/classes are blacklisted from being
-// implemented or extended.
-
-// bool.
-class MyBool implements bool {} //                    //# 01: compile-time error
-abstract class MyBoolInterface implements bool default F { // //# 02: syntax error
-  MyBoolInterface(); //                               //# 02: continued
-} //                                                  //# 02: continued
-
-// num.
-class MyNum implements num {} //                      //# 03: compile-time error
-abstract class MyNumInterface implements num default F { //   //# 04: syntax error
-  MyNumInterface(); //                                //# 04: continued
-} //                                                  //# 04: continued
-
-// int.
-class MyInt implements int {} //                      //# 05: compile-time error
-abstract class MyIntInterface implements int default F { //   //# 06: syntax error
-  MyIntInterface(); //                                //# 06: continued
-} //                                                  //# 06: continued
-
-// double.
-class MyDouble implements double {} //                    //# 07: compile-time error
-abstract class MyDoubleInterface implements double default F { // //# 08: syntax error
-  MyDoubleInterface(); //                                 //# 08: continued
-} //                                                      //# 08: continued
-
-// String.
-class MyString implements String {} //                    //# 09: compile-time error
-abstract class MyStringInterface implements String default F { // //# 10: syntax error
-  MyStringInterface(); //                                 //# 10: continued
-} //                                                      //# 10: continued
-
-// Function.
-class MyFunction implements Function {}
-
-class MyOtherFunction extends Function {}
-abstract class MyFunctionInterface implements Function default F { // //# 12: syntax error
-  MyFunctionInterface(); //                                   //# 12: continued
-} //                                                          //# 12: continued
-
-// dynamic.
-class MyDynamic implements dynamic {} //                     //# 13: compile-time error
-abstract class MyDynamicInterface implements dynamic default F { //  //# 14: syntax error
-  MyDynamicInterface(); //                                   //# 14: continued
-} //                                                         //# 14: continued
-
-class F {
-  factory MyBoolInterface() { return null; } //     //# 02: continued
-  factory MyNumInterface() { return null; } //      //# 04: continued
-  factory MyIntInterface() { return null; } //      //# 06: continued
-  factory MyDoubleInterface() { return null; } //   //# 08: continued
-  factory MyStringInterface() { return null; } //   //# 10: continued
-  factory MyFunctionInterface() { return null; } // //# 12: continued
-  factory MyDynamicInterface() { return null; } //  //# 14: continued
-}
-
-main() {
-  new MyBool(); //             //# 01: continued
-  new MyBoolInterface(); //    //# 02: continued
-  new MyNum(); //              //# 03: continued
-  new MyNumInterface(); //     //# 04: continued
-  new MyInt(); //              //# 05: continued
-  new MyIntInterface(); //     //# 06: continued
-  new MyDouble(); //           //# 07: continued
-  new MyDoubleInterface(); //  //# 08: continued
-  new MyString(); //           //# 09: continued
-  new MyStringInterface(); //  //# 10: continued
-  new MyFunction();
-  new MyOtherFunction();
-  new MyFunctionInterface(); //# 12: continued
-  new MyDynamic(); //          //# 13: continued
-  new MyDynamicInterface(); // //# 14: continued
-}
diff --git a/tests/language_2/unsorted/deny_listed_test.dart b/tests/language_2/unsorted/deny_listed_test.dart
new file mode 100644
index 0000000..ba49fdc
--- /dev/null
+++ b/tests/language_2/unsorted/deny_listed_test.dart
@@ -0,0 +1,79 @@
+// 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.
+// Dart test checking that static/instance field shadowing do not conflict.
+
+// Test that certain interfaces/classes are denylisted from being
+// implemented or extended.
+
+// bool.
+class MyBool implements bool {} //                    //# 01: compile-time error
+abstract class MyBoolInterface implements bool default F { // //# 02: syntax error
+  MyBoolInterface(); //                               //# 02: continued
+} //                                                  //# 02: continued
+
+// num.
+class MyNum implements num {} //                      //# 03: compile-time error
+abstract class MyNumInterface implements num default F { //   //# 04: syntax error
+  MyNumInterface(); //                                //# 04: continued
+} //                                                  //# 04: continued
+
+// int.
+class MyInt implements int {} //                      //# 05: compile-time error
+abstract class MyIntInterface implements int default F { //   //# 06: syntax error
+  MyIntInterface(); //                                //# 06: continued
+} //                                                  //# 06: continued
+
+// double.
+class MyDouble implements double {} //                    //# 07: compile-time error
+abstract class MyDoubleInterface implements double default F { // //# 08: syntax error
+  MyDoubleInterface(); //                                 //# 08: continued
+} //                                                      //# 08: continued
+
+// String.
+class MyString implements String {} //                    //# 09: compile-time error
+abstract class MyStringInterface implements String default F { // //# 10: syntax error
+  MyStringInterface(); //                                 //# 10: continued
+} //                                                      //# 10: continued
+
+// Function.
+class MyFunction implements Function {}
+
+class MyOtherFunction extends Function {}
+abstract class MyFunctionInterface implements Function default F { // //# 12: syntax error
+  MyFunctionInterface(); //                                   //# 12: continued
+} //                                                          //# 12: continued
+
+// dynamic.
+class MyDynamic implements dynamic {} //                     //# 13: compile-time error
+abstract class MyDynamicInterface implements dynamic default F { //  //# 14: syntax error
+  MyDynamicInterface(); //                                   //# 14: continued
+} //                                                         //# 14: continued
+
+class F {
+  factory MyBoolInterface() { return null; } //     //# 02: continued
+  factory MyNumInterface() { return null; } //      //# 04: continued
+  factory MyIntInterface() { return null; } //      //# 06: continued
+  factory MyDoubleInterface() { return null; } //   //# 08: continued
+  factory MyStringInterface() { return null; } //   //# 10: continued
+  factory MyFunctionInterface() { return null; } // //# 12: continued
+  factory MyDynamicInterface() { return null; } //  //# 14: continued
+}
+
+main() {
+  new MyBool(); //             //# 01: continued
+  new MyBoolInterface(); //    //# 02: continued
+  new MyNum(); //              //# 03: continued
+  new MyNumInterface(); //     //# 04: continued
+  new MyInt(); //              //# 05: continued
+  new MyIntInterface(); //     //# 06: continued
+  new MyDouble(); //           //# 07: continued
+  new MyDoubleInterface(); //  //# 08: continued
+  new MyString(); //           //# 09: continued
+  new MyStringInterface(); //  //# 10: continued
+  new MyFunction();
+  new MyOtherFunction();
+  new MyFunctionInterface(); //# 12: continued
+  new MyDynamic(); //          //# 13: continued
+  new MyDynamicInterface(); // //# 14: continued
+}
diff --git a/tests/lib/isolate/detect_nullsafety_1_test.dart b/tests/lib/isolate/detect_nullsafety_1_test.dart
new file mode 100644
index 0000000..1fecd54
--- /dev/null
+++ b/tests/lib/isolate/detect_nullsafety_1_test.dart
@@ -0,0 +1,39 @@
+// 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 "detect_nullsafety_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/strong.dart";
+  String dillPath = "$tmpDirPath/strong.dill";
+  String jitPath = "$tmpDirPath/strong.appjit";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "");
+  generateKernel(sourcePath, dillPath);
+  generateAppJIT(sourcePath, jitPath);
+
+  try {
+    // Running from Source.
+    testNullSafetyMode(sourcePath, 'Strong Mode');
+    // Without the enable experiment option it will be in weak mode.
+    testNullSafetyMode1(sourcePath, 'Weak Mode');
+
+    // Running from Kernel File.
+    testNullSafetyMode(dillPath, 'Strong Mode');
+    // Without the enable experiment option it will be inferred to strong.
+    testNullSafetyMode1(dillPath, 'Strong Mode');
+
+    // Running from app JIT File.
+    testNullSafetyMode(jitPath, 'Strong Mode');
+    // Without the enable experiment option it will be inferred to strong.
+    testNullSafetyMode1(jitPath, 'Strong Mode');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/detect_nullsafety_2_test.dart b/tests/lib/isolate/detect_nullsafety_2_test.dart
new file mode 100644
index 0000000..722f74e
--- /dev/null
+++ b/tests/lib/isolate/detect_nullsafety_2_test.dart
@@ -0,0 +1,38 @@
+// 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 "detect_nullsafety_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/weak.dart";
+  String dillPath = "$tmpDirPath/weak.dill";
+  String jitPath = "$tmpDirPath/weak.appjit";
+
+  // Generate code for an isolate to run in weak mode.
+  generateIsolateSource(sourcePath, "2.6");
+  generateKernel(sourcePath, dillPath);
+  generateAppJIT(sourcePath, jitPath);
+
+  try {
+    testNullSafetyMode(sourcePath, 'Weak Mode');
+    // Without the enable experiment option it will be in weak mode.
+    testNullSafetyMode1(sourcePath, 'Weak Mode');
+
+    // Running from Kernel File.
+    testNullSafetyMode(dillPath, 'Weak Mode');
+    // Without the enable experiment option it will be inferred to weak.
+    testNullSafetyMode1(dillPath, 'Weak Mode');
+
+    // Running from app JIT File.
+    testNullSafetyMode(jitPath, 'Weak Mode');
+    // Without the enable experiment option it will be inferred to weak.
+    testNullSafetyMode1(jitPath, 'Weak Mode');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/detect_nullsafety_helper.dart b/tests/lib/isolate/detect_nullsafety_helper.dart
new file mode 100644
index 0000000..c8c263c
--- /dev/null
+++ b/tests/lib/isolate/detect_nullsafety_helper.dart
@@ -0,0 +1,56 @@
+// 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 generateIsolateSource(String filePath, String version) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+    // @dart=$version
+    void main() {
+      try {
+        int x = null as int;
+        print("Weak Mode");
+      } catch (ex) {
+        print("Strong Mode");
+      }
+    }
+  ''');
+}
+
+void generateOutput(String sourcePath, String outPath, String type) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--snapshot-kind=$type");
+  args.add("--snapshot=$outPath");
+  args.add("--enable-experiment=non-nullable");
+  args.add(sourcePath);
+  var result = Process.runSync(exec, args);
+}
+
+void generateKernel(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "kernel");
+}
+
+void generateAppJIT(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "app-jit");
+}
+
+void testNullSafetyMode(String filePath, String expected) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--enable-experiment=non-nullable");
+  args.add(filePath);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
+
+void testNullSafetyMode1(String filePath, String expected) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add(filePath);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
diff --git a/tests/lib/isolate/nnbd_spawn_autodetect_1_test.dart b/tests/lib/isolate/nnbd_spawn_autodetect_1_test.dart
new file mode 100644
index 0000000..6b18ca1
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawn_autodetect_1_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.
+
+import "dart:io";
+import "nnbd_spawn_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/strong.dart";
+  String dillPath = "$tmpDirPath/strong.dill";
+  String jitPath = "$tmpDirPath/strong.appjit";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "");
+  generateKernel(sourcePath, dillPath);
+  generateAppJIT(sourcePath, jitPath);
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawn.
+    testNullSafetyMode(sourcePath, 're: strong');
+    testNullSafetyMode(dillPath, 're: strong');
+    testNullSafetyMode(jitPath, 're: strong');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawn_autodetect_2_test.dart b/tests/lib/isolate/nnbd_spawn_autodetect_2_test.dart
new file mode 100644
index 0000000..1d19f15
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawn_autodetect_2_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.
+
+import "dart:io";
+import "nnbd_spawn_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/strong.dart";
+  String dillPath = "$tmpDirPath/strong.dill";
+  String jitPath = "$tmpDirPath/strong.appjit";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "2.6");
+  generateKernel(sourcePath, dillPath);
+  generateAppJIT(sourcePath, jitPath);
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawn.
+    testNullSafetyMode(sourcePath, 're: weak');
+    testNullSafetyMode(dillPath, 're: weak');
+    testNullSafetyMode(jitPath, 're: weak');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawn_autodetect_helper.dart b/tests/lib/isolate/nnbd_spawn_autodetect_helper.dart
new file mode 100644
index 0000000..e689636
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawn_autodetect_helper.dart
@@ -0,0 +1,74 @@
+// 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 generateIsolateSource(String filePath, String version) {
+  File isolateSource = new File(filePath);
+  isolateSource.writeAsStringSync('''
+      // @dart=$version
+      import \'dart:isolate\';
+
+      spawnFunc(List args) {
+        var data = args[0];
+        var replyTo = args[1];
+        try {
+          int x = null as int;
+          replyTo.send(\'re: weak\');
+        } catch (ex) {
+          replyTo.send(\'re: strong\');
+        }
+      }
+
+      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.spawn(
+          spawnFunc,
+          [\'re: hi\', 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;
+      }
+  ''');
+}
+
+void generateOutput(String sourcePath, String outPath, String type) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--snapshot-kind=$type");
+  args.add("--snapshot=$outPath");
+  args.add("--enable-experiment=non-nullable");
+  args.add(sourcePath);
+  var result = Process.runSync(exec, args);
+}
+
+void generateKernel(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "kernel");
+}
+
+void generateAppJIT(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "app-jit");
+}
+
+void testNullSafetyMode(String filePath, String expected) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--enable-experiment=non-nullable");
+  args.add(filePath);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
diff --git a/tests/lib/isolate/nnbd_spawn_autodetect_test.dart b/tests/lib/isolate/nnbd_spawn_autodetect_test.dart
deleted file mode 100644
index 3e9c617..0000000
--- a/tests/lib/isolate/nnbd_spawn_autodetect_test.dart
+++ /dev/null
@@ -1,69 +0,0 @@
-// 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 testNullSafetyMode(String filePath, String version, String expected) {
-  File mainIsolate = new File(filePath);
-  mainIsolate.writeAsStringSync('''
-    // $version
-    import \'dart:isolate\';
-
-    spawnFunc(List args) {
-      var data = args[0];
-      var replyTo = args[1];
-      try {
-        int x = null as int;
-        replyTo.send(\'re: weak\');
-      } catch (ex) {
-        replyTo.send(\'re: strong\');
-      }
-    }
-
-    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.spawn(
-          spawnFunc,
-          [\'re: hi\', 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("--enable-experiment=non-nullable");
-  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;
-
-  try {
-    // Strong Isolate Spawning another Strong Isolate using spawn.
-    testNullSafetyMode("$tmpDirPath/strong.dart", '', 're: strong');
-
-    // Weak Isolate Spawning a Weak Isolate using spawn.
-    testNullSafetyMode("$tmpDirPath/weak.dart", '@dart=2.6', 're: weak');
-  } finally {
-    tmpDir.deleteSync(recursive: true);
-  }
-}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_1_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_1_test.dart
new file mode 100644
index 0000000..013d558
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_1_test.dart
@@ -0,0 +1,28 @@
+// 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 "nnbd_spawnuri_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/strong_isolate.dart";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "");
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/strong_strong.dart", "", sourcePath, 're: strong');
+
+    // Weak Isolate Spawning a Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_strong.dart", "2.6", sourcePath, 're: strong');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_2_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_2_test.dart
new file mode 100644
index 0000000..e2f9d1c
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_2_test.dart
@@ -0,0 +1,28 @@
+// 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 "nnbd_spawnuri_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/weak_isolate.dart";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "2.6");
+
+  try {
+    // Strong Isolate Spawning another weak Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/strong_weak.dart", "", sourcePath, 're: weak');
+
+    // Weak Isolate Spawning another Weak Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_weak.dart", "2.6", sourcePath, 're: weak');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_3_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_3_test.dart
new file mode 100644
index 0000000..b7650db
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_3_test.dart
@@ -0,0 +1,30 @@
+// 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 "nnbd_spawnuri_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/strong_isolate.dart";
+  String outPath = "$tmpDirPath/strong_isolate.dill";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "");
+  generateKernel(sourcePath, outPath);
+
+  try {
+    // Strong Isolate Spawning another Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/strong_strong.dart", "", outPath, 're: strong');
+
+    // Weak Isolate Spawning a Strong Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_strong.dart", "2.6", outPath, 're: strong');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_4_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_4_test.dart
new file mode 100644
index 0000000..875d4d0
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_4_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.
+
+import "dart:io";
+import "nnbd_spawnuri_autodetect_helper.dart";
+
+void main() {
+  // Create temporary directory.
+  var tmpDir = Directory.systemTemp.createTempSync();
+  var tmpDirPath = tmpDir.path;
+  String sourcePath = "$tmpDirPath/weak_isolate.dart";
+  String outPath = "$tmpDirPath/weak_isolate.dill";
+
+  // Generate code for an isolate to run in strong mode.
+  generateIsolateSource(sourcePath, "2.6");
+  generateKernel(sourcePath, outPath);
+
+  try {
+    // Strong Isolate Spawning another weak Isolate using spawnUri.
+    testNullSafetyMode("$tmpDirPath/strong_weak.dart", "", outPath, 're: weak');
+
+    // Weak Isolate Spawning another Weak Isolate using spawnUri.
+    testNullSafetyMode(
+        "$tmpDirPath/weak_weak.dart", "2.6", outPath, 're: weak');
+  } finally {
+    tmpDir.deleteSync(recursive: true);
+  }
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_helper.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_helper.dart
new file mode 100644
index 0000000..4cca7e9
--- /dev/null
+++ b/tests/lib/isolate/nnbd_spawnuri_autodetect_helper.dart
@@ -0,0 +1,81 @@
+// 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 generateIsolateSource(String filePath, String version) {
+  File isolateSource = new File("$filePath");
+  isolateSource.writeAsStringSync('''
+    // @dart=$version
+    library SpawnUriIsolate;
+    main(List<String> args, replyTo) {
+      var data = args[0];
+      try {
+        int x = null as int;
+        replyTo.send(\'re: weak\');
+      } catch (ex) {
+        replyTo.send(\'re: strong\');
+      }
+    }
+  ''');
+}
+
+void generateOutput(String sourcePath, String outPath, String type) {
+  var exec = Platform.resolvedExecutable;
+  var args = <String>[];
+  args.add("--snapshot-kind=$type");
+  args.add("--snapshot=$outPath");
+  args.add("--enable-experiment=non-nullable");
+  args.add(sourcePath);
+  var result = Process.runSync(exec, args);
+}
+
+void generateKernel(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "kernel");
+}
+
+void generateAppJIT(String sourcePath, String outPath) {
+  generateOutput(sourcePath, outPath, "app-jit");
+}
+
+void testNullSafetyMode(
+    String filePath, String version, String uri, String expected) {
+  File mainIsolate = new File(filePath);
+  mainIsolate.writeAsStringSync('''
+      // @dart=$version
+      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\'),
+            [\'re: hi\'],
+            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("--enable-experiment=non-nullable");
+  args.add(mainIsolate.path);
+  var result = Process.runSync(exec, args);
+  expect(result.stdout.contains('$expected'), true);
+}
diff --git a/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart b/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart
deleted file mode 100644
index 49afc571..0000000
--- a/tests/lib/isolate/nnbd_spawnuri_autodetect_test.dart
+++ /dev/null
@@ -1,101 +0,0 @@
-// 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 testNullSafetyMode(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\'),
-          [\'re: hi\'],
-          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("--enable-experiment=non-nullable");
-  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 in strong mode.
-  File strongIsolate = new File("$tmpDirPath/strong_isolate.dart");
-  strongIsolate.writeAsStringSync('''
-    library SpawnUriStrongIsolate;
-    main(List<String> args, replyTo) {
-      var data = args[0];
-      try {
-        int x = null as int;
-        replyTo.send(\'re: weak\');
-      } catch (ex) {
-        replyTo.send(\'re: strong\');
-      }
-    }
-    ''');
-
-  // Generate code for an isolate to run in weak mode.
-  File weakIsolate = new File("$tmpDirPath/weak_isolate.dart");
-  weakIsolate.writeAsStringSync('''
-    // @dart=2.7
-    library SpawnUriStrongIsolate;
-    main(List<String> args, replyTo) {
-      var data = args[0];
-      try {
-        int x = null as int;
-        replyTo.send(\'re: weak\');
-      } catch (ex) {
-        replyTo.send(\'re: strong\');
-      }
-    }
-    ''');
-
-  try {
-    // Strong Isolate Spawning another Strong Isolate using spawnUri.
-    testNullSafetyMode(
-        "$tmpDirPath/strong_strong.dart", strongIsolate.path, 're: strong');
-
-    // Strong Isolate Spawning a Weak Isolate using spawnUri.
-    testNullSafetyMode(
-        "$tmpDirPath/strong_weak.dart", weakIsolate.path, 're: weak');
-
-    // Weak Isolate Spawning a Strong Isolate using spawnUri.
-    testNullSafetyMode(
-        "$tmpDirPath/weak_strong.dart", strongIsolate.path, 're: strong');
-
-    // Weak Isolate Spawning a Weak Isolate using spawnUri.
-    testNullSafetyMode(
-        "$tmpDirPath/weak_weak.dart", weakIsolate.path, 're: weak');
-  } finally {
-    tmpDir.deleteSync(recursive: true);
-  }
-}
diff --git a/tests/lib/lib.status b/tests/lib/lib.status
index 6e52e77..9b87a8d 100644
--- a/tests/lib/lib.status
+++ b/tests/lib/lib.status
@@ -79,6 +79,8 @@
 isolate/cross_isolate_message_test: Skip # Isolate.spawnUri
 isolate/deferred_in_isolate2_test: Skip # Isolate.spawnUri
 isolate/deferred_in_isolate_test: Skip # Isolate.spawnUri
+isolate/detect_nullsafety_1_test: Skip # Tests Source, Kernel, appJIT modes
+isolate/detect_nullsafety_2_test: Skip # Tests Source, Kernel, appJIT modes
 isolate/error_at_spawnuri_test: Skip # Isolate.spawnUri
 isolate/error_exit_at_spawnuri_test: Skip # Isolate.spawnUri
 isolate/exit_at_spawnuri_test: Skip # Isolate.spawnUri
@@ -95,8 +97,12 @@
 isolate/mint_maker_test: Skip # Isolate.spawnUri
 isolate/nested_spawn2_test: Skip # Isolate.spawnUri
 isolate/nested_spawn_test: Skip # Isolate.spawnUri
-isolate/nnbd_spawn_autodetect_test: Skip # Auto detect not for precompiled.
-isolate/nnbd_spawnuri_autodetect_test: Skip # Auto detect not for precompiled.
+isolate/nnbd_spawn_autodetect_1_test: Skip # Tests Source, Kernel, appJIT modes
+isolate/nnbd_spawn_autodetect_2_test: Skip # Tests Source, Kernel, appJIT modes
+isolate/nnbd_spawnuri_autodetect_1_test: Skip # Uses Isolate.spawnUri
+isolate/nnbd_spawnuri_autodetect_2_test: Skip # Uses Isolate.spawnUri
+isolate/nnbd_spawnuri_autodetect_3_test: Skip # Uses Isolate.spawnUri
+isolate/nnbd_spawnuri_autodetect_4_test: Skip # Uses Isolate.spawnUri
 isolate/no_package_test: Skip # Isolate.spawnUri
 isolate/package_config_test: Skip # Isolate.spawnUri
 isolate/raw_port_test: Skip # Isolate.spawnUri
diff --git a/tests/lib/mirrors/invocation_fuzz_test.dart b/tests/lib/mirrors/invocation_fuzz_test.dart
index b241d49..ea8f546 100644
--- a/tests/lib/mirrors/invocation_fuzz_test.dart
+++ b/tests/lib/mirrors/invocation_fuzz_test.dart
@@ -14,7 +14,7 @@
 import 'dart:io';
 
 // Methods to be skipped, by qualified name.
-var blacklist = [
+var denylist = [
   // Don't recurse on this test.
   'test.invoke_natives',
 
@@ -39,9 +39,9 @@
   new RegExp(r"^dart\.async\._.*$"),
 ];
 
-bool isBlacklisted(Symbol qualifiedSymbol) {
+bool isDenylisted(Symbol qualifiedSymbol) {
   var qualifiedString = MirrorSystem.getName(qualifiedSymbol);
-  for (var pattern in blacklist) {
+  for (var pattern in denylist) {
     if (qualifiedString.contains(pattern)) {
       print('Skipping $qualifiedString');
       return true;
@@ -58,7 +58,7 @@
 var queue = <Task>[];
 
 checkMethod(MethodMirror m, ObjectMirror target, [origin]) {
-  if (isBlacklisted(m.qualifiedName)) return;
+  if (isDenylisted(m.qualifiedName)) return;
 
   var task = new Task();
   task.name = '${MirrorSystem.getName(m.qualifiedName)} from $origin';
@@ -97,7 +97,7 @@
   classMirror.declarations.values
       .where((d) => d is MethodMirror && d.isConstructor)
       .forEach((m) {
-    if (isBlacklisted(m.qualifiedName)) return;
+    if (isDenylisted(m.qualifiedName)) return;
     var task = new Task();
     task.name = MirrorSystem.getName(m.qualifiedName);
 
@@ -112,7 +112,7 @@
 
 checkLibrary(libraryMirror) {
   print(libraryMirror.simpleName);
-  if (isBlacklisted(libraryMirror.qualifiedName)) return;
+  if (isDenylisted(libraryMirror.qualifiedName)) return;
 
   libraryMirror.declarations.values
       .where((d) => d is ClassMirror)
diff --git a/tests/lib_2/mirrors/invocation_fuzz_test.dart b/tests/lib_2/mirrors/invocation_fuzz_test.dart
index 61124a8..5a5cdf2 100644
--- a/tests/lib_2/mirrors/invocation_fuzz_test.dart
+++ b/tests/lib_2/mirrors/invocation_fuzz_test.dart
@@ -14,7 +14,7 @@
 import 'dart:io';
 
 // Methods to be skipped, by qualified name.
-var blacklist = [
+var denylist = [
   // Don't recurse on this test.
   'test.invoke_natives',
 
@@ -39,9 +39,9 @@
   new RegExp(r"^dart\.async\._.*$"),
 ];
 
-bool isBlacklisted(Symbol qualifiedSymbol) {
+bool isDenylisted(Symbol qualifiedSymbol) {
   var qualifiedString = MirrorSystem.getName(qualifiedSymbol);
-  for (var pattern in blacklist) {
+  for (var pattern in denylist) {
     if (qualifiedString.contains(pattern)) {
       print('Skipping $qualifiedString');
       return true;
@@ -58,7 +58,7 @@
 var queue = new List<Task>();
 
 checkMethod(MethodMirror m, ObjectMirror target, [origin]) {
-  if (isBlacklisted(m.qualifiedName)) return;
+  if (isDenylisted(m.qualifiedName)) return;
 
   var task = new Task();
   task.name = '${MirrorSystem.getName(m.qualifiedName)} from $origin';
@@ -97,7 +97,7 @@
   classMirror.declarations.values
       .where((d) => d is MethodMirror && d.isConstructor)
       .forEach((m) {
-    if (isBlacklisted(m.qualifiedName)) return;
+    if (isDenylisted(m.qualifiedName)) return;
     var task = new Task();
     task.name = MirrorSystem.getName(m.qualifiedName);
 
@@ -112,7 +112,7 @@
 
 checkLibrary(libraryMirror) {
   print(libraryMirror.simpleName);
-  if (isBlacklisted(libraryMirror.qualifiedName)) return;
+  if (isDenylisted(libraryMirror.qualifiedName)) return;
 
   libraryMirror.declarations.values
       .where((d) => d is ClassMirror)
diff --git a/tests/standalone/io/file_copy_test.dart b/tests/standalone/io/file_copy_test.dart
index 8176d93..2302a4a 100644
--- a/tests/standalone/io/file_copy_test.dart
+++ b/tests/standalone/io/file_copy_test.dart
@@ -30,14 +30,6 @@
   Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
   Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
 
-  // Check there is no temporary files existing.
-  var list = tmp.listSync();
-  Expect.equals(2, list.length);
-  for (var file in list) {
-    final fileName = file.path.toString();
-    Expect.isTrue(fileName.contains("file1") || fileName.contains("file2"));
-  }
-
   // Fail when coping to directory.
   var dir = new Directory('${tmp.path}/dir')..createSync();
   Expect.throws(() => file1.copySync(dir.path));
diff --git a/tests/standalone/io/file_write_as_test.dart b/tests/standalone/io/file_write_as_test.dart
index d1d2d0d..0b0d082 100644
--- a/tests/standalone/io/file_write_as_test.dart
+++ b/tests/standalone/io/file_write_as_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:collection';
 import 'dart:io';
 import 'dart:typed_data';
 
@@ -90,8 +91,42 @@
 
 testWriteAsSubtypeSync(dir) {
   var f = new File('${dir.path}${Platform.pathSeparator}bytes_sync.txt');
-  f.writeAsBytesSync(UnmodifiableUint8ListView(Uint8List(10)));
-  Expect.equals(10, f.readAsBytesSync().length);
+  var input = Uint8List(5);
+  input[0] = 1;
+  input[1] = 2;
+  f.writeAsBytesSync(UnmodifiableUint8ListView(input));
+  var bytes = f.readAsBytesSync();
+  Expect.listEquals(input, bytes);
+}
+
+class MyUint8List extends ListBase<int> implements List<int> {
+  Uint8List _source;
+  MyUint8List(this._source);
+
+  // TypedData.
+  ByteBuffer get buffer => _source.buffer;
+  int get lengthInBytes => _source.lengthInBytes;
+  int get offsetInBytes => _source.offsetInBytes;
+
+  /// The methods that ListBase needs:
+  int operator [](int index) => _source[index];
+  operator []=(int index, int value) => _source[index] = value;
+  int get length => _source.length;
+  set length(_) => UnsupportedError("fixed length");
+  int get elementSizeInBytes => _source.elementSizeInBytes;
+
+  Uint8List sublist(int start, [int? end]) => _source.sublist(start, end);
+}
+
+void testCustomizedSubtypeSync(Directory dir) {
+  var f = new File('${dir.path}${Platform.pathSeparator}bytes_sync.txt');
+  var input = Uint8List(5);
+  input[0] = 1;
+  input[1] = 2;
+  MyUint8List list = MyUint8List(input);
+  f.writeAsBytesSync(list);
+  var bytes = f.readAsBytesSync();
+  Expect.listEquals(input, bytes);
 }
 
 main() {
@@ -101,6 +136,7 @@
   testWriteAsStringSync(tempDir);
   testWriteWithLargeList(tempDir);
   testWriteAsSubtypeSync(tempDir);
+  testCustomizedSubtypeSync(tempDir);
   testWriteAsBytes(tempDir).then((_) {
     return testWriteAsString(tempDir);
   }).then((_) {
diff --git a/tests/standalone_2/black_listed_test.dart b/tests/standalone_2/black_listed_test.dart
deleted file mode 100644
index 081b76e..0000000
--- a/tests/standalone_2/black_listed_test.dart
+++ /dev/null
@@ -1,59 +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.
-// Dart test checking that static/instance field shadowing do not conflict.
-
-// Test that certain interfaces/classes are blacklisted from being
-// implemented or extended (VM corelib only).
-
-library BlackListedTest;
-
-class MyBool extends Bool {} // //# 01: compile-time error
-
-class MyDouble extends Double {} // //# 02: compile-time error
-
-class MyObjectArray extends ObjectArray {} // //# 03: compile-time error
-
-class MyImmutableArray extends ImmutableArray {} // //# 04: compile-time error
-
-class MyGrowableObjectArray extends GrowableObjectArray {} // //# 05: compile-time error
-
-class MyIntegerImplementation extends IntegerImplementation {} // //# 06: compile-time error
-
-class MySmi extends Smi {} // //# 07: compile-time error
-
-class MyMint extends Mint {} // //# 08: compile-time error
-
-class MyBigint extends Bigint {} // //# 09: compile-time error
-
-class MyOneByteString extends OneByteString {} // //# 10: compile-time error
-
-class MyTwoByteString extends TwoByteString {} // //# 11: compile-time error
-
-class MyFourByteString extends FourByteString {} // //# 12: compile-time error
-
-main() {
-  new MyBool(); //# 01: continued
-
-  new MyDouble(); //# 02: continued
-
-  new MyObjectArray(); //# 03: continued
-
-  new MyImmutableArray(); //# 04: continued
-
-  new MyGrowableObjectArray(); //# 05: continued
-
-  new MyIntegerImplementation(); //# 06: continued
-
-  new MySmi(); //# 07: continued
-
-  new MyMint(); //# 08: continued
-
-  new MyBigint(); //# 09: continued
-
-  new MyOneByteString(); //# 10: continued
-
-  new MyTwoByteString(); //# 11: continued
-
-  new MyFourByteString(); //# 12: continued
-}
diff --git a/tests/standalone_2/deny_listed_test.dart b/tests/standalone_2/deny_listed_test.dart
new file mode 100644
index 0000000..2516b20
--- /dev/null
+++ b/tests/standalone_2/deny_listed_test.dart
@@ -0,0 +1,59 @@
+// 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.
+// Dart test checking that static/instance field shadowing do not conflict.
+
+// Test that certain interfaces/classes are denylisted from being
+// implemented or extended (VM corelib only).
+
+library BlackListedTest;
+
+class MyBool extends Bool {} // //# 01: compile-time error
+
+class MyDouble extends Double {} // //# 02: compile-time error
+
+class MyObjectArray extends ObjectArray {} // //# 03: compile-time error
+
+class MyImmutableArray extends ImmutableArray {} // //# 04: compile-time error
+
+class MyGrowableObjectArray extends GrowableObjectArray {} // //# 05: compile-time error
+
+class MyIntegerImplementation extends IntegerImplementation {} // //# 06: compile-time error
+
+class MySmi extends Smi {} // //# 07: compile-time error
+
+class MyMint extends Mint {} // //# 08: compile-time error
+
+class MyBigint extends Bigint {} // //# 09: compile-time error
+
+class MyOneByteString extends OneByteString {} // //# 10: compile-time error
+
+class MyTwoByteString extends TwoByteString {} // //# 11: compile-time error
+
+class MyFourByteString extends FourByteString {} // //# 12: compile-time error
+
+main() {
+  new MyBool(); //# 01: continued
+
+  new MyDouble(); //# 02: continued
+
+  new MyObjectArray(); //# 03: continued
+
+  new MyImmutableArray(); //# 04: continued
+
+  new MyGrowableObjectArray(); //# 05: continued
+
+  new MyIntegerImplementation(); //# 06: continued
+
+  new MySmi(); //# 07: continued
+
+  new MyMint(); //# 08: continued
+
+  new MyBigint(); //# 09: continued
+
+  new MyOneByteString(); //# 10: continued
+
+  new MyTwoByteString(); //# 11: continued
+
+  new MyFourByteString(); //# 12: continued
+}
diff --git a/tests/standalone_2/io/file_copy_test.dart b/tests/standalone_2/io/file_copy_test.dart
index 8176d93..2302a4a 100644
--- a/tests/standalone_2/io/file_copy_test.dart
+++ b/tests/standalone_2/io/file_copy_test.dart
@@ -30,14 +30,6 @@
   Expect.equals(FILE_CONTENT2, file1.readAsStringSync());
   Expect.equals(FILE_CONTENT2, file2.readAsStringSync());
 
-  // Check there is no temporary files existing.
-  var list = tmp.listSync();
-  Expect.equals(2, list.length);
-  for (var file in list) {
-    final fileName = file.path.toString();
-    Expect.isTrue(fileName.contains("file1") || fileName.contains("file2"));
-  }
-
   // Fail when coping to directory.
   var dir = new Directory('${tmp.path}/dir')..createSync();
   Expect.throws(() => file1.copySync(dir.path));
diff --git a/tests/standalone_2/io/file_write_as_test.dart b/tests/standalone_2/io/file_write_as_test.dart
index d1d2d0d..64b2e11 100644
--- a/tests/standalone_2/io/file_write_as_test.dart
+++ b/tests/standalone_2/io/file_write_as_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:async';
+import 'dart:collection';
 import 'dart:io';
 import 'dart:typed_data';
 
@@ -90,8 +91,42 @@
 
 testWriteAsSubtypeSync(dir) {
   var f = new File('${dir.path}${Platform.pathSeparator}bytes_sync.txt');
-  f.writeAsBytesSync(UnmodifiableUint8ListView(Uint8List(10)));
-  Expect.equals(10, f.readAsBytesSync().length);
+  var input = Uint8List(5);
+  input[0] = 1;
+  input[1] = 2;
+  f.writeAsBytesSync(UnmodifiableUint8ListView(input));
+  var bytes = f.readAsBytesSync();
+  Expect.listEquals(input, bytes);
+}
+
+class MyUint8List extends ListBase<int> implements List<int> {
+  Uint8List _source;
+  MyUint8List(this._source);
+
+  // TypedData.
+  ByteBuffer get buffer => _source.buffer;
+  int get lengthInBytes => _source.lengthInBytes;
+  int get offsetInBytes => _source.offsetInBytes;
+
+  /// The methods that ListBase needs:
+  int operator [](int index) => _source[index];
+  operator []=(int index, int value) => _source[index] = value;
+  int get length => _source.length;
+  set length(_) => UnsupportedError("fixed length");
+  int get elementSizeInBytes => _source.elementSizeInBytes;
+
+  Uint8List sublist(int start, [int end]) => _source.sublist(start, end);
+}
+
+void testCustomizedSubtypeSync(Directory dir) {
+  var f = new File('${dir.path}${Platform.pathSeparator}bytes_sync.txt');
+  var input = Uint8List(5);
+  input[0] = 1;
+  input[1] = 2;
+  MyUint8List list = MyUint8List(input);
+  f.writeAsBytesSync(list);
+  var bytes = f.readAsBytesSync();
+  Expect.listEquals(input, bytes);
 }
 
 main() {
@@ -101,6 +136,7 @@
   testWriteAsStringSync(tempDir);
   testWriteWithLargeList(tempDir);
   testWriteAsSubtypeSync(tempDir);
+  testCustomizedSubtypeSync(tempDir);
   testWriteAsBytes(tempDir).then((_) {
     return testWriteAsString(tempDir);
   }).then((_) {
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index decbb70..5ce0701 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -12,13 +12,13 @@
 Testing bots after GOLO <> gcs failures
 Trigger bots after github outage
 Trigger bots on github pull
-Trigger bots 
+Trigger bots
 Purple is the new green.
 googlecode back up
-CIT outage - all slaves rebooted
+CIT outage - all bots rebooted
 Authentication failure flake - rerun all bots
-Trigger bots after master restart - switch dart2js bots to use downloaded sdk.
-Trigger bots after master restart.
+Trigger bots after restart - switch dart2js bots to use downloaded sdk.
+Trigger bots after restart.
 Trigger mirroring of github repository
 Trigger mirroring of github repository
 Trigger mirroring of github repository
diff --git a/tools/VERSION b/tools/VERSION
index 7654d58..0bc4f82 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 9
 PATCH 0
-PRERELEASE 15
+PRERELEASE 16
 PRERELEASE_PATCH 0
-ABI_VERSION 35
-OLDEST_SUPPORTED_ABI_VERSION 35
+ABI_VERSION 37
+OLDEST_SUPPORTED_ABI_VERSION 37
diff --git a/tools/archive_crash.py b/tools/archive_crash.py
deleted file mode 100755
index f266b2b..0000000
--- a/tools/archive_crash.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2014, 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.
-#
-
-# A script that copies a core file and binary to GCS
-# We expect the dumps to be located in /tmp/coredump_PID directory
-# After we copy out the core files we delete the dumps localy
-
-import os
-import shutil
-import sys
-import subprocess
-import tarfile
-import utils
-import uuid
-
-from glob import glob
-
-GCS_FOLDER = 'dart-temp-crash-archive'
-GSUTIL = '/b/build/scripts/slave/gsutil'
-
-
-def CreateTarball(input_dir, tarname):
-    print 'Creating tar file: %s' % tarname
-    tar = tarfile.open(tarname, mode='w:gz')
-    tar.add(input_dir)
-    tar.close()
-
-
-def CopyToGCS(filename):
-    gs_location = 'gs://%s/%s/' % (GCS_FOLDER, uuid.uuid4())
-    cmd = [GSUTIL, 'cp', filename, gs_location]
-    print 'Running command: %s' % cmd
-    subprocess.check_call(cmd)
-    archived_filename = '%s%s' % (gs_location, filename.split('/').pop())
-    print 'Dump now available in %s' % archived_filename
-
-
-def TEMPArchiveBuild():
-    if not 'PWD' in os.environ:
-        return
-    pwd = os.environ['PWD']
-    print pwd
-    if not 'vm-' in pwd:
-        return
-    if 'win' in pwd or 'release' in pwd:
-        return
-    files = glob('%s/out/Debug*/dart' % pwd)
-    files.extend(glob('%s/xcodebuild/Debug*/dart' % pwd))
-    print('Archiving: %s' % files)
-    for f in files:
-        CopyToGCS(f)
-
-
-def Main():
-    TEMPArchiveBuild()
-    if utils.GuessOS() != 'linux':
-        print 'Currently only archiving crash dumps on linux'
-        return 0
-    print 'Looking for crash dumps'
-    num_dumps = 0
-    for v in os.listdir('/tmp'):
-        if v.startswith('coredump'):
-            fullpath = '/tmp/%s' % v
-            if os.path.isdir(fullpath):
-                num_dumps += 1
-                tarname = '%s.tar.gz' % fullpath
-                CreateTarball(fullpath, tarname)
-                CopyToGCS(tarname)
-                os.unlink(tarname)
-                shutil.rmtree(fullpath)
-    print 'Found %s core dumps' % num_dumps
-
-
-if __name__ == '__main__':
-    sys.exit(Main())
diff --git a/tools/bots/bot_utils.py b/tools/bots/bot_utils.py
index 2c16826..29f840b 100755
--- a/tools/bots/bot_utils.py
+++ b/tools/bots/bot_utils.py
@@ -195,52 +195,34 @@
 
 
 class GSUtil(object):
-    GSUTIL_IS_SHELL_SCRIPT = False
     GSUTIL_PATH = None
     USE_DART_REPO_VERSION = False
 
     def _layzCalculateGSUtilPath(self):
         if not GSUtil.GSUTIL_PATH:
-            buildbot_gsutil = '/b/build/scripts/slave/gsutil'
-            if platform.system() == 'Windows':
-                buildbot_gsutil = 'e:\\\\b\\build\\scripts\\slave\\gsutil'
-            if os.path.isfile(
-                    buildbot_gsutil) and not GSUtil.USE_DART_REPO_VERSION:
-                GSUtil.GSUTIL_IS_SHELL_SCRIPT = True
-                GSUtil.GSUTIL_PATH = buildbot_gsutil
+            dart_gsutil = os.path.join(DART_DIR, 'third_party', 'gsutil',
+                                       'gsutil')
+            if os.path.isfile(dart_gsutil):
+                GSUtil.GSUTIL_PATH = dart_gsutil
+            elif GSUtil.USE_DART_REPO_VERSION:
+                raise Exception("Dart repository version of gsutil required, "
+                                "but not found.")
             else:
-                dart_gsutil = os.path.join(DART_DIR, 'third_party', 'gsutil',
-                                           'gsutil')
-                if os.path.isfile(dart_gsutil):
-                    GSUtil.GSUTIL_IS_SHELL_SCRIPT = False
-                    GSUtil.GSUTIL_PATH = dart_gsutil
-                elif GSUtil.USE_DART_REPO_VERSION:
-                    raise Exception(
-                        "Dart repository version of gsutil required, "
-                        "but not found.")
-                else:
-                    # We did not find gsutil, look in path
-                    possible_locations = list(os.environ['PATH'].split(
-                        os.pathsep))
-                    for directory in possible_locations:
-                        location = os.path.join(directory, 'gsutil')
-                        if os.path.isfile(location):
-                            GSUtil.GSUTIL_IS_SHELL_SCRIPT = False
-                            GSUtil.GSUTIL_PATH = location
-                            break
+                # We did not find gsutil, look in path
+                possible_locations = list(os.environ['PATH'].split(os.pathsep))
+                for directory in possible_locations:
+                    location = os.path.join(directory, 'gsutil')
+                    if os.path.isfile(location):
+                        GSUtil.GSUTIL_PATH = location
+                        break
             assert GSUtil.GSUTIL_PATH
 
     def execute(self, gsutil_args):
         self._layzCalculateGSUtilPath()
 
-        if GSUtil.GSUTIL_IS_SHELL_SCRIPT:
-            gsutil_command = [GSUtil.GSUTIL_PATH]
-        else:
-            gsutil_command = [sys.executable, GSUtil.GSUTIL_PATH]
+        gsutil_command = [sys.executable, GSUtil.GSUTIL_PATH]
 
-        return run(
-            gsutil_command + gsutil_args,
-            shell=(GSUtil.GSUTIL_IS_SHELL_SCRIPT and sys.platform == 'win32'))
+        return run(gsutil_command + gsutil_args)
 
     def upload(self,
                local_path,
diff --git a/tools/bots/dart2js_d8_hostchecked_tests.isolate b/tools/bots/dart2js_d8_hostchecked_tests.isolate
deleted file mode 100644
index a655196..0000000
--- a/tools/bots/dart2js_d8_hostchecked_tests.isolate
+++ /dev/null
@@ -1,47 +0,0 @@
-{
-  'variables': {
-    'files': [
-              'out/ReleaseIA32/dart',
-              'out/ReleaseIA32/dart2js_platform.dill',
-              'out/ReleaseIA32/dart2js_platform_strong.dill',
-              'out/ReleaseX64/dart',
-              'out/ReleaseX64/dart2js_platform.dill',
-              'out/ReleaseX64/dart2js_platform_strong.dill',
-              'xcodebuild/ReleaseIA32/dart',
-              'xcodebuild/ReleaseIA32/dart2js_platform.dill',
-              'xcodebuild/ReleaseIA32/dart2js_platform_strong.dill',
-              'xcodebuild/ReleaseX64/dart',
-              'xcodebuild/ReleaseX64/dart2js_platform.dill',
-              'xcodebuild/ReleaseX64/dart2js_platform_strong.dill',
-              'samples/',
-              'samples-dev/',
-              'tools/',
-              'third_party/pkg/',
-              'third_party/pkg_tested/',
-              'third_party/d8/',
-              'tests/angular/',
-              'tests/compiler/',
-              'tests/corelib_2/',
-              'tests/dart/',
-              'tests/kernel/',
-              'tests/language_2/',
-              'tests/lib_2/',
-              'tests/light_unittest.dart',
-              'tests/search/',
-              'tests/standalone_2/',
-              'pkg/async_helper/',
-              'pkg/compiler/',
-              'pkg/dart_internal/',
-              'pkg/expect/',
-              'pkg/front_end/',
-              'pkg/js/',
-              'pkg/js_ast/',
-              'pkg/kernel/',
-              'pkg/meta/',
-              'pkg/pkg.status',
-              'pkg/status_file/',
-              'runtime/tests/',
-              'sdk/',
-              '.packages']
-  }
-}
diff --git a/tools/bots/dart_tests.isolate b/tools/bots/dart_tests.isolate
deleted file mode 100644
index bb9e7f6..0000000
--- a/tools/bots/dart_tests.isolate
+++ /dev/null
@@ -1,42 +0,0 @@
-{
-  'variables': {
-    'files': ['out/ReleaseIA32/dart-sdk/',
-              'out/ReleaseX64/dart-sdk/',
-              'xcodebuild/ReleaseIA32/dart-sdk/',
-              'xcodebuild/ReleaseX64/dart-sdk/',
-              'samples/',
-              'samples-dev/',
-              'tools/',
-              'third_party/pkg/',
-              'third_party/pkg_tested/',
-              'third_party/d8/',
-              'third_party/firefox_jsshell/',
-              'tests/angular/',
-              'tests/compiler/',
-              'tests/corelib_2/',
-              'tests/dart/',
-              'tests/kernel/',
-              'tests/language_2/',
-              'tests/lib_2/',
-              'tests/light_unittest.dart',
-              'tests/search/',
-              'tests/standalone_2/',
-              'pkg/async_helper/',
-              'pkg/browser/',
-              'pkg/compiler/',
-              'pkg/dart_internal/',
-              'pkg/expect/',
-              'pkg/front_end/',
-              'pkg/js/',
-              'pkg/js_ast/',
-              'pkg/kernel/',
-              'pkg/meta/',
-              'pkg/pkg.status',
-              'pkg/status_file/',
-              'pkg/vm/',
-              'runtime/tests/',
-              'sdk/lib/_internal/js_runtime/',
-              'sdk/lib/_internal/sdk_library_metadata/',
-              '.packages']
-  }
-}
diff --git a/tools/bots/dart_tests_extended.isolate b/tools/bots/dart_tests_extended.isolate
deleted file mode 100644
index d4fc2c3..0000000
--- a/tools/bots/dart_tests_extended.isolate
+++ /dev/null
@@ -1,13 +0,0 @@
-{
-  'includes': ['dart_tests.isolate'],
-  'variables': {
-    'files': ['out/ReleaseIA32/gen/',
-              'out/ReleaseX64/gen/',
-              'out/ReleaseIA32/patched_sdk/',
-              'out/ReleaseX64/patched_sdk/',
-              'xcodebuild/ReleaseIA32/gen/',
-              'xcodebuild/ReleaseX64/gen/',
-              'xcodebuild/ReleaseIA32/patched_sdk/',
-              'xcodebuild/ReleaseX64/patched_sdk/']
-  }
-}
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index fe21204..bdc666c 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -42,9 +42,8 @@
       "tests/co19/co19-dartdevc.status",
       "tests/co19/co19-kernel.status",
       "tests/co19/co19-runtime.status",
-      "tests/compiler/",
       "tests/corelib_2/",
-      "tests/dart/",
+      "tests/dart2js_2/",
       "tests/kernel/",
       "tests/language_2/",
       "tests/lib_2/",
@@ -82,9 +81,8 @@
       "tests/co19/co19-dartdevc.status",
       "tests/co19/co19-kernel.status",
       "tests/co19/co19-runtime.status",
-      "tests/compiler/",
       "tests/corelib/",
-      "tests/dart/",
+      "tests/dart2js/",
       "tests/kernel/",
       "tests/language/",
       "tests/lib/",
@@ -129,9 +127,8 @@
       "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
-      "tests/compiler/",
       "tests/corelib_2/",
-      "tests/dart/",
+      "tests/dart2js_2/",
       "tests/kernel/",
       "tests/language_2/",
       "tests/lib_2/",
@@ -177,9 +174,8 @@
       "tests/co19_2/co19_2-dartdevc.status",
       "tests/co19_2/co19_2-kernel.status",
       "tests/co19_2/co19_2-runtime.status",
-      "tests/compiler/",
       "tests/corelib_2/",
-      "tests/dart/",
+      "tests/dart2js_2/",
       "tests/kernel/",
       "tests/language_2/",
       "tests/lib_2/",
@@ -218,9 +214,8 @@
       "tests/co19/co19-dartdevc.status",
       "tests/co19/co19-kernel.status",
       "tests/co19/co19-runtime.status",
-      "tests/compiler/",
       "tests/corelib/",
-      "tests/dart/",
+      "tests/dart2js/",
       "tests/kernel/",
       "tests/language/",
       "tests/lib/",
@@ -265,7 +260,8 @@
       "tests/compiler/",
       "tests/corelib/",
       "tests/corelib_2/",
-      "tests/dart/",
+      "tests/dart2js/",
+      "tests/dart2js_2/",
       "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
@@ -373,7 +369,8 @@
       "tests/compiler/",
       "tests/corelib/",
       "tests/corelib_2/",
-      "tests/dart/",
+      "tests/dart2js/",
+      "tests/dart2js_2/",
       "tests/kernel/",
       "tests/language/",
       "tests/language_2/",
@@ -1122,6 +1119,24 @@
           ]
         },
         {
+          "name": "weak co19 tests",
+          "arguments": [
+            "-ncfe-weak-${system}",
+            "co19"
+          ],
+          "fileset": "front-end",
+          "shards": 1
+        },
+        {
+          "name": "strong co19 tests",
+          "arguments": [
+            "-ncfe-strong-${system}",
+            "co19"
+          ],
+          "fileset": "front-end",
+          "shards": 1
+        },
+        {
           "name": "weak sdk tests",
           "arguments": [
             "-ncfe-weak-${system}",
@@ -1132,13 +1147,6 @@
           ]
         },
         {
-          "name": "weak co19 tests",
-          "arguments": [
-            "-ncfe-weak-${system}",
-            "co19"
-          ]
-        },
-        {
           "name": "strong sdk tests",
           "arguments": [
             "-ncfe-strong-${system}",
@@ -1147,13 +1155,6 @@
             "language",
             "lib"
           ]
-        },
-        {
-          "name": "strong co19 tests",
-          "arguments": [
-            "-ncfe-strong-${system}",
-            "co19"
-          ]
         }
       ]
     },
@@ -1775,7 +1776,9 @@
             "co19",
             "standalone/io",
             "vm"
-          ]
+          ],
+          "fileset": "vm-kernel",
+          "shards": 2
         },
         {
           "name": "vm nnbd tests in strong mode",
@@ -1788,7 +1791,9 @@
             "co19",
             "standalone/io",
             "vm"
-          ]
+          ],
+          "fileset": "vm-kernel",
+          "shards": 2
         }
       ]
     },
@@ -2641,7 +2646,7 @@
             "--dart2js-batch",
             "language",
             "corelib",
-            "dart2js_2",
+            "dart2js",
             "kernel"
           ],
           "shards": 6,
@@ -2674,7 +2679,7 @@
             "--dart2js-batch",
             "language",
             "corelib",
-            "dart2js_2",
+            "dart2js",
             "kernel"
           ],
           "shards": 6,
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 628f1b2..f05959f 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -182,11 +182,11 @@
     out/ReleaseIA32/run_vm_tests InitialRSS
     out/ReleaseIA32/run_vm_tests GenKernelKernelLoadKernel
     out/ReleaseIA32/run_vm_tests KernelServiceCompileAll
-    out/ReleaseIA32/dart --profile-period=10000 --packages=.packages benchmarks/Example/dart/Example.dart
-    out/ReleaseIA32/dart benchmarks/FfiBoringssl/dart/FfiBoringssl.dart
-    out/ReleaseIA32/dart benchmarks/FfiCall/dart/FfiCall.dart
-    out/ReleaseIA32/dart benchmarks/FfiMemory/dart/FfiMemory.dart
-    out/ReleaseIA32/dart benchmarks/FfiStruct/dart/FfiStruct.dart
+    out/ReleaseIA32/dart --profile-period=10000 --packages=.packages benchmarks/Example/dart2/Example.dart
+    out/ReleaseIA32/dart benchmarks/FfiBoringssl/dart2/FfiBoringssl.dart
+    out/ReleaseIA32/dart benchmarks/FfiCall/dart2/FfiCall.dart
+    out/ReleaseIA32/dart benchmarks/FfiMemory/dart2/FfiMemory.dart
+    out/ReleaseIA32/dart benchmarks/FfiStruct/dart2/FfiStruct.dart
     cd ..
     rm -rf tmp
   elif [ "$command" = linux-x64-build ]; then
@@ -341,7 +341,7 @@
     out/ReleaseX64/run_vm_tests InitialRSS
     out/ReleaseX64/run_vm_tests GenKernelKernelLoadKernel
     out/ReleaseX64/run_vm_tests KernelServiceCompileAll
-    out/ReleaseX64/dart --profile-period=10000 --packages=.packages benchmarks/Example/dart/Example.dart
+    out/ReleaseX64/dart --profile-period=10000 --packages=.packages benchmarks/Example/dart2/Example.dart
     cd ..
     rm -rf tmp
   else
diff --git a/tools/dom/docs/docs.json b/tools/dom/docs/docs.json
index c827d9a..f24f9ed 100644
--- a/tools/dom/docs/docs.json
+++ b/tools/dom/docs/docs.json
@@ -2837,6 +2837,9 @@
         "onsignalingstatechange": [
           "/// Stream of `signalingstatechange` events handled by this [RtcPeerConnection]."
         ],
+        "ontrack": [
+          "/// Stream of `track` events handled by this [RtcPeerConnection]."
+        ],
         "removestreamEvent": [
           "/**",
           "   * Static factory designed to expose `removestream` events to event",
@@ -2852,6 +2855,14 @@
           "   *",
           "   * See [EventStreamProvider] for usage information.",
           "   */"
+        ],
+        "trackEvent": [
+          "/**",
+          "   * Static factory designed to expose `track` events to event",
+          "   * handlers that are not necessarily instances of [RtcPeerConnection].",
+          "   *",
+          "   * See [EventStreamProvider] for usage information.",
+          "   */"
         ]
       }
     },
diff --git a/tools/dom/scripts/dartmetadata.py b/tools/dom/scripts/dartmetadata.py
index f7a6bcb..71f7602 100644
--- a/tools/dom/scripts/dartmetadata.py
+++ b/tools/dom/scripts/dartmetadata.py
@@ -30,8 +30,7 @@
     'dartmetadata._dart2js_annotations',
     {
         'AnimationEffectTiming.duration': [
-            "@Creates('Null')",
-            "@Returns('num|String')",
+            "@Returns('num|String|Null')",
         ],
         'ArrayBufferView': [
             "@Creates('TypedData')",
diff --git a/tools/dom/scripts/htmleventgenerator.py b/tools/dom/scripts/htmleventgenerator.py
index f9c14c4..fcad117 100644
--- a/tools/dom/scripts/htmleventgenerator.py
+++ b/tools/dom/scripts/htmleventgenerator.py
@@ -210,6 +210,7 @@
         'RTCPeerConnection.removestream': ('removeStream', 'MediaStreamEvent'),
         'RTCPeerConnection.signalingstatechange':
         ('signalingStateChange', 'Event'),
+        'RTCPeerConnection.track': ('track', 'RtcTrackEvent'),
         'ScriptProcessorNode.audioprocess':
         ('audioProcess', 'AudioProcessingEvent'),
         'ServiceWorkerGlobalScope.activate': ('activate', 'Event'),
diff --git a/tools/dom/scripts/multiemitter.py b/tools/dom/scripts/multiemitter.py
index 8318edb..64a8b2d 100644
--- a/tools/dom/scripts/multiemitter.py
+++ b/tools/dom/scripts/multiemitter.py
@@ -101,21 +101,5 @@
                 # Sleep for 50 ms and try again
                 time.sleep(0.05)
             else:
-                # FIXME(kustermann): Remove this later on.
-                # We try to get more debugging information to figure out why we
-                # sometimes get a "Permission denied" error when opening the file for
-                # writing. (hypothesis: Another process has already opened the file.)
                 _logger.info('Got exception (%s) ' % error)
-
-                if sys.platform == 'win32':
-                    handle_file = r'E:\handle.exe'
-                    if os.path.exists(handle_file):
-                        _logger.info(
-                            'Running handle.exe for debugging purposes')
-                        subprocess.call(
-                            [handle_file, '-a', r'E:\b\build\slave'])
-                    else:
-                        _logger.info(
-                            "Couldn't find %s. Not printing open handles." %
-                            handle_file)
                 raise error
diff --git a/tools/dom/scripts/systemhtml.py b/tools/dom/scripts/systemhtml.py
index 4807cf8..70248c6 100644
--- a/tools/dom/scripts/systemhtml.py
+++ b/tools/dom/scripts/systemhtml.py
@@ -1394,6 +1394,14 @@
             self._AddAttributeUsingProperties(attribute, html_name, read_only)
             return
 
+        output_type = self.SecureOutputType(attribute.type.id,
+                                            can_narrow_type=read_only,
+                                            nullable=attribute.type.nullable)
+
+        rename = self._RenamingAnnotation(attribute.id, html_name)
+        metadata = self._Metadata(attribute.type.id, attribute.id, output_type,
+            attribute.type.nullable)
+
         # If the attribute is shadowing, we can't generate a shadowing
         # getter or setter (Issue 1633).
         # TODO(sra): _FindShadowedAttribute does not take into account the html
@@ -1426,7 +1434,8 @@
                                 'TreatNullAs' in attribute.ext_attrs))
                     return
             self._members_emitter.Emit('\n  // Shadowing definition.')
-            self._AddAttributeUsingProperties(attribute, html_name, read_only)
+            self._AddAttributeUsingProperties(attribute, html_name, read_only,
+                rename, metadata)
             return
 
         # If the attribute is shadowed incompatibly in a subclass then we also
@@ -1438,23 +1447,18 @@
         if (self._interface.id == 'DOMMatrixReadOnly' or
                 self._interface.id == 'DOMPointReadOnly' or
                 self._interface.id == 'DOMRectReadOnly'):
-            self._AddAttributeUsingProperties(attribute, html_name, read_only)
+            self._AddAttributeUsingProperties(attribute, html_name, read_only,
+                rename, metadata)
             return
 
         # If the type has a conversion we need a getter or setter to contain the
         # conversion code.
         if (self._OutputConversion(attribute.type.id, attribute.id) or
                 self._InputConversion(attribute.type.id, attribute.id)):
-            self._AddAttributeUsingProperties(attribute, html_name, read_only)
+            self._AddAttributeUsingProperties(attribute, html_name, read_only,
+                rename, metadata)
             return
 
-        rename = self._RenamingAnnotation(attribute.id, html_name)
-        output_type = self.SecureOutputType(attribute.type.id,
-                                            can_narrow_type=read_only,
-                                            nullable=attribute.type.nullable)
-        metadata = self._Metadata(attribute.type.id, attribute.id, output_type,
-            attribute.type.nullable)
-
         input_type = self._NarrowInputType(attribute.type.id)
         if self._nnbd and attribute.type.nullable:
             input_type += '?'
@@ -1536,7 +1540,6 @@
             return self._AddConvertingGetter(attr, html_name, conversion)
         return_type = self.SecureOutputType(attr.type.id,
             nullable=attr.type.nullable)
-        native_type = self._NarrowToImplementationType(attr.type.id)
         self._members_emitter.Emit(
             '\n  $RENAME'
             '\n  $METADATA'
diff --git a/tools/run_abi_tests.py b/tools/run_abi_tests.py
index cecf86a..1810df8 100644
--- a/tools/run_abi_tests.py
+++ b/tools/run_abi_tests.py
@@ -166,11 +166,18 @@
 def makeLog(diffs, results, logRecords, configuration_name):
     result = pickOne(results)
     logs = ["%s: %s" % (str(v), l['log']) for v, l in logRecords.items()]
+    log = ('This test fails if there is a difference in the test results\n'
+           'between ABI versions. The expected result is the result on the\n'
+           'current ABI: %s\n'
+           'These ABI versions reported a different result: %s\n\n'
+           'These are the logs of the test runs on different ABI versions.\n'
+           'There are no logs for versions where the test passed.\n\n%s' %
+           (result['result'], repr(diffs), '\n\n\n'.join(logs)))
     return {
         'name': result['name'],
         'configuration': configuration_name,
         'result': result['result'],
-        'log': '\n\n\n'.join([repr(diffs)] + logs),
+        'log': log,
     }
 
 
diff --git a/tools/utils.py b/tools/utils.py
index 5bb768f..9097006 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -292,13 +292,6 @@
 VERSION_FILE = os.path.join(DART_DIR, 'tools', 'VERSION')
 
 
-def GetBuildbotGSUtilPath():
-    gsutil = '/b/build/scripts/slave/gsutil'
-    if platform.system() == 'Windows':
-        gsutil = 'e:\\\\b\\build\\scripts\\slave\\gsutil'
-    return gsutil
-
-
 def GetBuildMode(mode):
     return BUILD_MODES[mode]