Version 2.2.1-dev.4.0

Merge commit '523e3789e05ea07cdd21feadb04dc8ea0174204e' into dev
diff --git a/.packages b/.packages
index cf69a8b..08c0d29 100644
--- a/.packages
+++ b/.packages
@@ -97,7 +97,6 @@
 typed_data:third_party/pkg/typed_data/lib
 unittest:third_party/pkg/unittest/lib
 usage:third_party/pkg/usage/lib
-utf:third_party/pkg/utf/lib
 vm:pkg/vm/lib
 watcher:third_party/pkg/watcher/lib
 web_components:third_party/pkg/web_components/lib
diff --git a/CHANGELOG.md b/CHANGELOG.md
index f3ef64c7..8aa7a1a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,21 @@
+## 2.2.1-dev.4.0
+
+### Dart VM
+
+* The VM service now requires an authentication code by default. This behavior
+  can be disabled by providing the `--disable-service-auth-codes` flag.
+
+### Tool Changes
+
+#### Linter
+
+The Linter was updated to `0.1.85` which includes the following changes:
+
+* (**BREAKING**) renamed `spread_collections` to `prefer_spread_collections`
+* new lint: `prefer_for_elements_to_map_fromIterable`
+* new lint: `prefer_if_elements_to_conditional_expressions`
+* new lint: `diagnostic_describe_all_properties`
+
 ## 2.2.1-dev.3.1
 
 * Cherry-pick 245576a096a2da54ef21d664d37d1f50f6f8dbb7 to dev
@@ -13,6 +31,10 @@
 
 ## 2.2.1-dev.3.0
 
+### Dart VM
+
+* Support for deprecated flags '-c' and '--checked' has been removed
+
 ### Core library changes
 
 #### `dart:isolate`
@@ -33,13 +55,10 @@
 The Linter was updated to `0.1.83` which includes the following changes:
 
 * updated `file_names` to skip prefixed-extension Dart files (e.g., `.css.dart`, `.g.dart`)
-* updated SDK constraint to `2.2.0`
 * miscellaneous rule documentation fixes
-* (internal) updated sources to use Set literals
 * fixed NPE in `avoid_shadowing_type_parameters`
 * added linter version numbering for use in analyzer summaries
 * fixed type utilities to handle inheritance cycles
-* (internal) changes to adopt new `package:analyzer` APIs
 * fixed `unnecessary_parenthesis` false positives
 
 ## 2.2.1-dev.2.0
diff --git a/DEPS b/DEPS
index 5c76e5a..9d0806f 100644
--- a/DEPS
+++ b/DEPS
@@ -36,7 +36,7 @@
   "chromium_git": "https://chromium.googlesource.com",
   "fuchsia_git": "https://fuchsia.googlesource.com",
 
-  "co19_2_rev": "c3b33ee90c5ee7f88fdb0ead08fdbb40c54954d2",
+  "co19_2_rev": "7e743ef29b4c06f1a2b8b9dc70ead60b31aab526",
 
   # As Flutter does, we use Fuchsia's GN and Clang toolchain. These revision
   # should be kept up to date with the revisions pulled by the Flutter engine.
@@ -84,7 +84,7 @@
   "dartdoc_tag" : "v0.28.2",
   "fixnum_tag": "0.10.9",
   "glob_tag": "1.1.7",
-  "html_tag" : "0.13.4+1",
+  "html_tag" : "0.14.0",
   "http_io_rev": "57da05a66f5bf7df3dd7aebe7b7efe0dfc477baa",
   "http_multi_server_tag" : "2.0.5",
   "http_parser_tag" : "3.1.3",
@@ -95,7 +95,7 @@
   "intl_tag": "0.15.7",
   "jinja2_rev": "2222b31554f03e62600cd7e383376a7c187967a1",
   "json_rpc_2_tag": "2.0.9",
-  "linter_tag": "0.1.83",
+  "linter_tag": "0.1.85",
   "logging_tag": "0.11.3+2",
   "markupsafe_rev": "8f45f5cfa0009d2a70589bcda0349b8cb2b72783",
   "markdown_tag": "2.0.2",
@@ -135,7 +135,6 @@
   "typed_data_tag": "1.1.6",
   "unittest_rev": "2b8375bc98bb9dc81c539c91aaea6adce12e1072",
   "usage_tag": "3.4.0",
-  "utf_tag": "0.9.0+5",
   "watcher_rev": "0.9.7+12",
   "web_components_rev": "8f57dac273412a7172c8ade6f361b407e2e4ed02",
   "web_socket_channel_tag": "1.0.9",
@@ -156,7 +155,7 @@
   Var("dart_root") + "/tools/sdks": {
       "packages": [{
           "package": "dart/dart-sdk/${{platform}}",
-          "version": "version:2.2.1-dev.1.1",
+          "version": "version:2.2.1-dev.3.1",
       }],
       "dep_type": "cipd",
   },
@@ -362,8 +361,6 @@
       "@" + Var("unittest_rev"),
   Var("dart_root") + "/third_party/pkg/usage":
       Var("dart_git") + "usage.git" + "@" + Var("usage_tag"),
-  Var("dart_root") + "/third_party/pkg/utf":
-      Var("dart_git") + "utf.git" + "@" + Var("utf_tag"),
   Var("dart_root") + "/third_party/pkg/watcher":
       Var("dart_git") + "watcher.git" + "@" + Var("watcher_rev"),
   Var("dart_root") + "/third_party/pkg/web_components":
diff --git a/WATCHLISTS b/WATCHLISTS
index 598f0ab..415a9bd 100644
--- a/WATCHLISTS
+++ b/WATCHLISTS
@@ -80,7 +80,7 @@
                 'alexmarkov@google.com' ],
     'messages_review': [ 'dart-uxr+reviews@google.com' ],
     'mirrors' : [ 'rmacnak@google.com' ],
-    'observatory': [ 'rmacnak@google.com' ],
+    'observatory': [ 'bkonyi@google.com', 'rmacnak@google.com' ],
     'package_vm': [ 'alexmarkov@google.com' ],
     'runtime': [ 'vm-dev@dartlang.org' ],
     'vm_compiler': [ 'dart-vm-compiler-team+reviews@google.com' ],
diff --git a/pkg/analysis_server/doc/api.html b/pkg/analysis_server/doc/api.html
index f384766..204d162 100644
--- a/pkg/analysis_server/doc/api.html
+++ b/pkg/analysis_server/doc/api.html
@@ -109,7 +109,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  1.25.0
+  1.26.0
 </h1>
 <p>
   This document contains a specification of the API provided by the
diff --git a/pkg/analysis_server/lib/protocol/protocol_constants.dart b/pkg/analysis_server/lib/protocol/protocol_constants.dart
index 0125a30..35174b9 100644
--- a/pkg/analysis_server/lib/protocol/protocol_constants.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.25.0';
+const String PROTOCOL_VERSION = '1.26.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -201,6 +201,7 @@
 const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file';
+const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE =
     'edit.isPostfixCompletionApplicable';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
diff --git a/pkg/analysis_server/lib/protocol/protocol_generated.dart b/pkg/analysis_server/lib/protocol/protocol_generated.dart
index ad7e249..6e7da59 100644
--- a/pkg/analysis_server/lib/protocol/protocol_generated.dart
+++ b/pkg/analysis_server/lib/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -10312,6 +10313,8 @@
 
   List<ImportedElements> _elements;
 
+  int _offset;
+
   /**
    * The file in which the specified elements are to be made accessible.
    */
@@ -10338,9 +10341,29 @@
     this._elements = value;
   }
 
-  EditImportElementsParams(String file, List<ImportedElements> elements) {
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  void set offset(int value) {
+    this._offset = value;
+  }
+
+  EditImportElementsParams(String file, List<ImportedElements> elements,
+      {int offset}) {
     this.file = file;
     this.elements = elements;
+    this.offset = offset;
   }
 
   factory EditImportElementsParams.fromJson(
@@ -10365,7 +10388,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "elements");
       }
-      return new EditImportElementsParams(file, elements);
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      }
+      return new EditImportElementsParams(file, elements, offset: offset);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json);
     }
@@ -10382,6 +10409,9 @@
     result["file"] = file;
     result["elements"] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    if (offset != null) {
+      result["offset"] = offset;
+    }
     return result;
   }
 
@@ -10398,7 +10428,8 @@
     if (other is EditImportElementsParams) {
       return file == other.file &&
           listEqual(elements, other.elements,
-              (ImportedElements a, ImportedElements b) => a == b);
+              (ImportedElements a, ImportedElements b) => a == b) &&
+          offset == other.offset;
     }
     return false;
   }
@@ -10408,6 +10439,7 @@
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -21541,7 +21573,7 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  *
@@ -21555,12 +21587,12 @@
   List<String> _validElementKinds;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   String get lexeme => _lexeme;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   void set lexeme(String value) {
     assert(value != null);
@@ -21568,31 +21600,38 @@
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   String get type => _type;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   void set type(String value) {
-    assert(value != null);
     this._type = value;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   List<String> get validElementKinds => _validElementKinds;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   void set validElementKinds(List<String> value) {
     this._validElementKinds = value;
   }
 
-  TokenDetails(String lexeme, String type, {List<String> validElementKinds}) {
+  TokenDetails(String lexeme, {String type, List<String> validElementKinds}) {
     this.lexeme = lexeme;
     this.type = type;
     this.validElementKinds = validElementKinds;
@@ -21613,8 +21652,6 @@
       String type;
       if (json.containsKey("type")) {
         type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, "type");
       }
       List<String> validElementKinds;
       if (json.containsKey("validElementKinds")) {
@@ -21623,8 +21660,8 @@
             json["validElementKinds"],
             jsonDecoder.decodeString);
       }
-      return new TokenDetails(lexeme, type,
-          validElementKinds: validElementKinds);
+      return new TokenDetails(lexeme,
+          type: type, validElementKinds: validElementKinds);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json);
     }
@@ -21634,7 +21671,9 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["lexeme"] = lexeme;
-    result["type"] = type;
+    if (type != null) {
+      result["type"] = type;
+    }
     if (validElementKinds != null) {
       result["validElementKinds"] = validElementKinds;
     }
diff --git a/pkg/analysis_server/lib/src/analysis_server_abstract.dart b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
index 50834b3..3ed2774 100644
--- a/pkg/analysis_server/lib/src/analysis_server_abstract.dart
+++ b/pkg/analysis_server/lib/src/analysis_server_abstract.dart
@@ -70,7 +70,8 @@
     '**/*.${AnalysisEngine.SUFFIX_HTM}',
     '**/${AnalysisEngine.ANALYSIS_OPTIONS_FILE}',
     '**/${AnalysisEngine.ANALYSIS_OPTIONS_YAML_FILE}',
-    '**/${AnalysisEngine.PUBSPEC_YAML_FILE}'
+    '**/${AnalysisEngine.PUBSPEC_YAML_FILE}',
+    '**/${AnalysisEngine.ANDROID_MANIFEST_FILE}'
   ];
 
   /// The [ResourceProvider] using which paths are converted into [Resource]s.
diff --git a/pkg/analysis_server/lib/src/context_manager.dart b/pkg/analysis_server/lib/src/context_manager.dart
index f9ce8ac..b8adeca 100644
--- a/pkg/analysis_server/lib/src/context_manager.dart
+++ b/pkg/analysis_server/lib/src/context_manager.dart
@@ -24,6 +24,7 @@
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:analyzer/src/plugin/resolver_provider.dart';
+import 'package:analyzer/src/manifest/manifest_validator.dart';
 import 'package:analyzer/src/pubspec/pubspec_validator.dart';
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/source/path_filter.dart';
@@ -394,6 +395,11 @@
   static const String LIB_DIR_NAME = 'lib';
 
   /**
+   * File name of Android manifest files.
+   */
+  static const String MANIFEST_NAME = 'AndroidManifest.xml';
+
+  /**
    * File name of pubspec files.
    */
   static const String PUBSPEC_NAME = 'pubspec.yaml';
@@ -891,6 +897,32 @@
         convertedErrors ?? <protocol.AnalysisError>[]);
   }
 
+  /**
+   * Use the given analysis [driver] to analyze the content of the 
+   * AndroidManifest file at the given [path].
+   */
+  void _analyzeManifestFile(AnalysisDriver driver, String path) {
+    List<protocol.AnalysisError> convertedErrors;
+    try {
+      String content = _readFile(path);
+      ManifestValidator validator =
+          new ManifestValidator(resourceProvider.getFile(path).createSource());
+      LineInfo lineInfo = _computeLineInfo(content);
+      List<AnalysisError> errors = validator.validate(
+          content, driver.analysisOptions.chromeOsManifestChecks);
+      AnalyzerConverter converter = new AnalyzerConverter();
+      convertedErrors = converter.convertAnalysisErrors(errors,
+          lineInfo: lineInfo, options: driver.analysisOptions);
+    } catch (exception) {
+      // If the file cannot be analyzed, fall through to clear any previous
+      // errors.
+    }
+    callbacks.notificationManager.recordAnalysisErrors(
+        NotificationManager.serverId,
+        path,
+        convertedErrors ?? <protocol.AnalysisError>[]);
+  }
+
   void _checkForAnalysisOptionsUpdate(String path, ContextInfo info) {
     if (AnalysisEngine.isAnalysisOptionsFileName(path, pathContext)) {
       AnalysisDriver driver = info.analysisDriver;
@@ -936,6 +968,19 @@
     }
   }
 
+  void _checkForManifestUpdate(String path, ContextInfo info) {
+    if (_isManifest(path)) {
+      AnalysisDriver driver = info.analysisDriver;
+      if (driver == null) {
+        // I suspect that this happens as a result of a race condition: server
+        // has determined that the file (at [path]) is in a context, but hasn't
+        // yet created a driver for that context.
+        return;
+      }
+      _analyzeManifestFile(driver, path);
+    }
+  }
+
   /**
    * Compute the set of files that are being flushed, this is defined as
    * the set of sources in the removed context (context.sources), that are
@@ -1094,6 +1139,10 @@
     if (pubspecFile.exists) {
       _analyzePubspecFile(info.analysisDriver, pubspecFile.path);
     }
+    File manifestFile = folder.getChildAssumingFile(MANIFEST_NAME);
+    if (manifestFile.exists) {
+      _analyzeManifestFile(info.analysisDriver, manifestFile.path);
+    }
     return info;
   }
 
@@ -1409,6 +1458,7 @@
     _checkForPackagespecUpdate(path, info);
     _checkForAnalysisOptionsUpdate(path, info);
     _checkForPubspecUpdate(path, info);
+    _checkForManifestUpdate(path, info);
   }
 
   /**
@@ -1465,6 +1515,8 @@
 
   bool _isPubspec(String path) => pathContext.basename(path) == PUBSPEC_NAME;
 
+  bool _isManifest(String path) => pathContext.basename(path) == MANIFEST_NAME;
+
   /**
    * Merges [info] context into its parent.
    */
diff --git a/pkg/analysis_server/lib/src/domain_completion.dart b/pkg/analysis_server/lib/src/domain_completion.dart
index e5d221d..3951541 100644
--- a/pkg/analysis_server/lib/src/domain_completion.dart
+++ b/pkg/analysis_server/lib/src/domain_completion.dart
@@ -39,7 +39,7 @@
   /**
    * The completion services that the client is currently subscribed.
    */
-  final Set<CompletionService> _subscriptions = Set<CompletionService>();
+  final Set<CompletionService> subscriptions = Set<CompletionService>();
 
   /**
    * The next completion response id.
@@ -365,7 +365,7 @@
     // create the kinds set, so signal the completion manager about opt-in.
     Set<ElementKind> includedElementKinds;
     List<IncludedSuggestionRelevanceTag> includedSuggestionRelevanceTags;
-    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+    if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
       includedElementKinds = Set<ElementKind>();
       includedSuggestionRelevanceTags = <IncludedSuggestionRelevanceTag>[];
     }
@@ -461,10 +461,10 @@
   Response setSubscriptions(Request request) {
     var params = CompletionSetSubscriptionsParams.fromRequest(request);
 
-    _subscriptions.clear();
-    _subscriptions.addAll(params.subscriptions);
+    subscriptions.clear();
+    subscriptions.addAll(params.subscriptions);
 
-    if (_subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
+    if (subscriptions.contains(CompletionService.AVAILABLE_SUGGESTION_SETS)) {
       server.createDeclarationsTracker((change) {
         server.sendNotification(
           createCompletionAvailableSuggestionsNotification(change),
diff --git a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
index c3085a7..bbe879f 100644
--- a/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
+++ b/pkg/analysis_server/lib/src/domains/completion/available_suggestions.dart
@@ -72,13 +72,7 @@
 ) {
   return protocol.CompletionAvailableSuggestionsParams(
     changedLibraries: change.changed.map((library) {
-      return protocol.AvailableSuggestionSet(
-        library.id,
-        library.uriStr,
-        library.declarations.map((declaration) {
-          return _protocolAvailableSuggestion(declaration);
-        }).toList(),
-      );
+      return _protocolAvailableSuggestionSet(library);
     }).toList(),
     removedLibraries: change.removed,
   ).toNotification();
@@ -103,13 +97,13 @@
     Declaration declaration) {
   var label = declaration.name;
   if (declaration.kind == DeclarationKind.CONSTRUCTOR) {
-    label = declaration.name2;
+    label = declaration.parent.name;
     if (declaration.name.isNotEmpty) {
       label += '.${declaration.name}';
     }
   }
   if (declaration.kind == DeclarationKind.ENUM_CONSTANT) {
-    label = '${declaration.name2}.${declaration.name}';
+    label = '${declaration.parent.name}.${declaration.name}';
   }
 
   List<String> relevanceTags;
@@ -134,6 +128,23 @@
   );
 }
 
+protocol.AvailableSuggestionSet _protocolAvailableSuggestionSet(
+    Library library) {
+  var items = <protocol.AvailableSuggestion>[];
+
+  void addItem(Declaration declaration) {
+    var suggestion = _protocolAvailableSuggestion(declaration);
+    items.add(suggestion);
+    declaration.children.forEach(addItem);
+  }
+
+  for (var declaration in library.declarations) {
+    addItem(declaration);
+  }
+
+  return protocol.AvailableSuggestionSet(library.id, library.uriStr, items);
+}
+
 protocol.Element _protocolElement(Declaration declaration) {
   return protocol.Element(
     _protocolElementKind(declaration.kind),
diff --git a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
index 931932e..0525b77 100644
--- a/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_dartfix.dart
@@ -21,6 +21,7 @@
   final AnalysisServer server;
 
   final Request request;
+  final pkgFolders = <Folder>[];
   final fixFolders = <Folder>[];
   final fixFiles = <File>[];
 
@@ -78,6 +79,11 @@
               contextManager.isInAnalysisRoot(filePath))) {
         return new Response.fileNotAnalyzed(request, filePath);
       }
+      var pkgFolder =
+          findPkgFolder(contextManager.getContextFolderFor(filePath));
+      if (pkgFolder != null && !pkgFolders.contains(pkgFolder)) {
+        pkgFolders.add(pkgFolder);
+      }
       if (res is Folder) {
         fixFolders.add(res);
       } else {
@@ -85,6 +91,11 @@
       }
     }
 
+    // Process each package
+    for (Folder pkgFolder in pkgFolders) {
+      await processPackage(pkgFolder);
+    }
+
     // Process each source file.
     bool hasErrors = false;
     String changedPath;
@@ -135,6 +146,17 @@
     ).toResponse(request.id);
   }
 
+  Folder findPkgFolder(Folder folder) {
+    while (folder != null) {
+      if (folder.getChild('analysis_options.yaml').exists ||
+          folder.getChild('pubspec.yaml').exists) {
+        return folder;
+      }
+      folder = folder.parent;
+    }
+    return null;
+  }
+
   /// Return `true` if the path in within the set of `included` files
   /// or is within an `included` directory.
   bool isIncluded(String filePath) {
diff --git a/pkg/analysis_server/lib/src/edit/edit_domain.dart b/pkg/analysis_server/lib/src/edit/edit_domain.dart
index 6b7a5a9..12a1d18 100644
--- a/pkg/analysis_server/lib/src/edit/edit_domain.dart
+++ b/pkg/analysis_server/lib/src/edit/edit_domain.dart
@@ -22,6 +22,7 @@
 import 'package:analysis_server/src/services/correction/assist_internal.dart';
 import 'package:analysis_server/src/services/correction/change_workspace.dart';
 import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
 import 'package:analysis_server/src/services/correction/fix_internal.dart';
 import 'package:analysis_server/src/services/correction/organize_directives.dart';
 import 'package:analysis_server/src/services/correction/sort_members.dart';
@@ -33,16 +34,23 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+// ignore: deprecated_member_use
+import 'package:analyzer/source/analysis_options_provider.dart';
+import 'package:analyzer/source/line_info.dart';
 import 'package:analyzer/src/dart/ast/utilities.dart';
 import 'package:analyzer/src/dart/scanner/scanner.dart' as engine;
 import 'package:analyzer/src/error/codes.dart' as engine;
 import 'package:analyzer/src/generated/engine.dart' as engine;
+import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart' as engine;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_plugin/protocol/protocol.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_constants.dart' as plugin;
 import 'package:analyzer_plugin/protocol/protocol_generated.dart' as plugin;
 import 'package:dart_style/dart_style.dart';
+import 'package:yaml/yaml.dart';
 
 int test_resetCount = 0;
 
@@ -231,9 +239,7 @@
       new EditGetDartfixInfoResult(allFixes.map((i) => i.asDartFix()).toList())
           .toResponse(request.id);
 
-  Future getFixes(Request request) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+  Future<void> getFixes(Request request) async {
     EditGetFixesParams params = new EditGetFixesParams.fromRequest(request);
     String file = params.file;
     int offset = params.offset;
@@ -241,7 +247,6 @@
     if (server.sendResponseErrorIfInvalidFilePath(request, file)) {
       return;
     }
-
     //
     // Allow plugins to start computing fixes.
     //
@@ -569,12 +574,49 @@
   }
 
   /**
-   * Compute and return the fixes associated with server-generated errors.
+   * Compute and return the fixes associated with server-generated errors in
+   * analysis options files.
    */
-  Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
+  Future<List<AnalysisErrorFixes>> _computeAnalysisOptionsFixes(
       String file, int offset) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+    List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
+    File optionsFile = server.resourceProvider.getFile(file);
+    String content = _safelyRead(optionsFile);
+    if (content == null) {
+      return errorFixesList;
+    }
+    LineInfo lineInfo = new LineInfo.fromContent(content);
+    SourceFactory sourceFactory = server.getAnalysisDriver(file).sourceFactory;
+    List<engine.AnalysisError> errors = analyzeAnalysisOptions(
+        optionsFile.createSource(), content, sourceFactory);
+    YamlMap options = _getOptions(sourceFactory, content);
+    if (options == null) {
+      return errorFixesList;
+    }
+    for (engine.AnalysisError error in errors) {
+      AnalysisOptionsFixGenerator generator =
+          new AnalysisOptionsFixGenerator(error, content, options);
+      List<Fix> fixes = await generator.computeFixes();
+      if (fixes.isNotEmpty) {
+        fixes.sort(Fix.SORT_BY_RELEVANCE);
+        AnalysisError serverError =
+            newAnalysisError_fromEngine(lineInfo, error);
+        AnalysisErrorFixes errorFixes = new AnalysisErrorFixes(serverError);
+        errorFixesList.add(errorFixes);
+        fixes.forEach((fix) {
+          errorFixes.fixes.add(fix.change);
+        });
+      }
+    }
+    return errorFixesList;
+  }
+
+  /**
+   * Compute and return the fixes associated with server-generated errors in
+   * Dart files.
+   */
+  Future<List<AnalysisErrorFixes>> _computeDartFixes(
+      String file, int offset) async {
     List<AnalysisErrorFixes> errorFixesList = <AnalysisErrorFixes>[];
     var result = await server.getResolvedUnit(file);
     if (result != null) {
@@ -603,6 +645,20 @@
     return errorFixesList;
   }
 
+  /**
+   * Compute and return the fixes associated with server-generated errors.
+   */
+  Future<List<AnalysisErrorFixes>> _computeServerErrorFixes(
+      String file, int offset) async {
+    if (AnalysisEngine.isDartFileName(file)) {
+      return _computeDartFixes(file, offset);
+    } else if (AnalysisEngine.isAnalysisOptionsFileName(
+        file, server.resourceProvider.pathContext)) {
+      return _computeAnalysisOptionsFixes(file, offset);
+    }
+    return <AnalysisErrorFixes>[];
+  }
+
   Response _getAvailableRefactorings(Request request) {
     _getAvailableRefactoringsImpl(request);
     return Response.DELAYED_RESPONSE;
@@ -676,6 +732,16 @@
     server.sendResponse(result.toResponse(request.id));
   }
 
+  YamlMap _getOptions(SourceFactory sourceFactory, String content) {
+    AnalysisOptionsProvider optionsProvider =
+        new AnalysisOptionsProvider(sourceFactory);
+    try {
+      return optionsProvider.getOptionsFromString(content);
+    } on OptionsFormatException {
+      return null;
+    }
+  }
+
   Response _getRefactoring(Request request) {
     if (refactoringManager.hasPendingRequest) {
       refactoringManager.cancel();
@@ -692,6 +758,16 @@
     refactoringManager = new _RefactoringManager(server, refactoringWorkspace);
   }
 
+  /// Return the contents of the [file], or `null` if the file does not exist or
+  /// cannot be read.
+  String _safelyRead(File file) {
+    try {
+      return file.readAsStringSync();
+    } on FileSystemException {
+      return null;
+    }
+  }
+
   static int _getNumberOfScanParseErrors(List<engine.AnalysisError> errors) {
     int numScanParseErrors = 0;
     for (engine.AnalysisError error in errors) {
diff --git a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
index 3e6c9c8..728bb580 100644
--- a/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/dartfix_info.dart
@@ -8,8 +8,11 @@
 import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
 import 'package:analysis_server/src/edit/fix/fix_error_task.dart';
 import 'package:analysis_server/src/edit/fix/non_nullable_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart';
 import 'package:analysis_server/src/edit/fix/prefer_int_literals_fix.dart';
 import 'package:analysis_server/src/edit/fix/prefer_mixin_fix.dart';
+import 'package:analysis_server/src/edit/fix/prefer_spread_collections_fix.dart';
 
 const allFixes = <DartFixInfo>[
   //
@@ -33,22 +36,40 @@
   const DartFixInfo(
     'double-to-int',
     'Find double literals ending in .0 and remove the .0\n'
-        'wherever double context can be inferred.',
+    'wherever double context can be inferred.',
     PreferIntLiteralsFix.task,
   ),
   //
-  // Expermimental fixes
+  // Experimental fixes
   //
   const DartFixInfo(
     'non-nullable',
     // TODO(danrubel) update description and make default/required
     // when NNBD fix is ready
     'Experimental: Update sources to be non-nullable by default.\n'
-        'Requires the experimental non-nullable flag to be enabled.\n'
-        'This is not applied unless explicitly included.',
+    'Requires the experimental non-nullable flag to be enabled.\n'
+    'This is not applied unless explicitly included.',
     NonNullableFix.task,
     isDefault: false,
   ),
+  const DartFixInfo(
+    'use-spread-collections',
+    'Convert to using collection spread operators.',
+    PreferSpreadCollectionsFix.task,
+    isDefault: false,
+  ),
+  const DartFixInfo(
+    'collection-if-elements',
+    'Convert to using if elements when building collections.',
+    PreferIfElementsToConditionalExpressionsFix.task,
+    isDefault: false,
+  ),
+  const DartFixInfo(
+    'map-for-elements',
+    'Convert to for elements when building maps from iterables.',
+    PreferForElementsToMapFromIterableFix.task,
+    isDefault: false,
+  ),
 ];
 
 /// [DartFixInfo] represents a fix that can be applied by [EditDartFix].
diff --git a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
index eaa28ad..e4f0b2e 100644
--- a/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/fix_code_task.dart
@@ -6,12 +6,17 @@
 
 import 'package:analysis_server/src/edit/edit_dartfix.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
 
 /// A general task for performing a fix.
 abstract class FixCodeTask {
   /// Number of times [processUnit] should be called for each compilation unit.
   int get numPhases;
 
+  /// [processPackage] is called once for each package
+  /// before [processUnit] is called for any compilation unit in any package.
+  Future<void> processPackage(Folder pkgFolder);
+
   /// [processUnit] is called for each phase and compilation unit.
   ///
   /// First [processUnit] will be called once for each compilation unit with
@@ -44,6 +49,12 @@
     }
   }
 
+  void processPackage(Folder pkgFolder) async {
+    for (FixCodeTask task in _codeTasks) {
+      await task.processPackage(pkgFolder);
+    }
+  }
+
   void registerCodeTask(FixCodeTask task) {
     _codeTasks.add(task);
     _numPhases = max(_numPhases, task.numPhases);
diff --git a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
index bc5b11b..61d3984 100644
--- a/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
+++ b/pkg/analysis_server/lib/src/edit/fix/non_nullable_fix.dart
@@ -7,7 +7,12 @@
 import 'package:analysis_server/src/edit/fix/fix_code_task.dart';
 import 'package:analysis_server/src/nullability/provisional_api.dart';
 import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/task/options.dart';
 import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:yaml/yaml.dart';
+import 'package:source_span/source_span.dart';
 
 /// [NonNullableFix] visits each named type in a resolved compilation unit
 /// and determines whether the associated variable or parameter can be null
@@ -21,6 +26,11 @@
 
   final NullabilityMigration migration;
 
+  /// If this flag has a value of `false`, then something happened to prevent
+  /// at least one package from being marked as non-nullable.
+  /// If this occurs, then don't update any code.
+  bool _packageIsNNBD = true;
+
   NonNullableFix(this.listener)
       : migration = new NullabilityMigration(
             new NullabilityMigrationAdapter(listener),
@@ -34,8 +44,123 @@
     migration.finish();
   }
 
+  /// If the package contains an analysis_options.yaml file, then update the
+  /// file to enabled NNBD. If that file does not exist, but the package
+  /// contains a pubspec.yaml, then create the analysis_options.yaml file.
+  @override
+  Future<void> processPackage(Folder pkgFolder) async {
+    if (!_packageIsNNBD) {
+      return;
+    }
+
+    // TODO(danrubel): Update pubspec.yaml to enable NNBD
+
+    File optionsFile = pkgFolder.getChildAssumingFile('analysis_options.yaml');
+    String optionsContent;
+    YamlNode optionsMap;
+    if (optionsFile.exists) {
+      try {
+        optionsContent = optionsFile.readAsStringSync();
+      } on FileSystemException catch (e) {
+        processYamlException('read', optionsFile.path, e);
+        return;
+      }
+      try {
+        optionsMap = loadYaml(optionsContent);
+      } on YamlException catch (e) {
+        processYamlException('parse', optionsFile.path, e);
+        return;
+      }
+    }
+
+    SourceSpan parentSpan;
+    String content;
+    YamlNode analyzerOptions;
+    if (optionsMap is YamlMap) {
+      analyzerOptions = optionsMap.nodes[AnalyzerOptions.analyzer];
+    }
+    if (analyzerOptions == null) {
+      var start = new SourceLocation(0, line: 0, column: 0);
+      parentSpan = new SourceSpan(start, start, '');
+      content = '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+
+''';
+    } else if (analyzerOptions is YamlMap) {
+      YamlNode experiments =
+          analyzerOptions.nodes[AnalyzerOptions.enableExperiment];
+      if (experiments == null) {
+        parentSpan = analyzerOptions.span;
+        content = '''
+
+  enable-experiment:
+    - non-nullable''';
+      } else if (experiments is YamlList) {
+        experiments.nodes.firstWhere(
+          (node) => node.span.text == EnableString.non_nullable,
+          orElse: () {
+            parentSpan = experiments.span;
+            content = '''
+
+    - non-nullable''';
+          },
+        );
+      }
+    }
+
+    if (parentSpan != null) {
+      final space = ' '.codeUnitAt(0);
+      final cr = '\r'.codeUnitAt(0);
+      final lf = '\n'.codeUnitAt(0);
+
+      int line = parentSpan.end.line;
+      int offset = parentSpan.end.offset;
+      while (offset > 0) {
+        int ch = optionsContent.codeUnitAt(offset - 1);
+        if (ch == space || ch == cr) {
+          --offset;
+        } else if (ch == lf) {
+          --offset;
+          --line;
+        } else {
+          break;
+        }
+      }
+      listener.addSourceFileEdit(
+          'enable non-nullable analysis',
+          new Location(
+            optionsFile.path,
+            offset,
+            content.length,
+            line,
+            0,
+          ),
+          new SourceFileEdit(optionsFile.path, 0,
+              edits: [new SourceEdit(offset, 0, content)]));
+    }
+  }
+
+  void processYamlException(String action, String optionsFilePath, error) {
+    listener.addRecommendation('''Failed to $action options file
+  $optionsFilePath
+  $error
+
+  Manually update this file to enable non-nullable by adding:
+
+    analyzer:
+      enable-experiment:
+        - non-nullable
+''');
+    _packageIsNNBD = false;
+  }
+
   @override
   Future<void> processUnit(int phase, ResolvedUnitResult result) async {
+    if (!_packageIsNNBD) {
+      return;
+    }
     switch (phase) {
       case 0:
         migration.prepareInput(result);
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart
new file mode 100644
index 0000000..84ecff9
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_for_elements_to_map_fromIterable_fix.dart
@@ -0,0 +1,69 @@
+// 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:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferForElementsToMapFromIterableFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferForElementsToMapFromIterableFix(DartFixListener listener)
+      : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            node.length),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_FOR_ELEMENT);
+
+      final location = listener.locationFor(result, node.offset, node.length);
+      if (assists.isNotEmpty) {
+        for (Assist assist in assists) {
+          listener.addSourceChange(
+              assist.kind.message, location, assist.change);
+        }
+      } else {
+        listener.addRecommendation(
+            'Convert to for elements assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_for_elements_to_map_fromIterable'],
+      new PreferForElementsToMapFromIterableFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart
new file mode 100644
index 0000000..0dbdf26
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_if_elements_to_conditional_expressions_fix.dart
@@ -0,0 +1,69 @@
+// 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:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferIfElementsToConditionalExpressionsFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferIfElementsToConditionalExpressionsFix(DartFixListener listener)
+      : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            node.length),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_IF_ELEMENT);
+
+      final location = listener.locationFor(result, node.offset, node.length);
+      if (assists.isNotEmpty) {
+        for (Assist assist in assists) {
+          listener.addSourceChange(
+              assist.kind.message, location, assist.change);
+        }
+      } else {
+        listener.addRecommendation(
+            'Convert to if elements assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_if_elements_to_conditional_expressions'],
+      new PreferIfElementsToConditionalExpressionsFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart
new file mode 100644
index 0000000..caff2e6
--- /dev/null
+++ b/pkg/analysis_server/lib/src/edit/fix/prefer_spread_collections_fix.dart
@@ -0,0 +1,68 @@
+// 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:analysis_server/plugin/edit/assist/assist_core.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_listener.dart';
+import 'package:analysis_server/src/edit/fix/dartfix_registrar.dart';
+import 'package:analysis_server/src/edit/fix/fix_lint_task.dart';
+import 'package:analysis_server/src/services/correction/assist.dart';
+import 'package:analysis_server/src/services/correction/assist_internal.dart';
+import 'package:analysis_server/src/services/correction/change_workspace.dart';
+import 'package:analyzer/dart/analysis/results.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/lint/registry.dart';
+
+class PreferSpreadCollectionsFix extends FixLintTask {
+  final List<AstNode> nodes = <AstNode>[];
+
+  PreferSpreadCollectionsFix(DartFixListener listener) : super(listener);
+
+  @override
+  Future<void> applyLocalFixes(ResolvedUnitResult result) async {
+    while (nodes.isNotEmpty) {
+      AstNode node = nodes.removeLast();
+      AssistProcessor processor = new AssistProcessor(
+        new DartAssistContextImpl(
+            DartChangeWorkspace(listener.server.currentSessions),
+            result,
+            node.offset,
+            0),
+      );
+      List<Assist> assists =
+          await processor.computeAssist(DartAssistKind.CONVERT_TO_SPREAD);
+
+      final location = listener.locationFor(result, node.offset, node.length);
+      if (assists.isNotEmpty) {
+        for (Assist assist in assists) {
+          listener.addSourceChange(
+              assist.kind.message, location, assist.change);
+        }
+      } else {
+        listener.addRecommendation(
+            'Convert to spread assist not found', location);
+      }
+    }
+
+    return null;
+  }
+
+  @override
+  Future<void> applyRemainingFixes() {
+    return null;
+  }
+
+  @override
+  void reportErrorForNode(ErrorCode errorCode, AstNode node,
+      [List<Object> arguments]) {
+    nodes.add(node);
+  }
+
+  static void task(DartFixRegistrar registrar, DartFixListener listener) {
+    registrar.registerLintTask(
+      Registry.ruleRegistry['prefer_spread_collections'],
+      new PreferSpreadCollectionsFix(listener),
+    );
+  }
+}
diff --git a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart b/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
index 4b47370..3e09ed4 100644
--- a/pkg/analysis_server/lib/src/nullability/conditional_discard.dart
+++ b/pkg/analysis_server/lib/src/nullability/conditional_discard.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:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 
 /// Container for information gathered during nullability migration about a
@@ -11,15 +12,21 @@
 /// whose boolean value influences control flow (e.g. the condition of an `if`
 /// statement).
 class ConditionalDiscard {
-  /// Constraint variable whose value will be `true` if the code path that
-  /// results from the condition evaluating to `true` will be reachable after
+  /// Nullability node that will be `nullable` if the code path that results
+  /// from the condition evaluating to `true` will be reachable after
   /// nullability migration, and therefore should be kept.
-  final ConstraintVariable keepTrue;
+  ///
+  /// `null` if the code path should be kept regardless of the outcome of
+  /// migration.
+  final NullabilityNode trueGuard;
 
-  /// Constraint variable whose value will be `false` if the code path that
-  /// results from the condition evaluating to `false` will be reachable after
+  /// Nullability node that will be `nullable` if the code path that results
+  /// from the condition evaluating to `false` will be reachable after
   /// nullability migration, and therefore should be kept.
-  final ConstraintVariable keepFalse;
+  ///
+  /// `null` if the code path should be kept regardless of the outcome of
+  /// migration.
+  final NullabilityNode falseGuard;
 
   /// Indicates whether the condition is pure (free from side effects).
   ///
@@ -27,11 +34,19 @@
   /// variable or static variable), because evaluating it has no user-visible
   /// effect other than returning a boolean value.
   ///
-  /// If [pureCondition] is `false`, and either [keepTrue] or [keepFalse] is
+  /// If [pureCondition] is `false`, and either [trueGuard] or [falseGuard] is
   /// `false`, that it is safe to delete the condition expression as well as the
   /// dead code branch (e.g. it means that `if (x == null) f(); else g();` could
   /// be changed to simply `g();`).
   final bool pureCondition;
 
-  ConditionalDiscard(this.keepTrue, this.keepFalse, this.pureCondition);
+  ConditionalDiscard(this.trueGuard, this.falseGuard, this.pureCondition);
+
+  /// Indicates whether the code path that results from the condition evaluating
+  /// to `false` is reachable after migration.
+  bool get keepFalse => falseGuard == null || falseGuard.isNullable;
+
+  /// Indicates whether the code path that results from the condition evaluating
+  /// to `true` is reachable after migration.
+  bool get keepTrue => trueGuard == null || trueGuard.isNullable;
 }
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
index d0802ad..a723c9a 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_gatherer.dart
@@ -6,6 +6,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -63,13 +64,13 @@
   /// boolean value could possibly affect nullability analysis.
   _ConditionInfo _conditionInfo;
 
-  /// The set of constraint variables that would have to be assigned the value
-  /// of `true` for the code currently being visited to be reachable.
+  /// The set of nullability nodes that would have to be `nullable` for the code
+  /// currently being visited to be reachable.
   ///
   /// Guard variables are attached to the left hand side of any generated
   /// constraints, so that constraints do not take effect if they come from
   /// code that can be proven unreachable by the migration tool.
-  final _guards = <ConstraintVariable>[];
+  final _guards = <NullabilityNode>[];
 
   /// Indicates whether the statement or expression being visited is within
   /// conditional control flow.  If `true`, this means that the enclosing
@@ -79,11 +80,14 @@
 
   ConstraintGatherer(TypeProvider typeProvider, this._variables,
       this._constraints, this._source, this._permissive, this.assumptions)
-      : _notNullType = DecoratedType(typeProvider.objectType, null),
-        _nonNullableBoolType = DecoratedType(typeProvider.boolType, null),
-        _nonNullableTypeType = DecoratedType(typeProvider.typeType, null),
+      : _notNullType =
+            DecoratedType(typeProvider.objectType, NullabilityNode.never),
+        _nonNullableBoolType =
+            DecoratedType(typeProvider.boolType, NullabilityNode.never),
+        _nonNullableTypeType =
+            DecoratedType(typeProvider.typeType, NullabilityNode.never),
         _nullType =
-            DecoratedType(typeProvider.nullType, ConstraintVariable.always);
+            DecoratedType(typeProvider.nullType, NullabilityNode.always);
 
   /// Gets the decorated type of [element] from [_variables], performing any
   /// necessary substitutions.
@@ -132,7 +136,8 @@
     if (identical(_conditionInfo?.condition, node.condition)) {
       if (!_inConditionalControlFlow &&
           _conditionInfo.trueDemonstratesNonNullIntent != null) {
-        _recordFact(_conditionInfo.trueDemonstratesNonNullIntent);
+        _conditionInfo.trueDemonstratesNonNullIntent
+            ?.recordNonNullIntent(_constraints, _guards);
       }
     }
     node.message?.accept(this);
@@ -154,8 +159,8 @@
           bool isPure = node.leftOperand is SimpleIdentifier;
           var conditionInfo = _ConditionInfo(node,
               isPure: isPure,
-              trueGuard: leftType.nullable,
-              falseDemonstratesNonNullIntent: leftType.nonNullIntent);
+              trueGuard: leftType.node,
+              falseDemonstratesNonNullIntent: leftType.node);
           _conditionInfo = node.operator.type == TokenType.EQ_EQ
               ? conditionInfo
               : conditionInfo.not(node);
@@ -182,7 +187,7 @@
 
   @override
   DecoratedType visitBooleanLiteral(BooleanLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
@@ -199,8 +204,10 @@
     assert(_isSimple(thenType)); // TODO(paulberry)
     var elseType = node.elseExpression.accept(this);
     assert(_isSimple(elseType)); // TODO(paulberry)
-    var overallType = DecoratedType(node.staticType,
-        _joinNullabilities(node, thenType.nullable, elseType.nullable));
+    var overallType = DecoratedType(
+        node.staticType,
+        NullabilityNode.forConditionalexpression(
+            node, thenType.node, elseType.node, _joinNullabilities));
     _variables.recordDecoratedExpressionType(node, overallType);
     return overallType;
   }
@@ -215,7 +222,13 @@
       } else if (node.declaredElement.isOptionalPositional ||
           assumptions.namedNoDefaultParameterHeuristic ==
               NamedNoDefaultParameterHeuristic.assumeNullable) {
-        _recordFact(getOrComputeElementType(node.declaredElement).nullable);
+        NullabilityNode.recordAssignment(
+            NullabilityNode.always,
+            getOrComputeElementType(node.declaredElement).node,
+            null,
+            _guards,
+            _constraints,
+            false);
       } else {
         assert(assumptions.namedNoDefaultParameterHeuristic ==
             NamedNoDefaultParameterHeuristic.assumeRequired);
@@ -255,16 +268,13 @@
     // treated like an implicit `assert(b != null)`?  Probably.
     _handleAssignment(_notNullType, node.condition);
     _inConditionalControlFlow = true;
-    ConstraintVariable trueGuard;
-    ConstraintVariable falseGuard;
+    NullabilityNode trueGuard;
+    NullabilityNode falseGuard;
     if (identical(_conditionInfo?.condition, node.condition)) {
       trueGuard = _conditionInfo.trueGuard;
       falseGuard = _conditionInfo.falseGuard;
-      _variables.recordConditionalDiscard(
-          _source,
-          node,
-          ConditionalDiscard(trueGuard ?? ConstraintVariable.always,
-              falseGuard ?? ConstraintVariable.always, _conditionInfo.isPure));
+      _variables.recordConditionalDiscard(_source, node,
+          ConditionalDiscard(trueGuard, falseGuard, _conditionInfo.isPure));
     }
     if (trueGuard != null) {
       _guards.add(trueGuard);
@@ -291,7 +301,7 @@
 
   @override
   DecoratedType visitIntegerLiteral(IntegerLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
@@ -337,10 +347,9 @@
       }
     }
     // Any parameters not supplied must be optional.
-    for (var entry in calleeType.namedParameterOptionalVariables.entries) {
-      assert(entry.value != null);
+    for (var entry in calleeType.namedParameters.entries) {
       if (suppliedNamedParameters.contains(entry.key)) continue;
-      _recordFact(entry.value);
+      entry.value.node.recordNamedParameterNotSupplied(_constraints, _guards);
     }
     return calleeType.returnType;
   }
@@ -393,24 +402,24 @@
 
   @override
   DecoratedType visitStringLiteral(StringLiteral node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitThisExpression(ThisExpression node) {
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitThrowExpression(ThrowExpression node) {
     node.expression.accept(this);
     // TODO(paulberry): do we need to check the expression type?  I think not.
-    return DecoratedType(node.staticType, null);
+    return DecoratedType(node.staticType, NullabilityNode.never);
   }
 
   @override
   DecoratedType visitTypeName(TypeName typeName) {
-    return DecoratedType(typeName.type, null);
+    return DecoratedType(typeName.type, NullabilityNode.never);
   }
 
   /// Creates the necessary constraint(s) for an assignment from [sourceType] to
@@ -419,40 +428,14 @@
   /// where a nullable source is assigned to a non-nullable destination.
   void _checkAssignment(DecoratedType destinationType, DecoratedType sourceType,
       Expression expression) {
-    if (sourceType.nullable != null) {
-      _guards.add(sourceType.nullable);
-      var destinationNonNullIntent = destinationType.nonNullIntent;
-      try {
-        CheckExpression checkNotNull;
-        if (expression != null) {
-          checkNotNull = CheckExpression(expression);
-          _variables.recordExpressionChecks(
-              _source, expression, ExpressionChecks(checkNotNull));
-        }
-        // nullable_src => nullable_dst | check_expr
-        _recordFact(ConstraintVariable.or(
-            _constraints, destinationType.nullable, checkNotNull));
-        if (checkNotNull != null) {
-          // nullable_src & nonNullIntent_dst => check_expr
-          if (destinationNonNullIntent != null) {
-            _recordConstraint(destinationNonNullIntent, checkNotNull);
-          }
-        }
-      } finally {
-        _guards.removeLast();
-      }
-      var sourceNonNullIntent = sourceType.nonNullIntent;
-      if (!_inConditionalControlFlow && sourceNonNullIntent != null) {
-        if (destinationType.nullable == null) {
-          // The destination type can never be nullable so this demonstrates
-          // non-null intent.
-          _recordFact(sourceNonNullIntent);
-        } else if (destinationNonNullIntent != null) {
-          // Propagate non-null intent from the destination to the source.
-          _recordConstraint(destinationNonNullIntent, sourceNonNullIntent);
-        }
-      }
+    CheckExpression checkNotNull;
+    if (expression != null) {
+      checkNotNull = CheckExpression(expression);
+      _variables.recordExpressionChecks(
+          _source, expression, ExpressionChecks(checkNotNull));
     }
+    NullabilityNode.recordAssignment(sourceType.node, destinationType.node,
+        checkNotNull, _guards, _constraints, _inConditionalControlFlow);
     // TODO(paulberry): it's a cheat to pass in expression=null for the
     // recursive checks.  Really we want to unify all the checks in a single
     // ExpressionChecks object.
@@ -524,31 +507,11 @@
       return ConstraintVariable.always;
     }
     var result = TypeIsNullable(node.offset);
-    _recordConstraint(a, result);
-    _recordConstraint(b, result);
-    _recordConstraint(result, ConstraintVariable.or(_constraints, a, b));
+    _constraints.record([a], result);
+    _constraints.record([b], result);
+    _constraints.record([result], ConstraintVariable.or(_constraints, a, b));
     return result;
   }
-
-  /// Records a constraint having [condition] as its left hand side and
-  /// [consequence] as its right hand side.  Any [_guards] are included in the
-  /// left hand side.
-  void _recordConstraint(
-      ConstraintVariable condition, ConstraintVariable consequence) {
-    _guards.add(condition);
-    try {
-      _recordFact(consequence);
-    } finally {
-      _guards.removeLast();
-    }
-  }
-
-  /// Records a constraint having [consequence] as its right hand side.  Any
-  /// [_guards] are used as the right hand side.
-  void _recordFact(ConstraintVariable consequence) {
-    assert(consequence != null);
-    _constraints.record(_guards, consequence);
-  }
 }
 
 /// Information about a binary expression whose boolean value could possibly
@@ -564,21 +527,21 @@
   /// effect other than returning a boolean value.
   final bool isPure;
 
-  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
   /// order for [condition] to evaluate to `true`.
-  final ConstraintVariable trueGuard;
+  final NullabilityNode trueGuard;
 
-  /// If not `null`, the [ConstraintVariable] whose value must be `true` in
+  /// If not `null`, the [NullabilityNode] that would need to be nullable in
   /// order for [condition] to evaluate to `false`.
-  final ConstraintVariable falseGuard;
+  final NullabilityNode falseGuard;
 
-  /// If not `null`, the [ConstraintVariable] whose value should be set to
-  /// `true` if [condition] is asserted to be `true`.
-  final ConstraintVariable trueDemonstratesNonNullIntent;
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  //  /// non-null intent if [condition] is asserted to be `true`.
+  final NullabilityNode trueDemonstratesNonNullIntent;
 
-  /// If not `null`, the [ConstraintVariable] whose value should be set to
-  /// `true` if [condition] is asserted to be `false`.
-  final ConstraintVariable falseDemonstratesNonNullIntent;
+  /// If not `null`, the [NullabilityNode] that should be asserted to have
+  /// non-null intent if [condition] is asserted to be `false`.
+  final NullabilityNode falseDemonstratesNonNullIntent;
 
   _ConditionInfo(this.condition,
       {@required this.isPure,
diff --git a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
index f917e72..8f5f170 100644
--- a/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
+++ b/pkg/analysis_server/lib/src/nullability/constraint_variable_gatherer.dart
@@ -5,6 +5,7 @@
 import 'package:analysis_server/src/nullability/conditional_discard.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -50,28 +51,19 @@
         // TODO(danrubel): Return something other than this
         // to indicate that we should insert a type for the declaration
         // that is missing a type reference.
-        ? new DecoratedType(DynamicTypeImpl.instance, ConstraintVariable.always)
+        ? new DecoratedType(
+            DynamicTypeImpl.instance, NullabilityNode.forInferredDynamicType())
         : type.accept(this);
   }
 
   @override
   DecoratedType visitDefaultFormalParameter(DefaultFormalParameter node) {
     var decoratedType = node.parameter.accept(this);
-    ConstraintVariable optional;
-    if (node.declaredElement.hasRequired) {
-      optional = null;
-    } else if (node.defaultValue != null) {
-      optional = ConstraintVariable.always;
-    } else {
-      optional = decoratedType.nullable;
-      _variables.recordPossiblyOptional(_source, node, optional);
+    if (node.declaredElement.hasRequired || node.defaultValue != null) {
+      return null;
     }
-    if (optional != null) {
-      _currentFunctionType
-              .namedParameterOptionalVariables[node.declaredElement.name] =
-          optional;
-    }
-    return null;
+    decoratedType.node.trackPossiblyOptional();
+    _variables.recordPossiblyOptional(_source, node, decoratedType.node);
   }
 
   @override
@@ -117,8 +109,7 @@
   DecoratedType visitSimpleFormalParameter(SimpleFormalParameter node) {
     var type = decorateType(node.type);
     var declaredElement = node.declaredElement;
-    assert(type.nonNullIntent == null);
-    type.nonNullIntent = NonNullIntent(node.offset);
+    type.node.trackNonNullIntent(node.offset);
     _variables.recordDecoratedElementType(declaredElement, type);
     if (declaredElement.isNamed) {
       _currentFunctionType.namedParameters[declaredElement.name] = type;
@@ -133,7 +124,10 @@
     assert(node != null); // TODO(paulberry)
     assert(node is NamedType); // TODO(paulberry)
     var type = node.type;
-    if (type.isVoid) return DecoratedType(type, ConstraintVariable.always);
+    if (type.isVoid) {
+      return DecoratedType(
+          type, NullabilityNode.forTypeAnnotation(node.end, always: true));
+    }
     assert(
         type is InterfaceType || type is TypeParameterType); // TODO(paulberry)
     var typeArguments = const <DecoratedType>[];
@@ -146,10 +140,11 @@
         assert(false); // TODO(paulberry): is this possible?
       }
     }
-    var nullable = node.question == null
-        ? TypeIsNullable(node.end)
-        : ConstraintVariable.always;
-    var decoratedType = DecoratedTypeAnnotation(type, nullable, node.end,
+    var decoratedType = DecoratedTypeAnnotation(
+        type,
+        NullabilityNode.forTypeAnnotation(node.end,
+            always: node.question != null),
+        node.end,
         typeArguments: typeArguments);
     _variables.recordDecoratedTypeAnnotation(_source, node, decoratedType);
     return decoratedType;
@@ -165,11 +160,11 @@
     var previousFunctionType = _currentFunctionType;
     // TODO(paulberry): test that it's correct to use `null` for the nullability
     // of the function type
-    var functionType = DecoratedType(declaredElement.type, null,
+    var functionType = DecoratedType(
+        declaredElement.type, NullabilityNode.never,
         returnType: decoratedReturnType,
         positionalParameters: [],
-        namedParameters: {},
-        namedParameterOptionalVariables: {});
+        namedParameters: {});
     _currentFunctionType = functionType;
     try {
       parameters.accept(this);
@@ -194,11 +189,11 @@
   void recordDecoratedTypeAnnotation(
       Source source, TypeAnnotation node, DecoratedTypeAnnotation type);
 
-  /// Associates a constraint variable with the question of whether the given
-  /// named parameter should be optional (should not have a `required`
+  /// Records that [node] is associated with the question of whether the named
+  /// [parameter] should be optional (should not have a `required`
   /// annotation added to it).
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable);
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node);
 }
 
 /// Repository of constraint variables and decorated types corresponding to the
diff --git a/pkg/analysis_server/lib/src/nullability/decorated_type.dart b/pkg/analysis_server/lib/src/nullability/decorated_type.dart
index 2dde11f..41fef69 100644
--- a/pkg/analysis_server/lib/src/nullability/decorated_type.dart
+++ b/pkg/analysis_server/lib/src/nullability/decorated_type.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:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -15,18 +16,7 @@
 class DecoratedType {
   final DartType type;
 
-  /// [ConstraintVariable] whose value will be set to `true` if this type needs
-  /// to be nullable.
-  ///
-  /// If `null`, that means that an external constraint (outside the code being
-  /// migrated) forces this type to be non-nullable.
-  final ConstraintVariable nullable;
-
-  /// [ConstraintVariable] whose value will be set to `true` if the usage of
-  /// this type suggests that it is intended to be non-null (because of the
-  /// presence of a statement or expression that would unconditionally lead to
-  /// an exception being thrown in the case of a `null` value at runtime).
-  ConstraintVariable nonNullIntent;
+  final NullabilityNode node;
 
   /// If `this` is a function type, the [DecoratedType] of its return type.
   final DecoratedType returnType;
@@ -40,31 +30,21 @@
   /// parameters.
   final Map<String, DecoratedType> namedParameters;
 
-  /// If `this` is a function type, [ConstraintVariable] for each of its named
-  /// parameters indicating whether the given named parameter needs to be
-  /// optional (no `required` annotation).
-  ///
-  /// If there is no entry in this map corresponding to a given named parameter,
-  /// that means that it has already been decided (prior to migration) that the
-  /// given named parameter is required.  TODO(paulberry): test that this works
-  /// for already-migrated code.
-  final Map<String, ConstraintVariable> namedParameterOptionalVariables;
-
   /// If `this` is a parameterized type, the [DecoratedType] of each of its
   /// type parameters.
   ///
   /// TODO(paulberry): how should we handle generic typedefs?
   final List<DecoratedType> typeArguments;
 
-  DecoratedType(this.type, this.nullable,
+  DecoratedType(this.type, this.node,
       {this.returnType,
       this.positionalParameters = const [],
       this.namedParameters = const {},
-      this.namedParameterOptionalVariables = const {},
       this.typeArguments = const []}) {
+    assert(node != null);
     // The type system doesn't have a non-nullable version of `dynamic`.  So if
     // the type is `dynamic`, verify that `nullable` is `always`.
-    assert(!type.isDynamic || identical(nullable, ConstraintVariable.always));
+    assert(!type.isDynamic || node.isAlwaysNullable);
   }
 
   /// Creates a [DecoratedType] corresponding to the given [element], which is
@@ -74,7 +54,7 @@
       assert((type as TypeImpl).nullability ==
           Nullability.indeterminate); // TODO(paulberry)
       if (type is FunctionType) {
-        var decoratedType = DecoratedType(type, null,
+        var decoratedType = DecoratedType(type, NullabilityNode.never,
             returnType: decorate(type.returnType), positionalParameters: []);
         for (var parameter in type.parameters) {
           assert(parameter.isPositional); // TODO(paulberry)
@@ -83,7 +63,7 @@
         return decoratedType;
       } else if (type is InterfaceType) {
         assert(type.typeParameters.isEmpty); // TODO(paulberry)
-        return DecoratedType(type, null);
+        return DecoratedType(type, NullabilityNode.never);
       } else {
         throw type.runtimeType; // TODO(paulberry)
       }
@@ -112,7 +92,7 @@
 
   @override
   String toString() {
-    var trailing = nullable == null ? '' : '?($nullable)';
+    var trailing = node.debugSuffix;
     var type = this.type;
     if (type is TypeParameterType || type is VoidType) {
       return '$type$trailing';
@@ -155,14 +135,14 @@
         newPositionalParameters.add(positionalParameters[i]
             ._substitute(constraints, substitution, undecoratedParameterType));
       }
-      return DecoratedType(undecoratedResult, nullable,
+      return DecoratedType(undecoratedResult, node,
           returnType: returnType._substitute(
               constraints, substitution, undecoratedResult.returnType),
           positionalParameters: newPositionalParameters);
     } else if (type is TypeParameterType) {
       var inner = substitution[type.element];
       return DecoratedType(undecoratedResult,
-          ConstraintVariable.or(constraints, inner?.nullable, nullable));
+          NullabilityNode.forSubstitution(constraints, inner?.node, node));
     } else if (type is VoidType) {
       return this;
     }
@@ -180,13 +160,12 @@
   final int _offset;
 
   DecoratedTypeAnnotation(
-      DartType type, ConstraintVariable nullable, this._offset,
+      DartType type, NullabilityNode nullabilityNode, this._offset,
       {List<DecoratedType> typeArguments = const []})
-      : super(type, nullable, typeArguments: typeArguments);
+      : super(type, nullabilityNode, typeArguments: typeArguments);
 
   @override
-  bool get isEmpty =>
-      identical(nullable, ConstraintVariable.always) || !nullable.value;
+  bool get isEmpty => node.isAlwaysNullable || !node.isNullable;
 
   @override
   Iterable<SourceEdit> get modifications =>
diff --git a/pkg/analysis_server/lib/src/nullability/nullability_node.dart b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
new file mode 100644
index 0000000..fd7d82b
--- /dev/null
+++ b/pkg/analysis_server/lib/src/nullability/nullability_node.dart
@@ -0,0 +1,201 @@
+// 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:analysis_server/src/nullability/decorated_type.dart';
+import 'package:analysis_server/src/nullability/transitional_api.dart';
+import 'package:analysis_server/src/nullability/unit_propagation.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:meta/meta.dart';
+
+/// Representation of a single node in the nullability inference graph.
+///
+/// Initially, this is just a wrapper over constraint variables, and the
+/// nullability inference graph is encoded into the wrapped constraint
+/// variables.  Over time this will be replaced by a first class representation
+/// of the nullability inference graph.
+class NullabilityNode {
+  /// [NullabilityNode] used for types that are known a priori to be nullable
+  /// (e.g. the type of the `null` literal).
+  static final always = NullabilityNode._(ConstraintVariable.always);
+
+  /// [NullabilityNode] used for types that are known a priori to be
+  /// non-nullable (e.g. the type of an integer literal).
+  static final never = NullabilityNode._(null);
+
+  /// [ConstraintVariable] whose value will be set to `true` if this type needs
+  /// to be nullable.
+  ///
+  /// If `null`, that means that an external constraint (outside the code being
+  /// migrated) forces this type to be non-nullable.
+  final ConstraintVariable nullable;
+
+  ConstraintVariable _nonNullIntent;
+
+  bool _isPossiblyOptional = false;
+
+  /// Creates a [NullabilityNode] representing the nullability of a conditional
+  /// expression which is nullable iff both [a] and [b] are nullable.
+  ///
+  /// The constraint variable contained in the new node is created using the
+  /// [joinNullabilities] callback.  TODO(paulberry): this should become
+  /// unnecessary once constraint solving is performed directly using
+  /// [NullabilityNode] objects.
+  NullabilityNode.forConditionalexpression(
+      ConditionalExpression conditionalExpression,
+      NullabilityNode a,
+      NullabilityNode b,
+      ConstraintVariable Function(
+              ConditionalExpression, ConstraintVariable, ConstraintVariable)
+          joinNullabilities)
+      : this._(
+            joinNullabilities(conditionalExpression, a.nullable, b.nullable));
+
+  /// Creates a [NullabilityNode] representing the nullability of a variable
+  /// whose type is `dynamic` due to type inference.
+  ///
+  /// TODO(paulberry): this should go away; we should decorate the actual
+  /// inferred type rather than assuming `dynamic`.
+  NullabilityNode.forInferredDynamicType() : this._(ConstraintVariable.always);
+
+  /// Creates a [NullabilityNode] representing the nullability of a type
+  /// substitution where [outerNode] is the nullability node for the type
+  /// variable being eliminated by the substitution, and [innerNode] is the
+  /// nullability node for the type being substituted in its place.
+  ///
+  /// [innerNode] may be `null`.  TODO(paulberry): when?
+  ///
+  /// Additional constraints are recorded in [constraints] as necessary to make
+  /// the new nullability node behave consistently with the old nodes.
+  /// TODO(paulberry): this should become unnecessary once constraint solving is
+  /// performed directly using [NullabilityNode] objects.
+  NullabilityNode.forSubstitution(Constraints constraints,
+      NullabilityNode innerNode, NullabilityNode outerNode)
+      : this._(ConstraintVariable.or(
+            constraints, innerNode?.nullable, outerNode.nullable));
+
+  /// Creates a [NullabilityNode] representing the nullability of a type
+  /// annotation appearing explicitly in the user's program.
+  NullabilityNode.forTypeAnnotation(int endOffset, {@required bool always})
+      : this._(always ? ConstraintVariable.always : TypeIsNullable(endOffset));
+
+  NullabilityNode._(this.nullable);
+
+  /// Gets a string that can be appended to a type name during debugging to help
+  /// annotate the nullability of that type.
+  String get debugSuffix => nullable == null ? '' : '?($nullable)';
+
+  /// Indicates whether this node is always nullable, by construction.
+  bool get isAlwaysNullable => identical(nullable, ConstraintVariable.always);
+
+  /// After constraint solving, this getter can be used to query whether the
+  /// type associated with this node should be considered nullable.
+  bool get isNullable => nullable.value;
+
+  /// Indicates whether this node is associated with a named parameter for which
+  /// nullability migration needs to decide whether it is optional or required.
+  bool get isPossiblyOptional => _isPossiblyOptional;
+
+  /// [ConstraintVariable] whose value will be set to `true` if the usage of
+  /// this type suggests that it is intended to be non-null (because of the
+  /// presence of a statement or expression that would unconditionally lead to
+  /// an exception being thrown in the case of a `null` value at runtime).
+  ConstraintVariable get nonNullIntent => _nonNullIntent;
+
+  /// Records the fact that an invocation was made to a function with named
+  /// parameters, and the named parameter associated with this node was not
+  /// supplied.
+  void recordNamedParameterNotSupplied(
+      Constraints constraints, List<NullabilityNode> guards) {
+    if (isPossiblyOptional) {
+      _recordConstraints(constraints, guards, const [], nullable);
+    }
+  }
+
+  void recordNonNullIntent(
+      Constraints constraints, List<NullabilityNode> guards) {
+    _recordConstraints(constraints, guards, const [], nonNullIntent);
+  }
+
+  /// Tracks that the possibility that this nullability node might demonstrate
+  /// non-null intent, based on the fact that it corresponds to a formal
+  /// parameter declaration at location [offset].
+  ///
+  /// TODO(paulberry): consider eliminating this method altogether, and simply
+  /// allowing all nullability nodes to track non-null intent if necessary.
+  void trackNonNullIntent(int offset) {
+    assert(_nonNullIntent == null);
+    _nonNullIntent = NonNullIntent(offset);
+  }
+
+  /// Tracks the possibility that this node is associated with a named parameter
+  /// for which nullability migration needs to decide whether it is optional or
+  /// required.
+  void trackPossiblyOptional() {
+    _isPossiblyOptional = true;
+  }
+
+  /// Connect the nullability nodes [sourceNode] and [destinationNode]
+  /// appopriately to account for an assignment in the source code being
+  /// analyzed.  Any constraints generated are recorded in [constraints].
+  ///
+  /// If [checkNotNull] is non-null, then it tracks the expression that may
+  /// require null-checking.
+  ///
+  /// [inConditionalControlFlow] indicates whether the assignment being analyzed
+  /// is reachable conditionally or unconditionally from the entry point of the
+  /// function; this affects how non-null intent is back-propagated.
+  static void recordAssignment(
+      NullabilityNode sourceNode,
+      NullabilityNode destinationNode,
+      CheckExpression checkNotNull,
+      List<NullabilityNode> guards,
+      Constraints constraints,
+      bool inConditionalControlFlow) {
+    var additionalConditions = <ConstraintVariable>[];
+    if (sourceNode.nullable != null) {
+      additionalConditions.add(sourceNode.nullable);
+      var destinationNonNullIntent = destinationNode.nonNullIntent;
+      // nullable_src => nullable_dst | check_expr
+      _recordConstraints(
+          constraints,
+          guards,
+          additionalConditions,
+          ConstraintVariable.or(
+              constraints, destinationNode.nullable, checkNotNull));
+      if (checkNotNull != null) {
+        // nullable_src & nonNullIntent_dst => check_expr
+        if (destinationNonNullIntent != null) {
+          additionalConditions.add(destinationNonNullIntent);
+          _recordConstraints(
+              constraints, guards, additionalConditions, checkNotNull);
+        }
+      }
+      additionalConditions.clear();
+      var sourceNonNullIntent = sourceNode.nonNullIntent;
+      if (!inConditionalControlFlow && sourceNonNullIntent != null) {
+        if (destinationNode.nullable == null) {
+          // The destination type can never be nullable so this demonstrates
+          // non-null intent.
+          _recordConstraints(
+              constraints, guards, additionalConditions, sourceNonNullIntent);
+        } else if (destinationNonNullIntent != null) {
+          // Propagate non-null intent from the destination to the source.
+          additionalConditions.add(destinationNonNullIntent);
+          _recordConstraints(
+              constraints, guards, additionalConditions, sourceNonNullIntent);
+        }
+      }
+    }
+  }
+
+  static void _recordConstraints(
+      Constraints constraints,
+      List<NullabilityNode> guards,
+      List<ConstraintVariable> additionalConditions,
+      ConstraintVariable consequence) {
+    var conditions = guards.map((node) => node.nullable).toList();
+    conditions.addAll(additionalConditions);
+    constraints.record(conditions, consequence);
+  }
+}
diff --git a/pkg/analysis_server/lib/src/nullability/provisional_api.dart b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
index 3fa023b..99080c9 100644
--- a/pkg/analysis_server/lib/src/nullability/provisional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/provisional_api.dart
@@ -18,6 +18,10 @@
 
 /// Kinds of fixes that might be performed by nullability migration.
 class NullabilityFixKind {
+  /// An import needs to be added.
+  static const addImport =
+      const NullabilityFixKind._(appliedMessage: 'Add an import');
+
   /// A formal parameter needs to have a required annotation added.
   static const addRequired =
       const NullabilityFixKind._(appliedMessage: 'Add a required annotation');
@@ -144,9 +148,11 @@
     } else if (potentialModification is analyzer.DecoratedTypeAnnotation) {
       kind = NullabilityFixKind.makeTypeNullable;
     } else if (potentialModification is analyzer.ConditionalModification) {
-      kind = potentialModification.discard.keepFalse.value
+      kind = potentialModification.discard.keepFalse
           ? NullabilityFixKind.discardThen
           : NullabilityFixKind.discardElse;
+    } else if (potentialModification is analyzer.PotentiallyAddImport) {
+      kind = NullabilityFixKind.addImport;
     } else if (potentialModification is analyzer.PotentiallyAddRequired) {
       kind = NullabilityFixKind.addRequired;
     } else {
diff --git a/pkg/analysis_server/lib/src/nullability/transitional_api.dart b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
index ff2a53f..7a1b505 100644
--- a/pkg/analysis_server/lib/src/nullability/transitional_api.dart
+++ b/pkg/analysis_server/lib/src/nullability/transitional_api.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
@@ -60,7 +61,7 @@
       this.discard, this.condition, this.thenStatement, this.elseStatement);
 
   @override
-  bool get isEmpty => discard.keepTrue.value && discard.keepFalse.value;
+  bool get isEmpty => discard.keepTrue && discard.keepFalse;
 
   @override
   Iterable<SourceEdit> get modifications {
@@ -72,10 +73,10 @@
     if (!discard.pureCondition) {
       keepNodes.add(condition); // TODO(paulberry): test
     }
-    if (discard.keepTrue.value) {
+    if (discard.keepTrue) {
       keepNodes.add(thenStatement); // TODO(paulberry): test
     }
-    if (discard.keepFalse.value) {
+    if (discard.keepFalse) {
       keepNodes.add(elseStatement); // TODO(paulberry): test
     }
     // TODO(paulberry): test thoroughly
@@ -196,19 +197,54 @@
           NamedNoDefaultParameterHeuristic.assumeNullable});
 }
 
+/// Records information about the possible addition of an import
+/// to the source code.
+class PotentiallyAddImport extends PotentialModification {
+  final _usages = <PotentialModification>[];
+
+  final int _offset;
+  final String _importPath;
+
+  PotentiallyAddImport(
+      AstNode beforeNode, this._importPath, PotentialModification usage)
+      : _offset = beforeNode.offset {
+    _usages.add(usage);
+  }
+
+  get importPath => _importPath;
+
+  @override
+  bool get isEmpty {
+    for (PotentialModification usage in _usages) {
+      if (!usage.isEmpty) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  // TODO(danrubel): change all of dartfix NNBD to use DartChangeBuilder
+  @override
+  Iterable<SourceEdit> get modifications =>
+      isEmpty ? const [] : [SourceEdit(_offset, 0, "import '$_importPath';\n")];
+
+  void addUsage(PotentialModification usage) {
+    _usages.add(usage);
+  }
+}
+
 /// Records information about the possible addition of a `@required` annotation
 /// to the source code.
 class PotentiallyAddRequired extends PotentialModification {
-  final ConstraintVariable _optionalVariable;
+  final NullabilityNode _node;
 
   final int _offset;
 
-  PotentiallyAddRequired(
-      DefaultFormalParameter parameter, this._optionalVariable)
+  PotentiallyAddRequired(DefaultFormalParameter parameter, this._node)
       : _offset = parameter.offset;
 
   @override
-  bool get isEmpty => _optionalVariable.value;
+  bool get isEmpty => _node.isNullable;
 
   @override
   Iterable<SourceEdit> get modifications =>
@@ -264,10 +300,57 @@
   }
 
   @override
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable) {
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
+    var modification = PotentiallyAddRequired(parameter, node);
+    _addPotentialModification(source, modification);
+    _addPotentialImport(
+        source, parameter, modification, 'package:meta/meta.dart');
+  }
+
+  void _addPotentialImport(Source source, AstNode node,
+      PotentialModification usage, String importPath) {
+    // Get the compilation unit - assume not null
+    while (node is! CompilationUnit) {
+      node = node.parent;
+    }
+    var unit = node as CompilationUnit;
+
+    // Find an existing import
+    for (var directive in unit.directives) {
+      if (directive is ImportDirective) {
+        if (directive.uri.stringValue == importPath) {
+          return;
+        }
+      }
+    }
+
+    // Add the usage to an existing modification if possible
+    for (var modification in (_potentialModifications[source] ??= [])) {
+      if (modification is PotentiallyAddImport) {
+        if (modification.importPath == importPath) {
+          modification.addUsage(usage);
+          return;
+        }
+      }
+    }
+
+    // Create a new import modification
+    AstNode beforeNode;
+    for (var directive in unit.directives) {
+      if (directive is ImportDirective || directive is ExportDirective) {
+        beforeNode = directive;
+        break;
+      }
+    }
+    if (beforeNode == null) {
+      for (var declaration in unit.declarations) {
+        beforeNode = declaration;
+        break;
+      }
+    }
     _addPotentialModification(
-        source, PotentiallyAddRequired(parameter, variable));
+        source, PotentiallyAddImport(beforeNode, importPath, usage));
   }
 
   void _addPotentialModification(
diff --git a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
index 1add712..b587e33 100644
--- a/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
+++ b/pkg/analysis_server/lib/src/nullability/unit_propagation.dart
@@ -66,7 +66,7 @@
 
   /// The value assigned to this constraint variable by the solution currently
   /// being computed.
-  get value => _value;
+  bool get value => _value;
 
   @override
   String toString() =>
diff --git a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
index 7da4335..693b94e 100644
--- a/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
+++ b/pkg/analysis_server/lib/src/services/completion/token_details/token_detail_builder.dart
@@ -6,6 +6,8 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/ast/syntactic_entity.dart';
 import 'package:analyzer/dart/ast/token.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
 
 /// An object used to build the details for each token in the code being
 /// analyzed.
@@ -21,15 +23,29 @@
   void visitNode(AstNode node) {
     for (SyntacticEntity entity in node.childEntities) {
       if (entity is Token) {
-        _createDetails(entity, null);
+        _createDetails(entity, null, null);
       } else if (entity is SimpleIdentifier) {
+        String type = _getType(entity);
+        if (_isTypeName(entity)) {
+          type = 'dart:core;Type<$type>';
+        }
         List<String> kinds = [];
         if (entity.inDeclarationContext()) {
           kinds.add('declaration');
         } else {
-          kinds.add('identifier');
+          kinds.add('reference');
         }
-        _createDetails(entity.token, kinds);
+        _createDetails(entity.token, type, kinds);
+      } else if (entity is BooleanLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is DoubleLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is IntegerLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is SimpleStringLiteral) {
+        _createDetails(entity.literal, _getType(entity), null);
+      } else if (entity is Comment) {
+        // Ignore comments and the references within them.
       } else if (entity is AstNode) {
         visitNode(entity);
       }
@@ -37,8 +53,68 @@
   }
 
   /// Create the details for a single [token], using the given list of [kinds].
-  void _createDetails(Token token, List<String> kinds) {
-    details.add(new TokenDetails(token.lexeme, token.type.name,
-        validElementKinds: kinds));
+  void _createDetails(Token token, String type, List<String> kinds) {
+    details.add(
+        new TokenDetails(token.lexeme, type: type, validElementKinds: kinds));
+  }
+
+  /// Return a unique identifier for the type of the given [expression].
+  String _getType(Expression expression) {
+    StringBuffer buffer = new StringBuffer();
+    _writeType(buffer, expression.staticType);
+    return buffer.toString();
+  }
+
+  /// Return `true` if the [identifier] represents the name of a type.
+  bool _isTypeName(SimpleIdentifier identifier) {
+    AstNode parent = identifier.parent;
+    if (parent is TypeName && identifier == parent.name) {
+      return true;
+    } else if (parent is PrefixedIdentifier &&
+        parent.identifier == identifier) {
+      AstNode parent2 = parent.parent;
+      if (parent2 is TypeName && parent == parent2.name) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /// Return a unique identifier for the type of the given [expression].
+  void _writeType(StringBuffer buffer, DartType type) {
+    if (type == null) {
+      // This should never happen if the AST has been resolved.
+      buffer.write('dynamic');
+    } else if (type is FunctionType) {
+      _writeType(buffer, type.returnType);
+      buffer.write(' Function(');
+      bool first = true;
+      for (var parameter in type.parameters) {
+        if (first) {
+          first = false;
+        } else {
+          buffer.write(', ');
+        }
+        _writeType(buffer, parameter.type);
+      }
+      buffer.write(')');
+    } else if (type is InterfaceType) {
+      Element element = type.element;
+      if (element == null || element.isSynthetic) {
+        buffer.write(type.displayName);
+      } else {
+        String uri = element.library.source.uri.toString();
+        String name = element.name;
+        if (element is ClassMemberElement) {
+          String className = element.enclosingElement.name;
+          buffer.write('$uri;$className;$name');
+        } else {
+          buffer.write('$uri;$name');
+        }
+      }
+    } else {
+      // Handle `void` and `dynamic`.
+      buffer.write(type.displayName);
+    }
   }
 }
diff --git a/pkg/analysis_server/lib/src/services/correction/assist.dart b/pkg/analysis_server/lib/src/services/correction/assist.dart
index bb459c1..5f64118 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist.dart
@@ -88,8 +88,16 @@
       'dart.assist.convert.toConstructorFieldParameter',
       30,
       "Convert to field formal parameter");
+  static const CONVERT_TO_FOR_ELEMENT = const AssistKind(
+      'dart.assist.convertToForElement', 30, "Convert to a 'for' element",
+      associatedErrorCodes: <String>[
+        'prefer_for_elements_to_map_fromIterable'
+      ]);
   static const CONVERT_TO_IF_ELEMENT = const AssistKind(
-      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element");
+      'dart.assist.convertToIfElement', 30, "Convert to an 'if' element",
+      associatedErrorCodes: <String>[
+        'prefer_if_elements_to_conditional_expressions'
+      ]);
   static const CONVERT_TO_INT_LITERAL = const AssistKind(
       'dart.assist.convert.toIntLiteral', 30, "Convert to an int literal",
       associatedErrorCodes: <String>['prefer_int_literals']);
@@ -122,7 +130,8 @@
       "Convert to single quoted string",
       associatedErrorCodes: <String>['prefer_single_quotes']);
   static const CONVERT_TO_SPREAD = const AssistKind(
-      'dart.assist.convertToSpread', 30, "Convert to a spread");
+      'dart.assist.convertToSpread', 30, "Convert to a spread",
+      associatedErrorCodes: <String>['spread_collections']);
   static const ENCAPSULATE_FIELD =
       const AssistKind('dart.assist.encapsulateField', 30, "Encapsulate field");
   static const EXCHANGE_OPERANDS =
diff --git a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
index b373465..64d8880 100644
--- a/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/assist_internal.dart
@@ -150,7 +150,7 @@
 
     if (experimentStatus.control_flow_collections) {
       await _addProposal_convertConditionalExpressionToIfElement();
-      await _addProposal_convertMapFromIterableToIfLiteral();
+      await _addProposal_convertMapFromIterableToForLiteral();
     }
     if (experimentStatus.spread_collections) {
       await _addProposal_convertAddAllToSpread();
@@ -169,6 +169,18 @@
       await _addProposal_convertClassToMixin();
     } else if (assistKind == DartAssistKind.CONVERT_TO_INT_LITERAL) {
       await _addProposal_convertToIntLiteral();
+    } else if (assistKind == DartAssistKind.CONVERT_TO_SPREAD) {
+      if (experimentStatus.spread_collections) {
+        await _addProposal_convertAddAllToSpread();
+      }
+    } else if (assistKind == DartAssistKind.CONVERT_TO_FOR_ELEMENT) {
+      if (experimentStatus.control_flow_collections) {
+        await _addProposal_convertMapFromIterableToForLiteral();
+      }
+    } else if (assistKind == DartAssistKind.CONVERT_TO_IF_ELEMENT) {
+      if (experimentStatus.control_flow_collections) {
+        await _addProposal_convertConditionalExpressionToIfElement();
+      }
     }
     return assists;
   }
@@ -484,7 +496,13 @@
     elementText ??= '...${utils.getNodeText(argument)}';
     DartChangeBuilder changeBuilder = _newDartChangeBuilder();
     await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
-      builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      // ['a']..addAll(['b', 'c']);
+      if (list.elements.isNotEmpty) {
+        builder.addSimpleInsertion(list.elements.last.end, ', $elementText');
+      } else {
+        //
+        builder.addSimpleInsertion(list.leftBracket.end, elementText);
+      } // []..addAll(['b', 'c']);
       builder.addDeletion(range.node(invocation));
     });
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_SPREAD);
@@ -547,8 +565,8 @@
   }
 
   Future<void> _addProposal_convertConditionalExpressionToIfElement() async {
-    AstNode node = this.node;
-    if (node is! ConditionalExpression) {
+    AstNode node = this.node.thisOrAncestorOfType<ConditionalExpression>();
+    if (node == null) {
       _coverageMarker();
       return;
     }
@@ -923,7 +941,7 @@
     _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_MAP_LITERAL);
   }
 
-  Future<void> _addProposal_convertMapFromIterableToIfLiteral() async {
+  Future<void> _addProposal_convertMapFromIterableToForLiteral() async {
     //
     // Ensure that the selection is inside an invocation of Map.fromIterable.
     //
@@ -1077,7 +1095,7 @@
         builder.write(' }');
       });
     });
-    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_IF_ELEMENT);
+    _addAssistFromBuilder(changeBuilder, DartAssistKind.CONVERT_TO_FOR_ELEMENT);
   }
 
   Future<void> _addProposal_convertPartOfToUri() async {
diff --git a/pkg/analysis_server/lib/src/services/correction/fix.dart b/pkg/analysis_server/lib/src/services/correction/fix.dart
index b800b5d..3c54bcb 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix.dart
@@ -11,9 +11,7 @@
 import 'package:analyzer_plugin/utilities/change_builder/change_workspace.dart';
 import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
 
-/**
- * Return true if this [errorCode] is likely to have a fix associated with it.
- */
+/// Return true if this [errorCode] is likely to have a fix associated with it.
 bool hasFix(ErrorCode errorCode) =>
     errorCode == StaticWarningCode.UNDEFINED_CLASS_BOOLEAN ||
     errorCode == StaticWarningCode.CONCRETE_CLASS_WITH_ABSTRACT_MEMBER ||
@@ -103,9 +101,14 @@
             errorCode.name == LintNames.unnecessary_this ||
             errorCode.name == LintNames.use_rethrow_when_possible));
 
-/**
- * The implementation of [DartFixContext].
- */
+/// An enumeration of quick fix kinds for the errors found in an analysis
+/// options file.
+class AnalysisOptionsFixKind {
+  static const REMOVE_SETTING =
+      const FixKind('REMOVE_SETTING', 50, "Remove '{0}'");
+}
+
+/// The implementation of [DartFixContext].
 class DartFixContextImpl implements DartFixContext {
   @override
   final ChangeWorkspace workspace;
@@ -119,9 +122,7 @@
   DartFixContextImpl(this.workspace, this.resolveResult, this.error);
 }
 
-/**
- * An enumeration of possible quick fix kinds.
- */
+/// An enumeration of quick fix kinds found in a Dart file.
 class DartFixKind {
   static const ADD_ASYNC =
       const FixKind('ADD_ASYNC', 50, "Add 'async' modifier");
@@ -304,6 +305,10 @@
       'REPLACE_WITH_CONDITIONAL_ASSIGNMENT', 50, "Replace with ??=");
   static const REPLACE_WITH_IDENTIFIER =
       const FixKind('REPLACE_WITH_IDENTIFIER', 50, "Replace with identifier");
+  static const REPLACE_WITH_IS_EMPTY =
+      const FixKind('REPLACE_WITH_IS_EMPTY', 50, "Replace with 'isEmpty'");
+  static const REPLACE_WITH_IS_NOT_EMPTY = const FixKind(
+      'REPLACE_WITH_IS_NOT_EMPTY', 50, "Replace with 'isNotEmpty'");
   static const REPLACE_WITH_NULL_AWARE = const FixKind(
       'REPLACE_WITH_NULL_AWARE',
       50,
diff --git a/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
new file mode 100644
index 0000000..f558372
--- /dev/null
+++ b/pkg/analysis_server/lib/src/services/correction/fix/analysis_options/fix_generator.dart
@@ -0,0 +1,238 @@
+// 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:math' as math;
+
+import 'package:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/strings.dart';
+import 'package:analyzer/error/error.dart';
+import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/source/source_range.dart';
+import 'package:analyzer/src/analysis_options/error/option_codes.dart';
+import 'package:analyzer/src/generated/java_core.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show SourceChange;
+import 'package:analyzer_plugin/utilities/change_builder/change_builder_core.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:meta/meta.dart';
+import 'package:source_span/src/span.dart';
+import 'package:yaml/yaml.dart';
+
+/// The generator used to generate fixes in analysis options files.
+class AnalysisOptionsFixGenerator {
+  final AnalysisError error;
+
+  final int errorOffset;
+
+  final int errorLength;
+
+  final String content;
+
+  final YamlMap options;
+
+  final LineInfo lineInfo;
+
+  final List<Fix> fixes = <Fix>[];
+
+  List<YamlNode> coveringNodePath;
+
+  AnalysisOptionsFixGenerator(this.error, this.content, this.options)
+      : errorOffset = error.offset,
+        errorLength = error.length,
+        lineInfo = new LineInfo.fromContent(content);
+
+  /// Return the absolute, normalized path to the file in which the error was
+  /// reported.
+  String get file => error.source.fullName;
+
+  /// Return the list of fixes that apply to the error being fixed.
+  Future<List<Fix>> computeFixes() async {
+    YamlNodeLocator locator = new YamlNodeLocator(
+        start: errorOffset, end: errorOffset + errorLength - 1);
+    coveringNodePath = locator.searchWithin(options);
+    if (coveringNodePath.isEmpty) {
+      return fixes;
+    }
+
+    ErrorCode errorCode = error.errorCode;
+//    if (errorCode == AnalysisOptionsErrorCode.INCLUDED_FILE_PARSE_ERROR) {
+//    } else if (errorCode == AnalysisOptionsErrorCode.PARSE_ERROR) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.DEPRECATED_ANALYSIS_OPTIONS_FILE_NAME) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.PREVIEW_DART_2_SETTING_DEPRECATED) {
+//    } else if (errorCode ==
+//        AnalysisOptionsHintCode.STRONG_MODE_SETTING_DEPRECATED) {
+//    } else
+    if (errorCode == AnalysisOptionsHintCode.SUPER_MIXINS_SETTING_DEPRECATED) {
+      await _addFix_removeSetting();
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.ANALYSIS_OPTION_DEPRECATED) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDED_FILE_WARNING) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INCLUDE_FILE_NOT_FOUND) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INVALID_OPTION) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.INVALID_SECTION_FORMAT) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.SPEC_MODE_REMOVED) {
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNRECOGNIZED_ERROR_CODE) {
+    } else if (errorCode ==
+        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITHOUT_VALUES) {
+      await _addFix_removeSetting();
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE) {
+//    } else if (errorCode ==
+//        AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUES) {
+//    } else if (errorCode == AnalysisOptionsWarningCode.UNSUPPORTED_VALUE) {
+    }
+    return fixes;
+  }
+
+  void _addFix_removeSetting() async {
+    if (coveringNodePath[0] is YamlScalar) {
+      SourceRange deletionRange;
+      int index = 1;
+      while (index < coveringNodePath.length) {
+        YamlNode parent = coveringNodePath[index];
+        if (parent is YamlList) {
+          if (parent.nodes.length > 1) {
+            YamlNode nodeToDelete = coveringNodePath[index - 1];
+            deletionRange = _lines(
+                nodeToDelete.span.start.offset, nodeToDelete.span.end.offset);
+            break;
+          }
+        } else if (parent is YamlMap) {
+          Map<dynamic, YamlNode> nodes = parent.nodes;
+          if (nodes.length > 1) {
+            YamlNode key;
+            YamlNode value;
+            YamlNode child = coveringNodePath[index - 1];
+            if (nodes.containsKey(child)) {
+              key = child;
+              value = nodes[child];
+            } else if (nodes.containsValue(child)) {
+              for (var entry in nodes.entries) {
+                if (child == entry.value) {
+                  key = entry.key;
+                  value = child;
+                  break;
+                }
+              }
+            }
+            if (key == null || value == null) {
+              throw StateError(
+                  'Child is neither a key nor a value in the parent');
+            }
+            deletionRange = _lines(key.span.start.offset,
+                _firstNonWhitespaceBefore(value.span.end.offset));
+            break;
+          }
+        } else if (parent is YamlDocument) {
+          break;
+        }
+        index++;
+      }
+      YamlNode nodeToDelete = coveringNodePath[index - 1];
+      deletionRange ??=
+          _lines(nodeToDelete.span.start.offset, nodeToDelete.span.end.offset);
+      ChangeBuilder builder = new ChangeBuilder();
+      await builder.addFileEdit(file, (builder) {
+        builder.addDeletion(deletionRange);
+      });
+      _addFixFromBuilder(builder, AnalysisOptionsFixKind.REMOVE_SETTING,
+          args: [coveringNodePath[0].toString()]);
+    }
+  }
+
+  /// Add a fix whose edits were built by the [builder] that has the given
+  /// [kind]. If [args] are provided, they will be used to fill in the message
+  /// for the fix.
+  void _addFixFromBuilder(ChangeBuilder builder, FixKind kind,
+      {List args: null}) {
+    SourceChange change = builder.sourceChange;
+    if (change.edits.isEmpty) {
+      return;
+    }
+    change.message = formatList(kind.message, args);
+    fixes.add(new Fix(kind, change));
+  }
+
+  int _firstNonWhitespaceBefore(int offset) {
+    while (offset > 0 && isWhitespace(content.codeUnitAt(offset - 1))) {
+      offset--;
+    }
+    return offset;
+  }
+
+  SourceRange _lines(int start, int end) {
+    CharacterLocation startLocation = lineInfo.getLocation(start);
+    int startOffset = lineInfo.getOffsetOfLine(startLocation.lineNumber - 1);
+    CharacterLocation endLocation = lineInfo.getLocation(end);
+    int endOffset = lineInfo.getOffsetOfLine(
+        math.min(endLocation.lineNumber, lineInfo.lineCount - 1));
+    return new SourceRange(startOffset, endOffset - startOffset);
+  }
+}
+
+/// An object used to locate the [YamlNode] associated with a source range.
+/// More specifically, it will return the deepest [YamlNode] which completely
+/// encompasses the specified range.
+class YamlNodeLocator {
+  /// The inclusive start offset of the range used to identify the node.
+  int _startOffset = 0;
+
+  /// The inclusive end offset of the range used to identify the node.
+  int _endOffset = 0;
+
+  /// Initialize a newly created locator to locate the deepest [YamlNode] for
+  /// which `node.offset <= [start]` and `[end] < node.end`.
+  ///
+  /// If the [end] offset is not provided, then it is considered the same as the
+  /// [start] offset.
+  YamlNodeLocator({@required int start, int end})
+      : this._startOffset = start,
+        this._endOffset = end ?? start;
+
+  /// Search within the given Yaml [node] and return the path to the most deeply
+  /// nested node that includes the whole target range, or an empty list if no
+  /// node was found. The path is represented by all of the elements from the
+  /// starting [node] to the most deeply nested node, in reverse order.
+  List<YamlNode> searchWithin(YamlNode node) {
+    List<YamlNode> path = [];
+    _searchWithin(path, node);
+    return path;
+  }
+
+  void _searchWithin(List<YamlNode> path, YamlNode node) {
+    SourceSpan span = node.span;
+    if (span.start.offset > _endOffset || span.end.offset < _startOffset) {
+      return;
+    }
+    if (node is YamlList) {
+      for (YamlNode element in node.nodes) {
+        _searchWithin(path, element);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+      }
+    } else if (node is YamlMap) {
+      Map<dynamic, YamlNode> nodeMap = node.nodes;
+      for (YamlNode key in nodeMap.keys) {
+        _searchWithin(path, key);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+        _searchWithin(path, nodeMap[key]);
+        if (path.isNotEmpty) {
+          path.add(node);
+          return;
+        }
+      }
+    }
+    path.add(node);
+  }
+}
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 05d16f0..e605378 100644
--- a/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
+++ b/pkg/analysis_server/lib/src/services/correction/fix_internal.dart
@@ -621,6 +621,9 @@
       if (name == LintNames.prefer_final_locals) {
         await _addFix_makeVariableFinal();
       }
+      if (name == LintNames.prefer_is_empty) {
+        await _addFix_replaceWithIsEmpty();
+      }
       if (name == LintNames.prefer_is_not_empty) {
         await _addFix_isNotEmpty();
       }
@@ -1146,7 +1149,7 @@
           sessionHelper,
           namedExpression.parent.parent,
         );
-        return parameters.namedNames;
+        return parameters?.namedNames;
       }
       return null;
     }
@@ -2373,7 +2376,8 @@
         DartFixKind.IMPORT_ASYNC, Uri.parse('dart:async'));
   }
 
-  Future<void> _addFix_importLibrary(FixKind kind, Uri library) async {
+  Future<void> _addFix_importLibrary(FixKind kind, Uri library,
+      [String relativeURI = null]) async {
     // TODO(brianwilkerson) Determine whether this await is necessary.
     await null;
     String uriText;
@@ -2382,6 +2386,16 @@
       uriText = builder.importLibrary(library);
     });
     _addFixFromBuilder(changeBuilder, kind, args: [uriText]);
+
+    if (relativeURI != null && relativeURI.isNotEmpty) {
+      var changeBuilder2 = _newDartChangeBuilder();
+      await changeBuilder2.addFileEdit(file, (DartFileEditBuilder builder) {
+        if (builder is DartFileEditBuilderImpl) {
+          builder.importLibraryWithRelativeUri(relativeURI);
+        }
+      });
+      _addFixFromBuilder(changeBuilder2, kind, args: [relativeURI]);
+    }
   }
 
   Future<void> _addFix_importLibrary_withElement(
@@ -2486,7 +2500,9 @@
           fixKind = DartFixKind.IMPORT_LIBRARY_PROJECT1;
         }
         // Add the fix.
-        await _addFix_importLibrary(fixKind, librarySource.uri);
+        var relativeURI =
+            _getRelativeURIFromLibrary(unitLibraryElement, librarySource);
+        await _addFix_importLibrary(fixKind, librarySource.uri, relativeURI);
       }
     }
   }
@@ -3392,6 +3408,100 @@
     }
   }
 
+  Future<void> _addFix_replaceWithIsEmpty() async {
+    /// Return the value of an integer literal or prefix expression with a
+    /// minus and then an integer literal. For anything else, returns `null`.
+    int getIntValue(Expression expressions) {
+      // Copied from package:linter/src/rules/prefer_is_empty.dart.
+      if (expressions is IntegerLiteral) {
+        return expressions.value;
+      } else if (expressions is PrefixExpression) {
+        var operand = expressions.operand;
+        if (expressions.operator.type == TokenType.MINUS &&
+            operand is IntegerLiteral) {
+          return -operand.value;
+        }
+      }
+      return null;
+    }
+
+    /// Return the expression producing the object on which `length` is being
+    /// invoked, or `null` if there is no such expression.
+    Expression getLengthTarget(Expression expression) {
+      if (expression is PropertyAccess &&
+          expression.propertyName.name == 'length') {
+        return expression.target;
+      } else if (expression is PrefixedIdentifier &&
+          expression.identifier.name == 'length') {
+        return expression.prefix;
+      }
+      return null;
+    }
+
+    BinaryExpression binary = node.thisOrAncestorOfType();
+    TokenType operator = binary.operator.type;
+    String getter;
+    FixKind kind;
+    Expression lengthTarget;
+    int rightValue = getIntValue(binary.rightOperand);
+    if (rightValue != null) {
+      lengthTarget = getLengthTarget(binary.leftOperand);
+      if (rightValue == 0) {
+        if (operator == TokenType.EQ_EQ || operator == TokenType.LT_EQ) {
+          getter = 'isEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+        } else if (operator == TokenType.GT || operator == TokenType.BANG_EQ) {
+          getter = 'isNotEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+        }
+      } else if (rightValue == 1) {
+        // 'length >= 1' is same as 'isNotEmpty',
+        // and 'length < 1' is same as 'isEmpty'
+        if (operator == TokenType.GT_EQ) {
+          getter = 'isNotEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+        } else if (operator == TokenType.LT) {
+          getter = 'isEmpty';
+          kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+        }
+      }
+    } else {
+      int leftValue = getIntValue(binary.leftOperand);
+      if (leftValue != null) {
+        lengthTarget = getLengthTarget(binary.rightOperand);
+        if (leftValue == 0) {
+          if (operator == TokenType.EQ_EQ || operator == TokenType.GT_EQ) {
+            getter = 'isEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          } else if (operator == TokenType.LT ||
+              operator == TokenType.BANG_EQ) {
+            getter = 'isNotEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          }
+        } else if (leftValue == 1) {
+          // '1 <= length' is same as 'isNotEmpty',
+          // and '1 > length' is same as 'isEmpty'
+          if (operator == TokenType.LT_EQ) {
+            getter = 'isNotEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+          } else if (operator == TokenType.GT) {
+            getter = 'isEmpty';
+            kind = DartFixKind.REPLACE_WITH_IS_EMPTY;
+          }
+        }
+      }
+    }
+    if (lengthTarget == null || getter == null || kind == null) {
+      return;
+    }
+    String target = utils.getNodeText(lengthTarget);
+    DartChangeBuilder changeBuilder = _newDartChangeBuilder();
+    await changeBuilder.addFileEdit(file, (DartFileEditBuilder builder) {
+      builder.addSimpleReplacement(range.node(binary), '$target.$getter');
+    });
+    _addFixFromBuilder(changeBuilder, kind);
+  }
+
   Future<void> _addFix_replaceWithRethrow() async {
     if (coveredNode is ThrowExpression) {
       var changeBuilder = _newDartChangeBuilder();
@@ -4134,6 +4244,27 @@
   }
 
   /**
+   * Return the relative uri from the passed [library] to the passed
+   * [source]. If the [source] is not in the LibraryElement, `null` is returned.
+   */
+  String _getRelativeURIFromLibrary(LibraryElement library, Source source) {
+    var librarySource = library?.librarySource;
+    if (librarySource == null) {
+      return null;
+    }
+    var pathCtx = resourceProvider.pathContext;
+    var libraryDirectory = pathCtx.dirname(librarySource.fullName);
+    var sourceDirectory = pathCtx.dirname(source.fullName);
+    if (pathCtx.isWithin(libraryDirectory, source.fullName) ||
+        pathCtx.isWithin(sourceDirectory, libraryDirectory)) {
+      String relativeFile =
+          pathCtx.relative(source.fullName, from: libraryDirectory);
+      return pathCtx.split(relativeFile).join('/');
+    }
+    return null;
+  }
+
+  /**
    * Returns an expected [DartType] of [expression], may be `null` if cannot be
    * inferred.
    */
@@ -4485,6 +4616,7 @@
       'prefer_equal_for_default_values';
   static const String prefer_final_fields = 'prefer_final_fields';
   static const String prefer_final_locals = 'prefer_final_locals';
+  static const String prefer_is_empty = 'prefer_is_empty';
   static const String prefer_is_not_empty = 'prefer_is_not_empty';
   static const String type_init_formals = 'type_init_formals';
   static const String unawaited_futures = 'unawaited_futures';
@@ -4541,11 +4673,15 @@
   factory _ExecutableParameters(
       AnalysisSessionHelper sessionHelper, AstNode invocation) {
     Element element;
-    if (invocation is InstanceCreationExpression) {
+    // This doesn't handle FunctionExpressionInvocation.
+    if (invocation is Annotation) {
+      element = invocation.element;
+    } else if (invocation is InstanceCreationExpression) {
       element = invocation.staticElement;
-    }
-    if (invocation is MethodInvocation) {
+    } else if (invocation is MethodInvocation) {
       element = invocation.methodName.staticElement;
+    } else if (invocation is ConstructorReferenceNode) {
+      element = invocation.staticElement;
     }
     if (element is ExecutableElement && !element.isSynthetic) {
       return new _ExecutableParameters._(sessionHelper, element);
diff --git a/pkg/analysis_server/lib/src/status/diagnostics.dart b/pkg/analysis_server/lib/src/status/diagnostics.dart
index 57c725a..2723c18 100644
--- a/pkg/analysis_server/lib/src/status/diagnostics.dart
+++ b/pkg/analysis_server/lib/src/status/diagnostics.dart
@@ -40,6 +40,7 @@
 import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/source/sdk_ext.dart';
 import 'package:path/path.dart' as pathPackage;
+import 'package:analyzer/src/dartdoc/dartdoc_directive_info.dart';
 
 final String kCustomCss = '''
 .lead, .page-title+.markdown-body>p:first-child {
@@ -174,9 +175,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     List<CompletionPerformance> completions = performanceItems;
 
     if (completions.isEmpty) {
@@ -246,8 +244,6 @@
 
   @override
   Future<void> generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = params['file'];
     if (path == null) {
       p('No file path provided.');
@@ -274,8 +270,6 @@
 
   @override
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       _description = params['file'];
       await super.generatePage(params);
@@ -293,9 +287,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     void writeRow(List<String> data, {List<String> classes}) {
       buf.write("<tr>");
       for (int i = 0; i < data.length; i++) {
@@ -420,8 +411,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     Map<Folder, AnalysisDriver> driverMap = server.driverMap;
     if (driverMap.isEmpty) {
       blankslate('No contexts.');
@@ -560,6 +549,13 @@
         buf.write('</p>');
       }
     }
+
+    h3('Dartdoc template info');
+    DartdocDirectiveInfo info = (server as AnalysisServer).declarationsTracker
+        ?.getContext(driver.analysisContext)
+        ?.dartdocDirectiveInfo ??
+        new DartdocDirectiveInfo();
+    writeMap(info.templateMap);
   }
 
   void writeList<E>(List<E> list) {
@@ -600,14 +596,10 @@
   AbstractAnalysisServer get server => site.socketServer.analysisServer;
 
   Future<void> generateContainer(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<div class="columns docs-layout">');
     buf.writeln('<div class="three-fourths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       p(description);
       await generateContent(params);
     }, classes: 'markdown-body');
@@ -646,8 +638,6 @@
   }
 
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<!DOCTYPE html><html lang="en">');
     buf.write('<head>');
     buf.write('<meta charset="utf-8">');
@@ -686,8 +676,6 @@
   bool get showInNav => true;
 
   Future<void> generateContainer(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<div class="columns docs-layout">');
 
     bool shouldShowInNav(Page page) {
@@ -711,8 +699,6 @@
     buf.writeln('<div class="four-fifths column markdown-body">');
     h1(title, classes: 'page-title');
     await asyncDiv(() async {
-      // TODO(brianwilkerson) Determine whether this await is necessary.
-      await null;
       p(description);
       await generateContent(params);
     }, classes: 'markdown-body');
@@ -792,8 +778,6 @@
 
   @override
   Future<void> generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     String path = params['file'];
     if (path == null) {
       p('No file path provided.');
@@ -820,8 +804,6 @@
 
   @override
   Future<void> generatePage(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     try {
       _description = params['file'];
       await super.generatePage(params);
@@ -839,8 +821,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     buf.writeln('<table>');
     buf.writeln('<tr><th>Variable</th><th>Value</th></tr>');
     for (String key in Platform.environment.keys.toList()..sort()) {
@@ -858,8 +838,6 @@
       : super(site, '', '500 Oops', description: message);
 
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     p(trace.toString(), style: 'white-space: pre');
   }
 }
@@ -875,8 +853,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     if (exceptions.isEmpty) {
       blankslate('No exceptions encountered!');
     } else {
@@ -899,12 +875,10 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     final String issuesUrl = 'https://github.com/dart-lang/sdk/issues';
     p(
       'To file issues or feature requests, see our '
-          '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:',
+      '<a href="$issuesUrl">bug tracker</a>. When filing an issue, please describe:',
       raw: true,
     );
     ul([
@@ -941,8 +915,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     p(
         'Instrumentation can be enabled by starting the analysis server with the '
         '<code>--instrumentation-log-file=path/to/file</code> flag.',
@@ -1025,8 +997,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     UsageInfo usage = await profiler.getProcessUsage(pid);
 
     developer.ServiceProtocolInfo serviceProtocolInfo =
@@ -1090,8 +1060,6 @@
       : super(site, '', '404 Not found', description: "'$path' not found.");
 
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
   }
 }
 
@@ -1181,8 +1149,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
     h3('Profiling performance tag data');
 
     // prepare sorted tags
@@ -1330,9 +1296,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     buf.writeln('<div class="columns">');
 
     buf.writeln('<div class="column one-half">');
@@ -1369,9 +1332,6 @@
 
   @override
   Future generateContent(Map<String, String> params) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-
     // server domain
     h3('Server domain subscriptions');
     ul(ServerService.VALUES, (item) {
@@ -1390,5 +1350,18 @@
         buf.write('$item');
       });
     }
+
+    // completion domain
+    CompletionDomainHandler handler = server.handlers.firstWhere(
+        (handler) => handler is CompletionDomainHandler,
+        orElse: () => null);
+    h3('Completion domain subscriptions');
+    ul(CompletionService.VALUES, (service) {
+      if (handler.subscriptions.contains(service)) {
+        buf.write('$service (has subscriptions)');
+      } else {
+        buf.write('$service (no subscriptions)');
+      }
+    });
   }
 }
diff --git a/pkg/analysis_server/test/completion_test_support.dart b/pkg/analysis_server/test/completion_test_support.dart
index 0af04a9..8588391 100644
--- a/pkg/analysis_server/test/completion_test_support.dart
+++ b/pkg/analysis_server/test/completion_test_support.dart
@@ -13,7 +13,7 @@
 /**
  * A base class for classes containing completion tests.
  */
-class CompletionTestCase extends CompletionDomainHandlerTest {
+class CompletionTestCase extends CompletionDomainHandlerListTokenDetailsTest {
   static const String CURSOR_MARKER = '!';
 
   List get suggestedCompletions => suggestions
diff --git a/pkg/analysis_server/test/domain_completion_test.dart b/pkg/analysis_server/test/domain_completion_test.dart
index c98af16..3f0e266 100644
--- a/pkg/analysis_server/test/domain_completion_test.dart
+++ b/pkg/analysis_server/test/domain_completion_test.dart
@@ -24,7 +24,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CompletionDomainHandlerGetSuggestionsTest);
-    defineReflectiveTests(CompletionDomainHandlerTest);
+    defineReflectiveTests(CompletionDomainHandlerListTokenDetailsTest);
   });
 }
 
@@ -866,77 +866,348 @@
 }
 
 @reflectiveTest
-class CompletionDomainHandlerTest extends AbstractCompletionDomainTest {
-  test_listTokenDetails() async {
-    newFile(testFile, content: '''
-class A {
-  static A b(String s) {}
-  c(int i) {}
-}
-main() {
-  A.b('s').c(3);
-}
-''');
+class CompletionDomainHandlerListTokenDetailsTest
+    extends AbstractCompletionDomainTest {
+  String testFileUri;
+
+  void expectTokens(String content, List<TokenDetails> expectedTokens) async {
+    newFile(testFile, content: content);
     Request request =
         new CompletionListTokenDetailsParams(testFile).toRequest('0');
     Response response = await waitResponse(request);
     List<Map<String, dynamic>> tokens = response.result['tokens'];
-    _expectTokens(tokens, [
-      _token('class', 'CLASS', null),
-      _token('A', 'STRING_INT', ['declaration']),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('static', 'STATIC', null),
-      _token('A', 'STRING_INT', ['identifier']),
-      _token('b', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('String', 'STRING_INT', ['identifier']),
-      _token('s', 'STRING_INT', ['declaration']),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('c', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('int', 'STRING_INT', ['identifier']),
-      _token('i', 'STRING_INT', ['declaration']),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
-      _token('main', 'STRING_INT', ['declaration']),
-      _token('(', 'OPEN_PAREN', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('{', 'OPEN_CURLY_BRACKET', null),
-      _token('A', 'STRING_INT', ['identifier']),
-      _token('.', 'PERIOD', null),
-      _token('b', 'STRING_INT', ['identifier']),
-      _token('(', 'OPEN_PAREN', null),
-      _token("'s'", 'STRING', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token('.', 'PERIOD', null),
-      _token('c', 'STRING_INT', ['identifier']),
-      _token('(', 'OPEN_PAREN', null),
-      _token('3', 'INT', null),
-      _token(')', 'CLOSE_PAREN', null),
-      _token(';', 'SEMICOLON', null),
-      _token('}', 'CLOSE_CURLY_BRACKET', null),
+    _compareTokens(tokens, expectedTokens);
+  }
+
+  @override
+  void setUp() {
+    super.setUp();
+    testFileUri = toUriStr(testFile);
+  }
+
+  test_classDeclaration() async {
+    await expectTokens('''
+class A {}
+class B extends A {}
+class C implements B {}
+class D with C {}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('B', 'dart:core;Type', ['declaration']),
+      token('extends', null, null),
+      token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('C', 'dart:core;Type', ['declaration']),
+      token('implements', null, null),
+      token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('D', 'dart:core;Type', ['declaration']),
+      token('with', null, null),
+      token('C', 'dart:core;Type<$testFileUri;C>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
     ]);
   }
 
-  void _expectTokens(List<Map<String, dynamic>> actualTokens,
+  test_genericType() async {
+    await expectTokens('''
+List<int> x = null;
+''', [
+      token('List', 'dart:core;Type<dart:core;List>', ['reference']),
+      token('<', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('x', 'dart:core;List', ['declaration']),
+      token('=', null, null),
+      token('null', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_getterInvocation() async {
+    await expectTokens('''
+var x = 'a'.length;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token("'a'", 'dart:core;String', null),
+      token('.', null, null),
+      token('length', 'dart:core;int', ['reference']),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_bool() async {
+    await expectTokens('''
+var x = true;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;bool', ['declaration']),
+      token('=', null, null),
+      token('true', 'dart:core;bool', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_double() async {
+    await expectTokens('''
+var x = 3.4;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;double', ['declaration']),
+      token('=', null, null),
+      token('3.4', 'dart:core;double', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_int() async {
+    await expectTokens('''
+var x = 7;
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token('7', 'dart:core;int', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_list() async {
+    await expectTokens('''
+var x = <int>[];
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;List', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('[', null, null),
+      token(']', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_map() async {
+    await expectTokens('''
+var x = <int, int>{};
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;Map', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+//      token(',', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_null() async {
+    await expectTokens('''
+var x = null;
+''', [
+      token('var', null, null),
+      token('x', 'dynamic', ['declaration']),
+      token('=', null, null),
+      token('null', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_set() async {
+    await expectTokens('''
+var x = <int>{};
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;Set', ['declaration']),
+      token('=', null, null),
+      token('<', null, null),
+      token("int", 'dart:core;Type<dart:core;int>', ['reference']),
+      token('>', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_literal_string() async {
+    await expectTokens('''
+var x = 'a';
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;String', ['declaration']),
+      token('=', null, null),
+      token("'a'", 'dart:core;String', null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_methodDeclaration() async {
+    await expectTokens('''
+class A {
+  String c(int x, int y) {}
+}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('String', 'dart:core;Type<dart:core;String>', ['reference']),
+      token('c', 'dart:core;String Function(dart:core;int, dart:core;int)',
+          ['declaration']),
+      token('(', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('x', 'dart:core;int', ['declaration']),
+//      token(',', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('y', 'dart:core;int', ['declaration']),
+      token(')', null, null),
+      token('{', null, null),
+      token('}', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_methodInvocation() async {
+    await expectTokens('''
+var x = 'radar'.indexOf('r', 1);
+''', [
+      token('var', null, null),
+      token('x', 'dart:core;int', ['declaration']),
+      token('=', null, null),
+      token("'radar'", 'dart:core;String', null),
+      token('.', null, null),
+      token(
+          'indexOf',
+          'dart:core;int Function(dart:core;Pattern, dart:core;int)',
+          ['reference']),
+      token('(', null, null),
+      token("'r'", 'dart:core;String', null),
+//      token(',', null, null),
+      token('1', 'dart:core;int', null),
+      token(')', null, null),
+      token(';', null, null),
+    ]);
+  }
+
+  test_mixinDeclaration() async {
+    await expectTokens('''
+class A {}
+class B {}
+mixin D on A implements B {}
+''', [
+      token('class', null, null),
+      token('A', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('class', null, null),
+      token('B', 'dart:core;Type', ['declaration']),
+      token('{', null, null),
+      token('}', null, null),
+      token('mixin', null, null),
+      token('D', 'dart:core;Type', ['declaration']),
+      token('on', null, null),
+      token('A', 'dart:core;Type<$testFileUri;A>', ['reference']),
+      token('implements', null, null),
+      token('B', 'dart:core;Type<$testFileUri;B>', ['reference']),
+      token('{', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_parameterReference() async {
+    await expectTokens('''
+int f(int p) {
+  return p;
+}
+''', [
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('f', 'dart:core;int Function(dart:core;int)', ['declaration']),
+      token('(', null, null),
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('p', 'dart:core;int', ['declaration']),
+      token(')', null, null),
+      token('{', null, null),
+      token('return', null, null),
+      token('p', 'dart:core;int', ['reference']),
+      token(';', null, null),
+      token('}', null, null),
+    ]);
+  }
+
+  test_topLevelVariable_withDocComment() async {
+    await expectTokens('''
+/// Doc comment [x] with reference.
+int x;
+''', [
+      token('int', 'dart:core;Type<dart:core;int>', ['reference']),
+      token('x', 'dart:core;int', ['declaration']),
+      token(';', null, null),
+    ]);
+  }
+
+  TokenDetails token(String lexeme, String type, List<String> kinds) {
+    return new TokenDetails(lexeme, type: type, validElementKinds: kinds);
+  }
+
+  void _compareTokens(List<Map<String, dynamic>> actualTokens,
       List<TokenDetails> expectedTokens) {
     int length = expectedTokens.length;
     expect(actualTokens, hasLength(length));
+    List<String> errors = [];
     for (int i = 0; i < length; i++) {
       Map<String, dynamic> actual = actualTokens[i];
       TokenDetails expected = expectedTokens[i];
-      expect(actual['lexeme'], expected.lexeme);
-      expect(actual['type'], expected.type);
-      expect(actual['validElementKinds'], expected.validElementKinds);
+      if (actual['lexeme'] != expected.lexeme) {
+        errors.add('Lexeme at $i: '
+            'expected "${expected.lexeme}", '
+            'actual "${actual['lexeme']}"');
+      }
+      if (actual['type'] != expected.type) {
+        errors.add('Type at $i ("${expected.lexeme}"): '
+            'expected "${expected.type}", '
+            'actual "${actual['type']}"');
+      }
+      if (_differentKinds(
+          actual['validElementKinds'], expected.validElementKinds)) {
+        errors.add('Kinds at $i ("${expected.lexeme}"): '
+            'expected "${expected.validElementKinds}", '
+            'actual "${actual['validElementKinds']}"');
+      }
     }
+    expect(errors, isEmpty);
   }
 
-  TokenDetails _token(String lexeme, String type, List<String> kinds) {
-    return new TokenDetails(lexeme, type, validElementKinds: kinds);
+  /// Return `true` if the two lists of kinds are different.
+  bool _differentKinds(List<String> actual, List<String> expected) {
+    if (actual == null) {
+      return expected != null;
+    } else if (expected == null) {
+      return true;
+    }
+    int expectedLength = expected.length;
+    if (actual.length != expectedLength) {
+      return true;
+    }
+    for (int i = 0; i < expectedLength; i++) {
+      if (actual[i] != expected[i]) {
+        return true;
+      }
+    }
+    return false;
   }
 }
 
diff --git a/pkg/analysis_server/test/domain_edit_dartfix_test.dart b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
index 3f322e6..8a0e7b0 100644
--- a/pkg/analysis_server/test/domain_edit_dartfix_test.dart
+++ b/pkg/analysis_server/test/domain_edit_dartfix_test.dart
@@ -28,11 +28,12 @@
   void expectEdits(List<SourceFileEdit> fileEdits, String expectedSource) {
     expect(fileEdits, hasLength(1));
     expect(fileEdits[0].file, testFile);
-    List<SourceEdit> edits = fileEdits[0].edits;
-    String source = testCode;
-    for (SourceEdit edit in edits) {
-      source = edit.apply(source);
-    }
+    expectFileEdits(testCode, fileEdits[0], expectedSource);
+  }
+
+  void expectFileEdits(
+      String originalSource, SourceFileEdit fileEdit, String expectedSource) {
+    String source = SourceEdit.applySequence(originalSource, fileEdit.edits);
     expect(source, expectedSource);
   }
 
@@ -144,6 +145,78 @@
 ''');
   }
 
+  test_dartfix_non_nullable_analysis_options_created() async {
+    // Add pubspec for nnbd migration to detect
+    newFile('/project/pubspec.yaml', content: '''
+name: testnnbd
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits('', result.edits[0], '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+
+''');
+  }
+
+  test_dartfix_non_nullable_analysis_options_experiments_added() async {
+    String originalOptions = '''
+analyzer:
+  something:
+    - other
+
+linter:
+  - boo
+''';
+    newFile('/project/analysis_options.yaml', content: originalOptions);
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits(originalOptions, result.edits[0], '''
+analyzer:
+  something:
+    - other
+  enable-experiment:
+    - non-nullable
+
+linter:
+  - boo
+''');
+  }
+
+  test_dartfix_non_nullable_analysis_options_nnbd_added() async {
+    String originalOptions = '''
+analyzer:
+  enable-experiment:
+    - other
+linter:
+  - boo
+''';
+    newFile('/project/analysis_options.yaml', content: originalOptions);
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['non-nullable']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expect(result.edits, hasLength(1));
+    expectFileEdits(originalOptions, result.edits[0], '''
+analyzer:
+  enable-experiment:
+    - other
+    - non-nullable
+linter:
+  - boo
+''');
+  }
+
   test_dartfix_excludedSource() async {
     // Add analysis options to exclude the lib directory then reanalyze
     newFile('/project/analysis_options.yaml', content: '''
@@ -200,4 +273,77 @@
 const double myDouble = 42;
     ''');
   }
+
+  test_dartfix_spread_collections() async {
+    // Add analysis options to enable ui as code
+    newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+  enable-experiment:
+    - control-flow-collections
+    - spread-collections
+''');
+    addTestFile('''
+var l = ['a']..addAll(['b']);
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['use-spread-collections']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expectEdits(result.edits, '''
+var l = ['a', ...['b']];
+''');
+  }
+
+  test_dartfix_collection_if_elements() async {
+    // Add analysis options to enable ui as code
+    newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+  enable-experiment:
+    - control-flow-collections
+    - spread-collections
+''');
+    addTestFile('''
+f(bool b) {
+  return ['a', b ? 'c' : 'd', 'e'];
+}
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['collection-if-elements']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expectEdits(result.edits, '''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
+  test_dartfix_map_for_elements() async {
+    // Add analysis options to enable ui as code
+    newFile('/project/analysis_options.yaml', content: '''
+analyzer:
+  enable-experiment:
+    - control-flow-collections
+    - spread-collections
+''');
+    addTestFile('''
+f(Iterable<int> i) {
+  var k = 3;
+  return Map.fromIterable(i, key: (k) => k * 2, value: (v) => k);
+}
+''');
+    createProject();
+    EditDartfixResult result =
+        await performFix(includedFixes: ['map-for-elements']);
+    expect(result.suggestions.length, greaterThanOrEqualTo(1));
+    expect(result.hasErrors, isFalse);
+    expectEdits(result.edits, '''
+f(Iterable<int> i) {
+  var k = 3;
+  return { for (var e in i) e * 2 : k };
+}
+''');
+  }
 }
diff --git a/pkg/analysis_server/test/edit/test_all.dart b/pkg/analysis_server/test/edit/test_all.dart
index 79cc139..70251a6 100644
--- a/pkg/analysis_server/test/edit/test_all.dart
+++ b/pkg/analysis_server/test/edit/test_all.dart
@@ -4,24 +4,24 @@
 
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
-import 'assists_test.dart' as assists_test;
-import 'fixes_test.dart' as fixes_test;
-import 'format_test.dart' as format_test;
-import 'organize_directives_test.dart' as organize_directives_test;
-import 'postfix_completion_test.dart' as postfix_completion_test;
-import 'refactoring_test.dart' as refactoring_test;
-import 'sort_members_test.dart' as sort_members_test;
-import 'statement_completion_test.dart' as statement_completion_test;
+import 'assists_test.dart' as assists;
+import 'fixes_test.dart' as fixes;
+import 'format_test.dart' as format;
+import 'organize_directives_test.dart' as organize_directives;
+import 'postfix_completion_test.dart' as postfix_completion;
+import 'refactoring_test.dart' as refactoring;
+import 'sort_members_test.dart' as sort_members;
+import 'statement_completion_test.dart' as statement_completion;
 
 main() {
   defineReflectiveSuite(() {
-    assists_test.main();
-    fixes_test.main();
-    format_test.main();
-    organize_directives_test.main();
-    postfix_completion_test.main();
-    refactoring_test.main();
-    sort_members_test.main();
-    statement_completion_test.main();
+    assists.main();
+    fixes.main();
+    format.main();
+    organize_directives.main();
+    postfix_completion.main();
+    refactoring.main();
+    sort_members.main();
+    statement_completion.main();
   }, name: 'edit');
 }
diff --git a/pkg/analysis_server/test/integration/support/integration_test_methods.dart b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
index cfd4d3a..fe67037 100644
--- a/pkg/analysis_server/test/integration/support/integration_test_methods.dart
+++ b/pkg/analysis_server/test/integration/support/integration_test_methods.dart
@@ -2026,6 +2026,13 @@
    *
    *   The elements to be made accessible in the specified file.
    *
+   * offset: int (optional)
+   *
+   *   The offset at which the specified elements need to be made accessible.
+   *   If provided, this is used to guard against adding imports for text that
+   *   would be inserted into a comment, string literal, or other location
+   *   where the imports would not be necessary.
+   *
    * Returns
    *
    * edit: SourceFileEdit (optional)
@@ -2038,8 +2045,10 @@
    *   that need to be applied.
    */
   Future<EditImportElementsResult> sendEditImportElements(
-      String file, List<ImportedElements> elements) async {
-    var params = new EditImportElementsParams(file, elements).toJson();
+      String file, List<ImportedElements> elements,
+      {int offset}) async {
+    var params =
+        new EditImportElementsParams(file, elements, offset: offset).toJson();
     var result = await server.send("edit.importElements", params);
     ResponseDecoder decoder = new ResponseDecoder(null);
     return new EditImportElementsResult.fromJson(decoder, 'result', result);
diff --git a/pkg/analysis_server/test/integration/support/integration_tests.dart b/pkg/analysis_server/test/integration/support/integration_tests.dart
index 16f7d4b..7d348d6 100644
--- a/pkg/analysis_server/test/integration/support/integration_tests.dart
+++ b/pkg/analysis_server/test/integration/support/integration_tests.dart
@@ -712,6 +712,7 @@
     if (Platform.packageConfig != null) {
       arguments.add('--packages=${Platform.packageConfig}');
     }
+    arguments.add('--disable-service-auth-codes');
     //
     // Add the server executable.
     //
diff --git a/pkg/analysis_server/test/integration/support/protocol_matchers.dart b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
index 7cee89f..ec50cf1 100644
--- a/pkg/analysis_server/test/integration/support/protocol_matchers.dart
+++ b/pkg/analysis_server/test/integration/support/protocol_matchers.dart
@@ -1618,13 +1618,17 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  */
 final Matcher isTokenDetails = new LazyMatcher(() => new MatchesJsonObject(
-    "TokenDetails", {"lexeme": isString, "type": isString},
-    optionalFields: {"validElementKinds": isListOf(isString)}));
+        "TokenDetails", {
+      "lexeme": isString
+    }, optionalFields: {
+      "type": isString,
+      "validElementKinds": isListOf(isString)
+    }));
 
 /**
  * TypeHierarchyItem
@@ -2616,11 +2620,13 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  */
 final Matcher isEditImportElementsParams = new LazyMatcher(() =>
     new MatchesJsonObject("edit.importElements params",
-        {"file": isFilePath, "elements": isListOf(isImportedElements)}));
+        {"file": isFilePath, "elements": isListOf(isImportedElements)},
+        optionalFields: {"offset": isInt}));
 
 /**
  * edit.importElements result
diff --git a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
index 2da217e..03fa79b 100644
--- a/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
+++ b/pkg/analysis_server/test/src/domains/completion/available_suggestion_sets_test.dart
@@ -52,7 +52,9 @@
     var uriStr = 'package:test/a.dart';
 
     newFile(path, content: r'''
-class A {}
+class A {
+  A.a();
+}
 ''');
 
     var set = await waitForSetWithUri(uriStr);
@@ -77,6 +79,27 @@
   ]
 }
 ''');
+    assertJsonText(_getSuggestion(set, 'A.a'), '''
+{
+  "label": "A.a",
+  "element": {
+    "kind": "CONSTRUCTOR",
+    "name": "a",
+    "location": {
+      "file": ${jsonOfPath(path)},
+      "offset": 14,
+      "length": 0,
+      "startLine": 2,
+      "startColumn": 5
+    },
+    "flags": 0,
+    "parameters": "()"
+  },
+  "parameterNames": [],
+  "parameterTypes": [],
+  "requiredParameterCount": 0
+}
+''');
   }
 
   test_suggestion_enum() async {
diff --git a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
index e9db0d5..c3b1915 100644
--- a/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
+++ b/pkg/analysis_server/test/src/nullability/migration_visitor_test.dart
@@ -7,6 +7,7 @@
 import 'package:analysis_server/src/nullability/constraint_variable_gatherer.dart';
 import 'package:analysis_server/src/nullability/decorated_type.dart';
 import 'package:analysis_server/src/nullability/expression_checks.dart';
+import 'package:analysis_server/src/nullability/nullability_node.dart';
 import 'package:analysis_server/src/nullability/transitional_api.dart';
 import 'package:analysis_server/src/nullability/unit_propagation.dart';
 import 'package:analyzer/dart/ast/ast.dart';
@@ -48,6 +49,14 @@
             predicate((_Clause clause) => clause.consequence == consequence))));
   }
 
+  void assertNonNullIntent(NullabilityNode node, bool expected) {
+    if (expected) {
+      assertConstraint([], node.nonNullIntent);
+    } else {
+      assertNoConstraints(node.nonNullIntent);
+    }
+  }
+
   /// Gets the [ExpressionChecks] associated with the expression whose text
   /// representation is [text], or `null` if the expression has no
   /// [ExpressionChecks] associated with it.
@@ -78,7 +87,7 @@
 }
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
   }
 
   test_binaryExpression_add_left_check() async {
@@ -86,7 +95,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int i').nullable],
+    assertConstraint([decoratedTypeAnnotation('int i').node.nullable],
         checkExpression('i +').nullCheck);
   }
 
@@ -98,7 +107,7 @@
 Int f(Int i, Int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('Int i').nullable],
+    assertConstraint([decoratedTypeAnnotation('Int i').node.nullable],
         checkExpression('i +').nullCheck);
   }
 
@@ -111,8 +120,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('Int operator+').nullable],
-        _either(decoratedTypeAnnotation('Int f').nullable,
+        [decoratedTypeAnnotation('Int operator+').node.nullable],
+        _either(decoratedTypeAnnotation('Int f').node.nullable,
             checkExpression('(i + j)').nullCheck));
   }
 
@@ -121,7 +130,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int f').node.nullable);
   }
 
   test_binaryExpression_add_right_check() async {
@@ -129,7 +138,7 @@
 int f(int i, int j) => i + j;
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int j').nullable],
+    assertConstraint([decoratedTypeAnnotation('int j').node.nullable],
         checkExpression('j;').nullCheck);
   }
 
@@ -142,8 +151,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('Int j').nullable],
-        _either(decoratedTypeAnnotation('Int other').nullable,
+        [decoratedTypeAnnotation('Int j').node.nullable],
+        _either(decoratedTypeAnnotation('Int other').node.nullable,
             checkExpression('j/*check*/').nullCheck));
   }
 
@@ -152,7 +161,7 @@
 bool f(int i, int j) => i == j;
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('bool f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('bool f').node.nullable);
   }
 
   test_boolLiteral() async {
@@ -161,7 +170,7 @@
   return true;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('bool').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('bool').node.nullable);
   }
 
   test_conditionalExpression_condition_check() async {
@@ -171,7 +180,7 @@
 }
 ''');
 
-    var nullable_b = decoratedTypeAnnotation('bool b').nullable;
+    var nullable_b = decoratedTypeAnnotation('bool b').node.nullable;
     var check_b = checkExpression('b ?').nullCheck;
     assertConstraint([nullable_b], check_b);
   }
@@ -183,11 +192,11 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     var nullable_i_or_nullable_j = _either(nullable_i, nullable_j);
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i], nullable_conditional);
     assertConstraint([nullable_j], nullable_conditional);
     assertConstraint([nullable_conditional], nullable_i_or_nullable_j);
@@ -202,8 +211,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(nullable_i));
   }
 
@@ -214,7 +223,7 @@
 }
 ''');
 
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(ConstraintVariable.always));
   }
 
@@ -225,8 +234,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(nullable_i));
   }
 
@@ -237,7 +246,7 @@
 }
 ''');
 
-    var nullable_conditional = decoratedExpressionType('(b ?').nullable;
+    var nullable_conditional = decoratedExpressionType('(b ?').node.nullable;
     expect(nullable_conditional, same(ConstraintVariable.always));
   }
 
@@ -247,8 +256,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('int/*2*/').nullable],
-        _either(decoratedTypeAnnotation('int/*1*/').nullable,
+        [decoratedTypeAnnotation('int/*2*/').node.nullable],
+        _either(decoratedTypeAnnotation('int/*1*/').node.nullable,
             checkExpression('i/*3*/').nullCheck));
   }
 
@@ -257,7 +266,7 @@
 void f({int i = 1}) {}
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_default_null() async {
@@ -265,8 +274,8 @@
 void f({int i = null}) {}
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_nullable() async {
@@ -277,7 +286,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeNullable));
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_assume_required() async {
@@ -288,7 +298,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_required_assume_nullable() async {
@@ -301,7 +311,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeNullable));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_named_no_default_required_assume_required() async {
@@ -314,7 +324,7 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_default_notNull() async {
@@ -322,7 +332,7 @@
 void f([int i = 1]) {}
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_default_null() async {
@@ -330,8 +340,8 @@
 void f([int i = null]) {}
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default() async {
@@ -339,7 +349,8 @@
 void f([int i]) {}
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_parameter_positionalOptional_no_default_assume_required() async {
@@ -352,7 +363,8 @@
             namedNoDefaultParameterHeuristic:
                 NamedNoDefaultParameterHeuristic.assumeRequired));
 
-    assertConstraint([], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_functionDeclaration_resets_unconditional_control_flow() async {
@@ -366,9 +378,9 @@
   assert(k != null);
 }
 ''');
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
-    assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent);
-    assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
+    assertNonNullIntent(decoratedTypeAnnotation('int j').node, false);
+    assertNonNullIntent(decoratedTypeAnnotation('int k').node, true);
   }
 
   test_functionInvocation_parameter_fromLocalParameter() async {
@@ -382,9 +394,11 @@
     var int_1 = decoratedTypeAnnotation('int/*1*/');
     var int_2 = decoratedTypeAnnotation('int/*2*/');
     var i_3 = checkExpression('i/*3*/');
-    assertConstraint([int_2.nullable], _either(int_1.nullable, i_3.nullCheck));
-    assertConstraint([int_2.nullable, int_1.nonNullIntent], i_3.nullCheck);
-    assertConstraint([int_1.nonNullIntent], int_2.nonNullIntent);
+    assertConstraint(
+        [int_2.node.nullable], _either(int_1.node.nullable, i_3.nullCheck));
+    assertConstraint(
+        [int_2.node.nullable, int_1.node.nonNullIntent], i_3.nullCheck);
+    assertConstraint([int_1.node.nonNullIntent], int_2.node.nonNullIntent);
   }
 
   test_functionInvocation_parameter_named() async {
@@ -394,8 +408,8 @@
   f(i: j/*check*/);
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     assertConstraint([nullable_j],
         _either(nullable_i, checkExpression('j/*check*/').nullCheck));
   }
@@ -408,7 +422,7 @@
 }
 ''');
     var optional_i = possiblyOptionalParameter('int i');
-    assertConstraint([], optional_i);
+    assertConstraint([], optional_i.nullable);
   }
 
   test_functionInvocation_parameter_named_missing_required() async {
@@ -424,7 +438,7 @@
     // The call at `f()` is presumed to be in error; no constraint is recorded.
     var optional_i = possiblyOptionalParameter('int i');
     expect(optional_i, isNull);
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
     assertNoConstraints(nullable_i);
   }
 
@@ -438,7 +452,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('null').nullCheck));
   }
 
@@ -451,8 +465,8 @@
 ''');
 
     assertConstraint(
-        [decoratedTypeAnnotation('int/*1*/').nullable],
-        _either(decoratedTypeAnnotation('int/*2*/').nullable,
+        [decoratedTypeAnnotation('int/*1*/').node.nullable],
+        _either(decoratedTypeAnnotation('int/*2*/').node.nullable,
             checkExpression('(f())').nullCheck));
   }
 
@@ -463,7 +477,7 @@
 }
 ''');
 
-    assertConstraint([(decoratedTypeAnnotation('bool b').nullable)],
+    assertConstraint([(decoratedTypeAnnotation('bool b').node.nullable)],
         checkExpression('b) {}').nullCheck);
   }
 
@@ -477,7 +491,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, false);
   }
 
   test_if_conditional_control_flow_within() async {
@@ -492,7 +506,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('int i').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, false);
   }
 
   test_if_guard_equals_null() async {
@@ -505,17 +519,17 @@
   }
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
-    var nullable_k = decoratedTypeAnnotation('int k').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
+    var nullable_k = decoratedTypeAnnotation('int k').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i, nullable_j],
         _either(nullable_return, checkExpression('j/*check*/').nullCheck));
     assertConstraint([nullable_k],
         _either(nullable_return, checkExpression('k/*check*/').nullCheck));
     var discard = statementDiscard('if (i == null)');
-    expect(discard.keepTrue, same(nullable_i));
-    expect(discard.keepFalse, same(ConstraintVariable.always));
+    expect(discard.trueGuard.nullable, same(nullable_i));
+    expect(discard.falseGuard, null);
     expect(discard.pureCondition, true);
   }
 
@@ -530,9 +544,9 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i],
         _either(nullable_return, checkExpression('i/*check*/').nullCheck));
     assertConstraint([nullable_j],
@@ -549,8 +563,8 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_return = decoratedTypeAnnotation('int f').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_return = decoratedTypeAnnotation('int f').node.nullable;
     assertConstraint([nullable_i],
         _either(nullable_return, checkExpression('i/*check*/').nullCheck));
   }
@@ -561,7 +575,7 @@
   return 0;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_methodDeclaration_resets_unconditional_control_flow() async {
@@ -577,9 +591,9 @@
   }
 }
 ''');
-    assertConstraint([], decoratedTypeAnnotation('int i').nonNullIntent);
-    assertNoConstraints(decoratedTypeAnnotation('int j').nonNullIntent);
-    assertConstraint([], decoratedTypeAnnotation('int k').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('int i').node, true);
+    assertNonNullIntent(decoratedTypeAnnotation('int j').node, false);
+    assertNonNullIntent(decoratedTypeAnnotation('int k').node, true);
   }
 
   test_methodInvocation_parameter_contravariant() async {
@@ -592,10 +606,10 @@
 }
 ''');
 
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
     var nullable_c_t =
-        decoratedTypeAnnotation('C<int>').typeArguments[0].nullable;
-    var nullable_t = decoratedTypeAnnotation('T t').nullable;
+        decoratedTypeAnnotation('C<int>').typeArguments[0].node.nullable;
+    var nullable_t = decoratedTypeAnnotation('T t').node.nullable;
     var nullable_c_t_or_nullable_t = _either(nullable_c_t, nullable_t);
     assertConstraint(
         [nullable_i],
@@ -612,11 +626,11 @@
 }
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('int/*3*/').nullable],
-        decoratedTypeAnnotation('int/*1*/').nullable);
+    assertConstraint([decoratedTypeAnnotation('int/*3*/').node.nullable],
+        decoratedTypeAnnotation('int/*1*/').node.nullable);
     assertConstraint(
-        [decoratedTypeAnnotation('C<int/*3*/>/*4*/').nullable],
-        _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').nullable,
+        [decoratedTypeAnnotation('C<int/*3*/>/*4*/').node.nullable],
+        _either(decoratedTypeAnnotation('C<int/*1*/>/*2*/').node.nullable,
             checkExpression('c/*check*/').nullCheck));
   }
 
@@ -629,8 +643,8 @@
   c.f(i: j/*check*/);
 }
 ''');
-    var nullable_i = decoratedTypeAnnotation('int i').nullable;
-    var nullable_j = decoratedTypeAnnotation('int j').nullable;
+    var nullable_i = decoratedTypeAnnotation('int i').node.nullable;
+    var nullable_j = decoratedTypeAnnotation('int j').node.nullable;
     assertConstraint([nullable_j],
         _either(nullable_i, checkExpression('j/*check*/').nullCheck));
   }
@@ -645,7 +659,7 @@
 }
 ''');
 
-    assertConstraint([decoratedTypeAnnotation('C c').nullable],
+    assertConstraint([decoratedTypeAnnotation('C c').node.nullable],
         checkExpression('c.m').nullCheck);
   }
 
@@ -659,7 +673,7 @@
 }
 ''');
 
-    assertConstraint([], decoratedTypeAnnotation('C c').nonNullIntent);
+    assertNonNullIntent(decoratedTypeAnnotation('C c').node, true);
   }
 
   test_parenthesizedExpression() async {
@@ -671,7 +685,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('(null)').nullCheck));
   }
 
@@ -683,8 +697,8 @@
 }
 ''');
 
-    assertConstraint(
-        [ConstraintVariable.always], decoratedTypeAnnotation('int').nullable);
+    assertConstraint([ConstraintVariable.always],
+        decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_return_null() async {
@@ -696,7 +710,7 @@
 
     assertConstraint(
         [ConstraintVariable.always],
-        _either(decoratedTypeAnnotation('int').nullable,
+        _either(decoratedTypeAnnotation('int').node.nullable,
             checkExpression('null').nullCheck));
   }
 
@@ -707,7 +721,7 @@
   return 'x';
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('String').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('String').node.nullable);
   }
 
   test_thisExpression() async {
@@ -717,7 +731,7 @@
 }
 ''');
 
-    assertNoConstraints(decoratedTypeAnnotation('C f').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('C f').node.nullable);
   }
 
   test_throwExpression() async {
@@ -726,7 +740,7 @@
   return throw null;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('int').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('int').node.nullable);
   }
 
   test_typeName() async {
@@ -735,7 +749,7 @@
   return int;
 }
 ''');
-    assertNoConstraints(decoratedTypeAnnotation('Type').nullable);
+    assertNoConstraints(decoratedTypeAnnotation('Type').node.nullable);
   }
 
   /// Creates a variable representing the disjunction of [a] and [b] solely for
@@ -777,7 +791,7 @@
     var decoratedType = decoratedTypeAnnotation('int?');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_interfaceType_typeParameter() async {
@@ -787,10 +801,10 @@
     var decoratedListType = decoratedTypeAnnotation('List<int>');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedListType));
-    expect(decoratedListType.nullable, isNotNull);
+    expect(decoratedListType.node.nullable, isNotNull);
     var decoratedIntType = decoratedTypeAnnotation('int');
     expect(decoratedListType.typeArguments[0], same(decoratedIntType));
-    expect(decoratedIntType.nullable, isNotNull);
+    expect(decoratedIntType.node.nullable, isNotNull);
   }
 
   test_topLevelFunction_parameterType_implicit_dynamic() async {
@@ -802,7 +816,7 @@
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_topLevelFunction_parameterType_named_no_default() async {
@@ -812,10 +826,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
-    expect(functionType.namedParameterOptionalVariables['s'],
-        same(decoratedType.nullable));
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, true);
   }
 
   test_topLevelFunction_parameterType_named_no_default_required() async {
@@ -827,9 +840,9 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nullable, isNot(same(ConstraintVariable.always)));
-    expect(functionType.namedParameterOptionalVariables['s'], isNull);
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNot(same(ConstraintVariable.always)));
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
   test_topLevelFunction_parameterType_named_with_default() async {
@@ -839,9 +852,8 @@
     var decoratedType = decoratedTypeAnnotation('String');
     var functionType = decoratedFunctionType('f');
     expect(functionType.namedParameters['s'], same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(functionType.namedParameterOptionalVariables['s'],
-        same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(functionType.namedParameters['s'].node.isPossiblyOptional, false);
   }
 
   test_topLevelFunction_parameterType_positionalOptional() async {
@@ -851,7 +863,7 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
   }
 
   test_topLevelFunction_parameterType_simple() async {
@@ -861,8 +873,8 @@
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').positionalParameters[0],
         same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
-    expect(decoratedType.nonNullIntent, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
+    expect(decoratedType.node.nonNullIntent, isNotNull);
   }
 
   test_topLevelFunction_returnType_implicit_dynamic() async {
@@ -871,7 +883,7 @@
 ''');
     var decoratedType = decoratedFunctionType('f').returnType;
     expect(decoratedType.type.isDynamic, isTrue);
-    expect(decoratedType.nullable, same(ConstraintVariable.always));
+    expect(decoratedType.node.nullable, same(ConstraintVariable.always));
   }
 
   test_topLevelFunction_returnType_simple() async {
@@ -880,7 +892,7 @@
 ''');
     var decoratedType = decoratedTypeAnnotation('int');
     expect(decoratedFunctionType('f').returnType, same(decoratedType));
-    expect(decoratedType.nullable, isNotNull);
+    expect(decoratedType.node.nullable, isNotNull);
   }
 }
 
@@ -907,7 +919,7 @@
     return _variables.decoratedTypeAnnotation(findNode.typeAnnotation(text));
   }
 
-  ConstraintVariable possiblyOptionalParameter(String text) {
+  NullabilityNode possiblyOptionalParameter(String text) {
     return _variables
         .possiblyOptionalParameter(findNode.defaultParameter(text));
   }
@@ -988,7 +1000,7 @@
 
   final _expressionChecks = <Expression, ExpressionChecks>{};
 
-  final _possiblyOptional = <DefaultFormalParameter, ConstraintVariable>{};
+  final _possiblyOptional = <DefaultFormalParameter, NullabilityNode>{};
 
   /// Gets the [ExpressionChecks] associated with the given [expression].
   ExpressionChecks checkExpression(Expression expression) =>
@@ -1006,10 +1018,9 @@
   DecoratedType decoratedTypeAnnotation(TypeAnnotation typeAnnotation) =>
       _decoratedTypeAnnotations[typeAnnotation];
 
-  /// Gets the [ConstraintVariable] associated with the possibility that
+  /// Gets the [NullabilityNode] associated with the possibility that
   /// [parameter] may be optional.
-  ConstraintVariable possiblyOptionalParameter(
-          DefaultFormalParameter parameter) =>
+  NullabilityNode possiblyOptionalParameter(DefaultFormalParameter parameter) =>
       _possiblyOptional[parameter];
 
   @override
@@ -1038,10 +1049,10 @@
   }
 
   @override
-  void recordPossiblyOptional(Source source, DefaultFormalParameter parameter,
-      ConstraintVariable variable) {
-    _possiblyOptional[parameter] = variable;
-    super.recordPossiblyOptional(source, parameter, variable);
+  void recordPossiblyOptional(
+      Source source, DefaultFormalParameter parameter, NullabilityNode node) {
+    _possiblyOptional[parameter] = node;
+    super.recordPossiblyOptional(source, parameter, node);
   }
 
   /// Unwraps any parentheses surrounding [expression].
diff --git a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
index 1698262..d96f84d 100644
--- a/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
+++ b/pkg/analysis_server/test/src/nullability/provisional_api_test.dart
@@ -368,6 +368,31 @@
                 NamedNoDefaultParameterHeuristic.assumeNullable));
   }
 
+  test_named_parameter_no_default_unused_option2_assume_nullable_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
   test_named_parameter_no_default_unused_option2_assume_required() async {
     var content = '''
 void f({String s}) {}
@@ -387,6 +412,31 @@
                 NamedNoDefaultParameterHeuristic.assumeRequired));
   }
 
+  test_named_parameter_no_default_unused_option2_assume_required_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g();
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
   test_named_parameter_no_default_unused_required_option2_assume_nullable() async {
     // The `@required` annotation overrides the assumption of nullability.
     // The call at `f()` is presumed to be in error.
@@ -455,6 +505,31 @@
                 NamedNoDefaultParameterHeuristic.assumeNullable));
   }
 
+  test_named_parameter_no_default_used_non_null_option2_assume_nullable_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    var expected = '''
+void f(String? s) {}
+void g({String? s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeNullable));
+  }
+
   test_named_parameter_no_default_used_non_null_option2_assume_required() async {
     var content = '''
 void f({String s}) {}
@@ -463,6 +538,7 @@
 }
 ''';
     var expected = '''
+import 'package:meta/meta.dart';
 void f({@required String s}) {}
 main() {
   f(s: 'x');
@@ -474,6 +550,32 @@
                 NamedNoDefaultParameterHeuristic.assumeRequired));
   }
 
+  test_named_parameter_no_default_used_non_null_option2_assume_required_propagate() async {
+    var content = '''
+void f(String s) {}
+void g({String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    var expected = '''
+import 'package:meta/meta.dart';
+void f(String s) {}
+void g({@required String s}) {
+  f(s);
+}
+main() {
+  g(s: 'x');
+}
+''';
+    await _checkSingleFileChanges(content, expected,
+        assumptions: NullabilityMigrationAssumptions(
+            namedNoDefaultParameterHeuristic:
+                NamedNoDefaultParameterHeuristic.assumeRequired));
+  }
+
   test_named_parameter_no_default_used_non_null_required_option2_assume_required() async {
     // Even if we are using the "assumeRequired" heuristic, we should not add a
     // duplicate `@required` annotation.
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
new file mode 100644
index 0000000..597c353
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_for_element_test.dart
@@ -0,0 +1,190 @@
+// 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:analysis_server/src/services/correction/assist.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer_plugin/utilities/assist/assist.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'assist_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ConvertToIfElementTest);
+  });
+}
+
+@reflectiveTest
+class ConvertToIfElementTest extends AssistProcessorTest {
+  @override
+  AssistKind get kind => DartAssistKind.CONVERT_TO_FOR_ELEMENT;
+
+  void setUp() {
+    createAnalysisOptionsFile(
+        experiments: [EnableString.control_flow_collections]);
+    super.setUp();
+  }
+
+  test_mapFromIterable_complexKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) {
+    var result = e * 2;
+    return result;
+  }, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_complexValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) {
+    var result = e  + 3;
+    return result;
+  });
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var k = 3;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var k = 3;
+  return { for (var e in i) e * 2 : k };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var k in i) k * 2 : 0 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  var e = 2;
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  var e = 2;
+  return { for (var e1 in i) e1 * e : e1 + e };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int v = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int v = 0;
+  return { for (var e in i) v++ : e * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  int index = 0;
+  return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  int index = 0;
+  return { for (var v in i) index++ : v * 10 };
+}
+''');
+  }
+
+  test_mapFromIterable_missingKey() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, value: (e) => e + 3);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingKeyAndValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_missingValue() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2);
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_notMapFromIterable() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+class A {
+  A.fromIterable(i, {key, value});
+}
+''');
+    await assertNoAssist();
+  }
+
+  test_mapFromIterable_sameParameterNames() async {
+    await resolveTestUnit('''
+f(Iterable<int> i) {
+  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
+}
+''');
+    await assertHasAssist('''
+f(Iterable<int> i) {
+  return { for (var e in i) e * 2 : e + 3 };
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
index 8d8e3ef..5caae77 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_if_element_test.dart
@@ -39,6 +39,19 @@
 ''');
   }
 
+  test_conditional_list_caret_at_start_of_expression() async {
+    await resolveTestUnit('''
+f(bool b) {
+  return ['a', /*caret*/b ? 'c' : 'd', 'e'];
+}
+''');
+    await assertHasAssist('''
+f(bool b) {
+  return ['a', if (b) 'c' else 'd', 'e'];
+}
+''');
+  }
+
   test_conditional_list_withParentheses() async {
     await resolveTestUnit('''
 f(bool b) {
@@ -104,166 +117,4 @@
 }
 ''');
   }
-
-  test_mapFromIterable_complexKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) {
-    var result = e * 2;
-    return result;
-  }, value: (e) => e + 3);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_complexValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) {
-    var result = e  + 3;
-    return result;
-  });
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKey_conflictInValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  var k = 3;
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => k);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  var k = 3;
-  return { for (var e in i) e * 2 : k };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKey_noConflictInValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => 0);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var k in i) k * 2 : 0 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_conflictWithDefault() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  var e = 2;
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * e, value: (v) => v + e);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  var e = 2;
-  return { for (var e1 in i) e1 * e : e1 + e };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInKeyAndValue_noConflictWithDefault() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (k) => k * 2, value: (v) => v + 3);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var e in i) e * 2 : e + 3 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInValue_conflictInKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  int v = 0;
-  return Map.fromIt/*caret*/erable(i, key: (k) => v++, value: (v) => v * 10);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  int v = 0;
-  return { for (var e in i) v++ : e * 10 };
-}
-''');
-  }
-
-  test_mapFromIterable_differentParameterNames_usedInValue_noConflictInKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  int index = 0;
-  return Map.fromIt/*caret*/erable(i, key: (k) => index++, value: (v) => v * 10);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  int index = 0;
-  return { for (var v in i) index++ : v * 10 };
-}
-''');
-  }
-
-  test_mapFromIterable_missingKey() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, value: (e) => e + 3);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_missingKeyAndValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_missingValue() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2);
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_notMapFromIterable() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return A.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
-}
-class A {
-  A.fromIterable(i, {key, value});
-}
-''');
-    await assertNoAssist();
-  }
-
-  test_mapFromIterable_sameParameterNames() async {
-    await resolveTestUnit('''
-f(Iterable<int> i) {
-  return Map.fromIt/*caret*/erable(i, key: (e) => e * 2, value: (e) => e + 3);
-}
-''');
-    await assertHasAssist('''
-f(Iterable<int> i) {
-  return { for (var e in i) e * 2 : e + 3 };
-}
-''');
-  }
 }
diff --git a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
index 648502f..d026fb3 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/convert_to_spread_test.dart
@@ -41,6 +41,21 @@
 ''');
   }
 
+  test_addAll_expression_to_emptyList() async {
+    await resolveTestUnit('''
+f() {
+  var ints = [1, 2, 3];
+  print([]..addAl/*caret*/l(ints.map((i) => i.toString()))..addAll(['c']));
+}
+''');
+    await assertHasAssist('''
+f() {
+  var ints = [1, 2, 3];
+  print([...ints.map((i) => i.toString())]..addAll(['c']));
+}
+''');
+  }
+
   test_addAll_literal() async {
     await resolveTestUnit('''
 var l = ['a']..add/*caret*/All(['b'])..addAll(['c']);
diff --git a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
index 9bba973..bcf631e 100644
--- a/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
+++ b/pkg/analysis_server/test/src/services/correction/assist/test_all.dart
@@ -26,6 +26,7 @@
 import 'convert_to_double_quoted_string_test.dart'
     as convert_to_double_quoted_string;
 import 'convert_to_field_parameter_test.dart' as convert_to_field_parameter;
+import 'convert_to_for_element_test.dart' as convert_to_for_element;
 import 'convert_to_if_element_test.dart' as convert_to_if_element;
 import 'convert_to_int_literal_test.dart' as convert_to_int_literal;
 import 'convert_to_list_literal_test.dart' as convert_to_list_literal;
@@ -96,6 +97,7 @@
     convert_part_of_to_uri.main();
     convert_to_double_quoted_string.main();
     convert_to_field_parameter.main();
+    convert_to_for_element.main();
     convert_to_if_element.main();
     convert_to_int_literal.main();
     convert_to_list_literal.main();
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
new file mode 100644
index 0000000..5a19c8b
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/remove_setting_test.dart
@@ -0,0 +1,122 @@
+// 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:analysis_server/plugin/edit/fix/fix_core.dart';
+import 'package:analysis_server/src/protocol_server.dart' show SourceEdit;
+import 'package:analysis_server/src/services/correction/fix/analysis_options/fix_generator.dart';
+import 'package:analyzer/error/error.dart' as engine;
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/analysis_options/analysis_options_provider.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/task/options.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:analyzer_plugin/protocol/protocol_common.dart'
+    show SourceFileEdit;
+import 'package:analyzer_plugin/protocol/protocol_common.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+import 'package:yaml/src/yaml_node.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(RemoveSettingTest);
+  });
+}
+
+class NonDartFixTest with ResourceProviderMixin {
+  Future<void> assertHasFix(
+      String initialContent, String location, String expectedContent) async {
+    File optionsFile = resourceProvider.getFile('/analysis_options.yaml');
+    SourceFactory sourceFactory = new SourceFactory([]);
+    List<engine.AnalysisError> errors = analyzeAnalysisOptions(
+        optionsFile.createSource(), initialContent, sourceFactory);
+    expect(errors, hasLength(1));
+    engine.AnalysisError error = errors[0];
+    YamlMap options = _getOptions(sourceFactory, initialContent);
+    AnalysisOptionsFixGenerator generator =
+        new AnalysisOptionsFixGenerator(error, initialContent, options);
+    List<Fix> fixes = await generator.computeFixes();
+    expect(fixes, hasLength(1));
+    List<SourceFileEdit> fileEdits = fixes[0].change.edits;
+    expect(fileEdits, hasLength(1));
+
+    String actualContent =
+        SourceEdit.applySequence(initialContent, fileEdits[0].edits);
+    expect(actualContent, expectedContent);
+  }
+
+  YamlMap _getOptions(SourceFactory sourceFactory, String content) {
+    AnalysisOptionsProvider optionsProvider =
+        new AnalysisOptionsProvider(sourceFactory);
+    try {
+      return optionsProvider.getOptionsFromString(content);
+    } on OptionsFormatException {
+      return null;
+    }
+  }
+}
+
+@reflectiveTest
+class RemoveSettingTest extends NonDartFixTest {
+  test_enableSuperMixins() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+  language:
+    enableSuperMixins: true
+''',
+        'enable',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_first() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - not-an-experiment
+    - non-nullable
+''',
+        'not-',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_last() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+    - not-an-experiment
+''',
+        'not-',
+        '''
+analyzer:
+  enable-experiment:
+    - non-nullable
+''');
+  }
+
+  test_invalidExperiment_only() async {
+    await assertHasFix(
+        '''
+analyzer:
+  enable-experiment:
+    - not-an-experiment
+''',
+        'not-',
+        '''
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
new file mode 100644
index 0000000..c202ee9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/analysis_options/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'remove_setting_test.dart' as remove_setting;
+
+main() {
+  defineReflectiveSuite(() {
+    remove_setting.main();
+  });
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
index b24488f..2707a41 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/change_argument_name_test.dart
@@ -117,6 +117,23 @@
 ''');
   }
 
+  test_default_annotation() async {
+    await resolveTestUnit('''
+@A(boot: 2)
+f() => null;
+class A {
+  const A({int boat});
+}
+''');
+    await assertHasFix('''
+@A(boat: 2)
+f() => null;
+class A {
+  const A({int boat});
+}
+''');
+  }
+
   test_default_constructor() async {
     await resolveTestUnit('''
 f() => new A(boot: 2);
@@ -166,6 +183,40 @@
 ''');
   }
 
+  test_default_redirectingConstructor() async {
+    await resolveTestUnit('''
+class A {
+  A.one() : this.two(boot: 3);
+  A.two({int boat});
+}
+''');
+    await assertHasFix('''
+class A {
+  A.one() : this.two(boat: 3);
+  A.two({int boat});
+}
+''');
+  }
+
+  test_default_superConstructor() async {
+    await resolveTestUnit('''
+class A {
+  A.a({int boat});
+}
+class B extends A {
+  B.b() : super.a(boot: 3);
+}
+''');
+    await assertHasFix('''
+class A {
+  A.a({int boat});
+}
+class B extends A {
+  B.b() : super.a(boat: 3);
+}
+''');
+  }
+
   test_tooDistant_constructor() async {
     await resolveTestUnit('''
 f() => new A(bbbbb: 2);
diff --git a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
index e9b5fa2..beb7025 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/fix_processor.dart
@@ -64,9 +64,13 @@
   Future<void> assertHasFix(String expected,
       {bool Function(AnalysisError) errorFilter,
       int length,
-      String target}) async {
+      String target,
+      int expectedNumberOfFixesForKind,
+      String matchFixMessage}) async {
     AnalysisError error = await _findErrorToFix(errorFilter, length: length);
-    Fix fix = await _assertHasFix(error);
+    Fix fix = await _assertHasFix(error,
+        expectedNumberOfFixesForKind: expectedNumberOfFixesForKind,
+        matchFixMessage: matchFixMessage);
     change = fix.change;
 
     // apply to "file"
@@ -148,12 +152,38 @@
     verifyNoTestUnitErrors = false;
   }
 
-  /// Computes fixes and verifies that there is a fix for the given [error] of
-  /// the appropriate kind.
-  Future<Fix> _assertHasFix(AnalysisError error) async {
+  /// Computes fixes and verifies that there is a fix for the given [error] of the appropriate kind.
+  /// Optionally, if a [matchFixMessage] is passed, then the kind as well as the fix message must
+  /// match to be returned.
+  Future<Fix> _assertHasFix(AnalysisError error,
+      {int expectedNumberOfFixesForKind, String matchFixMessage}) async {
     // Compute the fixes for this AnalysisError
     final List<Fix> fixes = await _computeFixes(error);
 
+    if (expectedNumberOfFixesForKind != null) {
+      int actualNumberOfFixesForKind = 0;
+      for (Fix fix in fixes) {
+        if (fix.kind == kind) {
+          actualNumberOfFixesForKind++;
+        }
+      }
+      if (actualNumberOfFixesForKind != expectedNumberOfFixesForKind) {
+        fail(
+            "Expected $expectedNumberOfFixesForKind fixes of kind $kind, but found $actualNumberOfFixesForKind:\n${fixes.join('\n')}");
+      }
+    }
+
+    // If a matchFixMessage was provided,
+    if (matchFixMessage != null) {
+      for (Fix fix in fixes) {
+        if (matchFixMessage == fix?.change?.message) {
+          return fix;
+        }
+      }
+      fail(
+          'Expected to find fix $kind with name $matchFixMessage in\n${fixes.join('\n')}');
+    }
+
     // Assert that none of the fixes are a fix-all fix.
     Fix foundFix = null;
     for (Fix fix in fixes) {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
index 08bf63e..f1d1710 100644
--- a/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
+++ b/pkg/analysis_server/test/src/services/correction/fix/import_library_project_test.dart
@@ -65,7 +65,7 @@
   Test test = null;
   print(test);
 }
-''');
+''', expectedNumberOfFixesForKind: 1);
   }
 
   test_preferDirectOverExport_src() async {
@@ -83,7 +83,65 @@
   Test test = null;
   print(test);
 }
+''', expectedNumberOfFixesForKind: 1);
+  }
+
+  test_relativeDirective() async {
+    addSource('/home/test/lib/a.dart', '''
+import "b.dart";
 ''');
+    addSource('/home/test/lib/b.dart', '''
+class Foo {}
+''');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import 'b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library 'b.dart'");
+  }
+
+  test_relativeDirective_upOneDirectory() async {
+    addSource('/home/test/lib/a.dart', '''
+import "b.dart";
+''');
+    addSource('/home/test/lib/b.dart', '''
+class Foo {}
+''');
+    testFile = convertPath('/home/test/lib/dir/test.dart');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import '../b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library '../b.dart'");
+  }
+
+  test_relativeDirective_downOneDirectory() async {
+    addSource('/home/test/lib/dir/a.dart', '''
+import "b.dart";
+''');
+    addSource('/home/test/lib/dir/b.dart', '''
+class Foo {}
+''');
+    await resolveTestUnit('''
+main() { new Foo(); }
+''');
+    await assertHasFix('''
+import 'dir/b.dart';
+
+main() { new Foo(); }
+''',
+        expectedNumberOfFixesForKind: 2,
+        matchFixMessage: "Import library 'dir/b.dart'");
   }
 
   test_withClass_annotation() async {
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_test.dart
new file mode 100644
index 0000000..ef13aa9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_empty_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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithIsEmptyTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithIsEmptyTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REPLACE_WITH_IS_EMPTY;
+
+  @override
+  String get lintCode => LintNames.prefer_is_empty;
+
+  test_constantOnLeft_equal() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 == c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_greaterThan() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/1 > c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_greaterThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 >= c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_equal() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length == 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_lessThan() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length < 1) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_lessThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length <= 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isEmpty) {}
+}
+''');
+  }
+}
diff --git a/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_test.dart
new file mode 100644
index 0000000..9b621d9
--- /dev/null
+++ b/pkg/analysis_server/test/src/services/correction/fix/replace_with_is_not_empty_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.
+
+import 'package:analysis_server/src/services/correction/fix.dart';
+import 'package:analysis_server/src/services/correction/fix_internal.dart';
+import 'package:analyzer_plugin/utilities/fixes/fixes.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'fix_processor.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ReplaceWithIsNotEmptyTest);
+  });
+}
+
+@reflectiveTest
+class ReplaceWithIsNotEmptyTest extends FixProcessorLintTest {
+  @override
+  FixKind get kind => DartFixKind.REPLACE_WITH_IS_NOT_EMPTY;
+
+  @override
+  String get lintCode => LintNames.prefer_is_empty;
+
+  test_constantOnLeft_lessThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/1 <= c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnLeft_notEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/0 != c.length) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_greaterThanOrEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length >= 1) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+
+  test_constantOnRight_notEqual() async {
+    await resolveTestUnit('''
+f(List c) {
+  if (/*LINT*/c.length != 0) {}
+}
+''');
+    await assertHasFix('''
+f(List c) {
+  if (/*LINT*/c.isNotEmpty) {}
+}
+''');
+  }
+}
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 e9ea84e..de8cd2a 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
@@ -23,6 +23,7 @@
 import 'add_static_test.dart' as add_static;
 import 'add_super_constructor_invocation_test.dart'
     as add_super_constructor_invocation;
+import 'analysis_options/test_all.dart' as analysis_options;
 import 'change_argument_name_test.dart' as change_argument_name;
 import 'change_to_nearest_precise_value_test.dart'
     as change_to_nearest_precise_value;
@@ -95,6 +96,8 @@
 import 'replace_with_conditional_assignment_test.dart'
     as replace_with_conditional_assignment;
 import 'replace_with_identifier_test.dart' as replace_with_identifier;
+import 'replace_with_is_empty_test.dart' as replace_with_is_empty;
+import 'replace_with_is_not_empty_test.dart' as replace_with_is_not_empty;
 import 'replace_with_null_aware_test.dart' as replace_with_null_aware;
 import 'replace_with_tear_off_test.dart' as replace_with_tear_off;
 import 'update_sdk_constraints_test.dart' as update_sdk_constraints;
@@ -122,6 +125,7 @@
     add_required.main();
     add_static.main();
     add_super_constructor_invocation.main();
+    analysis_options.main();
     change_argument_name.main();
     change_to.main();
     change_to_nearest_precise_value.main();
@@ -188,6 +192,8 @@
     replace_with_brackets.main();
     replace_with_conditional_assignment.main();
     replace_with_identifier.main();
+    replace_with_is_empty.main();
+    replace_with_is_not_empty.main();
     replace_with_null_aware.main();
     replace_with_tear_off.main();
     update_sdk_constraints.main();
diff --git a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
index 1ad467a..da73811 100644
--- a/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
+++ b/pkg/analysis_server/tool/spec/generated/java/AnalysisServer.java
@@ -624,8 +624,12 @@
    *
    * @param file The file in which the specified elements are to be made accessible.
    * @param elements The elements to be made accessible in the specified file.
+   * @param offset The offset at which the specified elements need to be made accessible. If
+   *         provided, this is used to guard against adding imports for text that would be inserted
+   *         into a comment, string literal, or other location where the imports would not be
+   *         necessary.
    */
-  public void edit_importElements(String file, List<ImportedElements> elements, ImportElementsConsumer consumer);
+  public void edit_importElements(String file, List<ImportedElements> elements, int offset, ImportElementsConsumer consumer);
 
   /**
    * {@code edit.isPostfixCompletionApplicable}
diff --git a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
index 183ba52..071328a 100644
--- a/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
+++ b/pkg/analysis_server/tool/spec/generated/java/types/TokenDetails.java
@@ -36,17 +36,20 @@
   public static final List<TokenDetails> EMPTY_LIST = Lists.newArrayList();
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   private final String lexeme;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
+   * reference position.
    */
   private final String type;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference position. (If no other
+   * purpose is found for this field then it should be renamed and converted to a boolean value.)
+   * Omitted if the token is not an identifier.
    */
   private final List<String> validElementKinds;
 
@@ -73,7 +76,7 @@
 
   public static TokenDetails fromJson(JsonObject jsonObject) {
     String lexeme = jsonObject.get("lexeme").getAsString();
-    String type = jsonObject.get("type").getAsString();
+    String type = jsonObject.get("type") == null ? null : jsonObject.get("type").getAsString();
     List<String> validElementKinds = jsonObject.get("validElementKinds") == null ? null : JsonUtilities.decodeStringList(jsonObject.get("validElementKinds").getAsJsonArray());
     return new TokenDetails(lexeme, type, validElementKinds);
   }
@@ -91,21 +94,24 @@
   }
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   public String getLexeme() {
     return lexeme;
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an identifier in a
+   * reference position.
    */
   public String getType() {
     return type;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference position. (If no other
+   * purpose is found for this field then it should be renamed and converted to a boolean value.)
+   * Omitted if the token is not an identifier.
    */
   public List<String> getValidElementKinds() {
     return validElementKinds;
@@ -123,7 +129,9 @@
   public JsonObject toJson() {
     JsonObject jsonObject = new JsonObject();
     jsonObject.addProperty("lexeme", lexeme);
-    jsonObject.addProperty("type", type);
+    if (type != null) {
+      jsonObject.addProperty("type", type);
+    }
     if (validElementKinds != null) {
       JsonArray jsonArrayValidElementKinds = new JsonArray();
       for (String elt : validElementKinds) {
diff --git a/pkg/analysis_server/tool/spec/spec_input.html b/pkg/analysis_server/tool/spec/spec_input.html
index edbcba3..56f1243 100644
--- a/pkg/analysis_server/tool/spec/spec_input.html
+++ b/pkg/analysis_server/tool/spec/spec_input.html
@@ -7,7 +7,7 @@
 <body>
 <h1>Analysis Server API Specification</h1>
 <h1 style="color:#999999">Version
-  <version>1.25.0</version>
+  <version>1.26.0</version>
 </h1>
 <p>
   This document contains a specification of the API provided by the
@@ -2534,15 +2534,26 @@
           The elements to be made accessible in the specified file.
         </p>
       </field>
+      <field name="offset" optional="true">
+        <ref>int</ref>
+        <p>
+          The offset at which the specified elements need to be made accessible.
+          If provided, this is used to guard against adding imports for text
+          that would be inserted into a comment, string literal, or other
+          location where the imports would not be necessary.
+        </p>
+      </field>
     </params>
     <result>
       <field name="edit" optional="true">
         <ref>SourceFileEdit</ref>
         <p>
-          The edits to be applied in order to make the specified elements accessible. The file to be edited will be the
-          defining compilation unit of the library containing the file specified in the request, which can be different
-          than the file specified in the request if the specified file is a part file. This field will be omitted if
-          there are no edits that need to be applied.
+          The edits to be applied in order to make the specified elements
+          accessible. The file to be edited will be the defining compilation
+          unit of the library containing the file specified in the request,
+          which can be different than the file specified in the request if the
+          specified file is a part file. This field will be omitted if there are
+          no edits that need to be applied.
         </p>
       </field>
     </result>
@@ -3892,13 +3903,14 @@
       <field name="lexeme">
         <ref>String</ref>
         <p>
-          The raw token text.
+          The token's lexeme.
         </p>
       </field>
-      <field name="type">
+      <field name="type" optional="true">
         <ref>String</ref>
         <p>
-          The type of this token.
+          A unique id for the type of the identifier.
+          Omitted if the token is not an identifier in a reference position.
         </p>
       </field>
       <field name="validElementKinds" optional="true">
@@ -3906,7 +3918,10 @@
           <ref>String</ref>
         </list>
         <p>
-          The kinds of elements which could validly replace this token.
+          An indication of whether this token is in a declaration or reference
+          position. (If no other purpose is found for this field then it should
+          be renamed and converted to a boolean value.)
+          Omitted if the token is not an identifier.
         </p>
       </field>
     </object>
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
index 0125a30..35174b9 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_constants.dart
@@ -6,7 +6,7 @@
 // To regenerate the file, use the script
 // "pkg/analysis_server/tool/spec/generate_files".
 
-const String PROTOCOL_VERSION = '1.25.0';
+const String PROTOCOL_VERSION = '1.26.0';
 
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES = 'analysis.analyzedFiles';
 const String ANALYSIS_NOTIFICATION_ANALYZED_FILES_DIRECTORIES = 'directories';
@@ -201,6 +201,7 @@
 const String EDIT_REQUEST_IMPORT_ELEMENTS = 'edit.importElements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_ELEMENTS = 'elements';
 const String EDIT_REQUEST_IMPORT_ELEMENTS_FILE = 'file';
+const String EDIT_REQUEST_IMPORT_ELEMENTS_OFFSET = 'offset';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE =
     'edit.isPostfixCompletionApplicable';
 const String EDIT_REQUEST_IS_POSTFIX_COMPLETION_APPLICABLE_FILE = 'file';
diff --git a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
index b9d94ce..5d1b076 100644
--- a/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
+++ b/pkg/analysis_server_client/lib/src/protocol/protocol_generated.dart
@@ -10303,6 +10303,7 @@
  * {
  *   "file": FilePath
  *   "elements": List<ImportedElements>
+ *   "offset": optional int
  * }
  *
  * Clients may not extend, implement or mix-in this class.
@@ -10312,6 +10313,8 @@
 
   List<ImportedElements> _elements;
 
+  int _offset;
+
   /**
    * The file in which the specified elements are to be made accessible.
    */
@@ -10338,9 +10341,29 @@
     this._elements = value;
   }
 
-  EditImportElementsParams(String file, List<ImportedElements> elements) {
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  int get offset => _offset;
+
+  /**
+   * The offset at which the specified elements need to be made accessible. If
+   * provided, this is used to guard against adding imports for text that would
+   * be inserted into a comment, string literal, or other location where the
+   * imports would not be necessary.
+   */
+  void set offset(int value) {
+    this._offset = value;
+  }
+
+  EditImportElementsParams(String file, List<ImportedElements> elements,
+      {int offset}) {
     this.file = file;
     this.elements = elements;
+    this.offset = offset;
   }
 
   factory EditImportElementsParams.fromJson(
@@ -10365,7 +10388,11 @@
       } else {
         throw jsonDecoder.mismatch(jsonPath, "elements");
       }
-      return new EditImportElementsParams(file, elements);
+      int offset;
+      if (json.containsKey("offset")) {
+        offset = jsonDecoder.decodeInt(jsonPath + ".offset", json["offset"]);
+      }
+      return new EditImportElementsParams(file, elements, offset: offset);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "edit.importElements params", json);
     }
@@ -10382,6 +10409,9 @@
     result["file"] = file;
     result["elements"] =
         elements.map((ImportedElements value) => value.toJson()).toList();
+    if (offset != null) {
+      result["offset"] = offset;
+    }
     return result;
   }
 
@@ -10398,7 +10428,8 @@
     if (other is EditImportElementsParams) {
       return file == other.file &&
           listEqual(elements, other.elements,
-              (ImportedElements a, ImportedElements b) => a == b);
+              (ImportedElements a, ImportedElements b) => a == b) &&
+          offset == other.offset;
     }
     return false;
   }
@@ -10408,6 +10439,7 @@
     int hash = 0;
     hash = JenkinsSmiHash.combine(hash, file.hashCode);
     hash = JenkinsSmiHash.combine(hash, elements.hashCode);
+    hash = JenkinsSmiHash.combine(hash, offset.hashCode);
     return JenkinsSmiHash.finish(hash);
   }
 }
@@ -21541,7 +21573,7 @@
  *
  * {
  *   "lexeme": String
- *   "type": String
+ *   "type": optional String
  *   "validElementKinds": optional List<String>
  * }
  *
@@ -21555,12 +21587,12 @@
   List<String> _validElementKinds;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   String get lexeme => _lexeme;
 
   /**
-   * The raw token text.
+   * The token's lexeme.
    */
   void set lexeme(String value) {
     assert(value != null);
@@ -21568,31 +21600,38 @@
   }
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   String get type => _type;
 
   /**
-   * The type of this token.
+   * A unique id for the type of the identifier. Omitted if the token is not an
+   * identifier in a reference position.
    */
   void set type(String value) {
-    assert(value != null);
     this._type = value;
   }
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   List<String> get validElementKinds => _validElementKinds;
 
   /**
-   * The kinds of elements which could validly replace this token.
+   * An indication of whether this token is in a declaration or reference
+   * position. (If no other purpose is found for this field then it should be
+   * renamed and converted to a boolean value.) Omitted if the token is not an
+   * identifier.
    */
   void set validElementKinds(List<String> value) {
     this._validElementKinds = value;
   }
 
-  TokenDetails(String lexeme, String type, {List<String> validElementKinds}) {
+  TokenDetails(String lexeme, {String type, List<String> validElementKinds}) {
     this.lexeme = lexeme;
     this.type = type;
     this.validElementKinds = validElementKinds;
@@ -21613,8 +21652,6 @@
       String type;
       if (json.containsKey("type")) {
         type = jsonDecoder.decodeString(jsonPath + ".type", json["type"]);
-      } else {
-        throw jsonDecoder.mismatch(jsonPath, "type");
       }
       List<String> validElementKinds;
       if (json.containsKey("validElementKinds")) {
@@ -21623,8 +21660,8 @@
             json["validElementKinds"],
             jsonDecoder.decodeString);
       }
-      return new TokenDetails(lexeme, type,
-          validElementKinds: validElementKinds);
+      return new TokenDetails(lexeme,
+          type: type, validElementKinds: validElementKinds);
     } else {
       throw jsonDecoder.mismatch(jsonPath, "TokenDetails", json);
     }
@@ -21634,7 +21671,9 @@
   Map<String, dynamic> toJson() {
     Map<String, dynamic> result = {};
     result["lexeme"] = lexeme;
-    result["type"] = type;
+    if (type != null) {
+      result["type"] = type;
+    }
     if (validElementKinds != null) {
       result["validElementKinds"] = validElementKinds;
     }
diff --git a/pkg/analyzer/lib/dart/element/element.dart b/pkg/analyzer/lib/dart/element/element.dart
index 156688d..f79078a 100644
--- a/pkg/analyzer/lib/dart/element/element.dart
+++ b/pkg/analyzer/lib/dart/element/element.dart
@@ -523,6 +523,10 @@
   /// Return `true` if this element has an annotation of the form '@literal'.
   bool get hasLiteral;
 
+  /// Return `true` if this element has an annotation of the form
+  /// `@optionalTypeArgs`.
+  bool get hasOptionalTypeArgs;
+
   /// Return `true` if this element has an annotation of the form `@override`.
   bool get hasOverride;
 
@@ -747,6 +751,10 @@
   /// overriding methods to call super.
   bool get isMustCallSuper;
 
+  /// Return `true` if this annotation marks the associated type as
+  /// having "optional" type arguments.
+  bool get isOptionalTypeArgs;
+
   /// Return `true` if this annotation marks the associated method as being
   /// expected to override an inherited method.
   bool get isOverride;
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index c5b2489..266e0f2 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -11,6 +11,7 @@
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/resolver.dart' show ResolverErrorCode;
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/manifest/manifest_warning_code.dart';
 import 'package:front_end/src/base/errors.dart';
 import 'package:front_end/src/scanner/errors.dart';
 
@@ -230,6 +231,7 @@
   CompileTimeErrorCode.NOT_ENOUGH_REQUIRED_ARGUMENTS,
   CompileTimeErrorCode.NOT_ITERABLE_SPREAD,
   CompileTimeErrorCode.NOT_MAP_SPREAD,
+  CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
   CompileTimeErrorCode.NO_ANNOTATION_CONSTRUCTOR_ARGUMENTS,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_EXPLICIT,
   CompileTimeErrorCode.NO_DEFAULT_SUPER_CONSTRUCTOR_IMPLICIT,
@@ -355,6 +357,9 @@
   HintCode.UNUSED_LABEL,
   HintCode.UNUSED_LOCAL_VARIABLE,
   HintCode.UNUSED_SHOWN_NAME,
+  ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE,
+  ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE,
+  ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE,
   ParserErrorCode.ABSTRACT_CLASS_MEMBER,
   ParserErrorCode.ABSTRACT_ENUM,
   ParserErrorCode.ABSTRACT_STATIC_METHOD,
@@ -528,6 +533,7 @@
   ParserErrorCode.TOP_LEVEL_OPERATOR,
   ParserErrorCode.TYPEDEF_IN_CLASS,
   ParserErrorCode.TYPE_ARGUMENTS_ON_TYPE_VARIABLE,
+  ParserErrorCode.TYPE_BEFORE_FACTORY,
   ParserErrorCode.UNEXPECTED_TERMINATOR_FOR_PARAMETER_GROUP,
   ParserErrorCode.UNEXPECTED_TOKEN,
   ParserErrorCode.VAR_AND_TYPE,
diff --git a/pkg/analyzer/lib/src/dart/ast/utilities.dart b/pkg/analyzer/lib/src/dart/ast/utilities.dart
index f9db9f8..b5fde2b 100644
--- a/pkg/analyzer/lib/src/dart/ast/utilities.dart
+++ b/pkg/analyzer/lib/src/dart/ast/utilities.dart
@@ -7993,7 +7993,12 @@
         if (i > 0) {
           sink.write(separator);
         }
-        nodes[i].accept(this);
+        var node = nodes[i];
+        if (node != null) {
+          node.accept(this);
+        } else {
+          sink.write('<null>');
+        }
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/dart/constant/evaluation.dart b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
index 789609e..112dce6 100644
--- a/pkg/analyzer/lib/src/dart/constant/evaluation.dart
+++ b/pkg/analyzer/lib/src/dart/constant/evaluation.dart
@@ -1160,6 +1160,10 @@
       return _dartObjectComputer.eagerXor(
           node, leftResult, rightResult, experimentStatus.constant_update_2018);
     } else if (operatorType == TokenType.EQ_EQ) {
+      if (experimentStatus.constant_update_2018) {
+        return _dartObjectComputer.lazyEqualEqual(
+            node, leftResult, rightResult);
+      }
       return _dartObjectComputer.equalEqual(node, leftResult, rightResult);
     } else if (operatorType == TokenType.GT) {
       return _dartObjectComputer.greaterThan(node, leftResult, rightResult);
@@ -2012,6 +2016,18 @@
     return null;
   }
 
+  DartObjectImpl lazyEqualEqual(Expression node, DartObjectImpl leftOperand,
+      DartObjectImpl rightOperand) {
+    if (leftOperand != null && rightOperand != null) {
+      try {
+        return leftOperand.lazyEqualEqual(_typeProvider, rightOperand);
+      } on EvaluationException catch (exception) {
+        _errorReporter.reportErrorForNode(exception.errorCode, node);
+      }
+    }
+    return null;
+  }
+
   DartObjectImpl lazyOr(BinaryExpression node, DartObjectImpl leftOperand,
       DartObjectImpl rightOperandComputer()) {
     if (leftOperand != null) {
diff --git a/pkg/analyzer/lib/src/dart/constant/value.dart b/pkg/analyzer/lib/src/dart/constant/value.dart
index bb01428..1b93859 100644
--- a/pkg/analyzer/lib/src/dart/constant/value.dart
+++ b/pkg/analyzer/lib/src/dart/constant/value.dart
@@ -109,6 +109,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lazyOr(InstanceState rightOperandComputer()) {
     if (value == true) {
       return TRUE_STATE;
@@ -563,6 +568,31 @@
           _state.lazyAnd(() => rightOperandComputer()?._state));
 
   /**
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand]. The [typeProvider] is the type provider used to find known
+   * types.
+   *
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
+   */
+  DartObjectImpl lazyEqualEqual(
+      TypeProvider typeProvider, DartObjectImpl rightOperand) {
+    if (isNull || rightOperand.isNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType,
+          isNull && rightOperand.isNull
+              ? BoolState.TRUE_STATE
+              : BoolState.FALSE_STATE);
+    }
+    if (isBoolNumStringOrNull) {
+      return new DartObjectImpl(
+          typeProvider.boolType, _state.lazyEqualEqual(rightOperand._state));
+    }
+    throw new EvaluationException(
+        CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
+  }
+
+  /**
    * Return the result of invoking the '||' operator on this object with the
    * [rightOperand]. The [typeProvider] is the type provider used to find known
    * types.
@@ -1077,6 +1107,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -1313,6 +1348,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   BoolState lazyOr(InstanceState rightOperandComputer()) {
     InstanceState rightOperand = rightOperandComputer();
     assertBool(rightOperand);
@@ -1452,6 +1492,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => _element == null ? "-unknown-" : _element.name;
 }
 
@@ -1544,6 +1589,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     List<String> fieldNames = _fieldMap.keys.toList();
@@ -1855,6 +1905,15 @@
   }
 
   /**
+   * Return the result of invoking the '==' operator on this object with the
+   * [rightOperand].
+   *
+   * Throws an [EvaluationException] if the operator is not appropriate for an
+   * object of this kind.
+   */
+  BoolState lazyEqualEqual(InstanceState rightOperand);
+
+  /**
    * Return the result of invoking the '||' operator on this object with the
    * [rightOperand].
    *
@@ -2348,6 +2407,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     if (value == null) {
@@ -2640,6 +2704,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('[');
@@ -2724,6 +2793,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('{');
@@ -2791,6 +2865,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   BoolState logicalNot() {
     throw new EvaluationException(
         CompileTimeErrorCode.CONST_EVAL_THROWS_EXCEPTION);
@@ -2880,6 +2959,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return BoolState.UNKNOWN_VALUE;
+  }
+
+  @override
   BoolState lessThan(InstanceState rightOperand) {
     assertNumOrNull(rightOperand);
     return BoolState.UNKNOWN_VALUE;
@@ -2982,6 +3066,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() {
     StringBuffer buffer = new StringBuffer();
     buffer.write('{');
@@ -3078,6 +3167,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   IntState stringLength() {
     if (value == null) {
       return IntState.UNKNOWN_VALUE;
@@ -3145,6 +3239,11 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => value == null ? "-unknown-" : "#$value";
 }
 
@@ -3204,5 +3303,10 @@
   }
 
   @override
+  BoolState lazyEqualEqual(InstanceState rightOperand) {
+    return isIdentical(rightOperand);
+  }
+
+  @override
   String toString() => _type?.toString() ?? "-unknown-";
 }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 8cbeb21..743595d 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -32,6 +32,7 @@
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/util/comment.dart';
 
 /// Assert that the given [object] is null, which in the places where this
 /// function is called means that the element is not resynthesized.
@@ -61,7 +62,7 @@
   AbstractClassElementImpl(String name, int offset) : super(name, offset);
 
   AbstractClassElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
@@ -460,11 +461,9 @@
         super(name, offset);
 
   ClassElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
+      Reference reference, AstNode linkedNode)
       : _unlinkedClass = null,
-        super.forLinkedNode(enclosing, reference, linkedNode) {
-    enclosing.linkedContext.loadClassMemberReferences(reference);
-  }
+        super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
   ClassElementImpl.forNode(Identifier name)
@@ -484,11 +483,10 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
-    if (linkedNode != null) {
-      if (_accessors != null) return _accessors;
+    if (_accessors != null) return _accessors;
 
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
+    if (linkedNode != null) {
+      if (linkedNode is ClassOrMixinDeclaration) {
         _createPropertiesAndAccessors();
         assert(_accessors != null);
         return _accessors;
@@ -496,12 +494,14 @@
         return _accessors = const [];
       }
     }
+
     if (_accessors == null) {
       if (_unlinkedClass != null) {
         _resynthesizeFieldsAndPropertyAccessors();
       }
     }
-    return _accessors ?? const <PropertyAccessorElement>[];
+
+    return _accessors ??= const <PropertyAccessorElement>[];
   }
 
   @override
@@ -520,7 +520,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.codeRange?.length;
@@ -531,7 +531,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.codeRange?.offset;
@@ -552,16 +552,15 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@constructor');
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
-        _constructors = linkedNode.classOrMixinDeclaration_members
-            .where((node) => node.kind == LinkedNodeKind.constructorDeclaration)
-            .map((node) {
-          var name = context.getConstructorDeclarationName(node);
-          var reference = containerRef.getChild(name);
-          return ConstructorElementImpl.forLinkedNode(reference, node, this);
-        }).toList();
-      }
+      _constructors = context.getConstructors(linkedNode).map((node) {
+        var name = node.name?.name ?? '';
+        var reference = containerRef.getChild(name);
+        if (reference.element == null) {
+          reference.node2 = node;
+          ConstructorElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as ConstructorElement;
+      }).toList();
     }
 
     if (_unlinkedClass != null) {
@@ -619,9 +618,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.documentationComment?.text;
@@ -634,11 +633,10 @@
 
   @override
   List<FieldElement> get fields {
-    if (linkedNode != null) {
-      if (_fields != null) return _fields;
+    if (_fields != null) return _fields;
 
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
+    if (linkedNode != null) {
+      if (linkedNode is ClassOrMixinDeclaration) {
         _createPropertiesAndAccessors();
         assert(_fields != null);
         return _fields;
@@ -646,11 +644,13 @@
         _fields = const [];
       }
     }
+
     if (_fields == null) {
       if (_unlinkedClass != null) {
         _resynthesizeFieldsAndPropertyAccessors();
       }
     }
+
     return _fields ?? const <FieldElement>[];
   }
 
@@ -748,10 +748,13 @@
       var context = enclosingUnit.linkedContext;
       var implementsClause = context.getImplementsClause(linkedNode);
       if (implementsClause != null) {
-        return _interfaces = implementsClause.implementsClause_interfaces
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        return _interfaces = implementsClause.interfaces
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
+            .where(_isInterfaceTypeInterface)
             .toList();
+      } else {
+        return _interfaces = const [];
       }
     } else if (_unlinkedClass != null) {
       var unlinkedInterfaces = _unlinkedClass.interfaces;
@@ -792,11 +795,7 @@
   @override
   bool get isAbstract {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-        return linkedNode.classDeclaration_abstractKeyword != 0;
-      } else {
-        return linkedNode.classTypeAlias_abstractKeyword != 0;
-      }
+      return enclosingUnit.linkedContext.isAbstract(linkedNode);
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.isAbstract;
@@ -807,7 +806,7 @@
   @override
   bool get isMixinApplication {
     if (linkedNode != null) {
-      return linkedNode.kind == LinkedNodeKind.classTypeAlias;
+      return linkedNode is ClassTypeAlias;
     }
     if (_unlinkedClass != null) {
       return _unlinkedClass.isMixinApplication;
@@ -830,6 +829,14 @@
   }
 
   @override
+  bool get isSimplyBounded {
+//    if (linkedNode != null) {
+//      return linkedNode.simplyBoundable_isSimplyBounded;
+//    }
+    return super.isSimplyBounded;
+  }
+
+  @override
   bool get isValidMixin {
     if (hasReferenceToSuper) {
       return false;
@@ -863,19 +870,18 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@method');
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration ||
-          linkedNode.kind == LinkedNodeKind.mixinDeclaration) {
-        return _methods = linkedNode.classOrMixinDeclaration_members
-            .where((node) => node.kind == LinkedNodeKind.methodDeclaration)
-            .where((node) => node.methodDeclaration_propertyKeyword == 0)
-            .map((node) {
-          var name = context.getSimpleName(node.methodDeclaration_name);
-          var reference = containerRef.getChild(name);
-          return MethodElementImpl.forLinkedNode(reference, node, this);
-        }).toList();
-      } else {
-        return _methods = const <MethodElement>[];
-      }
+      return _methods = context
+          .getMethods(linkedNode)
+          .where((node) => node.propertyKeyword == null)
+          .map((node) {
+        var name = node.name.name;
+        var reference = containerRef.getChild(name);
+        if (reference.element == null) {
+          reference.node2 = node;
+          MethodElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as MethodElement;
+      }).toList();
     }
 
     if (_unlinkedClass != null) {
@@ -933,17 +939,15 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      LinkedNode withClause;
-      if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-        withClause = linkedNode.classDeclaration_withClause;
-      } else {
-        withClause = linkedNode.classTypeAlias_withClause;
-      }
+      var withClause = context.getWithClause(linkedNode);
       if (withClause != null) {
-        return _mixins = withClause.withClause_mixinTypes
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        return _mixins = withClause.mixinTypes
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
+            .where(_isInterfaceTypeInterface)
             .toList();
+      } else {
+        return _mixins = const [];
       }
     } else if (_unlinkedClass != null) {
       var unlinkedMixins = _unlinkedClass.mixins;
@@ -1013,37 +1017,31 @@
 
   @override
   InterfaceType get supertype {
-    if (_supertype == null) {
-      if (linkedNode != null) {
-        LinkedNode superclass;
-        if (linkedNode.kind == LinkedNodeKind.classDeclaration) {
-          superclass = linkedNode
-              .classDeclaration_extendsClause?.extendsClause_superclass;
-        } else {
-          superclass = linkedNode.classTypeAlias_superclass;
-        }
-        if (superclass != null) {
-          var context = enclosingUnit.linkedContext;
-          _supertype = context.getInterfaceType(superclass.typeName_type);
-        } else if (!linkedNode.classDeclaration_isDartObject) {
-          _supertype = context.typeProvider.objectType;
-        }
-      } else if (_unlinkedClass != null) {
-        if (_unlinkedClass.supertype != null) {
-          DartType type = enclosingUnit.resynthesizerContext
-              .resolveTypeRef(this, _unlinkedClass.supertype);
-          if (_isInterfaceTypeClass(type)) {
-            _supertype = type;
-          } else {
-            _supertype = context.typeProvider.objectType;
-          }
-        } else if (_unlinkedClass.hasNoSupertype) {
-          return null;
+    if (_supertype != null) return _supertype;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var type = context.getSuperclass(linkedNode)?.type;
+      if (_isInterfaceTypeClass(type)) {
+        return _supertype = type;
+      }
+      return _supertype = this.context.typeProvider.objectType;
+    } else if (_unlinkedClass != null) {
+      if (_unlinkedClass.supertype != null) {
+        DartType type = enclosingUnit.resynthesizerContext
+            .resolveTypeRef(this, _unlinkedClass.supertype);
+        if (_isInterfaceTypeClass(type)) {
+          _supertype = type;
         } else {
           _supertype = context.typeProvider.objectType;
         }
+      } else if (_unlinkedClass.hasNoSupertype) {
+        return null;
+      } else {
+        _supertype = context.typeProvider.objectType;
       }
     }
+
     return _supertype;
   }
 
@@ -1069,17 +1067,21 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
+      var typeParameters = context.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      return _typeParameterElements = typeParameters.map((node) {
-        var name = context.getSimpleName(node.typeParameter_name);
+      return _typeParameterElements = typeParameters.typeParameters.map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as TypeParameterElementImpl;
       }).toList();
     }
+
     return super.typeParameters;
   }
 
@@ -1308,9 +1310,9 @@
     var accessorList = <PropertyAccessorElementImpl>[];
     var fieldList = <FieldElementImpl>[];
 
-    var fields = context.classFields(linkedNode);
+    var fields = context.getFields(linkedNode);
     for (var field in fields) {
-      var name = context.getVariableName(field);
+      var name = field.name.name;
       var fieldElement = FieldElementImpl.forLinkedNodeFactory(
         this,
         reference.getChild('@field').getChild(name),
@@ -1324,44 +1326,43 @@
       }
     }
 
-    for (var node in linkedNode.classOrMixinDeclaration_members) {
-      if (node.kind == LinkedNodeKind.methodDeclaration) {
-        var isGetter = context.isGetterMethod(node);
-        var isSetter = context.isSetterMethod(node);
-        if (!isGetter && !isSetter) continue;
+    var methods = context.getMethods(linkedNode);
+    for (var method in methods) {
+      var isGetter = method.isGetter;
+      var isSetter = method.isSetter;
+      if (!isGetter && !isSetter) continue;
 
-        var name = context.getMethodName(node);
-        var containerRef = isGetter
-            ? reference.getChild('@getter')
-            : reference.getChild('@setter');
+      var name = method.name.name;
+      var containerRef = isGetter
+          ? reference.getChild('@getter')
+          : reference.getChild('@setter');
 
-        var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
-          this,
-          containerRef.getChild(name),
-          node,
-        );
-        accessorList.add(accessorElement);
+      var accessorElement = PropertyAccessorElementImpl.forLinkedNode(
+        this,
+        containerRef.getChild(name),
+        method,
+      );
+      accessorList.add(accessorElement);
 
-        var fieldRef = reference.getChild('@field').getChild(name);
-        FieldElementImpl field = fieldRef.element;
-        if (field == null) {
-          field = new FieldElementImpl(name, -1);
-          fieldRef.element = field;
-          field.enclosingElement = this;
-          field.isSynthetic = true;
-          field.isFinal = isGetter;
-          field.isStatic = accessorElement.isStatic;
-          fieldList.add(field);
-        } else {
-          field.isFinal = false;
-        }
+      var fieldRef = reference.getChild('@field').getChild(name);
+      FieldElementImpl field = fieldRef.element;
+      if (field == null) {
+        field = new FieldElementImpl(name, -1);
+        fieldRef.element = field;
+        field.enclosingElement = this;
+        field.isSynthetic = true;
+        field.isFinal = isGetter;
+        field.isStatic = accessorElement.isStatic;
+        fieldList.add(field);
+      } else {
+        field.isFinal = false;
+      }
 
-        accessorElement.variable = field;
-        if (isGetter) {
-          field.getter = accessorElement;
-        } else {
-          field.setter = accessorElement;
-        }
+      accessorElement.variable = field;
+      if (isGetter) {
+        field.getter = accessorElement;
+      } else {
+        field.setter = accessorElement;
       }
     }
 
@@ -1640,7 +1641,7 @@
         super(null, -1);
 
   CompilationUnitElementImpl.forLinkedNode(LibraryElementImpl enclosingLibrary,
-      this.linkedContext, Reference reference, LinkedNode linkedNode)
+      this.linkedContext, Reference reference, CompilationUnit linkedNode)
       : resynthesizerContext = null,
         _unlinkedUnit = null,
         _unlinkedPart = null,
@@ -1657,25 +1658,26 @@
 
   @override
   List<PropertyAccessorElement> get accessors {
+    if (_accessors != null) return _accessors;
+
     if (linkedNode != null) {
-      if (_accessors != null) return _accessors;
       _createPropertiesAndAccessors(this);
       assert(_accessors != null);
       return _accessors;
     }
-    if (_accessors == null) {
-      if (_unlinkedUnit != null) {
-        _explicitTopLevelAccessors ??=
-            resynthesizerContext.buildTopLevelAccessors();
-        _explicitTopLevelVariables ??=
-            resynthesizerContext.buildTopLevelVariables();
-      }
-      if (_explicitTopLevelAccessors != null) {
-        _accessors = <PropertyAccessorElementImpl>[]
-          ..addAll(_explicitTopLevelAccessors.accessors)
-          ..addAll(_explicitTopLevelVariables.implicitAccessors);
-      }
+
+    if (_unlinkedUnit != null) {
+      _explicitTopLevelAccessors ??=
+          resynthesizerContext.buildTopLevelAccessors();
+      _explicitTopLevelVariables ??=
+          resynthesizerContext.buildTopLevelVariables();
     }
+    if (_explicitTopLevelAccessors != null) {
+      _accessors = <PropertyAccessorElementImpl>[]
+        ..addAll(_explicitTopLevelAccessors.accessors)
+        ..addAll(_explicitTopLevelVariables.implicitAccessors);
+    }
+
     return _accessors ?? const <PropertyAccessorElement>[];
   }
 
@@ -1715,25 +1717,28 @@
 
   @override
   List<ClassElement> get enums {
+    if (_enums != null) return _enums;
+
     if (linkedNode != null) {
-      if (_enums != null) return _enums;
-      var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@enum');
-      _enums = linkedNode.compilationUnit_declarations
-          .where((node) => node.kind == LinkedNodeKind.enumDeclaration)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      CompilationUnit linkedNode = this.linkedNode;
+      _enums = linkedNode.declarations.whereType<EnumDeclaration>().map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return EnumElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          EnumElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as EnumElementImpl;
       }).toList();
     }
+
     if (_unlinkedUnit != null) {
-      _enums ??= _unlinkedUnit.enums
+      return _enums = _unlinkedUnit.enums
           .map((e) => new EnumElementImpl.forSerialized(e, this))
           .toList(growable: false);
     }
-    return _enums ?? const <ClassElement>[];
+    return _enums ??= const <ClassElement>[];
   }
 
   /// Set the enums contained in this compilation unit to the given [enums].
@@ -1750,17 +1755,19 @@
     if (_functions != null) return _functions;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@function');
-      _functions = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.functionDeclaration &&
-              !context.isGetterFunction(node) &&
-              !context.isSetterFunction(node))
+      return _functions = linkedNode.declarations
+          .whereType<FunctionDeclaration>()
+          .where((node) => !node.isGetter && !node.isSetter)
           .map((node) {
-        var name = context.getUnitMemberName(node);
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        return FunctionElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          FunctionElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as FunctionElementImpl;
       }).toList();
     } else if (_unlinkedUnit != null) {
       _functions = _unlinkedUnit.executables
@@ -1785,16 +1792,24 @@
     if (_typeAliases != null) return _typeAliases;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@typeAlias');
-      _typeAliases = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.functionTypeAlias ||
-              node.kind == LinkedNodeKind.genericTypeAlias)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      return _typeAliases = linkedNode.declarations.where((node) {
+        return node is FunctionTypeAlias || node is GenericTypeAlias;
+      }).map((node) {
+        String name;
+        if (node is FunctionTypeAlias) {
+          name = node.name.name;
+        } else {
+          name = (node as GenericTypeAlias).name.name;
+        }
+
         var reference = containerRef.getChild(name);
-        return GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          GenericTypeAliasElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as GenericTypeAliasElement;
       }).toList();
     }
 
@@ -1843,15 +1858,17 @@
     if (_mixins != null) return _mixins;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
-      return _mixins = linkedNode.compilationUnit_declarations
-          .where((node) => node.kind == LinkedNodeKind.mixinDeclaration)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      var declarations = linkedNode.declarations;
+      return _mixins = declarations.whereType<MixinDeclaration>().map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return MixinElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          MixinElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as MixinElementImpl;
       }).toList();
     }
 
@@ -1937,18 +1954,26 @@
     if (_types != null) return _types;
 
     if (linkedNode != null) {
-      var context = enclosingUnit.linkedContext;
+      CompilationUnit linkedNode = this.linkedNode;
       var containerRef = reference.getChild('@class');
-      return _types = linkedNode.compilationUnit_declarations
-          .where((node) =>
-              node.kind == LinkedNodeKind.classDeclaration ||
-              node.kind == LinkedNodeKind.classTypeAlias)
-          .map((node) {
-        var name = context.getUnitMemberName(node);
+      _types = <ClassElement>[];
+      for (var node in linkedNode.declarations) {
+        String name;
+        if (node is ClassDeclaration) {
+          name = node.name.name;
+        } else if (node is ClassTypeAlias) {
+          name = node.name.name;
+        } else {
+          continue;
+        }
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return ClassElementImpl.forLinkedNode(this, reference, node);
-      }).toList();
+        if (reference.element == null) {
+          reference.node2 = node;
+          ClassElementImpl.forLinkedNode(this, reference, node);
+        }
+        _types.add(reference.element);
+      }
+      return _types;
     }
 
     if (_unlinkedUnit != null) {
@@ -2131,9 +2156,12 @@
       var variableList = <TopLevelVariableElementImpl>[];
       variableMap[unit] = variableList;
 
-      var variables = context.topLevelVariables(unit.linkedNode);
+      var unitNode = unit.linkedContext.unit_withDeclarations;
+      var unitDeclarations = unitNode.declarations;
+
+      var variables = context.topLevelVariables(unitNode);
       for (var variable in variables) {
-        var name = context.getVariableName(variable);
+        var name = variable.name.name;
         var reference = unit.reference.getChild('@variable').getChild(name);
         var variableElement = TopLevelVariableElementImpl.forLinkedNodeFactory(
           unit,
@@ -2148,13 +2176,13 @@
         }
       }
 
-      for (var node in unit.linkedNode.compilationUnit_declarations) {
-        if (node.kind == LinkedNodeKind.functionDeclaration) {
-          var isGetter = context.isGetterFunction(node);
-          var isSetter = context.isSetterFunction(node);
+      for (var node in unitDeclarations) {
+        if (node is FunctionDeclaration) {
+          var isGetter = node.isGetter;
+          var isSetter = node.isSetter;
           if (!isGetter && !isSetter) continue;
 
-          var name = context.getUnitMemberName(node);
+          var name = node.name.name;
           var containerRef = isGetter
               ? unit.reference.getChild('@getter')
               : unit.reference.getChild('@setter');
@@ -2210,7 +2238,7 @@
   ConstFieldElementImpl(String name, int offset) : super(name, offset);
 
   ConstFieldElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created field element to have the given [name].
@@ -2232,7 +2260,7 @@
       : super(enumElement);
 
   ConstFieldElementImpl_EnumValue.forLinkedNode(EnumElementImpl enumElement,
-      Reference reference, LinkedNode linkedNode, this._index)
+      Reference reference, AstNode linkedNode, this._index)
       : _unlinkedEnumValue = null,
         super.forLinkedNode(enumElement, reference, linkedNode);
 
@@ -2242,9 +2270,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedEnumValue != null) {
       return _unlinkedEnumValue.documentationComment?.text;
@@ -2289,9 +2317,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.enumConstantDeclaration_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
     int offset = super.nameOffset;
     if (offset == -1) {
@@ -2350,7 +2376,7 @@
   }
 
   ConstFieldElementImpl_ofEnum.forLinkedNode(
-      this._enum, Reference reference, LinkedNode linkedNode)
+      this._enum, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(_enum, reference, linkedNode);
 
   @override
@@ -2429,8 +2455,8 @@
   /// and [offset].
   ConstructorElementImpl(String name, int offset) : super(name, offset);
 
-  ConstructorElementImpl.forLinkedNode(Reference reference,
-      LinkedNode linkedNode, ClassElementImpl enclosingClass)
+  ConstructorElementImpl.forLinkedNode(ClassElementImpl enclosingClass,
+      Reference reference, ConstructorDeclaration linkedNode)
       : super.forLinkedNode(enclosingClass, reference, linkedNode);
 
   /// Initialize a newly created constructor element to have the given [name].
@@ -2445,13 +2471,13 @@
   /// there are no initializers, or `null` if there was an error in the source.
   List<ConstructorInitializer> get constantInitializers {
     if (_constantInitializers == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        return _constantInitializers ??=
-            linkedNode.constructorDeclaration_initializers.map((node) {
-          return context.readNode(node) as ConstructorInitializer;
-        }).toList();
-      }
+//      if (linkedNode != null) {
+//        var context = enclosingUnit.linkedContext;
+//        return _constantInitializers ??=
+//            linkedNode.constructorDeclaration_initializers.map((node) {
+//          return context.readNode(node) as ConstructorInitializer;
+//        }).toList();
+//      }
 
       if (serializedExecutable != null) {
         _constantInitializers = serializedExecutable.constantInitializers
@@ -2493,7 +2519,8 @@
   @override
   bool get isConst {
     if (linkedNode != null) {
-      return linkedNode.constructorDeclaration_constKeyword != 0;
+      ConstructorDeclaration linkedNode = this.linkedNode;
+      return linkedNode.constKeyword != null;
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isConst;
@@ -2542,7 +2569,8 @@
   @override
   bool get isFactory {
     if (linkedNode != null) {
-      return linkedNode.constructorDeclaration_factoryKeyword != 0;
+      ConstructorDeclaration linkedNode = this.linkedNode;
+      return linkedNode.factoryKeyword != null;
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isFactory;
@@ -2599,24 +2627,24 @@
   @override
   ConstructorElement get redirectedConstructor {
     if (_redirectedConstructor == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        if (isFactory) {
-          var node = linkedNode.constructorDeclaration_redirectedConstructor;
-          if (node != null) {
-            ConstructorName ast = context.readNode(node);
-            return ast.staticElement;
-          }
-        } else {
-          for (var node in linkedNode.constructorDeclaration_initializers) {
-            if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) {
-              RedirectingConstructorInvocation ast = context.readNode(node);
-              return ast.staticElement;
-            }
-          }
-        }
-        return null;
-      }
+//      if (linkedNode != null) {
+//        var context = enclosingUnit.linkedContext;
+//        if (isFactory) {
+//          var node = linkedNode.constructorDeclaration_redirectedConstructor;
+//          if (node != null) {
+//            ConstructorName ast = context.readNode(node);
+//            return ast.staticElement;
+//          }
+//        } else {
+//          for (var node in linkedNode.constructorDeclaration_initializers) {
+//            if (node.kind == LinkedNodeKind.redirectingConstructorInvocation) {
+//              RedirectingConstructorInvocation ast = context.readNode(node);
+//              return ast.staticElement;
+//            }
+//          }
+//        }
+//        return null;
+//      }
 
       if (serializedExecutable != null) {
         if (serializedExecutable.isRedirectedConstructor) {
@@ -2759,7 +2787,7 @@
       : super(name, offset);
 
   ConstTopLevelVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created top-level variable element to have the given
@@ -2850,7 +2878,7 @@
       : super(name, nameOffset);
 
   DefaultFieldFormalParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -2872,7 +2900,7 @@
       : super(name, nameOffset);
 
   DefaultParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -2938,6 +2966,10 @@
   /// literal.
   static String _LITERAL_VARIABLE_NAME = "literal";
 
+  /// The name of the top-level variable used to mark a type as having
+  /// "optional" type arguments.
+  static String _OPTIONAL_TYPE_ARGS_VARIABLE_NAME = "optionalTypeArgs";
+
   /// The name of the top-level variable used to mark a function as running
   /// a single test.
   static String _IS_TEST_VARIABLE_NAME = "isTest";
@@ -3087,6 +3119,12 @@
       element.library?.name == _META_LIB_NAME;
 
   @override
+  bool get isOptionalTypeArgs =>
+      element is PropertyAccessorElement &&
+      element.name == _OPTIONAL_TYPE_ARGS_VARIABLE_NAME &&
+      element.library?.name == _META_LIB_NAME;
+
+  @override
   bool get isOverride =>
       element is PropertyAccessorElement &&
       element.name == _OVERRIDE_VARIABLE_NAME &&
@@ -3168,7 +3206,7 @@
   ElementImpl _enclosingElement;
 
   Reference reference;
-  final LinkedNode linkedNode;
+  final AstNode linkedNode;
 
   /// The name of this element.
   String _name;
@@ -3358,6 +3396,18 @@
   }
 
   @override
+  bool get hasOptionalTypeArgs {
+    var metadata = this.metadata;
+    for (var i = 0; i < metadata.length; i++) {
+      var annotation = metadata[i];
+      if (annotation.isOptionalTypeArgs) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
   bool get hasOverride {
     var metadata = this.metadata;
     for (var i = 0; i < metadata.length; i++) {
@@ -3492,6 +3542,10 @@
   @override
   Source get librarySource => library?.source;
 
+  LinkedUnitContext get linkedContext {
+    return _enclosingElement.linkedContext;
+  }
+
   @override
   ElementLocation get location {
     if (_cachedLocation == null) {
@@ -3506,7 +3560,7 @@
   List<ElementAnnotation> get metadata {
     if (linkedNode != null) {
       if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
+      var metadata = linkedContext.getMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
     return _metadata ?? const <ElementAnnotation>[];
@@ -3720,7 +3774,7 @@
 
   /// Return annotations for the given [nodeList] in the [unit].
   List<ElementAnnotation> _buildAnnotations2(
-      CompilationUnitElementImpl unit, List<LinkedNode> nodeList) {
+      CompilationUnitElementImpl unit, List<Annotation> nodeList) {
     var length = nodeList.length;
     if (length == 0) {
       return const <ElementAnnotation>[];
@@ -3728,7 +3782,7 @@
 
     var annotations = new List<ElementAnnotation>(length);
     for (int i = 0; i < length; i++) {
-      var ast = unit.linkedContext.readNode(nodeList[i]);
+      var ast = nodeList[i];
       annotations[i] = ElementAnnotationImpl(enclosingUnit)
         ..annotationAst = ast;
     }
@@ -3922,7 +3976,7 @@
         super(name, offset);
 
   EnumElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
+      Reference reference, EnumDeclaration linkedNode)
       : _unlinkedEnum = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -3966,7 +4020,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.codeRange?.length;
@@ -3977,7 +4031,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.codeRange?.offset;
@@ -3997,9 +4051,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedEnum != null) {
       return _unlinkedEnum.documentationComment?.text;
@@ -4209,13 +4263,12 @@
     }
 
     // Build fields for all enum constants.
-    var constants = linkedNode.enumDeclaration_constants;
+    var containerRef = this.reference.getChild('@constant');
+    var constants = linkedContext.getEnumConstants(linkedNode);
     for (var i = 0; i < constants.length; ++i) {
       var constant = constants[i];
-      var name = enclosingUnit.linkedContext.getSimpleName(
-        constant.enumConstantDeclaration_name,
-      );
-      var reference = this.reference.getChild('@constant').getChild(name);
+      var name = constant.name.name;
+      var reference = containerRef.getChild(name);
       var field = new ConstFieldElementImpl_EnumValue.forLinkedNode(
           this, reference, constant, i);
       fields.add(field);
@@ -4256,7 +4309,7 @@
 
   /// Initialize using the given linked node.
   ExecutableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : serializedExecutable = null,
         super.forLinkedNode(enclosing, reference, linkedNode) {
     reference.element = this;
@@ -4281,7 +4334,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.codeRange?.length;
@@ -4292,7 +4345,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.codeRange?.offset;
@@ -4319,9 +4372,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.documentationComment?.text;
@@ -4358,6 +4411,9 @@
 
   @override
   bool get isAbstract {
+    if (linkedNode != null) {
+      return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode);
+    }
     if (serializedExecutable != null) {
       return serializedExecutable.isAbstract;
     }
@@ -4426,9 +4482,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.namedCompilationUnitMember_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
 
     int offset = super.nameOffset;
@@ -4440,24 +4494,26 @@
 
   @override
   List<ParameterElement> get parameters {
-    if (_parameters == null) {
-      if (linkedNode != null) {
-        var context = enclosingUnit.linkedContext;
-        var containerRef = reference.getChild('@parameter');
-        var formalParameters = context.getFormalParameters(linkedNode);
-        _parameters = ParameterElementImpl.forLinkedNodeList(
-          this,
-          context,
-          containerRef,
-          formalParameters,
-        );
-      }
-      if (serializedExecutable != null) {
-        _parameters = ParameterElementImpl.resynthesizeList(
-            serializedExecutable.parameters, this);
-      }
+    if (_parameters != null) return _parameters;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var containerRef = reference.getChild('@parameter');
+      var formalParameters = context.getFormalParameters(linkedNode);
+      _parameters = ParameterElementImpl.forLinkedNodeList(
+        this,
+        context,
+        containerRef,
+        formalParameters,
+      );
     }
-    return _parameters ?? const <ParameterElement>[];
+
+    if (serializedExecutable != null) {
+      _parameters = ParameterElementImpl.resynthesizeList(
+          serializedExecutable.parameters, this);
+    }
+
+    return _parameters ??= const <ParameterElement>[];
   }
 
   /// Set the parameters defined by this executable element to the given
@@ -4473,8 +4529,10 @@
   @override
   DartType get returnType {
     if (linkedNode != null) {
-      return _returnType ??=
-          enclosingUnit.linkedContext.getReturnType(linkedNode);
+      if (_returnType != null) return _returnType;
+      return _returnType = enclosingUnit.linkedContext.getReturnType(
+        linkedNode,
+      );
     }
     if (serializedExecutable != null &&
         _declaredReturnType == null &&
@@ -4624,7 +4682,7 @@
         super(null, offset);
 
   ExportElementImpl.forLinkedNode(
-      LibraryElementImpl enclosing, LinkedNode linkedNode)
+      LibraryElementImpl enclosing, ExportDirective linkedNode)
       : _unlinkedExportPublic = null,
         _unlinkedExportNonPublic = null,
         super.forLinkedNode(enclosing, null, linkedNode);
@@ -4639,9 +4697,10 @@
     if (_combinators != null) return _combinators;
 
     if (linkedNode != null) {
+      ExportDirective node = linkedNode;
       return _combinators = ImportElementImpl._buildCombinators2(
         enclosingUnit.linkedContext,
-        linkedNode,
+        node.combinators,
       );
     }
 
@@ -4670,11 +4729,7 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      var relativeUriStr = context.getStringContent(
-        linkedNode.uriBasedDirective_uri,
-      );
-      var relativeUri = Uri.parse(relativeUriStr);
-      var uri = resolveRelativeUri(librarySource.uri, relativeUri);
+      var uri = context.directiveUri(librarySource.uri, linkedNode);
       var elementFactory = context.bundleContext.elementFactory;
       return _exportedLibrary = elementFactory.libraryOfUri('$uri');
     }
@@ -4700,11 +4755,6 @@
 
   @override
   List<ElementAnnotation> get metadata {
-    if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
-      return _metadata = _buildAnnotations2(enclosingUnit, metadata);
-    }
     if (_metadata == null) {
       if (_unlinkedExportNonPublic != null) {
         return _metadata = _buildAnnotations(library.definingCompilationUnit,
@@ -4789,7 +4839,7 @@
   FieldElementImpl(String name, int offset) : super(name, offset);
 
   FieldElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
@@ -4809,7 +4859,7 @@
   }
 
   factory FieldElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
+      ElementImpl enclosing, Reference reference, AstNode linkedNode) {
     if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) {
       return ConstFieldElementImpl.forLinkedNode(
         enclosing,
@@ -4850,14 +4900,13 @@
   @override
   bool get isCovariant {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.variableDeclaration) {
-        return linkedNode.variableDeclaration_declaration.isCovariant;
-      }
-      return false;
+      return linkedContext.isCovariantField(linkedNode);
     }
+
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.isCovariant;
     }
+
     return hasModifier(Modifier.COVARIANT);
   }
 
@@ -4922,7 +4971,7 @@
       : super(name, nameOffset);
 
   FieldFormalParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created parameter element to have the given [name].
@@ -5001,8 +5050,8 @@
   /// [offset].
   FunctionElementImpl(String name, int offset) : super(name, offset);
 
-  FunctionElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+  FunctionElementImpl.forLinkedNode(ElementImpl enclosing, Reference reference,
+      FunctionDeclaration linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created function element to have the given [name].
@@ -5030,6 +5079,14 @@
   }
 
   @override
+  String get displayName {
+    if (linkedNode != null) {
+      return reference.name;
+    }
+    return super.displayName;
+  }
+
+  @override
   TypeParameterizedElementMixin get enclosingTypeParameterContext {
     return (enclosingElement as ElementImpl).typeParameterContext;
   }
@@ -5056,20 +5113,18 @@
   ElementKind get kind => ElementKind.FUNCTION;
 
   @override
-  DartType get returnType {
+  String get name {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getType(
-        linkedNode.functionDeclaration_returnType2,
-      );
+      return reference.name;
     }
-    return super.returnType;
+    return super.name;
   }
 
   @override
   void set returnType(DartType returnType) {
-    if (linkedNode != null) {
-      enclosingUnit.linkedContext.setReturnType(linkedNode, returnType);
-    }
+//    if (linkedNode != null) {
+//      enclosingUnit.linkedContext.setReturnType(linkedNode, returnType);
+//    }
     super.returnType = returnType;
   }
 
@@ -5242,7 +5297,7 @@
   FunctionType _type;
 
   GenericFunctionTypeElementImpl.forLinkedNode(
-      ElementImpl enclosingElement, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosingElement, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosingElement, reference, linkedNode);
 
   /// Initialize a newly created function element to have no name and the given
@@ -5335,7 +5390,7 @@
   @override
   List<TypeParameterElement> get typeParameters {
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.functionTypeAlias) {
+      if (linkedNode is FunctionTypeAlias) {
         return const <TypeParameterElement>[];
       }
     }
@@ -5425,7 +5480,7 @@
   GenericTypeAliasElementImpl.forLinkedNode(
       CompilationUnitElementImpl enclosingUnit,
       Reference reference,
-      LinkedNode linkedNode)
+      AstNode linkedNode)
       : _unlinkedTypedef = null,
         super.forLinkedNode(enclosingUnit, reference, linkedNode);
 
@@ -5442,7 +5497,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.codeRange?.length;
@@ -5453,7 +5508,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.codeRange?.offset;
@@ -5467,9 +5522,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.annotatedNode_comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedTypedef != null) {
       return _unlinkedTypedef.documentationComment?.text;
@@ -5493,11 +5548,12 @@
     if (_function != null) return _function;
 
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.genericTypeAlias) {
-        _function = GenericFunctionTypeElementImpl.forLinkedNode(
+      if (linkedNode is GenericTypeAlias) {
+        var context = enclosingUnit.linkedContext;
+        return _function = GenericFunctionTypeElementImpl.forLinkedNode(
           this,
           reference.getChild('@function'),
-          linkedNode.genericTypeAlias_functionType,
+          context.getGeneticTypeAliasFunction(linkedNode),
         );
       } else {
         return _function = GenericFunctionTypeElementImpl.forLinkedNode(
@@ -5506,7 +5562,6 @@
           linkedNode,
         );
       }
-      return _function;
     }
 
     if (_unlinkedTypedef != null) {
@@ -5546,6 +5601,14 @@
   }
 
   @override
+  bool get isSimplyBounded {
+//    if (linkedNode != null) {
+//      return linkedNode.simplyBoundable_isSimplyBounded;
+//    }
+    return super.isSimplyBounded;
+  }
+
+  @override
   ElementKind get kind => ElementKind.FUNCTION_TYPE_ALIAS;
 
   @override
@@ -5706,7 +5769,7 @@
   final UnlinkedCombinator _unlinkedCombinator;
 
   final LinkedUnitContext linkedContext;
-  final LinkedNode linkedNode;
+  final HideCombinator linkedNode;
 
   /// The names that are not to be made visible in the importing library even if
   /// they are defined in the imported library.
@@ -5730,9 +5793,7 @@
     if (_hiddenNames != null) return _hiddenNames;
 
     if (linkedNode != null) {
-      return _hiddenNames = linkedNode.hideCombinator_hiddenNames
-          .map((node) => linkedContext.getSimpleName(node))
-          .toList();
+      return _hiddenNames = linkedNode.hiddenNames.map((i) => i.name).toList();
     }
 
     if (_unlinkedCombinator != null) {
@@ -5800,7 +5861,7 @@
         super(null, offset);
 
   ImportElementImpl.forLinkedNode(
-      LibraryElementImpl enclosing, LinkedNode linkedNode)
+      LibraryElementImpl enclosing, ImportDirective linkedNode)
       : _unlinkedImport = null,
         _linkedDependency = null,
         super.forLinkedNode(enclosing, null, linkedNode);
@@ -5815,9 +5876,10 @@
     if (_combinators != null) return _combinators;
 
     if (linkedNode != null) {
-      return _combinators = _buildCombinators2(
+      ImportDirective node = linkedNode;
+      return _combinators = ImportElementImpl._buildCombinators2(
         enclosingUnit.linkedContext,
-        linkedNode,
+        node.combinators,
       );
     }
 
@@ -5854,14 +5916,11 @@
 
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
-      var relativeUriStr = context.getStringContent(
-        linkedNode.uriBasedDirective_uri,
-      );
-      var relativeUri = Uri.parse(relativeUriStr);
-      var uri = resolveRelativeUri(librarySource.uri, relativeUri);
+      var uri = context.directiveUri(librarySource.uri, linkedNode);
       var elementFactory = context.bundleContext.elementFactory;
       return _importedLibrary = elementFactory.libraryOfUri('$uri');
     }
+
     if (_linkedDependency != null) {
       if (_importedLibrary == null) {
         LibraryElementImpl library = enclosingElement as LibraryElementImpl;
@@ -5873,6 +5932,7 @@
         }
       }
     }
+
     return _importedLibrary;
   }
 
@@ -5884,7 +5944,8 @@
   @override
   bool get isDeferred {
     if (linkedNode != null) {
-      return linkedNode.importDirective_deferredKeyword != 0;
+      ImportDirective linkedNode = this.linkedNode;
+      return linkedNode.deferredKeyword != null;
     }
     if (_unlinkedImport != null) {
       return _unlinkedImport.isDeferred;
@@ -5905,11 +5966,6 @@
 
   @override
   List<ElementAnnotation> get metadata {
-    if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      var metadata = enclosingUnit.linkedContext.getMetadataOrEmpty(linkedNode);
-      return _metadata = _buildAnnotations2(enclosingUnit, metadata);
-    }
     if (_metadata == null) {
       if (_unlinkedImport != null) {
         return _metadata = _buildAnnotations(
@@ -5943,25 +5999,27 @@
   }
 
   PrefixElement get prefix {
-    if (_prefix == null) {
-      if (linkedNode != null) {
-        var prefix = linkedNode.importDirective_prefix;
-        if (prefix != null) {
-          var context = enclosingUnit.linkedContext;
-          var name = context.getSimpleName(prefix);
-          LibraryElementImpl library = enclosingElement as LibraryElementImpl;
-          _prefix = new PrefixElementImpl.forLinkedNode(
-            library,
-            library.reference.getChild('@prefix').getChild(name),
-            prefix,
-          );
-        }
-      }
-      if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) {
-        LibraryElementImpl library = enclosingElement as LibraryElementImpl;
-        _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
+    if (_prefix != null) return _prefix;
+
+    if (linkedNode != null) {
+      ImportDirective linkedNode = this.linkedNode;
+      var prefix = linkedNode.prefix;
+      if (prefix != null) {
+        var name = prefix.name;
+        var library = enclosingElement as LibraryElementImpl;
+        _prefix = new PrefixElementImpl.forLinkedNode(
+          library,
+          library.reference.getChild('@prefix').getChild(name),
+          prefix,
+        );
       }
     }
+
+    if (_unlinkedImport != null && _unlinkedImport.prefixReference != 0) {
+      LibraryElementImpl library = enclosingElement as LibraryElementImpl;
+      _prefix = new PrefixElementImpl.forSerialized(_unlinkedImport, library);
+    }
+
     return _prefix;
   }
 
@@ -6069,16 +6127,15 @@
   }
 
   static List<NamespaceCombinator> _buildCombinators2(
-      LinkedUnitContext context, LinkedNode linkedNode) {
-    return linkedNode.namespaceDirective_combinators.map((node) {
-      var kind = node.kind;
-      if (kind == LinkedNodeKind.hideCombinator) {
+      LinkedUnitContext context, List<Combinator> combinators) {
+    return combinators.map((node) {
+      if (node is HideCombinator) {
         return HideElementCombinatorImpl.forLinkedNode(context, node);
       }
-      if (kind == LinkedNodeKind.showCombinator) {
+      if (node is ShowCombinator) {
         return ShowElementCombinatorImpl.forLinkedNode(context, node);
       }
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }).toList();
   }
 }
@@ -6212,7 +6269,7 @@
       this.nameLength,
       this.linkedContext,
       Reference reference,
-      LinkedNode linkedNode)
+      CompilationUnit linkedNode)
       : resynthesizerContext = null,
         unlinkedDefiningUnit = null,
         super.forLinkedNode(null, reference, linkedNode) {
@@ -6311,14 +6368,17 @@
 
   @override
   Namespace get exportNamespace {
+    if (_exportNamespace != null) return _exportNamespace;
+
     if (linkedNode != null) {
-      if (_exportNamespace != null) return _exportNamespace;
       var elements = linkedContext.bundleContext.elementFactory;
       return _exportNamespace = elements.buildExportNamespace(source.uri);
     }
+
     if (resynthesizerContext != null) {
       _exportNamespace ??= resynthesizerContext.buildExportNamespace();
     }
+
     return _exportNamespace;
   }
 
@@ -6328,41 +6388,42 @@
 
   @override
   List<ExportElement> get exports {
-    if (_exports == null) {
-      if (linkedNode != null) {
-        return _exports = linkedNode.compilationUnit_directives
-            .where((node) => node.kind == LinkedNodeKind.exportDirective)
-            .map((node) {
-          return ExportElementImpl.forLinkedNode(this, node);
-        }).toList();
-      }
-      if (unlinkedDefiningUnit != null) {
-        List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
-            unlinkedDefiningUnit.exports;
-        List<UnlinkedExportPublic> unlinkedPublicExports =
-            unlinkedDefiningUnit.publicNamespace.exports;
-        assert(unlinkedDefiningUnit.exports.length ==
-            unlinkedPublicExports.length);
-        int length = unlinkedNonPublicExports.length;
-        if (length != 0) {
-          List<ExportElement> exports = new List<ExportElement>();
-          for (int i = 0; i < length; i++) {
-            UnlinkedExportPublic serializedExportPublic =
-                unlinkedPublicExports[i];
-            UnlinkedExportNonPublic serializedExportNonPublic =
-                unlinkedNonPublicExports[i];
-            ExportElementImpl exportElement =
-                new ExportElementImpl.forSerialized(
-                    serializedExportPublic, serializedExportNonPublic, library);
-            exports.add(exportElement);
-          }
-          _exports = exports;
-        } else {
-          _exports = const <ExportElement>[];
+    if (_exports != null) return _exports;
+
+    if (linkedNode != null) {
+      var unit = linkedContext.unit_withDirectives;
+      return _exports = unit.directives
+          .whereType<ExportDirective>()
+          .map((node) => ExportElementImpl.forLinkedNode(this, node))
+          .toList();
+    }
+
+    if (unlinkedDefiningUnit != null) {
+      List<UnlinkedExportNonPublic> unlinkedNonPublicExports =
+          unlinkedDefiningUnit.exports;
+      List<UnlinkedExportPublic> unlinkedPublicExports =
+          unlinkedDefiningUnit.publicNamespace.exports;
+      assert(
+          unlinkedDefiningUnit.exports.length == unlinkedPublicExports.length);
+      int length = unlinkedNonPublicExports.length;
+      if (length != 0) {
+        List<ExportElement> exports = new List<ExportElement>();
+        for (int i = 0; i < length; i++) {
+          UnlinkedExportPublic serializedExportPublic =
+              unlinkedPublicExports[i];
+          UnlinkedExportNonPublic serializedExportNonPublic =
+              unlinkedNonPublicExports[i];
+          ExportElementImpl exportElement = new ExportElementImpl.forSerialized(
+              serializedExportPublic, serializedExportNonPublic, library);
+          exports.add(exportElement);
         }
+        _exports = exports;
+      } else {
+        _exports = const <ExportElement>[];
       }
     }
-    return _exports ?? const <ExportElement>[];
+
+    return _exports ??= const <ExportElement>[];
   }
 
   /// Set the specifications of all of the exports defined in this library to
@@ -6424,20 +6485,30 @@
 
   @override
   List<ImportElement> get imports {
-    if (_imports == null) {
-      if (linkedNode != null) {
-        return _imports = linkedNode.compilationUnit_directives
-            .where((node) => node.kind == LinkedNodeKind.importDirective)
-            .map((node) {
-          return ImportElementImpl.forLinkedNode(this, node);
-        }).toList();
+    if (_imports != null) return _imports;
+
+    if (linkedNode != null) {
+      var unit = linkedContext.unit_withDirectives;
+      _imports = unit.directives
+          .whereType<ImportDirective>()
+          .map((node) => ImportElementImpl.forLinkedNode(this, node))
+          .toList();
+      var hasCore = _imports.any((import) => import.importedLibrary.isDartCore);
+      if (!hasCore) {
+        var elements = linkedContext.bundleContext.elementFactory;
+        _imports.add(ImportElementImpl(-1)
+          ..importedLibrary = elements.libraryOfUri('dart:core')
+          ..isSynthetic = true);
       }
-      if (unlinkedDefiningUnit != null) {
-        _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports,
-            resynthesizerContext.linkedLibrary.importDependencies);
-      }
+      return _imports;
     }
-    return _imports ?? const <ImportElement>[];
+
+    if (unlinkedDefiningUnit != null) {
+      _imports = buildImportsFromSummary(this, unlinkedDefiningUnit.imports,
+          resynthesizerContext.linkedLibrary.importDependencies);
+    }
+
+    return _imports ??= const <ImportElement>[];
   }
 
   /// Set the specifications of all of the imports defined in this library to
@@ -6599,21 +6670,19 @@
 
   @override
   List<ElementAnnotation> get metadata {
+    if (_metadata != null) return _metadata;
+
     if (linkedNode != null) {
-      if (_metadata != null) return _metadata;
-      CompilationUnitElementImpl enclosingUnit = _definingCompilationUnit;
-      var context = enclosingUnit.linkedContext;
-      var metadata = context.getLibraryMetadataOrEmpty(linkedNode);
+      var metadata = linkedContext.getLibraryMetadata(linkedNode);
       return _metadata = _buildAnnotations2(enclosingUnit, metadata);
     }
-    if (_metadata == null) {
-      if (unlinkedDefiningUnit != null) {
-        _metadata = _buildAnnotations(
-            _definingCompilationUnit as CompilationUnitElementImpl,
-            unlinkedDefiningUnit.libraryAnnotations);
-        return _metadata;
-      }
+
+    if (unlinkedDefiningUnit != null) {
+      return _metadata = _buildAnnotations(
+          _definingCompilationUnit as CompilationUnitElementImpl,
+          unlinkedDefiningUnit.libraryAnnotations);
     }
+
     return super.metadata;
   }
 
@@ -6990,8 +7059,8 @@
   /// given [offset].
   MethodElementImpl(String name, int offset) : super(name, offset);
 
-  MethodElementImpl.forLinkedNode(Reference reference, LinkedNode linkedNode,
-      ClassElementImpl enclosingClass)
+  MethodElementImpl.forLinkedNode(ClassElementImpl enclosingClass,
+      Reference reference, MethodDeclaration linkedNode)
       : super.forLinkedNode(enclosingClass, reference, linkedNode);
 
   /// Initialize a newly created method element to have the given [name].
@@ -7025,14 +7094,6 @@
       super.enclosingElement as ClassElementImpl;
 
   @override
-  bool get isAbstract {
-    if (linkedNode != null) {
-      return !isExternal && enclosingUnit.linkedContext.isAbstract(linkedNode);
-    }
-    return super.isAbstract;
-  }
-
-  @override
   bool get isOperator {
     String name = displayName;
     if (name.isEmpty) {
@@ -7048,7 +7109,7 @@
   @override
   bool get isStatic {
     if (linkedNode != null) {
-      return linkedNode.methodDeclaration_modifierKeyword != 0;
+      return enclosingUnit.linkedContext.isStatic(linkedNode);
     }
     if (serializedExecutable != null) {
       return serializedExecutable.isStatic;
@@ -7076,11 +7137,11 @@
 
   @override
   DartType get returnType {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getType(
-        linkedNode.methodDeclaration_returnType2,
-      );
-    }
+//    if (linkedNode != null) {
+//      return enclosingUnit.linkedContext.getType(
+//        linkedNode.methodDeclaration_returnType2,
+//      );
+//    }
     return super.returnType;
   }
 
@@ -7151,10 +7212,8 @@
   MixinElementImpl(String name, int offset) : super(name, offset);
 
   MixinElementImpl.forLinkedNode(CompilationUnitElementImpl enclosing,
-      Reference reference, LinkedNode linkedNode)
-      : super.forLinkedNode(enclosing, reference, linkedNode) {
-    enclosing.linkedContext.loadClassMemberReferences(reference);
-  }
+      Reference reference, MixinDeclaration linkedNode)
+      : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created class element to have the given [name].
   MixinElementImpl.forNode(Identifier name) : super.forNode(name);
@@ -7179,12 +7238,11 @@
 
     if (linkedNode != null) {
       List<InterfaceType> constraints;
-      var onClause = linkedNode.mixinDeclaration_onClause;
+      var onClause = enclosingUnit.linkedContext.getOnClause(linkedNode);
       if (onClause != null) {
-        var context = enclosingUnit.linkedContext;
-        constraints = onClause.onClause_superclassConstraints
-            .map((node) => context.getInterfaceType(node.typeName_type))
-            .where((type) => type != null)
+        constraints = onClause.superclassConstraints
+            .map((node) => node.type)
+            .whereType<InterfaceType>()
             .toList();
       }
       if (constraints == null || constraints.isEmpty) {
@@ -7443,6 +7501,9 @@
   bool get hasLiteral => false;
 
   @override
+  bool get hasOptionalTypeArgs => false;
+
+  @override
   bool get hasOverride => false;
 
   @override
@@ -7651,7 +7712,7 @@
         super(name, offset);
 
   NonParameterVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : _unlinkedVariable = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -7668,7 +7729,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.codeRange?.length;
@@ -7679,7 +7740,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.codeRange?.offset;
@@ -7690,9 +7751,9 @@
   @override
   String get documentationComment {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getCommentText(
-        linkedNode.variableDeclaration_declaration.comment,
-      );
+      var context = enclosingUnit.linkedContext;
+      var comment = context.getDocumentationComment(linkedNode);
+      return getCommentNodeRawText(comment);
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.documentationComment?.text;
@@ -7778,9 +7839,7 @@
   @override
   String get name {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleName(
-        linkedNode.variableDeclaration_name,
-      );
+      return reference.name;
     }
     if (_unlinkedVariable != null) {
       return _unlinkedVariable.name;
@@ -7791,10 +7850,9 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.variableDeclaration_name,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
+
     int offset = super.nameOffset;
     if (offset == 0) {
       if (_unlinkedVariable != null) {
@@ -7864,28 +7922,23 @@
         super(name, nameOffset);
 
   ParameterElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, FormalParameter linkedNode)
       : unlinkedParam = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
   factory ParameterElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
-    var kind = linkedNode.kind;
-    if (kind == LinkedNodeKind.fieldFormalParameter) {
+      ElementImpl enclosing, Reference reference, FormalParameter node) {
+    if (node is FieldFormalParameter) {
       return FieldFormalParameterElementImpl.forLinkedNode(
         enclosing,
         reference,
-        linkedNode,
+        node,
       );
-    } else if (kind == LinkedNodeKind.functionTypedFormalParameter ||
-        kind == LinkedNodeKind.simpleFormalParameter) {
-      return ParameterElementImpl.forLinkedNode(
-        enclosing,
-        reference,
-        linkedNode,
-      );
+    } else if (node is FunctionTypedFormalParameter ||
+        node is SimpleFormalParameter) {
+      return ParameterElementImpl.forLinkedNode(enclosing, reference, node);
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
@@ -7938,7 +7991,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (unlinkedParam != null) {
       return unlinkedParam.codeRange?.length;
@@ -7949,7 +8002,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (unlinkedParam != null) {
       return unlinkedParam.codeRange?.offset;
@@ -8046,13 +8099,13 @@
 
   @override
   bool get isCovariant {
-    if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-        var parameter = linkedNode.defaultFormalParameter_parameter;
-        return parameter.normalFormalParameter_isCovariant;
-      }
-      return linkedNode.normalFormalParameter_isCovariant;
-    }
+//    if (linkedNode != null) {
+//      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
+//        var parameter = linkedNode.defaultFormalParameter_parameter;
+//        return parameter.normalFormalParameter_isCovariant;
+//      }
+//      return linkedNode.normalFormalParameter_isCovariant;
+//    }
     if (isExplicitlyCovariant || inheritsCovariant) {
       return true;
     }
@@ -8077,7 +8130,8 @@
   @override
   bool get isFinal {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.isFinal(linkedNode);
+      FormalParameter linkedNode = this.linkedNode;
+      return linkedNode.isFinal;
     }
     if (unlinkedParam != null) {
       return unlinkedParam.isFinal;
@@ -8126,9 +8180,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      return enclosingUnit.linkedContext.getSimpleOffset(
-        linkedNode.normalFormalParameter_identifier,
-      );
+      return enclosingUnit.linkedContext.getNameOffset(linkedNode);
     }
 
     int offset = super.nameOffset;
@@ -8151,14 +8203,9 @@
     if (_parameterKind != null) return _parameterKind;
 
     if (linkedNode != null) {
-      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-        if (linkedNode.defaultFormalParameter_isNamed) {
-          return _parameterKind = ParameterKind.NAMED;
-        } else {
-          return _parameterKind = ParameterKind.POSITIONAL;
-        }
-      }
-      return _parameterKind = ParameterKind.REQUIRED;
+      FormalParameter linkedNode = this.linkedNode;
+      // ignore: deprecated_member_use_from_same_package
+      return linkedNode.kind;
     }
     if (unlinkedParam != null) {
       switch (unlinkedParam.kind) {
@@ -8191,7 +8238,7 @@
     if (linkedNode != null) {
       if (_type != null) return _type;
       var context = enclosingUnit.linkedContext;
-      return _type = context.getFormalParameterType(linkedNode);
+      return _type = context.getType(linkedNode);
     }
     _resynthesizeTypeAndParameters();
     return super.type;
@@ -8305,18 +8352,18 @@
       ElementImpl enclosing,
       LinkedUnitContext context,
       Reference containerRef,
-      List<LinkedNode> formalParameters) {
+      List<FormalParameter> formalParameters) {
     if (formalParameters == null) {
       return const [];
     }
 
     return formalParameters.map((node) {
-      if (node.kind == LinkedNodeKind.defaultFormalParameter) {
-        var parameterNode = node.defaultFormalParameter_parameter;
-        var name = context.getFormalParameterName(parameterNode);
+      if (node is DefaultFormalParameter) {
+        NormalFormalParameter parameterNode = node.parameter;
+        var name = parameterNode.identifier.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        if (parameterNode.kind == LinkedNodeKind.fieldFormalParameter) {
+        reference.node2 = node;
+        if (parameterNode is FieldFormalParameter) {
           return DefaultFieldFormalParameterElementImpl.forLinkedNode(
             enclosing,
             reference,
@@ -8330,14 +8377,17 @@
           );
         }
       } else {
-        var name = context.getFormalParameterName(node);
+        var name = node.identifier.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return ParameterElementImpl.forLinkedNodeFactory(
-          enclosing,
-          reference,
-          node,
-        );
+        if (reference.element == null) {
+          reference.node2 = node;
+          ParameterElementImpl.forLinkedNodeFactory(
+            enclosing,
+            reference,
+            node,
+          );
+        }
+        return reference.element as ParameterElement;
       }
     }).toList();
   }
@@ -8465,7 +8515,7 @@
         super(name, nameOffset);
 
   PrefixElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, SimpleIdentifier linkedNode)
       : _unlinkedImport = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -8510,8 +8560,7 @@
   @override
   int get nameOffset {
     if (linkedNode != null) {
-      LibraryElementImpl library = enclosingElement;
-      return library.linkedContext.getSimpleOffset(linkedNode);
+      return (linkedNode as SimpleIdentifier).offset;
     }
     int offset = super.nameOffset;
     if (offset == 0 && _unlinkedImport != null) {
@@ -8541,7 +8590,7 @@
   PropertyAccessorElementImpl(String name, int offset) : super(name, offset);
 
   PropertyAccessorElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created property accessor element to have the given
@@ -8614,14 +8663,6 @@
   }
 
   @override
-  bool get isAbstract {
-    if (linkedNode != null) {
-      return enclosingUnit.linkedContext.isAbstract(linkedNode);
-    }
-    return super.isAbstract;
-  }
-
-  @override
   bool get isGetter {
     if (linkedNode != null) {
       return enclosingUnit.linkedContext.isGetter(linkedNode);
@@ -8813,7 +8854,7 @@
   PropertyInducingElementImpl(String name, int offset) : super(name, offset);
 
   PropertyInducingElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created element to have the given [name].
@@ -8838,9 +8879,7 @@
   DartType get type {
     if (linkedNode != null) {
       if (_type != null) return _type;
-      return _type = enclosingUnit.linkedContext.getType(
-        linkedNode.variableDeclaration_type2,
-      );
+      return _type = enclosingUnit.linkedContext.getType(linkedNode);
     }
     if (isSynthetic && _type == null) {
       if (getter != null) {
@@ -8914,7 +8953,7 @@
   final UnlinkedCombinator _unlinkedCombinator;
 
   final LinkedUnitContext linkedContext;
-  final LinkedNode linkedNode;
+  final ShowCombinator linkedNode;
 
   /// The names that are to be made visible in the importing library if they are
   /// defined in the imported library.
@@ -8956,7 +8995,7 @@
   @override
   int get offset {
     if (linkedNode != null) {
-      return linkedContext.getTokenOffset(linkedNode.combinator_keyword);
+      return linkedNode.keyword.offset;
     }
     if (_unlinkedCombinator != null) {
       return _unlinkedCombinator.offset;
@@ -8974,9 +9013,7 @@
     if (_shownNames != null) return _shownNames;
 
     if (linkedNode != null) {
-      return _shownNames = linkedNode.showCombinator_shownNames
-          .map((node) => linkedContext.getSimpleName(node))
-          .toList();
+      return _shownNames = linkedNode.shownNames.map((i) => i.name).toList();
     }
 
     if (_unlinkedCombinator != null) {
@@ -9037,7 +9074,7 @@
   TopLevelVariableElementImpl(String name, int offset) : super(name, offset);
 
   TopLevelVariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode) {
     if (!linkedNode.isSynthetic) {
       var enclosingRef = enclosing.reference;
@@ -9057,7 +9094,7 @@
   }
 
   factory TopLevelVariableElementImpl.forLinkedNodeFactory(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode) {
+      ElementImpl enclosing, Reference reference, AstNode linkedNode) {
     if (enclosing.enclosingUnit.linkedContext.isConst(linkedNode)) {
       return ConstTopLevelVariableElementImpl.forLinkedNode(
         enclosing,
@@ -9121,7 +9158,7 @@
   TypeParameterElementImpl.forLinkedNode(
       TypeParameterizedElementMixin enclosing,
       Reference reference,
-      LinkedNode linkedNode)
+      TypeParameter linkedNode)
       : _unlinkedTypeParam = null,
         super.forLinkedNode(enclosing, reference, linkedNode);
 
@@ -9148,13 +9185,8 @@
     if (_bound != null) return _bound;
 
     if (linkedNode != null) {
-      var bound = linkedNode.typeParameter_bound;
-      if (bound != null) {
-        var context = enclosingUnit.linkedContext;
-        return _bound = context.getTypeAnnotationType(bound);
-      } else {
-        return null;
-      }
+      var context = enclosingUnit.linkedContext;
+      return _bound = context.getTypeParameterBound(linkedNode)?.type;
     }
 
     if (_unlinkedTypeParam != null) {
@@ -9177,7 +9209,7 @@
   @override
   int get codeLength {
     if (linkedNode != null) {
-      return linkedNode.codeLength;
+      return linkedContext.getCodeLength(linkedNode);
     }
     if (_unlinkedTypeParam != null) {
       return _unlinkedTypeParam.codeRange?.length;
@@ -9188,7 +9220,7 @@
   @override
   int get codeOffset {
     if (linkedNode != null) {
-      return linkedNode.codeOffset;
+      return linkedContext.getCodeOffset(linkedNode);
     }
     if (_unlinkedTypeParam != null) {
       return _unlinkedTypeParam.codeRange?.offset;
@@ -9290,15 +9322,18 @@
     if (linkedNode != null) {
       var context = enclosingUnit.linkedContext;
       var containerRef = reference.getChild('@typeParameter');
-      var typeParameters = LinkedUnitContext.getTypeParameters(linkedNode);
+      var typeParameters = context.getTypeParameters2(linkedNode);
       if (typeParameters == null) {
         return _typeParameterElements = const [];
       }
-      return _typeParameterElements = typeParameters.map((node) {
-        var name = context.getSimpleName(node.typeParameter_name);
+      return _typeParameterElements = typeParameters.typeParameters.map((node) {
+        var name = node.name.name;
         var reference = containerRef.getChild(name);
-        reference.node = node;
-        return TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        if (reference.element == null) {
+          reference.node2 = node;
+          TypeParameterElementImpl.forLinkedNode(this, reference, node);
+        }
+        return reference.element as TypeParameterElementImpl;
       }).toList();
     }
 
@@ -9411,7 +9446,7 @@
   UriReferencedElementImpl(String name, int offset) : super(name, offset);
 
   UriReferencedElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize using the given serialized information.
@@ -9475,7 +9510,7 @@
   VariableElementImpl(String name, int offset) : super(name, offset);
 
   VariableElementImpl.forLinkedNode(
-      ElementImpl enclosing, Reference reference, LinkedNode linkedNode)
+      ElementImpl enclosing, Reference reference, AstNode linkedNode)
       : super.forLinkedNode(enclosing, reference, linkedNode);
 
   /// Initialize a newly created variable element to have the given [name].
@@ -9498,9 +9533,9 @@
   DartObject get constantValue => evaluationResult?.value;
 
   void set declaredType(DartType type) {
-    if (linkedNode != null) {
-      enclosingUnit.linkedContext.setVariableType(linkedNode, type);
-    }
+//    if (linkedNode != null) {
+//      enclosingUnit.linkedContext.setVariableType(linkedNode, type);
+//    }
     _declaredType = _checkElementOfType(type);
   }
 
diff --git a/pkg/analyzer/lib/src/dart/element/handle.dart b/pkg/analyzer/lib/src/dart/element/handle.dart
index 67f47f7..7384095d 100644
--- a/pkg/analyzer/lib/src/dart/element/handle.dart
+++ b/pkg/analyzer/lib/src/dart/element/handle.dart
@@ -395,6 +395,9 @@
   bool get hasLiteral => actualElement.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => actualElement.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => actualElement.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 845d59d..7472796 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -425,6 +425,9 @@
   bool get hasLiteral => _baseElement.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => _baseElement.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => _baseElement.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/element/type_algebra.dart b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
new file mode 100644
index 0000000..b3fd95f
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_algebra.dart
@@ -0,0 +1,292 @@
+// 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/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_visitor.dart';
+
+/// Returns a type where all occurrences of the given type parameters have been
+/// replaced with the corresponding types.
+///
+/// This will copy only the sub-terms of [type] that contain substituted
+/// variables; all other [DartType] objects will be reused.
+///
+/// In particular, if no type parameters were substituted, this is guaranteed
+/// to return the [type] instance (not a copy), so the caller may use
+/// [identical] to efficiently check if a distinct type was created.
+DartType substitute(
+  DartType type,
+  Map<TypeParameterElement, DartType> substitution,
+) {
+  if (substitution.isEmpty) {
+    return type;
+  }
+  return Substitution.fromMap(substitution).substituteType(type);
+}
+
+abstract class Substitution {
+  static const Substitution empty = _NullSubstitution.instance;
+
+  const Substitution();
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound);
+
+  DartType substituteType(DartType type, {bool contravariant: false}) {
+    return new _TopSubstitutor(this, contravariant).visit(type);
+  }
+
+  /// Substitutes the type parameters on the class of [type] with the
+  /// type arguments provided in [type].
+  static Substitution fromInterfaceType(InterfaceType type) {
+    if (type.typeArguments.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return fromPairs(type.element.typeParameters, type.typeArguments);
+  }
+
+  /// Substitutes each parameter to the type it maps to in [map].
+  static Substitution fromMap(Map<TypeParameterElement, DartType> map) {
+    if (map.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return new _MapSubstitution(map, map);
+  }
+
+  /// Substitutes the Nth parameter in [parameters] with the Nth type in
+  /// [types].
+  static Substitution fromPairs(
+    List<TypeParameterElement> parameters,
+    List<DartType> types,
+  ) {
+    assert(parameters.length == types.length);
+    if (parameters.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return fromMap(
+      new Map<TypeParameterElement, DartType>.fromIterables(
+        parameters,
+        types,
+      ),
+    );
+  }
+
+  /// Substitutes all occurrences of the given type parameters with the
+  /// corresponding upper or lower bound, depending on the variance of the
+  /// context where it occurs.
+  ///
+  /// For example the type `(T) => T` with the bounds `bottom <: T <: num`
+  /// becomes `(bottom) => num` (in this example, `num` is the upper bound,
+  /// and `bottom` is the lower bound).
+  ///
+  /// This is a way to obtain an upper bound for a type while eliminating all
+  /// references to certain type variables.
+  static Substitution fromUpperAndLowerBounds(
+    Map<TypeParameterElement, DartType> upper,
+    Map<TypeParameterElement, DartType> lower,
+  ) {
+    if (upper.isEmpty && lower.isEmpty) {
+      return _NullSubstitution.instance;
+    }
+    return new _MapSubstitution(upper, lower);
+  }
+}
+
+class _FreshTypeParametersSubstitutor extends _TypeSubstitutor {
+  final Map<TypeParameterElement, DartType> substitution = {};
+
+  _FreshTypeParametersSubstitutor(_TypeSubstitutor outer) : super(outer);
+
+  TypeParameterElement freshTypeParameter(TypeParameterElement element) {
+    var freshElement = new TypeParameterElementImpl(element.name, -1);
+    var freshType = new TypeParameterTypeImpl(freshElement);
+    freshElement.type = freshType;
+    substitution[element] = freshType;
+    if (element.bound != null) {
+      freshElement.bound = visit(element.bound);
+    }
+    return freshElement;
+  }
+
+  DartType lookup(TypeParameterElement parameter, bool upperBound) {
+    return substitution[parameter];
+  }
+}
+
+class _MapSubstitution extends Substitution {
+  final Map<TypeParameterElement, DartType> upper;
+  final Map<TypeParameterElement, DartType> lower;
+
+  _MapSubstitution(this.upper, this.lower);
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
+    return upperBound ? upper[parameter] : lower[parameter];
+  }
+}
+
+class _NullSubstitution extends Substitution {
+  static const _NullSubstitution instance = const _NullSubstitution();
+
+  const _NullSubstitution();
+
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
+    return new TypeParameterTypeImpl(parameter);
+  }
+
+  @override
+  DartType substituteType(DartType type, {bool contravariant: false}) => type;
+}
+
+class _TopSubstitutor extends _TypeSubstitutor {
+  final Substitution substitution;
+
+  _TopSubstitutor(this.substitution, bool contravariant) : super(null) {
+    if (contravariant) {
+      invertVariance();
+    }
+  }
+
+  @override
+  TypeParameterElement freshTypeParameter(TypeParameterElement element) {
+    throw 'Create a fresh environment first';
+  }
+
+  @override
+  DartType lookup(TypeParameterElement parameter, bool upperBound) {
+    return substitution.getSubstitute(parameter, upperBound);
+  }
+}
+
+abstract class _TypeSubstitutor extends DartTypeVisitor<DartType> {
+  final _TypeSubstitutor outer;
+  bool covariantContext = true;
+
+  /// The number of times a variable from this environment has been used in
+  /// a substitution.
+  ///
+  /// There is a strict requirement that we must return the same instance for
+  /// types that were not altered by the substitution.  This counter lets us
+  /// check quickly if anything happened in a substitution.
+  int useCounter = 0;
+
+  _TypeSubstitutor(this.outer) {
+    covariantContext = outer == null ? true : outer.covariantContext;
+  }
+
+  void bumpCountersUntil(_TypeSubstitutor target) {
+    var substitutor = this;
+    while (substitutor != target) {
+      substitutor.useCounter++;
+      substitutor = substitutor.outer;
+    }
+    target.useCounter++;
+  }
+
+  TypeParameterElement freshTypeParameter(TypeParameterElement element);
+
+  List<TypeParameterElement> freshTypeParameters(
+      List<TypeParameterElement> parameters) {
+    if (parameters.isEmpty) {
+      return const <TypeParameterElement>[];
+    }
+    return parameters.map(freshTypeParameter).toList();
+  }
+
+  DartType getSubstitute(TypeParameterElement parameter) {
+    var environment = this;
+    while (environment != null) {
+      var replacement = environment.lookup(parameter, covariantContext);
+      if (replacement != null) {
+        bumpCountersUntil(environment);
+        return replacement;
+      }
+      environment = environment.outer;
+    }
+    return null;
+  }
+
+  void invertVariance() {
+    covariantContext = !covariantContext;
+  }
+
+  DartType lookup(TypeParameterElement parameter, bool upperBound);
+
+  _FreshTypeParametersSubstitutor newInnerEnvironment() {
+    return new _FreshTypeParametersSubstitutor(this);
+  }
+
+  DartType visit(DartType type) {
+    return DartTypeVisitor.visit(type, this);
+  }
+
+  @override
+  DartType visitBottomType(BottomTypeImpl type) => type;
+
+  @override
+  DartType visitDynamicType(DynamicTypeImpl type) => type;
+
+  @override
+  DartType visitFunctionType(FunctionType type) {
+    // This is a bit tricky because we have to generate fresh type parameters
+    // in order to change the bounds.  At the same time, if the function type
+    // was unaltered, we have to return the [type] object (not a copy!).
+    // Substituting a type for a fresh type variable should not be confused
+    // with a "real" substitution.
+    //
+    // Create an inner environment to generate fresh type parameters.  The use
+    // counter on the inner environment tells if the fresh type parameters have
+    // any uses, but does not tell if the resulting function type is distinct.
+    // Our own use counter will get incremented if something from our
+    // environment has been used inside the function.
+    var inner = type.typeFormals.isEmpty ? this : newInnerEnvironment();
+    int before = this.useCounter;
+
+    // Invert the variance when translating parameters.
+    inner.invertVariance();
+
+    var typeFormals = inner.freshTypeParameters(type.typeFormals);
+
+    var parameters = type.parameters.map((parameter) {
+      var type = inner.visit(parameter.type);
+      return ParameterElementImpl.synthetic(
+        parameter.name,
+        type,
+        // ignore: deprecated_member_use_from_same_package
+        parameter.parameterKind,
+      );
+    }).toList();
+
+    inner.invertVariance();
+
+    var returnType = inner.visit(type.returnType);
+
+    if (this.useCounter == before) return type;
+
+    return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
+  }
+
+  @override
+  DartType visitInterfaceType(InterfaceType type) {
+    if (type.typeArguments.isEmpty) {
+      return type;
+    }
+
+    int before = useCounter;
+    var typeArguments = type.typeArguments.map(visit).toList();
+    if (useCounter == before) {
+      return type;
+    }
+
+    return new InterfaceTypeImpl.explicit(type.element, typeArguments);
+  }
+
+  @override
+  DartType visitTypeParameterType(TypeParameterType type) {
+    return getSubstitute(type.element) ?? type;
+  }
+
+  @override
+  DartType visitVoidType(VoidType type) => type;
+}
diff --git a/pkg/analyzer/lib/src/dart/element/type_visitor.dart b/pkg/analyzer/lib/src/dart/element/type_visitor.dart
new file mode 100644
index 0000000..6b0ffbe
--- /dev/null
+++ b/pkg/analyzer/lib/src/dart/element/type_visitor.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:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+
+class DartTypeVisitor<R> {
+  const DartTypeVisitor();
+
+  R defaultDartType(DartType type) => null;
+
+  R visitBottomType(BottomTypeImpl type) => defaultDartType(type);
+
+  R visitDynamicType(DynamicTypeImpl type) => defaultDartType(type);
+
+  R visitFunctionType(FunctionType type) => defaultDartType(type);
+
+  R visitInterfaceType(InterfaceType type) => defaultDartType(type);
+
+  R visitTypeParameterType(TypeParameterType type) => defaultDartType(type);
+
+  R visitVoidType(VoidType type) => defaultDartType(type);
+
+  static R visit<R>(DartType type, DartTypeVisitor<R> visitor) {
+    if (type is BottomTypeImpl) {
+      return visitor.visitBottomType(type);
+    }
+    if (type is DynamicTypeImpl) {
+      return visitor.visitDynamicType(type);
+    }
+    if (type is FunctionType) {
+      return visitor.visitFunctionType(type);
+    }
+    if (type is InterfaceType) {
+      return visitor.visitInterfaceType(type);
+    }
+    if (type is TypeParameterType) {
+      return visitor.visitTypeParameterType(type);
+    }
+    if (type is VoidType) {
+      return visitor.visitVoidType(type);
+    }
+    throw UnimplementedError('(${type.runtimeType}) $type');
+  }
+}
diff --git a/pkg/analyzer/lib/src/dart/element/wrapped.dart b/pkg/analyzer/lib/src/dart/element/wrapped.dart
index 984a7b1..5aebd1d 100644
--- a/pkg/analyzer/lib/src/dart/element/wrapped.dart
+++ b/pkg/analyzer/lib/src/dart/element/wrapped.dart
@@ -71,6 +71,9 @@
   bool get hasLoadLibraryFunction => wrappedUnit.hasLoadLibraryFunction;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedUnit.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedUnit.hasOverride;
 
   @override
@@ -261,6 +264,9 @@
   bool get hasLiteral => wrappedImport.hasLiteral;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedImport.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedImport.hasOverride;
 
   @override
@@ -466,6 +472,9 @@
   bool get hasLoadLibraryFunction => wrappedLib.hasLoadLibraryFunction;
 
   @override
+  bool get hasOptionalTypeArgs => wrappedLib.hasOptionalTypeArgs;
+
+  @override
   bool get hasOverride => wrappedLib.hasOverride;
 
   @override
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
index 67fbccc..6e31a4b 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.dart
@@ -693,6 +693,8 @@
   static const ParserErrorCode TYPE_ARGUMENTS_ON_TYPE_VARIABLE =
       _TYPE_ARGUMENTS_ON_TYPE_VARIABLE;
 
+  static const ParserErrorCode TYPE_BEFORE_FACTORY = _TYPE_BEFORE_FACTORY;
+
   static const ParserErrorCode TYPEDEF_IN_CLASS = _TYPEDEF_IN_CLASS;
 
   /**
@@ -716,7 +718,7 @@
 
   static const ParserErrorCode WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER =
       const ParserErrorCode('WRONG_SEPARATOR_FOR_POSITIONAL_PARAMETER',
-          "The default value of a positional parameter should be preceeded by '='.",
+          "The default value of a positional parameter should be preceded by '='.",
           correction: "Try replacing the ':' with '='.");
 
   /**
diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
index 598d093..b12e351 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -104,6 +104,7 @@
   _EXPECTED_ELSE_OR_COMMA,
   _INVALID_SUPER_IN_INITIALIZER,
   _INVALID_THIS_IN_INITIALIZER,
+  _TYPE_BEFORE_FACTORY,
 ];
 
 const ParserErrorCode _ABSTRACT_CLASS_MEMBER = const ParserErrorCode(
@@ -216,7 +217,7 @@
 
 const ParserErrorCode _DUPLICATED_MODIFIER = const ParserErrorCode(
     'DUPLICATED_MODIFIER', r"The modifier '#lexeme' was already specified.",
-    correction: "Try removing all but one occurance of the modifier.");
+    correction: "Try removing all but one occurence of the modifier.");
 
 const ParserErrorCode _DUPLICATE_DEFERRED = const ParserErrorCode(
     'DUPLICATE_DEFERRED',
@@ -256,7 +257,7 @@
 
 const ParserErrorCode _EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
     const ParserErrorCode('EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
-        r"Export directives must preceed part directives.",
+        r"Export directives must precede part directives.",
         correction:
             "Try moving the export directives before the part directives.");
 
@@ -360,7 +361,7 @@
 
 const ParserErrorCode _IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE =
     const ParserErrorCode('IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE',
-        r"Import directives must preceed part directives.",
+        r"Import directives must precede part directives.",
         correction:
             "Try moving the import directives before the part directives.");
 
@@ -438,7 +439,7 @@
 
 const ParserErrorCode _MISSING_KEYWORD_OPERATOR = const ParserErrorCode(
     'MISSING_KEYWORD_OPERATOR',
-    r"Operator declarations must be preceeded by the keyword 'operator'.",
+    r"Operator declarations must be preceded by the keyword 'operator'.",
     correction: "Try adding the keyword 'operator'.");
 
 const ParserErrorCode _MISSING_PREFIX_IN_DEFERRED_IMPORT =
@@ -550,6 +551,10 @@
     r"Can't use type arguments with type variable '#name'.",
     correction: "Try removing the type arguments.");
 
+const ParserErrorCode _TYPE_BEFORE_FACTORY = const ParserErrorCode(
+    'TYPE_BEFORE_FACTORY', r"Factory constructors cannot have a return type.",
+    correction: "Try removing the type appearing before 'factory'.");
+
 const ParserErrorCode _VAR_AND_TYPE = const ParserErrorCode('VAR_AND_TYPE',
     r"Variables can't be declared using both 'var' and a type name.",
     correction: "Try removing 'var.'");
diff --git a/pkg/analyzer/lib/src/error/codes.dart b/pkg/analyzer/lib/src/error/codes.dart
index 41a977e..570fc8f 100644
--- a/pkg/analyzer/lib/src/error/codes.dart
+++ b/pkg/analyzer/lib/src/error/codes.dart
@@ -331,7 +331,7 @@
           "Class '{0}' can't define field '{1}' and have method '{2}.{1}' "
           "with the same name.",
           correction: "Try converting the getter to a method, or "
-              "renaming the field to a name that doesn't conflit.");
+              "renaming the field to a name that doesn't conflict.");
 
   /**
    * 10.10 Superinterfaces: It is a compile-time error if a class `C` has two
@@ -366,7 +366,7 @@
           "Class '{0}' can't define method '{1}' and have field '{2}.{1}' "
           "with the same name.",
           correction: "Try converting the method to a getter, or "
-              "renaming the method to a name that doesn't conflit.");
+              "renaming the method to a name that doesn't conflict.");
 
   /**
    * 10.11 Class Member Conflicts: Let `C` be a class. It is a compile-time
@@ -384,7 +384,7 @@
           "Class '{0}' can't define static member '{1}' and have instance "
           "member '{2}.{1}' with the same name.",
           correction:
-              "Try renaming the member to a name that doesn't conflit.");
+              "Try renaming the member to a name that doesn't conflict.");
 
   /**
    * 7. Classes: It is a compile time error if a generic class declares a type
@@ -761,7 +761,7 @@
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR',
           "The class '{0}' doesn't have a constant constructor '{1}'.",
-          correction: "Try calling a different contructor.");
+          correction: "Try calling a different constructor.");
 
   /**
    * 16.12.2 Const: It is a compile-time error if <i>T.id</i> is not the name of
@@ -773,7 +773,7 @@
   static const CompileTimeErrorCode CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT =
       const CompileTimeErrorCode('CONST_WITH_UNDEFINED_CONSTRUCTOR_DEFAULT',
           "The class '{0}' doesn't have a default constant constructor.",
-          correction: "Try calling a different contructor.");
+          correction: "Try calling a different constructor.");
 
   /**
    * 15.3.1 Typedef: It is a compile-time error if any default values are
@@ -1173,7 +1173,7 @@
   static const CompileTimeErrorCode IMPLEMENTS_REPEATED =
       const CompileTimeErrorCode(
           'IMPLEMENTS_REPEATED', "'{0}' can only be implemented once.",
-          correction: "Try removing all but one occurance of the class name.");
+          correction: "Try removing all but one occurrence of the class name.");
 
   /**
    * 7.10 Superinterfaces: It is a compile-time error if the superclass of a
@@ -1186,7 +1186,7 @@
   static const CompileTimeErrorCode IMPLEMENTS_SUPER_CLASS =
       const CompileTimeErrorCode('IMPLEMENTS_SUPER_CLASS',
           "'{0}' can't be used in both 'extends' and 'implements' clauses.",
-          correction: "Try removing one of the occurances.");
+          correction: "Try removing one of the occurrences.");
 
   /**
    * 7.6.1 Generative Constructors: Note that <b>this</b> is not in scope on the
@@ -2184,6 +2184,10 @@
       'NOT_MAP_SPREAD',
       "Spread elements in map literals must implement 'Map'.");
 
+  static const CompileTimeErrorCode NOT_NULL_AWARE_NULL_SPREAD =
+      const CompileTimeErrorCode('NOT_NULL_AWARE_NULL_SPREAD',
+          "The Null typed expression can't be used with a non-null-aware spread.");
+
   /**
    * 7.6.1 Generative Constructors: Let <i>C</i> be the class in which the
    * superinitializer appears and let <i>S</i> be the superclass of <i>C</i>.
@@ -2217,7 +2221,7 @@
   static const CompileTimeErrorCode ON_REPEATED = const CompileTimeErrorCode(
       'ON_REPEATED',
       "'{0}' can only be used in super-class constraints only once.",
-      correction: "Try removing all but one occurance of the class name.");
+      correction: "Try removing all but one occurrence of the class name.");
 
   /**
    * 7.1.1 Operators: It is a compile-time error to declare an optional
diff --git a/pkg/analyzer/lib/src/error/literal_element_verifier.dart b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
index 29b65b9..89dcdce 100644
--- a/pkg/analyzer/lib/src/error/literal_element_verifier.dart
+++ b/pkg/analyzer/lib/src/error/literal_element_verifier.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/element/type.dart';
@@ -82,11 +83,13 @@
             CompileTimeErrorCode.MAP_ENTRY_NOT_IN_MAP, element);
       }
     } else if (element is SpreadElement) {
+      var isNullAware = element.spreadOperator.type ==
+          TokenType.PERIOD_PERIOD_PERIOD_QUESTION;
       Expression expression = element.expression;
       if (forList || forSet) {
-        _verifySpreadForListOrSet(expression);
+        _verifySpreadForListOrSet(isNullAware, expression);
       } else if (forMap) {
-        _verifySpreadForMap(expression);
+        _verifySpreadForMap(isNullAware, expression);
       }
     }
   }
@@ -123,12 +126,19 @@
 
   /// Verify that the type of the elements of the given [expression] can be
   /// assigned to the [elementType] of the enclosing collection.
-  void _verifySpreadForListOrSet(Expression expression) {
+  void _verifySpreadForListOrSet(bool isNullAware, Expression expression) {
     var expressionType = expression.staticType;
     if (expressionType.isDynamic) return;
 
-    // TODO(scheglov) Check for non-null-aware spread?
-    if (expressionType.isDartCoreNull) return;
+    if (expressionType.isDartCoreNull) {
+      if (!isNullAware) {
+        errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     InterfaceType iterableType;
     var iterableObjectType = typeProvider.iterableObjectType;
@@ -161,12 +171,19 @@
 
   /// Verify that the [expression] is a subtype of `Map<Object, Object>`, and
   /// its key and values are assignable to [mapKeyType] and [mapValueType].
-  void _verifySpreadForMap(Expression expression) {
+  void _verifySpreadForMap(bool isNullAware, Expression expression) {
     var expressionType = expression.staticType;
     if (expressionType.isDynamic) return;
 
-    // TODO(scheglov) Check for non-null-aware spread?
-    if (expressionType.isDartCoreNull) return;
+    if (expressionType.isDartCoreNull) {
+      if (!isNullAware) {
+        errorReporter.reportErrorForNode(
+          CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD,
+          expression,
+        );
+      }
+      return;
+    }
 
     InterfaceType mapType;
     var mapObjectObjectType = typeProvider.mapObjectObjectType;
diff --git a/pkg/analyzer/lib/src/generated/constant.dart b/pkg/analyzer/lib/src/generated/constant.dart
index b4a0bda..ea8336f 100644
--- a/pkg/analyzer/lib/src/generated/constant.dart
+++ b/pkg/analyzer/lib/src/generated/constant.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/error/error.dart';
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/dart/constant/evaluation.dart';
 import 'package:analyzer/src/dart/constant/value.dart';
@@ -128,9 +129,15 @@
         new ConstantEvaluationEngine(_typeProvider, new DeclaredVariables(),
             typeSystem: _typeSystem),
         errorReporter));
+    List<AnalysisError> errors = errorListener.errors;
+    if (errors.isNotEmpty) {
+      return EvaluationResult.forErrors(errors);
+    }
     if (result != null) {
       return EvaluationResult.forValue(result);
     }
-    return EvaluationResult.forErrors(errorListener.errors);
+    // We should not get here. Either there should be a valid value or there
+    // should be an error explaining why a value could not be generated.
+    return EvaluationResult.forErrors(errors);
   }
 }
diff --git a/pkg/analyzer/lib/src/generated/engine.dart b/pkg/analyzer/lib/src/generated/engine.dart
index cdffbef..0c23f5c 100644
--- a/pkg/analyzer/lib/src/generated/engine.dart
+++ b/pkg/analyzer/lib/src/generated/engine.dart
@@ -733,6 +733,11 @@
   static const String PUBSPEC_YAML_FILE = 'pubspec.yaml';
 
   /**
+   * The file name used for Android manifest files.
+   */
+  static const String ANDROID_MANIFEST_FILE = 'AndroidManifest.xml';
+
+  /**
    * The unique instance of this class.
    */
   static final AnalysisEngine instance = new AnalysisEngine._();
@@ -1023,6 +1028,12 @@
   @deprecated
   int get cacheSize;
 
+  /*
+   * A flag indicating whether to run checks on AndroidManifest.xml file to
+   * see if it is complaint with Chrome OS.
+   */
+  bool get chromeOsManifestChecks;
+
   /**
    * Return `true` if analysis is to generate dart2js related hint results.
    */
@@ -1391,6 +1402,9 @@
    */
   bool strictRawTypes = false;
 
+  @override
+  bool chromeOsManifestChecks = false;
+
   /**
    * Initialize a newly created set of analysis options to have their default
    * values.
diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart
index c372f0d..236bfe4 100644
--- a/pkg/analyzer/lib/src/generated/error_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/error_verifier.dart
@@ -4739,17 +4739,8 @@
           return;
         }
       }
-      if (element.metadata.isNotEmpty) {
-        for (var annotation in element.metadata) {
-          var e = annotation.element;
-          // TODO(jmesserly): similar "package:meta" annotations are added to
-          // the element as boolean getters, that may be worth considering.
-          if (e?.name == 'optionalTypeArgs' &&
-              e.librarySource.uri.toString() == 'package:meta/meta.dart') {
-            // Type is marked with `@optionalTypeArgs`: not an error.
-            return;
-          }
-        }
+      if (element.hasOptionalTypeArgs) {
+        return;
       }
       _errorReporter.reportErrorForNode(HintCode.STRICT_RAW_TYPE, node, [type]);
     }
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index a6fdb03..fa863d1 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5164,7 +5164,7 @@
 
   FunctionType _inferArgumentTypesForGeneric(AstNode inferenceNode,
       DartType uninstantiatedType, TypeArgumentList typeArguments,
-      {AstNode errorNode}) {
+      {AstNode errorNode, bool isConst: false}) {
     errorNode ??= inferenceNode;
     TypeSystem ts = typeSystem;
     if (typeArguments == null &&
@@ -5177,6 +5177,7 @@
           const <DartType>[],
           InferenceContext.getContext(inferenceNode),
           downwards: true,
+          isConst: isConst,
           errorReporter: errorReporter,
           errorNode: errorNode);
     }
@@ -5218,7 +5219,7 @@
 
       inferred = _inferArgumentTypesForGeneric(
           node, constructorType, constructor.type.typeArguments,
-          errorNode: node.constructorName);
+          isConst: node.isConst, errorNode: node.constructorName);
 
       if (inferred != null) {
         ArgumentList arguments = node.argumentList;
diff --git a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
index f3b066e..682b4f3 100644
--- a/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
+++ b/pkg/analyzer/lib/src/generated/static_type_analyzer.dart
@@ -175,6 +175,7 @@
     InterfaceType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
         _typeProvider.listType, parameters, elementTypes, contextType,
         downwards: downwards,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -190,6 +191,7 @@
     ParameterizedType inferred = ts.inferGenericFunctionOrType(
         _typeProvider.mapType, [], [], contextType,
         downwards: true,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -204,6 +206,7 @@
     DartType inferred = ts.inferGenericFunctionOrType<InterfaceType>(
         _typeProvider.setType, [], [], contextType,
         downwards: true,
+        isConst: node.isConst,
         errorReporter: _resolver.errorReporter,
         errorNode: node);
     return inferred;
@@ -1546,7 +1549,8 @@
       DartType fnType,
       TypeArgumentList typeArguments,
       ArgumentList argumentList,
-      AstNode errorNode) {
+      AstNode errorNode,
+      {bool isConst: false}) {
     TypeSystem ts = _typeSystem;
     if (typeArguments == null &&
         fnType is FunctionType &&
@@ -1568,7 +1572,9 @@
       }
       return ts.inferGenericFunctionOrType(
           fnType, params, argTypes, InferenceContext.getContext(node),
-          errorReporter: _resolver.errorReporter, errorNode: errorNode);
+          isConst: isConst,
+          errorReporter: _resolver.errorReporter,
+          errorNode: errorNode);
     }
     return null;
   }
@@ -1606,7 +1612,8 @@
 
     ArgumentList arguments = node.argumentList;
     FunctionType inferred = _inferGenericInvoke(node, constructorType,
-        constructor.type.typeArguments, arguments, node.constructorName);
+        constructor.type.typeArguments, arguments, node.constructorName,
+        isConst: node.isConst);
 
     if (inferred != null && inferred != originalElement.type) {
       // Fix up the parameter elements based on inferred method.
@@ -1888,7 +1895,9 @@
       ..addAll(valueTypes);
     return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
         _typeProvider.mapType, typeParameters, elementTypes, contextType,
-        errorReporter: _resolver.errorReporter, errorNode: node);
+        isConst: node.isConst,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
   }
 
   DartType _toSetType(SetOrMapLiteral node, DartType contextType,
@@ -1908,7 +1917,9 @@
         growable: true);
     return (_typeSystem as Dart2TypeSystem).inferGenericFunctionOrType(
         _typeProvider.setType, parameters, elementTypes, contextType,
-        errorReporter: _resolver.errorReporter, errorNode: node);
+        isConst: node.isConst,
+        errorReporter: _resolver.errorReporter,
+        errorNode: node);
   }
 
   /**
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 969cac5..ec1a06f 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -225,7 +225,8 @@
       DartType returnContextType,
       {ErrorReporter errorReporter,
       AstNode errorNode,
-      bool downwards: false}) {
+      bool downwards: false,
+      bool isConst: false}) {
     // TODO(jmesserly): expose typeFormals on ParameterizedType.
     List<TypeParameterElement> typeFormals = typeFormalsAsElements(genericType);
     if (typeFormals.isEmpty) {
@@ -242,6 +243,9 @@
         genericType is FunctionType ? genericType.returnType : genericType;
 
     if (returnContextType != null) {
+      if (isConst) {
+        returnContextType = _eliminateTypeVariables(returnContextType);
+      }
       inferrer.constrainReturnType(declaredReturnType, returnContextType);
     }
 
@@ -652,6 +656,30 @@
   }
 
   /**
+   * Eliminates type variables from the context [type], replacing them with
+   * `Null` or `Object` as appropriate.
+   *
+   * For example in `List<T> list = const []`, the context type for inferring
+   * the list should be changed from `List<T>` to `List<Null>` so the constant
+   * doesn't depend on the type variables `T` (because it can't be canonicalized
+   * at compile time, as `T` is unknown).
+   *
+   * Conceptually this is similar to the "least closure", except instead of
+   * eliminating `?` ([UnknownInferredType]) it eliminates all type variables
+   * ([TypeParameterType]).
+   *
+   * The equivalent CFE code can be found in the `TypeVariableEliminator` class.
+   */
+  DartType _eliminateTypeVariables(DartType type) {
+    return _substituteType(type, true, (type, lowerBound) {
+      if (type is TypeParameterType) {
+        return lowerBound ? typeProvider.nullType : typeProvider.objectType;
+      }
+      return type;
+    });
+  }
+
+  /**
    * Compute the greatest lower bound of function types [f] and [g].
    *
    * The spec rules for GLB on function types, informally, are pretty simple:
@@ -891,19 +919,43 @@
     return false;
   }
 
+  /**
+   * Returns the greatest or least closure of [type], which replaces `?`
+   * ([UnknownInferredType]) with `dynamic` or `Null` as appropriate.
+   *
+   * If [lowerBound] is true, this will return the "least closure", otherwise
+   * it returns the "greatest closure".
+   */
   DartType _substituteForUnknownType(DartType type, {bool lowerBound: false}) {
-    if (identical(type, UnknownInferredType.instance)) {
-      if (lowerBound) {
-        // TODO(jmesserly): this should be the bottom type, once it can be
-        // reified.
-        return typeProvider.nullType;
+    return _substituteType(type, lowerBound, (type, lowerBound) {
+      if (identical(type, UnknownInferredType.instance)) {
+        return lowerBound ? typeProvider.nullType : typeProvider.dynamicType;
       }
-      return typeProvider.dynamicType;
+      return type;
+    });
+  }
+
+  /**
+   * Apply the [visitType] substitution to [type], using the result value if
+   * different, otherwise recursively apply the substitution.
+   *
+   * This method is used for substituting `?` ([UnknownInferredType]) with its
+   * greatest/least closure, and for eliminating type parameters for inference
+   * of `const` objects.
+   *
+   * See also [_eliminateTypeVariables] and [_substituteForUnknownType].
+   */
+  DartType _substituteType(DartType type, bool lowerBound,
+      DartType Function(DartType, bool) visitType) {
+    // Apply the substitution to this type, and return the result if different.
+    var newType = visitType(type, lowerBound);
+    if (!identical(newType, type)) {
+      return newType;
     }
     if (type is InterfaceTypeImpl) {
       // Generic types are covariant, so keep the constraint direction.
-      var newTypeArgs = _transformList(type.typeArguments,
-          (t) => _substituteForUnknownType(t, lowerBound: lowerBound));
+      var newTypeArgs = _transformList(
+          type.typeArguments, (t) => _substituteType(t, lowerBound, visitType));
       if (identical(type.typeArguments, newTypeArgs)) return type;
       return new InterfaceTypeImpl(
           type.element, type.prunedTypedefs, type.nullability)
@@ -914,8 +966,7 @@
       var returnType = type.returnType;
       var newParameters = _transformList(parameters, (ParameterElement p) {
         // Parameters are contravariant, so flip the constraint direction.
-        var newType =
-            _substituteForUnknownType(p.type, lowerBound: !lowerBound);
+        var newType = _substituteType(p.type, !lowerBound, visitType);
         return new ParameterElementImpl.synthetic(
             p.name,
             newType,
@@ -923,8 +974,7 @@
             p.parameterKind);
       });
       // Return type is covariant.
-      var newReturnType =
-          _substituteForUnknownType(returnType, lowerBound: lowerBound);
+      var newReturnType = _substituteType(returnType, lowerBound, visitType);
       if (identical(parameters, newParameters) &&
           identical(returnType, newReturnType)) {
         return type;
@@ -1179,8 +1229,8 @@
             ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
           typeParam,
           ' Inferred candidate type $inferred has type parameters'
-              ' ${(inferred as FunctionType).typeFormals}, but a function with'
-              ' type parameters cannot be used as a type argument.'
+          ' ${(inferred as FunctionType).typeFormals}, but a function with'
+          ' type parameters cannot be used as a type argument.'
         ]);
 
         // Heuristic: Using a generic function type as a bound makes subtyping
@@ -1211,8 +1261,8 @@
             ?.reportErrorForNode(StrongModeCode.COULD_NOT_INFER, errorNode, [
           typeParam,
           "\nRecursive bound cannot be instantiated: '$typeParamBound'."
-              "\nConsider passing explicit type argument(s) "
-              "to the generic.\n\n'"
+          "\nConsider passing explicit type argument(s) "
+          "to the generic.\n\n'"
         ]);
       }
     }
diff --git a/pkg/analyzer/lib/src/manifest/manifest_validator.dart b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
new file mode 100644
index 0000000..f18f9bd
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_validator.dart
@@ -0,0 +1,112 @@
+// 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/error/error.dart';
+import 'package:analyzer/error/listener.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:html/dom.dart';
+import 'package:html/parser.dart' show parseFragment;
+import 'package:source_span/source_span.dart';
+
+import 'manifest_values.dart';
+import 'manifest_warning_code.dart';
+
+class ManifestValidator {
+  /**
+   * The source representing the file being validated.
+   */
+  final Source source;
+
+  /**
+   * Initialize a newly create validator to validate the content of the given
+   * [source].
+   */
+  ManifestValidator(this.source);
+
+  /*
+   * Validate the [contents] of the Android Manifest file.
+   */
+  List<AnalysisError> validate(String contents, bool checkManifest) {
+    RecordingErrorListener recorder = new RecordingErrorListener();
+    ErrorReporter reporter = new ErrorReporter(recorder, source);
+
+    if (checkManifest) {
+      var document =
+          parseFragment(contents, container: MANIFEST_TAG, generateSpans: true);
+      var manifest = document.children.firstWhere(
+          (element) => element.localName == MANIFEST_TAG,
+          orElse: () => null);
+      var features = manifest?.getElementsByTagName(USES_FEATURE_TAG) ?? [];
+      var permissions =
+          manifest?.getElementsByTagName(USES_PERMISSION_TAG) ?? [];
+
+      _validateFeatures(features, reporter);
+      _validatePermissions(permissions, features, reporter);
+    }
+    return recorder.errors;
+  }
+
+  /*
+   * Validate the `uses-feature` tags.
+   */
+  _validateFeatures(List<Element> features, ErrorReporter reporter) {
+    var unsupported = features
+        .where((element) => UNSUPPORTED_HARDWARE_FEATURES
+            .contains(element.attributes[ANDROID_NAME]))
+        .toList();
+    unsupported.forEach((element) {
+      if (!element.attributes.containsKey(ANDROID_REQUIRED)) {
+        _reportErrorForNode(reporter, element, ANDROID_NAME,
+            ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE);
+      } else if (element.attributes[ANDROID_REQUIRED] == true) {
+        _reportErrorForNode(reporter, element, ANDROID_NAME,
+            ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE);
+      }
+    });
+  }
+
+  /*
+   * Validate the `uses-permission` tags.
+   */
+  _validatePermissions(List<Element> permissions, List<Element> features,
+      ErrorReporter reporter) {
+    permissions.forEach((permission) {
+      if (permission.attributes[ANDROID_NAME] == ANDROID_PERMISSION_CAMERA) {
+        if (!_hasFeatureCamera(features) ||
+            !_hasFeatureCameraAutoFocus(features)) {
+          _reportErrorForNode(reporter, permission, ANDROID_NAME,
+              ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE);
+        }
+      } else {
+        var featureName =
+            getImpliedUnsupportedHardware(permission.attributes[ANDROID_NAME]);
+        if (featureName != null) {
+          _reportErrorForNode(
+              reporter,
+              permission,
+              ANDROID_NAME,
+              ManifestWarningCode.PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE,
+              [featureName]);
+        }
+      }
+    });
+  }
+
+  bool _hasFeatureCamera(List<Element> features) =>
+      features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA);
+
+  bool _hasFeatureCameraAutoFocus(List<Element> features) =>
+      features.any((f) => f.localName == HARDWARE_FEATURE_CAMERA_AUTOFOCUS);
+
+  /**
+   * Report an error for the given node.
+   */
+  void _reportErrorForNode(
+      ErrorReporter reporter, Node node, dynamic key, ErrorCode errorCode,
+      [List<Object> arguments]) {
+    FileSpan span = node.attributeValueSpans[key];
+    reporter.reportErrorForOffset(
+        errorCode, span.start.offset, span.length, arguments);
+  }
+}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_values.dart b/pkg/analyzer/lib/src/manifest/manifest_values.dart
new file mode 100644
index 0000000..ea1b59d
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_values.dart
@@ -0,0 +1,101 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*
+*  The arritbute values to check for compatibiltiy with Chrome OS.
+*
+ */
+
+const String MANIFEST_TAG = 'manifest';
+
+const String USES_PERMISSION_TAG = 'uses-permission';
+
+const String USES_FEATURE_TAG = 'uses-feature';
+
+const String ANDROID_NAME = 'android:name';
+
+const String ANDROID_REQUIRED = 'android:required';
+
+const String HARDWARE_FEATURE_CAMERA = 'android.hardware.camera';
+
+const String HARDWARE_FEATURE_CAMERA_AUTOFOCUS =
+    'android.hardware.camera.autofocus';
+
+const String HARDWARE_FEATURE_TELEPHONY = 'android.hardware.telephony';
+
+const String ANDROID_PERMISSION_CAMERA = 'android.permission.CAMERA';
+
+const UNSUPPORTED_HARDWARE_FEATURES = <String>[
+  HARDWARE_FEATURE_CAMERA,
+  HARDWARE_FEATURE_CAMERA_AUTOFOCUS,
+  'android.hardware.camera.capability.manual_post_processing',
+  'android.hardware.camera.capability.manual_sensor',
+  'android.hardware.camera.capability.raw',
+  'android.hardware.camera.flash',
+  'android.hardware.camera.level.full',
+  'android.hardware.consumerir',
+  'android.hardware.location.gps',
+  'android.hardware.nfc',
+  'android.hardware.nfc.hce',
+  'android.hardware.sensor.barometer',
+  HARDWARE_FEATURE_TELEPHONY,
+  'android.hardware.telephony.cdma',
+  'android.hardware.telephony.gsm',
+  'android.hardware.touchscreen',
+  'android.hardware.type.automotive',
+  'android.hardware.type.television',
+  'android.hardware.usb.accessory',
+  'android.hardware.usb.host',
+  // Partially-supported, only on some Chrome OS devices.
+  'android.hardware.sensor.accelerometer',
+  'android.hardware.sensor.compass',
+  'android.hardware.sensor.gyroscope',
+  'android.hardware.sensor.light',
+  'android.hardware.sensor.proximity',
+  'android.hardware.sensor.stepcounter',
+  'android.hardware.sensor.stepdetector',
+  // Software features that are not supported
+  'android.software.app_widgets',
+  'android.software.device_admin',
+  'android.software.home_screen',
+  'android.software.input_methods',
+  'android.software.leanback',
+  'android.software.live_wallpaper',
+  'android.software.live_tv',
+  'android.software.managed_users',
+  'android.software.midi',
+  'android.software.sip',
+  'android.software.sip.voip',
+];
+
+String getImpliedUnsupportedHardware(String permission) {
+  switch (permission) {
+    case ANDROID_PERMISSION_CAMERA:
+      return HARDWARE_FEATURE_CAMERA;
+    case 'android.permission.CALL_PHONE':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.CALL_PRIVILEGED':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.MODIFY_PHONE_STATE':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.PROCESS_OUTGOING_CALLS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.READ_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_MMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.RECEIVE_WAP_PUSH':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.SEND_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.WRITE_APN_SETTINGS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    case 'android.permission.WRITE_SMS':
+      return HARDWARE_FEATURE_TELEPHONY;
+    default:
+      return null;
+  }
+}
diff --git a/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
new file mode 100644
index 0000000..0e0928c
--- /dev/null
+++ b/pkg/analyzer/lib/src/manifest/manifest_warning_code.dart
@@ -0,0 +1,60 @@
+// 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/error/error.dart';
+
+/**
+ * The error codes used for warnings in analysis options files. The convention
+ * for this class is for the name of the error code to indicate the problem that
+ * caused the error to be generated and for the error message to explain what is
+ * wrong and, when appropriate, how the problem can be corrected.
+ */
+class ManifestWarningCode extends ErrorCode {
+  /**
+   * A code indicating that a specified hardware feature is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode UNSUPPORTED_CHROME_OS_HARDWARE =
+      const ManifestWarningCode('UNSUPPORTED_CHROME_OS_HARDWARE',
+          "This hardware feature is not supported on Chrome OS.",
+          correction:
+              "Try adding `android:required=\"false\"` for this hardware " +
+                  "feature.");
+
+  /**
+   * A code indicating that a specified permission is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE =
+      const ManifestWarningCode(
+          'PERMISSION_IMPLIES_UNSUPPORTED_HARDWARE',
+          "Permission exists without corresponding hardware tag `<uses-feature " +
+              "android:name=\"{0}\"  android:required=\"false\">`.",
+          correction:
+              "Try adding the uses-feature with required=\"false\" attribute value.");
+
+  /**
+   * A code indicating that the camera permissions is not supported on Chrome OS.
+   */
+  static const ManifestWarningCode CAMERA_PERMISSIONS_INCOMPATIBLE =
+      const ManifestWarningCode(
+          'CAMERA_PERMISSIONS_INCOMPATIBLE',
+          "Permission exists without corresponding hardware `<uses-feature " +
+              "android:name=\"android.hardware.camera\"  android:required=\"false\">` " +
+              "`<uses-feature " +
+              "android:name=\"android.hardware.camera.autofocus\"  android:required=\"false\">`.",
+          correction:
+              "Try adding the uses-feature with required=\"false\" attribute value.");
+
+  /**
+   * Initialize a newly created warning code to have the given [name], [message]
+   * and [correction].
+   */
+  const ManifestWarningCode(String name, String message, {String correction})
+      : super.temporary(name, message, correction: correction);
+
+  @override
+  ErrorSeverity get errorSeverity => ErrorSeverity.WARNING;
+
+  @override
+  ErrorType get type => ErrorType.STATIC_WARNING;
+}
diff --git a/pkg/analyzer/lib/src/services/available_declarations.dart b/pkg/analyzer/lib/src/services/available_declarations.dart
index 539b719..8337641 100644
--- a/pkg/analyzer/lib/src/services/available_declarations.dart
+++ b/pkg/analyzer/lib/src/services/available_declarations.dart
@@ -32,6 +32,7 @@
 
 /// A top-level public declaration.
 class Declaration {
+  final List<Declaration> children;
   final String defaultArgumentListString;
   final List<int> defaultArgumentListTextRanges;
   final String docComplete;
@@ -45,18 +46,11 @@
   final String locationPath;
   final int locationStartColumn;
   final int locationStartLine;
-
-  /// The name of the declaration.
-  /// For enum constants, the name of the constant.
   final String name;
-
-  /// Usually `null`.
-  /// For enum constants, the name of the enum.
-  final String name2;
-
   final String parameters;
   final List<String> parameterNames;
   final List<String> parameterTypes;
+  final Declaration parent;
   final int requiredParameterCount;
   final String returnType;
   final String typeParameters;
@@ -64,6 +58,7 @@
   List<String> _relevanceTags;
 
   Declaration({
+    @required this.children,
     @required this.defaultArgumentListString,
     @required this.defaultArgumentListTextRanges,
     @required this.docComplete,
@@ -78,10 +73,10 @@
     @required this.locationStartColumn,
     @required this.locationStartLine,
     @required this.name,
-    @required this.name2,
     @required this.parameters,
     @required this.parameterNames,
     @required this.parameterTypes,
+    @required this.parent,
     @required List<String> relevanceTags,
     @required this.requiredParameterCount,
     @required this.returnType,
@@ -92,11 +87,7 @@
 
   @override
   String toString() {
-    if (name2 == null) {
-      return '($kind, $name)';
-    } else {
-      return '($kind, $name, $name2)';
-    }
+    return '($kind, $name)';
   }
 }
 
@@ -735,8 +726,8 @@
         var name = declaration.name;
         return <String>['$uriStr::$name'];
       case DeclarationKind.ENUM_CONSTANT:
-        var name2 = declaration.name2;
-        return <String>['$uriStr::$name2'];
+        var enumName = declaration.parent.name;
+        return <String>['$uriStr::$enumName'];
       default:
         return null;
     }
@@ -767,15 +758,14 @@
 
 class _DeclarationStorage {
   static const fieldDocMask = 1 << 0;
-  static const fieldName2Mask = 1 << 1;
-  static const fieldParametersMask = 1 << 2;
-  static const fieldReturnTypeMask = 1 << 3;
-  static const fieldTypeParametersMask = 1 << 4;
+  static const fieldParametersMask = 1 << 1;
+  static const fieldReturnTypeMask = 1 << 2;
+  static const fieldTypeParametersMask = 1 << 3;
 
-  static Declaration fromIdl(String path, idl.AvailableDeclaration d) {
+  static Declaration fromIdl(
+      String path, Declaration parent, idl.AvailableDeclaration d) {
     var fieldMask = d.fieldMask;
     var hasDoc = fieldMask & fieldDocMask != 0;
-    var hasName2 = fieldMask & fieldName2Mask != 0;
     var hasParameters = fieldMask & fieldParametersMask != 0;
     var hasReturnType = fieldMask & fieldReturnTypeMask != 0;
     var hasTypeParameters = fieldMask & fieldTypeParametersMask != 0;
@@ -787,7 +777,9 @@
       relevanceTags = null;
     }
 
-    return Declaration(
+    var children = <Declaration>[];
+    var declaration = Declaration(
+      children: children,
       defaultArgumentListString: d.defaultArgumentListString.isNotEmpty
           ? d.defaultArgumentListString
           : null,
@@ -806,15 +798,22 @@
       locationStartColumn: d.locationStartColumn,
       locationStartLine: d.locationStartLine,
       name: d.name,
-      name2: hasName2 ? d.name2 : null,
       parameters: hasParameters ? d.parameters : null,
       parameterNames: hasParameters ? d.parameterNames : null,
       parameterTypes: hasParameters ? d.parameterTypes.toList() : null,
+      parent: parent,
       relevanceTags: relevanceTags,
       requiredParameterCount: hasParameters ? d.requiredParameterCount : null,
       returnType: hasReturnType ? d.returnType : null,
       typeParameters: hasTypeParameters ? d.typeParameters : null,
     );
+
+    for (var childIdl in d.children) {
+      var child = fromIdl(path, declaration, childIdl);
+      children.add(child);
+    }
+
+    return declaration;
   }
 
   static DeclarationKind kindFromIdl(idl.AvailableDeclarationKind kind) {
@@ -880,9 +879,6 @@
     if (d.docComplete != null) {
       fieldMask |= fieldDocMask;
     }
-    if (d.name2 != null) {
-      fieldMask |= fieldName2Mask;
-    }
     if (d.parameters != null) {
       fieldMask |= fieldParametersMask;
     }
@@ -895,6 +891,7 @@
 
     var idlKind = kindToIdl(d.kind);
     return idl.AvailableDeclarationBuilder(
+      children: d.children.map(toIdl).toList(),
       defaultArgumentListString: d.defaultArgumentListString,
       defaultArgumentListTextRanges: d.defaultArgumentListTextRanges,
       docComplete: d.docComplete,
@@ -909,7 +906,6 @@
       locationStartColumn: d.locationStartColumn,
       locationStartLine: d.locationStartLine,
       name: d.name,
-      name2: d.name2,
       parameters: d.parameters,
       parameterNames: d.parameterNames,
       parameterTypes: d.parameterTypes,
@@ -938,7 +934,7 @@
 
   Iterable<Declaration> filter(List<Declaration> declarations) {
     return declarations.where((d) {
-      var name = d.name2 ?? d.name;
+      var name = d.name;
       for (var combinator in combinators) {
         if (combinator.shows.isNotEmpty) {
           if (!combinator.shows.contains(name)) return false;
@@ -961,7 +957,7 @@
 
 class _File {
   /// The version of data format, should be incremented on every format change.
-  static const int DATA_VERSION = 9;
+  static const int DATA_VERSION = 11;
 
   /// The next value for [id].
   static int _nextId = 0;
@@ -1083,7 +1079,7 @@
       for (var part in parts) {
         libraryDeclarations.addAll(part.file.fileDeclarations);
       }
-      _computeRelevanceTagsForLibraryDeclarations();
+      _computeRelevanceTags(libraryDeclarations);
     }
   }
 
@@ -1093,6 +1089,8 @@
     fileDeclarations = [];
     libraryDeclarations = null;
     exportedDeclarations = null;
+    templateNames = [];
+    templateValues = [];
 
     for (var astDirective in unit.directives) {
       if (astDirective is ExportDirective) {
@@ -1143,7 +1141,7 @@
       }
     }
 
-    void addDeclaration({
+    Declaration addDeclaration({
       String defaultArgumentListString,
       List<int> defaultArgumentListTextRanges,
       bool isAbstract = false,
@@ -1152,23 +1150,23 @@
       bool isFinal = false,
       @required DeclarationKind kind,
       @required Identifier name,
-      Identifier name2,
       String parameters,
       List<String> parameterNames,
       List<String> parameterTypes,
+      Declaration parent,
       List<String> relevanceTags,
       int requiredParameterCount,
       String returnType,
       String typeParameters,
     }) {
-      if (Identifier.isPrivateName(name.name) ||
-          name2 != null && Identifier.isPrivateName(name2.name)) {
-        return;
+      if (Identifier.isPrivateName(name.name)) {
+        return null;
       }
 
       var locationOffset = name.offset;
       var lineLocation = lineInfo.getLocation(locationOffset);
-      fileDeclarations.add(Declaration(
+      var declaration = Declaration(
+        children: <Declaration>[],
         defaultArgumentListString: defaultArgumentListString,
         defaultArgumentListTextRanges: defaultArgumentListTextRanges,
         docComplete: docComplete,
@@ -1181,17 +1179,24 @@
         locationOffset: locationOffset,
         locationPath: path,
         name: name.name,
-        name2: name2?.name,
         locationStartColumn: lineLocation.columnNumber,
         locationStartLine: lineLocation.lineNumber,
         parameters: parameters,
         parameterNames: parameterNames,
         parameterTypes: parameterTypes,
+        parent: parent,
         relevanceTags: relevanceTags,
         requiredParameterCount: requiredParameterCount,
         returnType: returnType,
         typeParameters: typeParameters,
-      ));
+      );
+
+      if (parent != null) {
+        parent.children.add(declaration);
+      } else {
+        fileDeclarations.add(declaration);
+      }
+      return declaration;
     }
 
     for (var node in unit.declarations) {
@@ -1199,12 +1204,15 @@
       var isDeprecated = _hasDeprecatedAnnotation(node);
 
       if (node is ClassDeclaration) {
-        addDeclaration(
+        var classDeclaration = addDeclaration(
           isAbstract: node.isAbstract,
           isDeprecated: isDeprecated,
           kind: DeclarationKind.CLASS,
           name: node.name,
         );
+        if (classDeclaration == null) continue;
+
+        var hasConstructor = false;
         for (var classMember in node.members) {
           if (classMember is ConstructorDeclaration) {
             setDartDoc(classMember);
@@ -1228,15 +1236,44 @@
               isDeprecated: isDeprecated,
               kind: DeclarationKind.CONSTRUCTOR,
               name: constructorName,
-              name2: node.name,
               parameters: parameters.toSource(),
               parameterNames: _getFormalParameterNames(parameters),
               parameterTypes: _getFormalParameterTypes(parameters),
+              parent: classDeclaration,
               requiredParameterCount:
                   _getFormalParameterRequiredCount(parameters),
             );
+            hasConstructor = true;
           }
         }
+
+        if (!hasConstructor) {
+          classDeclaration.children.add(Declaration(
+            children: [],
+            defaultArgumentListString: null,
+            defaultArgumentListTextRanges: null,
+            docComplete: null,
+            docSummary: null,
+            isAbstract: false,
+            isConst: false,
+            isDeprecated: false,
+            isFinal: false,
+            kind: DeclarationKind.CONSTRUCTOR,
+            locationOffset: -1,
+            locationPath: path,
+            name: '',
+            locationStartColumn: 0,
+            locationStartLine: 0,
+            parameters: '()',
+            parameterNames: [],
+            parameterTypes: [],
+            parent: classDeclaration,
+            relevanceTags: null,
+            requiredParameterCount: 0,
+            returnType: null,
+            typeParameters: null,
+          ));
+        }
       } else if (node is ClassTypeAlias) {
         addDeclaration(
           isDeprecated: isDeprecated,
@@ -1244,11 +1281,13 @@
           name: node.name,
         );
       } else if (node is EnumDeclaration) {
-        addDeclaration(
+        var enumDeclaration = addDeclaration(
           isDeprecated: isDeprecated,
           kind: DeclarationKind.ENUM,
           name: node.name,
         );
+        if (enumDeclaration == null) continue;
+
         for (var constant in node.constants) {
           setDartDoc(constant);
           var isDeprecated = _hasDeprecatedAnnotation(constant);
@@ -1256,7 +1295,7 @@
             isDeprecated: isDeprecated,
             kind: DeclarationKind.ENUM_CONSTANT,
             name: constant.name,
-            name2: node.name,
+            parent: enumDeclaration,
           );
         }
       } else if (node is FunctionDeclaration) {
@@ -1299,6 +1338,8 @@
         }
       } else if (node is GenericTypeAlias) {
         var functionType = node.functionType;
+        if (functionType == null) continue;
+
         var parameters = functionType.parameters;
         addDeclaration(
           isDeprecated: isDeprecated,
@@ -1335,10 +1376,11 @@
     }
   }
 
-  void _computeRelevanceTagsForLibraryDeclarations() {
-    for (var declaration in libraryDeclarations) {
+  void _computeRelevanceTags(List<Declaration> declarations) {
+    for (var declaration in declarations) {
       declaration._relevanceTags ??=
           RelevanceTags._forDeclaration(uriStr, declaration);
+      _computeRelevanceTags(declaration.children);
     }
   }
 
@@ -1429,11 +1471,11 @@
     }).toList();
 
     fileDeclarations = idlFile.declarations.map((e) {
-      return _DeclarationStorage.fromIdl(path, e);
+      return _DeclarationStorage.fromIdl(path, null, e);
     }).toList();
 
-    templateNames = idlFile.directiveInfo.templateNames;
-    templateValues = idlFile.directiveInfo.templateValues;
+    templateNames = idlFile.directiveInfo.templateNames.toList();
+    templateValues = idlFile.directiveInfo.templateValues.toList();
   }
 
   static _DefaultArguments _computeDefaultArguments(
@@ -1649,7 +1691,7 @@
   static Set<Declaration> _newDeclarationSet() {
     return HashSet<Declaration>(
       hashCode: (e) => e.name.hashCode,
-      equals: (a, b) => a.name == b.name && a.name2 == b.name2,
+      equals: (a, b) => a.name == b.name,
     );
   }
 }
diff --git a/pkg/analyzer/lib/src/summary/format.dart b/pkg/analyzer/lib/src/summary/format.dart
index 004943b..fd78d94 100644
--- a/pkg/analyzer/lib/src/summary/format.dart
+++ b/pkg/analyzer/lib/src/summary/format.dart
@@ -322,7 +322,7 @@
   String get exception => _exception ??= '';
 
   /// The exception string.
-  void set exception(String value) {
+  set exception(String value) {
     this._exception = value;
   }
 
@@ -331,7 +331,7 @@
       _files ??= <AnalysisDriverExceptionFileBuilder>[];
 
   /// The state of files when the exception happened.
-  void set files(List<AnalysisDriverExceptionFileBuilder> value) {
+  set files(List<AnalysisDriverExceptionFileBuilder> value) {
     this._files = value;
   }
 
@@ -339,7 +339,7 @@
   String get path => _path ??= '';
 
   /// The path of the file being analyzed when the exception happened.
-  void set path(String value) {
+  set path(String value) {
     this._path = value;
   }
 
@@ -347,7 +347,7 @@
   String get stackTrace => _stackTrace ??= '';
 
   /// The exception stack trace string.
-  void set stackTrace(String value) {
+  set stackTrace(String value) {
     this._stackTrace = value;
   }
 
@@ -361,16 +361,12 @@
         _path = path,
         _stackTrace = stackTrace;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _files?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._path ?? '');
     signature.addString(this._exception ?? '');
@@ -517,7 +513,7 @@
   String get content => _content ??= '';
 
   /// The content of the file.
-  void set content(String value) {
+  set content(String value) {
     this._content = value;
   }
 
@@ -525,7 +521,7 @@
   String get path => _path ??= '';
 
   /// The path of the file.
-  void set path(String value) {
+  set path(String value) {
     this._path = value;
   }
 
@@ -533,14 +529,10 @@
       : _content = content,
         _path = path;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._path ?? '');
     signature.addString(this._content ?? '');
@@ -631,7 +623,7 @@
       _errors ??= <AnalysisDriverUnitErrorBuilder>[];
 
   /// The full list of analysis errors, both syntactic and semantic.
-  void set errors(List<AnalysisDriverUnitErrorBuilder> value) {
+  set errors(List<AnalysisDriverUnitErrorBuilder> value) {
     this._errors = value;
   }
 
@@ -639,7 +631,7 @@
   AnalysisDriverUnitIndexBuilder get index => _index;
 
   /// The index of the unit.
-  void set index(AnalysisDriverUnitIndexBuilder value) {
+  set index(AnalysisDriverUnitIndexBuilder value) {
     this._index = value;
   }
 
@@ -649,17 +641,13 @@
       : _errors = errors,
         _index = index;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _errors?.forEach((b) => b.flushInformative());
     _index?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._errors == null) {
       signature.addInt(0);
@@ -775,7 +763,7 @@
   /// The names of defined instance members.
   /// They are indexes into [AnalysisDriverUnitError.strings] list.
   /// The list is sorted in ascending order.
-  void set members(List<int> value) {
+  set members(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._members = value;
   }
@@ -785,7 +773,7 @@
 
   /// The name of the class.
   /// It is an index into [AnalysisDriverUnitError.strings] list.
-  void set name(int value) {
+  set name(int value) {
     assert(value == null || value >= 0);
     this._name = value;
   }
@@ -794,14 +782,10 @@
       : _members = members,
         _name = name;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._name ?? 0);
     if (this._members == null) {
@@ -897,7 +881,7 @@
   String get correction => _correction ??= '';
 
   /// The optional correction hint for the error.
-  void set correction(String value) {
+  set correction(String value) {
     this._correction = value;
   }
 
@@ -905,7 +889,7 @@
   int get length => _length ??= 0;
 
   /// The length of the error in the file.
-  void set length(int value) {
+  set length(int value) {
     assert(value == null || value >= 0);
     this._length = value;
   }
@@ -914,7 +898,7 @@
   String get message => _message ??= '';
 
   /// The message of the error.
-  void set message(String value) {
+  set message(String value) {
     this._message = value;
   }
 
@@ -922,7 +906,7 @@
   int get offset => _offset ??= 0;
 
   /// The offset from the beginning of the file.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -931,7 +915,7 @@
   String get uniqueName => _uniqueName ??= '';
 
   /// The unique name of the error code.
-  void set uniqueName(String value) {
+  set uniqueName(String value) {
     this._uniqueName = value;
   }
 
@@ -947,14 +931,10 @@
         _offset = offset,
         _uniqueName = uniqueName;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._offset ?? 0);
     signature.addInt(this._length ?? 0);
@@ -1106,7 +1086,7 @@
 
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the kind of the synthetic element.
-  void set elementKinds(List<idl.IndexSyntheticElementKind> value) {
+  set elementKinds(List<idl.IndexSyntheticElementKind> value) {
     this._elementKinds = value;
   }
 
@@ -1119,7 +1099,7 @@
   /// is a top-level element.  The list is sorted in ascending order, so that
   /// the client can quickly check whether an element is referenced in this
   /// index.
-  void set elementNameClassMemberIds(List<int> value) {
+  set elementNameClassMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameClassMemberIds = value;
   }
@@ -1131,7 +1111,7 @@
   /// the identifier of the named parameter name, or `null` if the element is
   /// not a named parameter.  The list is sorted in ascending order, so that the
   /// client can quickly check whether an element is referenced in this index.
-  void set elementNameParameterIds(List<int> value) {
+  set elementNameParameterIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameParameterIds = value;
   }
@@ -1144,7 +1124,7 @@
   /// the identifier of the top-level element name, or `null` if the element is
   /// the unit.  The list is sorted in ascending order, so that the client can
   /// quickly check whether an element is referenced in this index.
-  void set elementNameUnitMemberIds(List<int> value) {
+  set elementNameUnitMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameUnitMemberIds = value;
   }
@@ -1155,7 +1135,7 @@
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the index into [unitLibraryUris] and [unitUnitUris] for the library
   /// specific unit where the element is declared.
-  void set elementUnits(List<int> value) {
+  set elementUnits(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementUnits = value;
   }
@@ -1164,7 +1144,7 @@
   int get nullStringId => _nullStringId ??= 0;
 
   /// Identifier of the null string in [strings].
-  void set nullStringId(int value) {
+  set nullStringId(int value) {
     assert(value == null || value >= 0);
     this._nullStringId = value;
   }
@@ -1175,7 +1155,7 @@
   /// List of unique element strings used in this index.  The list is sorted in
   /// ascending order, so that the client can quickly check the presence of a
   /// string in this index.
-  void set strings(List<String> value) {
+  set strings(List<String> value) {
     this._strings = value;
   }
 
@@ -1184,7 +1164,7 @@
       _subtypes ??= <AnalysisDriverSubtypeBuilder>[];
 
   /// The list of classes declared in the unit.
-  void set subtypes(List<AnalysisDriverSubtypeBuilder> value) {
+  set subtypes(List<AnalysisDriverSubtypeBuilder> value) {
     this._subtypes = value;
   }
 
@@ -1195,7 +1175,7 @@
   /// in [subtypes].  They are indexes into [strings] list. The list is sorted
   /// in ascending order.  There might be more than one element with the same
   /// value if there is more than one subtype of this supertype.
-  void set supertypes(List<int> value) {
+  set supertypes(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._supertypes = value;
   }
@@ -1206,7 +1186,7 @@
   /// Each item of this list corresponds to the library URI of a unique library
   /// specific unit referenced in the index.  It is an index into [strings]
   /// list.
-  void set unitLibraryUris(List<int> value) {
+  set unitLibraryUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitLibraryUris = value;
   }
@@ -1217,7 +1197,7 @@
   /// Each item of this list corresponds to the unit URI of a unique library
   /// specific unit referenced in the index.  It is an index into [strings]
   /// list.
-  void set unitUnitUris(List<int> value) {
+  set unitUnitUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitUnitUris = value;
   }
@@ -1228,7 +1208,7 @@
 
   /// Each item of this list is the `true` if the corresponding element usage
   /// is qualified with some prefix.
-  void set usedElementIsQualifiedFlags(List<bool> value) {
+  set usedElementIsQualifiedFlags(List<bool> value) {
     this._usedElementIsQualifiedFlags = value;
   }
 
@@ -1237,7 +1217,7 @@
       _usedElementKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the element usage.
-  void set usedElementKinds(List<idl.IndexRelationKind> value) {
+  set usedElementKinds(List<idl.IndexRelationKind> value) {
     this._usedElementKinds = value;
   }
 
@@ -1245,7 +1225,7 @@
   List<int> get usedElementLengths => _usedElementLengths ??= <int>[];
 
   /// Each item of this list is the length of the element usage.
-  void set usedElementLengths(List<int> value) {
+  set usedElementLengths(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementLengths = value;
   }
@@ -1255,7 +1235,7 @@
 
   /// Each item of this list is the offset of the element usage relative to the
   /// beginning of the file.
-  void set usedElementOffsets(List<int> value) {
+  set usedElementOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementOffsets = value;
   }
@@ -1267,7 +1247,7 @@
   /// [elementNameUnitMemberIds], [elementNameClassMemberIds] and
   /// [elementNameParameterIds].  The list is sorted in ascending order, so
   /// that the client can quickly find element references in this index.
-  void set usedElements(List<int> value) {
+  set usedElements(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElements = value;
   }
@@ -1278,7 +1258,7 @@
 
   /// Each item of this list is the `true` if the corresponding name usage
   /// is qualified with some prefix.
-  void set usedNameIsQualifiedFlags(List<bool> value) {
+  set usedNameIsQualifiedFlags(List<bool> value) {
     this._usedNameIsQualifiedFlags = value;
   }
 
@@ -1287,7 +1267,7 @@
       _usedNameKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the name usage.
-  void set usedNameKinds(List<idl.IndexRelationKind> value) {
+  set usedNameKinds(List<idl.IndexRelationKind> value) {
     this._usedNameKinds = value;
   }
 
@@ -1296,7 +1276,7 @@
 
   /// Each item of this list is the offset of the name usage relative to the
   /// beginning of the file.
-  void set usedNameOffsets(List<int> value) {
+  set usedNameOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNameOffsets = value;
   }
@@ -1307,7 +1287,7 @@
   /// Each item of this list is the index into [strings] for a used name.  The
   /// list is sorted in ascending order, so that the client can quickly find
   /// whether a name is used in this index.
-  void set usedNames(List<int> value) {
+  set usedNames(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNames = value;
   }
@@ -1354,16 +1334,12 @@
         _usedNameOffsets = usedNameOffsets,
         _usedNames = usedNames;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _subtypes?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._strings == null) {
       signature.addInt(0);
@@ -1960,7 +1936,7 @@
       _definedClassMemberNames ??= <String>[];
 
   /// List of class member names defined by the unit.
-  void set definedClassMemberNames(List<String> value) {
+  set definedClassMemberNames(List<String> value) {
     this._definedClassMemberNames = value;
   }
 
@@ -1968,7 +1944,7 @@
   List<String> get definedTopLevelNames => _definedTopLevelNames ??= <String>[];
 
   /// List of top-level names defined by the unit.
-  void set definedTopLevelNames(List<String> value) {
+  set definedTopLevelNames(List<String> value) {
     this._definedTopLevelNames = value;
   }
 
@@ -1976,7 +1952,7 @@
   List<String> get referencedNames => _referencedNames ??= <String>[];
 
   /// List of external names referenced by the unit.
-  void set referencedNames(List<String> value) {
+  set referencedNames(List<String> value) {
     this._referencedNames = value;
   }
 
@@ -1985,7 +1961,7 @@
 
   /// List of names which are used in `extends`, `with` or `implements` clauses
   /// in the file. Import prefixes and type arguments are not included.
-  void set subtypedNames(List<String> value) {
+  set subtypedNames(List<String> value) {
     this._subtypedNames = value;
   }
 
@@ -1993,7 +1969,7 @@
   UnlinkedUnitBuilder get unit => _unit;
 
   /// Unlinked information for the unit.
-  void set unit(UnlinkedUnitBuilder value) {
+  set unit(UnlinkedUnitBuilder value) {
     this._unit = value;
   }
 
@@ -2009,16 +1985,12 @@
         _subtypedNames = subtypedNames,
         _unit = unit;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _unit?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._referencedNames == null) {
       signature.addInt(0);
@@ -2208,6 +2180,7 @@
 class AvailableDeclarationBuilder extends Object
     with _AvailableDeclarationMixin
     implements idl.AvailableDeclaration {
+  List<AvailableDeclarationBuilder> _children;
   String _defaultArgumentListString;
   List<int> _defaultArgumentListTextRanges;
   String _docComplete;
@@ -2222,7 +2195,6 @@
   int _locationStartColumn;
   int _locationStartLine;
   String _name;
-  String _name2;
   List<String> _parameterNames;
   String _parameters;
   List<String> _parameterTypes;
@@ -2232,9 +2204,17 @@
   String _typeParameters;
 
   @override
+  List<AvailableDeclarationBuilder> get children =>
+      _children ??= <AvailableDeclarationBuilder>[];
+
+  set children(List<AvailableDeclarationBuilder> value) {
+    this._children = value;
+  }
+
+  @override
   String get defaultArgumentListString => _defaultArgumentListString ??= '';
 
-  void set defaultArgumentListString(String value) {
+  set defaultArgumentListString(String value) {
     this._defaultArgumentListString = value;
   }
 
@@ -2242,7 +2222,7 @@
   List<int> get defaultArgumentListTextRanges =>
       _defaultArgumentListTextRanges ??= <int>[];
 
-  void set defaultArgumentListTextRanges(List<int> value) {
+  set defaultArgumentListTextRanges(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._defaultArgumentListTextRanges = value;
   }
@@ -2250,21 +2230,21 @@
   @override
   String get docComplete => _docComplete ??= '';
 
-  void set docComplete(String value) {
+  set docComplete(String value) {
     this._docComplete = value;
   }
 
   @override
   String get docSummary => _docSummary ??= '';
 
-  void set docSummary(String value) {
+  set docSummary(String value) {
     this._docSummary = value;
   }
 
   @override
   int get fieldMask => _fieldMask ??= 0;
 
-  void set fieldMask(int value) {
+  set fieldMask(int value) {
     assert(value == null || value >= 0);
     this._fieldMask = value;
   }
@@ -2272,28 +2252,28 @@
   @override
   bool get isAbstract => _isAbstract ??= false;
 
-  void set isAbstract(bool value) {
+  set isAbstract(bool value) {
     this._isAbstract = value;
   }
 
   @override
   bool get isConst => _isConst ??= false;
 
-  void set isConst(bool value) {
+  set isConst(bool value) {
     this._isConst = value;
   }
 
   @override
   bool get isDeprecated => _isDeprecated ??= false;
 
-  void set isDeprecated(bool value) {
+  set isDeprecated(bool value) {
     this._isDeprecated = value;
   }
 
   @override
   bool get isFinal => _isFinal ??= false;
 
-  void set isFinal(bool value) {
+  set isFinal(bool value) {
     this._isFinal = value;
   }
 
@@ -2302,14 +2282,14 @@
       _kind ??= idl.AvailableDeclarationKind.CLASS;
 
   /// The kind of the declaration.
-  void set kind(idl.AvailableDeclarationKind value) {
+  set kind(idl.AvailableDeclarationKind value) {
     this._kind = value;
   }
 
   @override
   int get locationOffset => _locationOffset ??= 0;
 
-  void set locationOffset(int value) {
+  set locationOffset(int value) {
     assert(value == null || value >= 0);
     this._locationOffset = value;
   }
@@ -2317,7 +2297,7 @@
   @override
   int get locationStartColumn => _locationStartColumn ??= 0;
 
-  void set locationStartColumn(int value) {
+  set locationStartColumn(int value) {
     assert(value == null || value >= 0);
     this._locationStartColumn = value;
   }
@@ -2325,7 +2305,7 @@
   @override
   int get locationStartLine => _locationStartLine ??= 0;
 
-  void set locationStartLine(int value) {
+  set locationStartLine(int value) {
     assert(value == null || value >= 0);
     this._locationStartLine = value;
   }
@@ -2335,37 +2315,28 @@
 
   /// The first part of the declaration name, usually the only one, for example
   /// the name of a class like `MyClass`, or a function like `myFunction`.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
   @override
-  String get name2 => _name2 ??= '';
-
-  /// The second, optional, part of the declaration name.  For example enum
-  /// constants all have the same [name], but their own [name2].
-  void set name2(String value) {
-    this._name2 = value;
-  }
-
-  @override
   List<String> get parameterNames => _parameterNames ??= <String>[];
 
-  void set parameterNames(List<String> value) {
+  set parameterNames(List<String> value) {
     this._parameterNames = value;
   }
 
   @override
   String get parameters => _parameters ??= '';
 
-  void set parameters(String value) {
+  set parameters(String value) {
     this._parameters = value;
   }
 
   @override
   List<String> get parameterTypes => _parameterTypes ??= <String>[];
 
-  void set parameterTypes(List<String> value) {
+  set parameterTypes(List<String> value) {
     this._parameterTypes = value;
   }
 
@@ -2376,14 +2347,14 @@
   /// example, function do not currently), and not every declaration has to
   /// store one (for classes it can be computed when we know the library that
   /// includes this file).
-  void set relevanceTags(List<String> value) {
+  set relevanceTags(List<String> value) {
     this._relevanceTags = value;
   }
 
   @override
   int get requiredParameterCount => _requiredParameterCount ??= 0;
 
-  void set requiredParameterCount(int value) {
+  set requiredParameterCount(int value) {
     assert(value == null || value >= 0);
     this._requiredParameterCount = value;
   }
@@ -2391,19 +2362,20 @@
   @override
   String get returnType => _returnType ??= '';
 
-  void set returnType(String value) {
+  set returnType(String value) {
     this._returnType = value;
   }
 
   @override
   String get typeParameters => _typeParameters ??= '';
 
-  void set typeParameters(String value) {
+  set typeParameters(String value) {
     this._typeParameters = value;
   }
 
   AvailableDeclarationBuilder(
-      {String defaultArgumentListString,
+      {List<AvailableDeclarationBuilder> children,
+      String defaultArgumentListString,
       List<int> defaultArgumentListTextRanges,
       String docComplete,
       String docSummary,
@@ -2417,7 +2389,6 @@
       int locationStartColumn,
       int locationStartLine,
       String name,
-      String name2,
       List<String> parameterNames,
       String parameters,
       List<String> parameterTypes,
@@ -2425,7 +2396,8 @@
       int requiredParameterCount,
       String returnType,
       String typeParameters})
-      : _defaultArgumentListString = defaultArgumentListString,
+      : _children = children,
+        _defaultArgumentListString = defaultArgumentListString,
         _defaultArgumentListTextRanges = defaultArgumentListTextRanges,
         _docComplete = docComplete,
         _docSummary = docSummary,
@@ -2439,7 +2411,6 @@
         _locationStartColumn = locationStartColumn,
         _locationStartLine = locationStartLine,
         _name = name,
-        _name2 = name2,
         _parameterNames = parameterNames,
         _parameters = parameters,
         _parameterTypes = parameterTypes,
@@ -2448,15 +2419,21 @@
         _returnType = returnType,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
-  void flushInformative() {}
+  /// Flush [informative] data recursively.
+  void flushInformative() {
+    _children?.forEach((b) => b.flushInformative());
+  }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
+    if (this._children == null) {
+      signature.addInt(0);
+    } else {
+      signature.addInt(this._children.length);
+      for (var x in this._children) {
+        x?.collectApiSignature(signature);
+      }
+    }
     signature.addString(this._defaultArgumentListString ?? '');
     if (this._defaultArgumentListTextRanges == null) {
       signature.addInt(0);
@@ -2478,7 +2455,6 @@
     signature.addInt(this._locationStartColumn ?? 0);
     signature.addInt(this._locationStartLine ?? 0);
     signature.addString(this._name ?? '');
-    signature.addString(this._name2 ?? '');
     if (this._parameterNames == null) {
       signature.addInt(0);
     } else {
@@ -2510,18 +2486,22 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_children;
     fb.Offset offset_defaultArgumentListString;
     fb.Offset offset_defaultArgumentListTextRanges;
     fb.Offset offset_docComplete;
     fb.Offset offset_docSummary;
     fb.Offset offset_name;
-    fb.Offset offset_name2;
     fb.Offset offset_parameterNames;
     fb.Offset offset_parameters;
     fb.Offset offset_parameterTypes;
     fb.Offset offset_relevanceTags;
     fb.Offset offset_returnType;
     fb.Offset offset_typeParameters;
+    if (!(_children == null || _children.isEmpty)) {
+      offset_children = fbBuilder
+          .writeList(_children.map((b) => b.finish(fbBuilder)).toList());
+    }
     if (_defaultArgumentListString != null) {
       offset_defaultArgumentListString =
           fbBuilder.writeString(_defaultArgumentListString);
@@ -2540,9 +2520,6 @@
     if (_name != null) {
       offset_name = fbBuilder.writeString(_name);
     }
-    if (_name2 != null) {
-      offset_name2 = fbBuilder.writeString(_name2);
-    }
     if (!(_parameterNames == null || _parameterNames.isEmpty)) {
       offset_parameterNames = fbBuilder.writeList(
           _parameterNames.map((b) => fbBuilder.writeString(b)).toList());
@@ -2565,50 +2542,50 @@
       offset_typeParameters = fbBuilder.writeString(_typeParameters);
     }
     fbBuilder.startTable();
+    if (offset_children != null) {
+      fbBuilder.addOffset(0, offset_children);
+    }
     if (offset_defaultArgumentListString != null) {
-      fbBuilder.addOffset(0, offset_defaultArgumentListString);
+      fbBuilder.addOffset(1, offset_defaultArgumentListString);
     }
     if (offset_defaultArgumentListTextRanges != null) {
-      fbBuilder.addOffset(1, offset_defaultArgumentListTextRanges);
+      fbBuilder.addOffset(2, offset_defaultArgumentListTextRanges);
     }
     if (offset_docComplete != null) {
-      fbBuilder.addOffset(2, offset_docComplete);
+      fbBuilder.addOffset(3, offset_docComplete);
     }
     if (offset_docSummary != null) {
-      fbBuilder.addOffset(3, offset_docSummary);
+      fbBuilder.addOffset(4, offset_docSummary);
     }
     if (_fieldMask != null && _fieldMask != 0) {
-      fbBuilder.addUint32(4, _fieldMask);
+      fbBuilder.addUint32(5, _fieldMask);
     }
     if (_isAbstract == true) {
-      fbBuilder.addBool(5, true);
-    }
-    if (_isConst == true) {
       fbBuilder.addBool(6, true);
     }
-    if (_isDeprecated == true) {
+    if (_isConst == true) {
       fbBuilder.addBool(7, true);
     }
-    if (_isFinal == true) {
+    if (_isDeprecated == true) {
       fbBuilder.addBool(8, true);
     }
+    if (_isFinal == true) {
+      fbBuilder.addBool(9, true);
+    }
     if (_kind != null && _kind != idl.AvailableDeclarationKind.CLASS) {
-      fbBuilder.addUint8(9, _kind.index);
+      fbBuilder.addUint8(10, _kind.index);
     }
     if (_locationOffset != null && _locationOffset != 0) {
-      fbBuilder.addUint32(10, _locationOffset);
+      fbBuilder.addUint32(11, _locationOffset);
     }
     if (_locationStartColumn != null && _locationStartColumn != 0) {
-      fbBuilder.addUint32(11, _locationStartColumn);
+      fbBuilder.addUint32(12, _locationStartColumn);
     }
     if (_locationStartLine != null && _locationStartLine != 0) {
-      fbBuilder.addUint32(12, _locationStartLine);
+      fbBuilder.addUint32(13, _locationStartLine);
     }
     if (offset_name != null) {
-      fbBuilder.addOffset(13, offset_name);
-    }
-    if (offset_name2 != null) {
-      fbBuilder.addOffset(14, offset_name2);
+      fbBuilder.addOffset(14, offset_name);
     }
     if (offset_parameterNames != null) {
       fbBuilder.addOffset(15, offset_parameterNames);
@@ -2652,6 +2629,7 @@
 
   _AvailableDeclarationImpl(this._bc, this._bcOffset);
 
+  List<idl.AvailableDeclaration> _children;
   String _defaultArgumentListString;
   List<int> _defaultArgumentListTextRanges;
   String _docComplete;
@@ -2666,7 +2644,6 @@
   int _locationStartColumn;
   int _locationStartLine;
   String _name;
-  String _name2;
   List<String> _parameterNames;
   String _parameters;
   List<String> _parameterTypes;
@@ -2676,102 +2653,104 @@
   String _typeParameters;
 
   @override
+  List<idl.AvailableDeclaration> get children {
+    _children ??= const fb.ListReader<idl.AvailableDeclaration>(
+            const _AvailableDeclarationReader())
+        .vTableGet(_bc, _bcOffset, 0, const <idl.AvailableDeclaration>[]);
+    return _children;
+  }
+
+  @override
   String get defaultArgumentListString {
     _defaultArgumentListString ??=
-        const fb.StringReader().vTableGet(_bc, _bcOffset, 0, '');
+        const fb.StringReader().vTableGet(_bc, _bcOffset, 1, '');
     return _defaultArgumentListString;
   }
 
   @override
   List<int> get defaultArgumentListTextRanges {
     _defaultArgumentListTextRanges ??=
-        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 1, const <int>[]);
+        const fb.Uint32ListReader().vTableGet(_bc, _bcOffset, 2, const <int>[]);
     return _defaultArgumentListTextRanges;
   }
 
   @override
   String get docComplete {
-    _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 2, '');
+    _docComplete ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
     return _docComplete;
   }
 
   @override
   String get docSummary {
-    _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 3, '');
+    _docSummary ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 4, '');
     return _docSummary;
   }
 
   @override
   int get fieldMask {
-    _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 4, 0);
+    _fieldMask ??= const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 5, 0);
     return _fieldMask;
   }
 
   @override
   bool get isAbstract {
-    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 5, false);
+    _isAbstract ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
     return _isAbstract;
   }
 
   @override
   bool get isConst {
-    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 6, false);
+    _isConst ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
     return _isConst;
   }
 
   @override
   bool get isDeprecated {
-    _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 7, false);
+    _isDeprecated ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
     return _isDeprecated;
   }
 
   @override
   bool get isFinal {
-    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 8, false);
+    _isFinal ??= const fb.BoolReader().vTableGet(_bc, _bcOffset, 9, false);
     return _isFinal;
   }
 
   @override
   idl.AvailableDeclarationKind get kind {
     _kind ??= const _AvailableDeclarationKindReader()
-        .vTableGet(_bc, _bcOffset, 9, idl.AvailableDeclarationKind.CLASS);
+        .vTableGet(_bc, _bcOffset, 10, idl.AvailableDeclarationKind.CLASS);
     return _kind;
   }
 
   @override
   int get locationOffset {
     _locationOffset ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 10, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
     return _locationOffset;
   }
 
   @override
   int get locationStartColumn {
     _locationStartColumn ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 11, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
     return _locationStartColumn;
   }
 
   @override
   int get locationStartLine {
     _locationStartLine ??=
-        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 12, 0);
+        const fb.Uint32Reader().vTableGet(_bc, _bcOffset, 13, 0);
     return _locationStartLine;
   }
 
   @override
   String get name {
-    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 13, '');
+    _name ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, '');
     return _name;
   }
 
   @override
-  String get name2 {
-    _name2 ??= const fb.StringReader().vTableGet(_bc, _bcOffset, 14, '');
-    return _name2;
-  }
-
-  @override
   List<String> get parameterNames {
     _parameterNames ??= const fb.ListReader<String>(const fb.StringReader())
         .vTableGet(_bc, _bcOffset, 15, const <String>[]);
@@ -2823,6 +2802,8 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
+    if (children.isNotEmpty)
+      _result["children"] = children.map((_value) => _value.toJson()).toList();
     if (defaultArgumentListString != '')
       _result["defaultArgumentListString"] = defaultArgumentListString;
     if (defaultArgumentListTextRanges.isNotEmpty)
@@ -2842,7 +2823,6 @@
     if (locationStartLine != 0)
       _result["locationStartLine"] = locationStartLine;
     if (name != '') _result["name"] = name;
-    if (name2 != '') _result["name2"] = name2;
     if (parameterNames.isNotEmpty) _result["parameterNames"] = parameterNames;
     if (parameters != '') _result["parameters"] = parameters;
     if (parameterTypes.isNotEmpty) _result["parameterTypes"] = parameterTypes;
@@ -2856,6 +2836,7 @@
 
   @override
   Map<String, Object> toMap() => {
+        "children": children,
         "defaultArgumentListString": defaultArgumentListString,
         "defaultArgumentListTextRanges": defaultArgumentListTextRanges,
         "docComplete": docComplete,
@@ -2870,7 +2851,6 @@
         "locationStartColumn": locationStartColumn,
         "locationStartLine": locationStartLine,
         "name": name,
-        "name2": name2,
         "parameterNames": parameterNames,
         "parameters": parameters,
         "parameterTypes": parameterTypes,
@@ -2887,36 +2867,36 @@
 class AvailableFileBuilder extends Object
     with _AvailableFileMixin
     implements idl.AvailableFile {
-  DirectiveInfoBuilder _directiveInfo;
   List<AvailableDeclarationBuilder> _declarations;
+  DirectiveInfoBuilder _directiveInfo;
   List<AvailableFileExportBuilder> _exports;
   bool _isLibrary;
   bool _isLibraryDeprecated;
   List<String> _parts;
 
   @override
-  DirectiveInfoBuilder get directiveInfo => _directiveInfo;
-
-  /// The Dartdoc directives in the file.
-  void set directiveInfo(DirectiveInfoBuilder value) {
-    this._directiveInfo = value;
-  }
-
-  @override
   List<AvailableDeclarationBuilder> get declarations =>
       _declarations ??= <AvailableDeclarationBuilder>[];
 
   /// Declarations of the file.
-  void set declarations(List<AvailableDeclarationBuilder> value) {
+  set declarations(List<AvailableDeclarationBuilder> value) {
     this._declarations = value;
   }
 
   @override
+  DirectiveInfoBuilder get directiveInfo => _directiveInfo;
+
+  /// The Dartdoc directives in the file.
+  set directiveInfo(DirectiveInfoBuilder value) {
+    this._directiveInfo = value;
+  }
+
+  @override
   List<AvailableFileExportBuilder> get exports =>
       _exports ??= <AvailableFileExportBuilder>[];
 
   /// Exports directives of the file.
-  void set exports(List<AvailableFileExportBuilder> value) {
+  set exports(List<AvailableFileExportBuilder> value) {
     this._exports = value;
   }
 
@@ -2924,7 +2904,7 @@
   bool get isLibrary => _isLibrary ??= false;
 
   /// Is `true` if this file is a library.
-  void set isLibrary(bool value) {
+  set isLibrary(bool value) {
     this._isLibrary = value;
   }
 
@@ -2932,7 +2912,7 @@
   bool get isLibraryDeprecated => _isLibraryDeprecated ??= false;
 
   /// Is `true` if this file is a library, and it is deprecated.
-  void set isLibraryDeprecated(bool value) {
+  set isLibraryDeprecated(bool value) {
     this._isLibraryDeprecated = value;
   }
 
@@ -2940,36 +2920,32 @@
   List<String> get parts => _parts ??= <String>[];
 
   /// URIs of `part` directives.
-  void set parts(List<String> value) {
+  set parts(List<String> value) {
     this._parts = value;
   }
 
   AvailableFileBuilder(
-      {DirectiveInfoBuilder directiveInfo,
-      List<AvailableDeclarationBuilder> declarations,
+      {List<AvailableDeclarationBuilder> declarations,
+      DirectiveInfoBuilder directiveInfo,
       List<AvailableFileExportBuilder> exports,
       bool isLibrary,
       bool isLibraryDeprecated,
       List<String> parts})
-      : _directiveInfo = directiveInfo,
-        _declarations = declarations,
+      : _declarations = declarations,
+        _directiveInfo = directiveInfo,
         _exports = exports,
         _isLibrary = isLibrary,
         _isLibraryDeprecated = isLibraryDeprecated,
         _parts = parts;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
-    _directiveInfo?.flushInformative();
     _declarations?.forEach((b) => b.flushInformative());
+    _directiveInfo?.flushInformative();
     _exports?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._declarations == null) {
       signature.addInt(0);
@@ -3007,17 +2983,17 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
-    fb.Offset offset_directiveInfo;
     fb.Offset offset_declarations;
+    fb.Offset offset_directiveInfo;
     fb.Offset offset_exports;
     fb.Offset offset_parts;
-    if (_directiveInfo != null) {
-      offset_directiveInfo = _directiveInfo.finish(fbBuilder);
-    }
     if (!(_declarations == null || _declarations.isEmpty)) {
       offset_declarations = fbBuilder
           .writeList(_declarations.map((b) => b.finish(fbBuilder)).toList());
     }
+    if (_directiveInfo != null) {
+      offset_directiveInfo = _directiveInfo.finish(fbBuilder);
+    }
     if (!(_exports == null || _exports.isEmpty)) {
       offset_exports = fbBuilder
           .writeList(_exports.map((b) => b.finish(fbBuilder)).toList());
@@ -3027,12 +3003,12 @@
           .writeList(_parts.map((b) => fbBuilder.writeString(b)).toList());
     }
     fbBuilder.startTable();
-    if (offset_directiveInfo != null) {
-      fbBuilder.addOffset(5, offset_directiveInfo);
-    }
     if (offset_declarations != null) {
       fbBuilder.addOffset(0, offset_declarations);
     }
+    if (offset_directiveInfo != null) {
+      fbBuilder.addOffset(5, offset_directiveInfo);
+    }
     if (offset_exports != null) {
       fbBuilder.addOffset(1, offset_exports);
     }
@@ -3070,21 +3046,14 @@
 
   _AvailableFileImpl(this._bc, this._bcOffset);
 
-  idl.DirectiveInfo _directiveInfo;
   List<idl.AvailableDeclaration> _declarations;
+  idl.DirectiveInfo _directiveInfo;
   List<idl.AvailableFileExport> _exports;
   bool _isLibrary;
   bool _isLibraryDeprecated;
   List<String> _parts;
 
   @override
-  idl.DirectiveInfo get directiveInfo {
-    _directiveInfo ??=
-        const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null);
-    return _directiveInfo;
-  }
-
-  @override
   List<idl.AvailableDeclaration> get declarations {
     _declarations ??= const fb.ListReader<idl.AvailableDeclaration>(
             const _AvailableDeclarationReader())
@@ -3093,6 +3062,13 @@
   }
 
   @override
+  idl.DirectiveInfo get directiveInfo {
+    _directiveInfo ??=
+        const _DirectiveInfoReader().vTableGet(_bc, _bcOffset, 5, null);
+    return _directiveInfo;
+  }
+
+  @override
   List<idl.AvailableFileExport> get exports {
     _exports ??= const fb.ListReader<idl.AvailableFileExport>(
             const _AvailableFileExportReader())
@@ -3125,11 +3101,11 @@
   @override
   Map<String, Object> toJson() {
     Map<String, Object> _result = <String, Object>{};
-    if (directiveInfo != null)
-      _result["directiveInfo"] = directiveInfo.toJson();
     if (declarations.isNotEmpty)
       _result["declarations"] =
           declarations.map((_value) => _value.toJson()).toList();
+    if (directiveInfo != null)
+      _result["directiveInfo"] = directiveInfo.toJson();
     if (exports.isNotEmpty)
       _result["exports"] = exports.map((_value) => _value.toJson()).toList();
     if (isLibrary != false) _result["isLibrary"] = isLibrary;
@@ -3141,8 +3117,8 @@
 
   @override
   Map<String, Object> toMap() => {
-        "directiveInfo": directiveInfo,
         "declarations": declarations,
+        "directiveInfo": directiveInfo,
         "exports": exports,
         "isLibrary": isLibrary,
         "isLibraryDeprecated": isLibraryDeprecated,
@@ -3164,7 +3140,7 @@
       _combinators ??= <AvailableFileExportCombinatorBuilder>[];
 
   /// Combinators contained in this export directive.
-  void set combinators(List<AvailableFileExportCombinatorBuilder> value) {
+  set combinators(List<AvailableFileExportCombinatorBuilder> value) {
     this._combinators = value;
   }
 
@@ -3172,7 +3148,7 @@
   String get uri => _uri ??= '';
 
   /// URI of the exported library.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -3181,16 +3157,12 @@
       : _combinators = combinators,
         _uri = uri;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _combinators?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._combinators == null) {
@@ -3291,7 +3263,7 @@
   List<String> get hides => _hides ??= <String>[];
 
   /// List of names which are hidden.  Empty if this is a `show` combinator.
-  void set hides(List<String> value) {
+  set hides(List<String> value) {
     this._hides = value;
   }
 
@@ -3299,7 +3271,7 @@
   List<String> get shows => _shows ??= <String>[];
 
   /// List of names which are shown.  Empty if this is a `hide` combinator.
-  void set shows(List<String> value) {
+  set shows(List<String> value) {
     this._shows = value;
   }
 
@@ -3307,14 +3279,10 @@
       : _hides = hides,
         _shows = shows;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._shows == null) {
       signature.addInt(0);
@@ -3422,7 +3390,7 @@
   int get length => _length ??= 0;
 
   /// Length of the element code.
-  void set length(int value) {
+  set length(int value) {
     assert(value == null || value >= 0);
     this._length = value;
   }
@@ -3431,7 +3399,7 @@
   int get offset => _offset ??= 0;
 
   /// Offset of the element code relative to the beginning of the file.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -3440,14 +3408,10 @@
       : _length = length,
         _offset = offset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._offset ?? 0);
     signature.addInt(this._length ?? 0);
@@ -3526,7 +3490,7 @@
   List<String> get templateNames => _templateNames ??= <String>[];
 
   /// The names of the defined templates.
-  void set templateNames(List<String> value) {
+  set templateNames(List<String> value) {
     this._templateNames = value;
   }
 
@@ -3534,7 +3498,7 @@
   List<String> get templateValues => _templateValues ??= <String>[];
 
   /// The values of the defined templates.
-  void set templateValues(List<String> value) {
+  set templateValues(List<String> value) {
     this._templateValues = value;
   }
 
@@ -3543,14 +3507,10 @@
       : _templateNames = templateNames,
         _templateValues = templateValues;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._templateNames == null) {
       signature.addInt(0);
@@ -3663,7 +3623,7 @@
   idl.EntityRefKind get entityKind => _entityKind ??= idl.EntityRefKind.named;
 
   /// The kind of entity being represented.
-  void set entityKind(idl.EntityRefKind value) {
+  set entityKind(idl.EntityRefKind value) {
     this._entityKind = value;
   }
 
@@ -3697,7 +3657,7 @@
   /// Note that if the entity being referred to is a generic method inside a
   /// generic class, then the type arguments in [typeArguments] are applied
   /// first to the class and then to the method.
-  void set implicitFunctionTypeIndices(List<int> value) {
+  set implicitFunctionTypeIndices(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._implicitFunctionTypeIndices = value;
   }
@@ -3722,7 +3682,7 @@
   ///
   /// If the type being referred to is not a type parameter, [paramReference] is
   /// zero.
-  void set paramReference(int value) {
+  set paramReference(int value) {
     assert(value == null || value >= 0);
     this._paramReference = value;
   }
@@ -3732,7 +3692,7 @@
 
   /// Index into [UnlinkedUnit.references] for the entity being referred to, or
   /// zero if this is a reference to a type parameter.
-  void set reference(int value) {
+  set reference(int value) {
     assert(value == null || value >= 0);
     this._reference = value;
   }
@@ -3750,7 +3710,7 @@
   /// This is called `refinedSlot` to clarify that if it points to an inferred
   /// type, it points to a type that is a "refinement" of this one (one in which
   /// some type arguments have been inferred).
-  void set refinedSlot(int value) {
+  set refinedSlot(int value) {
     assert(value == null || value >= 0);
     this._refinedSlot = value;
   }
@@ -3763,7 +3723,7 @@
   /// propagation or type inference with which this [EntityRef] is associated.
   ///
   /// Otherwise zero.
-  void set slot(int value) {
+  set slot(int value) {
     assert(value == null || value >= 0);
     this._slot = value;
   }
@@ -3776,7 +3736,7 @@
   /// [FunctionElement] is not in any library (e.g. a function type that was
   /// synthesized by a LUB computation), the function parameters.  Otherwise
   /// empty.
-  void set syntheticParams(List<UnlinkedParamBuilder> value) {
+  set syntheticParams(List<UnlinkedParamBuilder> value) {
     this._syntheticParams = value;
   }
 
@@ -3787,7 +3747,7 @@
   /// [FunctionElement] is not in any library (e.g. a function type that was
   /// synthesized by a LUB computation), the return type of the function.
   /// Otherwise `null`.
-  void set syntheticReturnType(EntityRefBuilder value) {
+  set syntheticReturnType(EntityRefBuilder value) {
     this._syntheticReturnType = value;
   }
 
@@ -3797,7 +3757,7 @@
 
   /// If this is an instantiation of a generic type or generic executable, the
   /// type arguments used to instantiate it (if any).
-  void set typeArguments(List<EntityRefBuilder> value) {
+  set typeArguments(List<EntityRefBuilder> value) {
     this._typeArguments = value;
   }
 
@@ -3807,7 +3767,7 @@
 
   /// If this is a function type, the type parameters defined for the function
   /// type (if any).
-  void set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
     this._typeParameters = value;
   }
 
@@ -3833,9 +3793,7 @@
         _typeArguments = typeArguments,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _syntheticParams?.forEach((b) => b.flushInformative());
     _syntheticReturnType?.flushInformative();
@@ -3843,9 +3801,7 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._reference ?? 0);
     if (this._typeArguments == null) {
@@ -4101,7 +4057,7 @@
 
   /// Absolute URI for the compilation units listed in the library's `part`
   /// declarations, empty string for invalid URI.
-  void set parts(List<String> value) {
+  set parts(List<String> value) {
     this._parts = value;
   }
 
@@ -4109,7 +4065,7 @@
   String get uri => _uri ??= '';
 
   /// The absolute URI of the dependent library, e.g. `package:foo/bar.dart`.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -4117,14 +4073,10 @@
       : _parts = parts,
         _uri = uri;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._parts == null) {
@@ -4223,7 +4175,7 @@
 
   /// Index into [LinkedLibrary.dependencies] for the library in which the
   /// entity is defined.
-  void set dependency(int value) {
+  set dependency(int value) {
     assert(value == null || value >= 0);
     this._dependency = value;
   }
@@ -4232,7 +4184,7 @@
   idl.ReferenceKind get kind => _kind ??= idl.ReferenceKind.classOrEnum;
 
   /// The kind of the entity being referred to.
-  void set kind(idl.ReferenceKind value) {
+  set kind(idl.ReferenceKind value) {
     this._kind = value;
   }
 
@@ -4241,7 +4193,7 @@
 
   /// Name of the exported entity.  For an exported setter, this name includes
   /// the trailing '='.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -4252,7 +4204,7 @@
   /// definition of the entity.  As with indices into [LinkedLibrary.units],
   /// zero represents the defining compilation unit, and nonzero values
   /// represent parts in the order of the corresponding `part` declarations.
-  void set unit(int value) {
+  set unit(int value) {
     assert(value == null || value >= 0);
     this._unit = value;
   }
@@ -4264,14 +4216,10 @@
         _name = name,
         _unit = unit;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._dependency ?? 0);
     signature.addString(this._name ?? '');
@@ -4400,7 +4348,7 @@
   /// implicitly refers to an element declared in the library) or
   /// anti-dependency (e.g. the result of type propagation or type inference
   /// depends on the lack of a certain declaration in the library).
-  void set dependencies(List<LinkedDependencyBuilder> value) {
+  set dependencies(List<LinkedDependencyBuilder> value) {
     this._dependencies = value;
   }
 
@@ -4409,7 +4357,7 @@
 
   /// For each export in [UnlinkedUnit.exports], an index into [dependencies]
   /// of the library being exported.
-  void set exportDependencies(List<int> value) {
+  set exportDependencies(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._exportDependencies = value;
   }
@@ -4423,7 +4371,7 @@
   /// brought into the namespace via `export` directives).
   ///
   /// Sorted by name.
-  void set exportNames(List<LinkedExportNameBuilder> value) {
+  set exportNames(List<LinkedExportNameBuilder> value) {
     this._exportNames = value;
   }
 
@@ -4436,7 +4384,7 @@
 
   /// For each import in [UnlinkedUnit.imports], an index into [dependencies]
   /// of the library being imported.
-  void set importDependencies(List<int> value) {
+  set importDependencies(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._importDependencies = value;
   }
@@ -4447,7 +4395,7 @@
   /// The number of elements in [dependencies] which are not "linked"
   /// dependencies (that is, the number of libraries in the direct imports plus
   /// the transitive closure of exports, plus the library itself).
-  void set numPrelinkedDependencies(int value) {
+  set numPrelinkedDependencies(int value) {
     assert(value == null || value >= 0);
     this._numPrelinkedDependencies = value;
   }
@@ -4459,7 +4407,7 @@
   /// library.  The summary of the defining compilation unit is listed first,
   /// followed by the summary of each part, in the order of the `part`
   /// declarations in the defining compilation unit.
-  void set units(List<LinkedUnitBuilder> value) {
+  set units(List<LinkedUnitBuilder> value) {
     this._units = value;
   }
 
@@ -4477,18 +4425,14 @@
         _numPrelinkedDependencies = numPrelinkedDependencies,
         _units = units;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _dependencies?.forEach((b) => b.flushInformative());
     _exportNames?.forEach((b) => b.flushInformative());
     _units?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._dependencies == null) {
       signature.addInt(0);
@@ -4702,6 +4646,7 @@
 class LinkedNodeBuilder extends Object
     with _LinkedNodeMixin
     implements idl.LinkedNode {
+  LinkedNodeTypeBuilder _variantField_24;
   List<LinkedNodeBuilder> _variantField_2;
   LinkedNodeBuilder _variantField_11;
   List<LinkedNodeBuilder> _variantField_4;
@@ -4713,7 +4658,6 @@
   int _variantField_17;
   int _variantField_18;
   int _variantField_19;
-  LinkedNodeTypeBuilder _variantField_24;
   bool _variantField_27;
   LinkedNodeBuilder _variantField_9;
   LinkedNodeBuilder _variantField_12;
@@ -4739,6 +4683,78 @@
   LinkedNodeVariablesDeclarationBuilder _variantField_32;
 
   @override
+  LinkedNodeTypeBuilder get actualReturnType {
+    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionExpression ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericFunctionType ||
+        kind == idl.LinkedNodeKind.methodDeclaration);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get actualType {
+    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get binaryExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get invocationExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
+        kind == idl.LinkedNodeKind.methodInvocation);
+    return _variantField_24;
+  }
+
+  @override
+  LinkedNodeTypeBuilder get typeName_type {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    return _variantField_24;
+  }
+
+  /// The explicit or inferred return type of a function typed node.
+  set actualReturnType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionExpression ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericFunctionType ||
+        kind == idl.LinkedNodeKind.methodDeclaration);
+    _variantField_24 = value;
+  }
+
+  set actualType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    _variantField_24 = value;
+  }
+
+  set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    _variantField_24 = value;
+  }
+
+  set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
+        kind == idl.LinkedNodeKind.methodInvocation);
+    _variantField_24 = value;
+  }
+
+  set typeName_type(LinkedNodeTypeBuilder value) {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    _variantField_24 = value;
+  }
+
+  @override
   List<LinkedNodeBuilder> get adjacentStrings_strings {
     assert(kind == idl.LinkedNodeKind.adjacentStrings);
     return _variantField_2 ??= <LinkedNodeBuilder>[];
@@ -4889,128 +4905,128 @@
     return _variantField_2 ??= <LinkedNodeBuilder>[];
   }
 
-  void set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
+  set adjacentStrings_strings(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.adjacentStrings);
     _variantField_2 = value;
   }
 
-  void set argumentList_arguments(List<LinkedNodeBuilder> value) {
+  set argumentList_arguments(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     _variantField_2 = value;
   }
 
-  void set block_statements(List<LinkedNodeBuilder> value) {
+  set block_statements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.block);
     _variantField_2 = value;
   }
 
-  void set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
+  set cascadeExpression_sections(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.cascadeExpression);
     _variantField_2 = value;
   }
 
-  void set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
+  set compilationUnit_declarations(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     _variantField_2 = value;
   }
 
-  void set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
+  set constructorDeclaration_initializers(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_2 = value;
   }
 
-  void set dottedName_components(List<LinkedNodeBuilder> value) {
+  set dottedName_components(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.dottedName);
     _variantField_2 = value;
   }
 
-  void set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
+  set enumDeclaration_constants(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     _variantField_2 = value;
   }
 
-  void set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
+  set formalParameterList_parameters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     _variantField_2 = value;
   }
 
-  void set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) {
+  set hideCombinator_hiddenNames(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.hideCombinator);
     _variantField_2 = value;
   }
 
-  void set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
+  set implementsClause_interfaces(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.implementsClause);
     _variantField_2 = value;
   }
 
-  void set labeledStatement_labels(List<LinkedNodeBuilder> value) {
+  set labeledStatement_labels(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.labeledStatement);
     _variantField_2 = value;
   }
 
-  void set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
+  set libraryIdentifier_components(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.libraryIdentifier);
     _variantField_2 = value;
   }
 
-  void set listLiteral_elements(List<LinkedNodeBuilder> value) {
+  set listLiteral_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     _variantField_2 = value;
   }
 
-  void set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
+  set namespaceDirective_combinators(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
     _variantField_2 = value;
   }
 
-  void set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
+  set onClause_superclassConstraints(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.onClause);
     _variantField_2 = value;
   }
 
-  void set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
+  set setOrMapLiteral_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     _variantField_2 = value;
   }
 
-  void set showCombinator_shownNames(List<LinkedNodeBuilder> value) {
+  set showCombinator_shownNames(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.showCombinator);
     _variantField_2 = value;
   }
 
-  void set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
+  set stringInterpolation_elements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.stringInterpolation);
     _variantField_2 = value;
   }
 
-  void set switchStatement_members(List<LinkedNodeBuilder> value) {
+  set switchStatement_members(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     _variantField_2 = value;
   }
 
-  void set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
+  set tryStatement_catchClauses(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_2 = value;
   }
 
-  void set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
+  set typeArgumentList_arguments(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     _variantField_2 = value;
   }
 
-  void set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
+  set typeParameterList_typeParameters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     _variantField_2 = value;
   }
 
-  void set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
+  set variableDeclarationList_variables(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     _variantField_2 = value;
   }
 
-  void set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
+  set withClause_mixinTypes(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.withClause);
     _variantField_2 = value;
   }
@@ -5041,7 +5057,7 @@
     return _variantField_11;
   }
 
-  void set annotatedNode_comment(LinkedNodeBuilder value) {
+  set annotatedNode_comment(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -5107,7 +5123,7 @@
     return _variantField_4 ??= <LinkedNodeBuilder>[];
   }
 
-  void set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
+  set annotatedNode_metadata(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -5132,14 +5148,14 @@
     _variantField_4 = value;
   }
 
-  void set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
+  set normalFormalParameter_metadata(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_4 = value;
   }
 
-  void set switchMember_statements(List<LinkedNodeBuilder> value) {
+  set switchMember_statements(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     _variantField_4 = value;
@@ -5617,398 +5633,397 @@
     return _variantField_6;
   }
 
-  void set annotation_arguments(LinkedNodeBuilder value) {
+  set annotation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_6 = value;
   }
 
-  void set asExpression_expression(LinkedNodeBuilder value) {
+  set asExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     _variantField_6 = value;
   }
 
-  void set assertInitializer_condition(LinkedNodeBuilder value) {
+  set assertInitializer_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     _variantField_6 = value;
   }
 
-  void set assertStatement_condition(LinkedNodeBuilder value) {
+  set assertStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     _variantField_6 = value;
   }
 
-  void set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
+  set assignmentExpression_leftHandSide(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     _variantField_6 = value;
   }
 
-  void set awaitExpression_expression(LinkedNodeBuilder value) {
+  set awaitExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.awaitExpression);
     _variantField_6 = value;
   }
 
-  void set binaryExpression_leftOperand(LinkedNodeBuilder value) {
+  set binaryExpression_leftOperand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     _variantField_6 = value;
   }
 
-  void set blockFunctionBody_block(LinkedNodeBuilder value) {
+  set blockFunctionBody_block(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     _variantField_6 = value;
   }
 
-  void set breakStatement_label(LinkedNodeBuilder value) {
+  set breakStatement_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     _variantField_6 = value;
   }
 
-  void set cascadeExpression_target(LinkedNodeBuilder value) {
+  set cascadeExpression_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.cascadeExpression);
     _variantField_6 = value;
   }
 
-  void set catchClause_body(LinkedNodeBuilder value) {
+  set catchClause_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_6 = value;
   }
 
-  void set classDeclaration_extendsClause(LinkedNodeBuilder value) {
+  set classDeclaration_extendsClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_6 = value;
   }
 
-  void set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set classTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_6 = value;
   }
 
-  void set compilationUnit_scriptTag(LinkedNodeBuilder value) {
+  set compilationUnit_scriptTag(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     _variantField_6 = value;
   }
 
-  void set conditionalExpression_condition(LinkedNodeBuilder value) {
+  set conditionalExpression_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_6 = value;
   }
 
-  void set configuration_name(LinkedNodeBuilder value) {
+  set configuration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_6 = value;
   }
 
-  void set constructorDeclaration_body(LinkedNodeBuilder value) {
+  set constructorDeclaration_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_6 = value;
   }
 
-  void set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
+  set constructorFieldInitializer_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_6 = value;
   }
 
-  void set constructorName_name(LinkedNodeBuilder value) {
+  set constructorName_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     _variantField_6 = value;
   }
 
-  void set continueStatement_label(LinkedNodeBuilder value) {
+  set continueStatement_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     _variantField_6 = value;
   }
 
-  void set declaredIdentifier_identifier(LinkedNodeBuilder value) {
+  set declaredIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     _variantField_6 = value;
   }
 
-  void set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
+  set defaultFormalParameter_defaultValue(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_6 = value;
   }
 
-  void set doStatement_body(LinkedNodeBuilder value) {
+  set doStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     _variantField_6 = value;
   }
 
-  void set enumConstantDeclaration_name(LinkedNodeBuilder value) {
+  set enumConstantDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.enumConstantDeclaration);
     _variantField_6 = value;
   }
 
-  void set expressionFunctionBody_expression(LinkedNodeBuilder value) {
+  set expressionFunctionBody_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     _variantField_6 = value;
   }
 
-  void set expressionStatement_expression(LinkedNodeBuilder value) {
+  set expressionStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.expressionStatement);
     _variantField_6 = value;
   }
 
-  void set extendsClause_superclass(LinkedNodeBuilder value) {
+  set extendsClause_superclass(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.extendsClause);
     _variantField_6 = value;
   }
 
-  void set fieldDeclaration_fields(LinkedNodeBuilder value) {
+  set fieldDeclaration_fields(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     _variantField_6 = value;
   }
 
-  void set fieldFormalParameter_type(LinkedNodeBuilder value) {
+  set fieldFormalParameter_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_6 = value;
   }
 
-  void set forEachParts_iterable(LinkedNodeBuilder value) {
+  set forEachParts_iterable(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
         kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     _variantField_6 = value;
   }
 
-  void set forMixin_forLoopParts(LinkedNodeBuilder value) {
+  set forMixin_forLoopParts(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     _variantField_6 = value;
   }
 
-  void set forParts_condition(LinkedNodeBuilder value) {
+  set forParts_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     _variantField_6 = value;
   }
 
-  void set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
+  set functionDeclaration_functionExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     _variantField_6 = value;
   }
 
-  void set functionDeclarationStatement_functionDeclaration(
+  set functionDeclarationStatement_functionDeclaration(
       LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclarationStatement);
     _variantField_6 = value;
   }
 
-  void set functionExpression_body(LinkedNodeBuilder value) {
+  set functionExpression_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_6 = value;
   }
 
-  void set functionExpressionInvocation_function(LinkedNodeBuilder value) {
+  set functionExpressionInvocation_function(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation);
     _variantField_6 = value;
   }
 
-  void set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
+  set functionTypeAlias_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_6 = value;
   }
 
-  void set functionTypedFormalParameter_formalParameters(
-      LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_6 = value;
   }
 
-  void set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
+  set genericFunctionType_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_6 = value;
   }
 
-  void set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set genericTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     _variantField_6 = value;
   }
 
-  void set ifMixin_condition(LinkedNodeBuilder value) {
+  set ifMixin_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     _variantField_6 = value;
   }
 
-  void set importDirective_prefix(LinkedNodeBuilder value) {
+  set importDirective_prefix(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     _variantField_6 = value;
   }
 
-  void set indexExpression_index(LinkedNodeBuilder value) {
+  set indexExpression_index(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_6 = value;
   }
 
-  void set instanceCreationExpression_arguments(LinkedNodeBuilder value) {
+  set instanceCreationExpression_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_6 = value;
   }
 
-  void set interpolationExpression_expression(LinkedNodeBuilder value) {
+  set interpolationExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     _variantField_6 = value;
   }
 
-  void set isExpression_expression(LinkedNodeBuilder value) {
+  set isExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     _variantField_6 = value;
   }
 
-  void set label_label(LinkedNodeBuilder value) {
+  set label_label(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.label);
     _variantField_6 = value;
   }
 
-  void set labeledStatement_statement(LinkedNodeBuilder value) {
+  set labeledStatement_statement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.labeledStatement);
     _variantField_6 = value;
   }
 
-  void set libraryDirective_name(LinkedNodeBuilder value) {
+  set libraryDirective_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.libraryDirective);
     _variantField_6 = value;
   }
 
-  void set mapLiteralEntry_key(LinkedNodeBuilder value) {
+  set mapLiteralEntry_key(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     _variantField_6 = value;
   }
 
-  void set methodDeclaration_body(LinkedNodeBuilder value) {
+  set methodDeclaration_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_6 = value;
   }
 
-  void set methodInvocation_methodName(LinkedNodeBuilder value) {
+  set methodInvocation_methodName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_6 = value;
   }
 
-  void set mixinDeclaration_onClause(LinkedNodeBuilder value) {
+  set mixinDeclaration_onClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mixinDeclaration);
     _variantField_6 = value;
   }
 
-  void set namedExpression_expression(LinkedNodeBuilder value) {
+  set namedExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.namedExpression);
     _variantField_6 = value;
   }
 
-  void set nativeClause_name(LinkedNodeBuilder value) {
+  set nativeClause_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.nativeClause);
     _variantField_6 = value;
   }
 
-  void set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
+  set nativeFunctionBody_stringLiteral(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     _variantField_6 = value;
   }
 
-  void set parenthesizedExpression_expression(LinkedNodeBuilder value) {
+  set parenthesizedExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     _variantField_6 = value;
   }
 
-  void set partOfDirective_libraryName(LinkedNodeBuilder value) {
+  set partOfDirective_libraryName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     _variantField_6 = value;
   }
 
-  void set postfixExpression_operand(LinkedNodeBuilder value) {
+  set postfixExpression_operand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     _variantField_6 = value;
   }
 
-  void set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
+  set prefixedIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     _variantField_6 = value;
   }
 
-  void set prefixExpression_operand(LinkedNodeBuilder value) {
+  set prefixExpression_operand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     _variantField_6 = value;
   }
 
-  void set propertyAccess_propertyName(LinkedNodeBuilder value) {
+  set propertyAccess_propertyName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     _variantField_6 = value;
   }
 
-  void set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
+  set redirectingConstructorInvocation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     _variantField_6 = value;
   }
 
-  void set returnStatement_expression(LinkedNodeBuilder value) {
+  set returnStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     _variantField_6 = value;
   }
 
-  void set simpleFormalParameter_type(LinkedNodeBuilder value) {
+  set simpleFormalParameter_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_6 = value;
   }
 
-  void set spreadElement_expression(LinkedNodeBuilder value) {
+  set spreadElement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.spreadElement);
     _variantField_6 = value;
   }
 
-  void set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
+  set superConstructorInvocation_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     _variantField_6 = value;
   }
 
-  void set switchCase_expression(LinkedNodeBuilder value) {
+  set switchCase_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.switchCase);
     _variantField_6 = value;
   }
 
-  void set throwExpression_expression(LinkedNodeBuilder value) {
+  set throwExpression_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.throwExpression);
     _variantField_6 = value;
   }
 
-  void set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
+  set topLevelVariableDeclaration_variableList(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
     _variantField_6 = value;
   }
 
-  void set tryStatement_body(LinkedNodeBuilder value) {
+  set tryStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_6 = value;
   }
 
-  void set typeName_name(LinkedNodeBuilder value) {
+  set typeName_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     _variantField_6 = value;
   }
 
-  void set typeParameter_bound(LinkedNodeBuilder value) {
+  set typeParameter_bound(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     _variantField_6 = value;
   }
 
-  void set variableDeclaration_initializer(LinkedNodeBuilder value) {
+  set variableDeclaration_initializer(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_6 = value;
   }
 
-  void set variableDeclarationList_type(LinkedNodeBuilder value) {
+  set variableDeclarationList_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     _variantField_6 = value;
   }
 
-  void set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
+  set variableDeclarationStatement_variables(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
     _variantField_6 = value;
   }
 
-  void set whileStatement_body(LinkedNodeBuilder value) {
+  set whileStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_6 = value;
   }
 
-  void set yieldStatement_expression(LinkedNodeBuilder value) {
+  set yieldStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     _variantField_6 = value;
   }
@@ -6570,558 +6585,558 @@
     return _variantField_15 ??= 0;
   }
 
-  void set annotation_atSign(int value) {
+  set annotation_atSign(int value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set argumentList_leftParenthesis(int value) {
+  set argumentList_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set asExpression_asOperator(int value) {
+  set asExpression_asOperator(int value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assertInitializer_assertKeyword(int value) {
+  set assertInitializer_assertKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assertStatement_assertKeyword(int value) {
+  set assertStatement_assertKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set assignmentExpression_element(int value) {
+  set assignmentExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set awaitExpression_awaitKeyword(int value) {
+  set awaitExpression_awaitKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.awaitExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set binaryExpression_element(int value) {
+  set binaryExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set block_leftBracket(int value) {
+  set block_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.block);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set blockFunctionBody_keyword(int value) {
+  set blockFunctionBody_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set booleanLiteral_literal(int value) {
+  set booleanLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.booleanLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set breakStatement_breakKeyword(int value) {
+  set breakStatement_breakKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set catchClause_catchKeyword(int value) {
+  set catchClause_catchKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set classDeclaration_abstractKeyword(int value) {
+  set classDeclaration_abstractKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set classTypeAlias_abstractKeyword(int value) {
+  set classTypeAlias_abstractKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set compilationUnit_beginToken(int value) {
+  set compilationUnit_beginToken(int value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set conditionalExpression_colon(int value) {
+  set conditionalExpression_colon(int value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set configuration_ifKeyword(int value) {
+  set configuration_ifKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorDeclaration_constKeyword(int value) {
+  set constructorDeclaration_constKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorFieldInitializer_equals(int value) {
+  set constructorFieldInitializer_equals(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set constructorName_element(int value) {
+  set constructorName_element(int value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set continueStatement_continueKeyword(int value) {
+  set continueStatement_continueKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set declaredIdentifier_keyword(int value) {
+  set declaredIdentifier_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set defaultFormalParameter_separator(int value) {
+  set defaultFormalParameter_separator(int value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set doStatement_leftParenthesis(int value) {
+  set doStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set doubleLiteral_literal(int value) {
+  set doubleLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.doubleLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set emptyFunctionBody_semicolon(int value) {
+  set emptyFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.emptyFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set emptyStatement_semicolon(int value) {
+  set emptyStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.emptyStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set enumDeclaration_enumKeyword(int value) {
+  set enumDeclaration_enumKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set expressionFunctionBody_arrow(int value) {
+  set expressionFunctionBody_arrow(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set expressionStatement_semicolon(int value) {
+  set expressionStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.expressionStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set extendsClause_extendsKeyword(int value) {
+  set extendsClause_extendsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.extendsClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set fieldDeclaration_covariantKeyword(int value) {
+  set fieldDeclaration_covariantKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set fieldFormalParameter_keyword(int value) {
+  set fieldFormalParameter_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forEachParts_inKeyword(int value) {
+  set forEachParts_inKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration ||
         kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set formalParameterList_leftDelimiter(int value) {
+  set formalParameterList_leftDelimiter(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forMixin_awaitKeyword(int value) {
+  set forMixin_awaitKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set forParts_leftSeparator(int value) {
+  set forParts_leftSeparator(int value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set functionDeclaration_externalKeyword(int value) {
+  set functionDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set genericFunctionType_functionKeyword(int value) {
+  set genericFunctionType_functionKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set ifMixin_elseKeyword(int value) {
+  set ifMixin_elseKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set implementsClause_implementsKeyword(int value) {
+  set implementsClause_implementsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.implementsClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set importDirective_asKeyword(int value) {
+  set importDirective_asKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set indexExpression_element(int value) {
+  set indexExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set instanceCreationExpression_keyword(int value) {
+  set instanceCreationExpression_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set integerLiteral_literal(int value) {
+  set integerLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.integerLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set interpolationExpression_leftBracket(int value) {
+  set interpolationExpression_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set interpolationString_token(int value) {
+  set interpolationString_token(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationString);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set isExpression_isOperator(int value) {
+  set isExpression_isOperator(int value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set label_colon(int value) {
+  set label_colon(int value) {
     assert(kind == idl.LinkedNodeKind.label);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set listLiteral_leftBracket(int value) {
+  set listLiteral_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set mapLiteralEntry_separator(int value) {
+  set mapLiteralEntry_separator(int value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set methodDeclaration_externalKeyword(int value) {
+  set methodDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set methodInvocation_operator(int value) {
+  set methodInvocation_operator(int value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set mixinDeclaration_mixinKeyword(int value) {
+  set mixinDeclaration_mixinKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nativeClause_nativeKeyword(int value) {
+  set nativeClause_nativeKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.nativeClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nativeFunctionBody_nativeKeyword(int value) {
+  set nativeFunctionBody_nativeKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set nullLiteral_literal(int value) {
+  set nullLiteral_literal(int value) {
     assert(kind == idl.LinkedNodeKind.nullLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set onClause_onKeyword(int value) {
+  set onClause_onKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.onClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set parenthesizedExpression_leftParenthesis(int value) {
+  set parenthesizedExpression_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set postfixExpression_element(int value) {
+  set postfixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set prefixedIdentifier_period(int value) {
+  set prefixedIdentifier_period(int value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set prefixExpression_element(int value) {
+  set prefixExpression_element(int value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set propertyAccess_operator(int value) {
+  set propertyAccess_operator(int value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set redirectingConstructorInvocation_element(int value) {
+  set redirectingConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set rethrowExpression_rethrowKeyword(int value) {
+  set rethrowExpression_rethrowKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.rethrowExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set returnStatement_returnKeyword(int value) {
+  set returnStatement_returnKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set scriptTag_scriptTag(int value) {
+  set scriptTag_scriptTag(int value) {
     assert(kind == idl.LinkedNodeKind.scriptTag);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set setOrMapLiteral_leftBracket(int value) {
+  set setOrMapLiteral_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleFormalParameter_keyword(int value) {
+  set simpleFormalParameter_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleIdentifier_element(int value) {
+  set simpleIdentifier_element(int value) {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set simpleStringLiteral_token(int value) {
+  set simpleStringLiteral_token(int value) {
     assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set spreadElement_spreadOperator(int value) {
+  set spreadElement_spreadOperator(int value) {
     assert(kind == idl.LinkedNodeKind.spreadElement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set superConstructorInvocation_element(int value) {
+  set superConstructorInvocation_element(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set superExpression_superKeyword(int value) {
+  set superExpression_superKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.superExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set switchMember_keyword(int value) {
+  set switchMember_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set switchStatement_leftParenthesis(int value) {
+  set switchStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set symbolLiteral_poundSign(int value) {
+  set symbolLiteral_poundSign(int value) {
     assert(kind == idl.LinkedNodeKind.symbolLiteral);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set thisExpression_thisKeyword(int value) {
+  set thisExpression_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.thisExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set throwExpression_throwKeyword(int value) {
+  set throwExpression_throwKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.throwExpression);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set topLevelVariableDeclaration_semicolon(int value) {
+  set topLevelVariableDeclaration_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.topLevelVariableDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set tryStatement_finallyKeyword(int value) {
+  set tryStatement_finallyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeArgumentList_leftBracket(int value) {
+  set typeArgumentList_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeName_question(int value) {
+  set typeName_question(int value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeParameter_extendsKeyword(int value) {
+  set typeParameter_extendsKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set typeParameterList_leftBracket(int value) {
+  set typeParameterList_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclaration_equals(int value) {
+  set variableDeclaration_equals(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclarationList_keyword(int value) {
+  set variableDeclarationList_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationList);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set variableDeclarationStatement_semicolon(int value) {
+  set variableDeclarationStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.variableDeclarationStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set whileStatement_leftParenthesis(int value) {
+  set whileStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set withClause_withKeyword(int value) {
+  set withClause_withKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.withClause);
     assert(value == null || value >= 0);
     _variantField_15 = value;
   }
 
-  void set yieldStatement_yieldKeyword(int value) {
+  set yieldStatement_yieldKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_15 = value;
@@ -7421,248 +7436,248 @@
     return _variantField_7;
   }
 
-  void set annotation_constructorName(LinkedNodeBuilder value) {
+  set annotation_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_7 = value;
   }
 
-  void set asExpression_type(LinkedNodeBuilder value) {
+  set asExpression_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.asExpression);
     _variantField_7 = value;
   }
 
-  void set assertInitializer_message(LinkedNodeBuilder value) {
+  set assertInitializer_message(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     _variantField_7 = value;
   }
 
-  void set assertStatement_message(LinkedNodeBuilder value) {
+  set assertStatement_message(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     _variantField_7 = value;
   }
 
-  void set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
+  set assignmentExpression_rightHandSide(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     _variantField_7 = value;
   }
 
-  void set binaryExpression_rightOperand(LinkedNodeBuilder value) {
+  set binaryExpression_rightOperand(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     _variantField_7 = value;
   }
 
-  void set catchClause_exceptionParameter(LinkedNodeBuilder value) {
+  set catchClause_exceptionParameter(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_7 = value;
   }
 
-  void set classDeclaration_withClause(LinkedNodeBuilder value) {
+  set classDeclaration_withClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_7 = value;
   }
 
-  void set classTypeAlias_superclass(LinkedNodeBuilder value) {
+  set classTypeAlias_superclass(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_7 = value;
   }
 
-  void set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
+  set conditionalExpression_elseExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_7 = value;
   }
 
-  void set configuration_value(LinkedNodeBuilder value) {
+  set configuration_value(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_7 = value;
   }
 
-  void set constructorDeclaration_name(LinkedNodeBuilder value) {
+  set constructorDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_7 = value;
   }
 
-  void set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
+  set constructorFieldInitializer_fieldName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     _variantField_7 = value;
   }
 
-  void set constructorName_type(LinkedNodeBuilder value) {
+  set constructorName_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     _variantField_7 = value;
   }
 
-  void set declaredIdentifier_type(LinkedNodeBuilder value) {
+  set declaredIdentifier_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.declaredIdentifier);
     _variantField_7 = value;
   }
 
-  void set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
+  set defaultFormalParameter_parameter(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_7 = value;
   }
 
-  void set doStatement_condition(LinkedNodeBuilder value) {
+  set doStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     _variantField_7 = value;
   }
 
-  void set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
+  set fieldFormalParameter_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_7 = value;
   }
 
-  void set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
+  set forEachPartsWithDeclaration_loopVariable(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithDeclaration);
     _variantField_7 = value;
   }
 
-  void set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
+  set forEachPartsWithIdentifier_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forEachPartsWithIdentifier);
     _variantField_7 = value;
   }
 
-  void set forElement_body(LinkedNodeBuilder value) {
+  set forElement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forElement);
     _variantField_7 = value;
   }
 
-  void set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
+  set forPartsWithDeclarations_variables(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations);
     _variantField_7 = value;
   }
 
-  void set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
+  set forPartsWithExpression_initialization(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithExpression);
     _variantField_7 = value;
   }
 
-  void set forStatement_body(LinkedNodeBuilder value) {
+  set forStatement_body(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.forStatement);
     _variantField_7 = value;
   }
 
-  void set functionDeclaration_returnType(LinkedNodeBuilder value) {
+  set functionDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     _variantField_7 = value;
   }
 
-  void set functionExpression_formalParameters(LinkedNodeBuilder value) {
+  set functionExpression_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_7 = value;
   }
 
-  void set functionTypeAlias_returnType(LinkedNodeBuilder value) {
+  set functionTypeAlias_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_7 = value;
   }
 
-  void set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_7 = value;
   }
 
-  void set genericFunctionType_returnType(LinkedNodeBuilder value) {
+  set genericFunctionType_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_7 = value;
   }
 
-  void set genericTypeAlias_functionType(LinkedNodeBuilder value) {
+  set genericTypeAlias_functionType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     _variantField_7 = value;
   }
 
-  void set ifStatement_elseStatement(LinkedNodeBuilder value) {
+  set ifStatement_elseStatement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifStatement);
     _variantField_7 = value;
   }
 
-  void set indexExpression_target(LinkedNodeBuilder value) {
+  set indexExpression_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     _variantField_7 = value;
   }
 
-  void set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
+  set instanceCreationExpression_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_7 = value;
   }
 
-  void set isExpression_type(LinkedNodeBuilder value) {
+  set isExpression_type(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     _variantField_7 = value;
   }
 
-  void set mapLiteralEntry_value(LinkedNodeBuilder value) {
+  set mapLiteralEntry_value(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.mapLiteralEntry);
     _variantField_7 = value;
   }
 
-  void set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
+  set methodDeclaration_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_7 = value;
   }
 
-  void set methodInvocation_target(LinkedNodeBuilder value) {
+  set methodInvocation_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_7 = value;
   }
 
-  void set namedExpression_name(LinkedNodeBuilder value) {
+  set namedExpression_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.namedExpression);
     _variantField_7 = value;
   }
 
-  void set partOfDirective_uri(LinkedNodeBuilder value) {
+  set partOfDirective_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     _variantField_7 = value;
   }
 
-  void set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
+  set prefixedIdentifier_prefix(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.prefixedIdentifier);
     _variantField_7 = value;
   }
 
-  void set propertyAccess_target(LinkedNodeBuilder value) {
+  set propertyAccess_target(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.propertyAccess);
     _variantField_7 = value;
   }
 
-  void set redirectingConstructorInvocation_constructorName(
+  set redirectingConstructorInvocation_constructorName(
       LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     _variantField_7 = value;
   }
 
-  void set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
+  set superConstructorInvocation_constructorName(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     _variantField_7 = value;
   }
 
-  void set switchStatement_expression(LinkedNodeBuilder value) {
+  set switchStatement_expression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     _variantField_7 = value;
   }
 
-  void set tryStatement_finallyBlock(LinkedNodeBuilder value) {
+  set tryStatement_finallyBlock(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     _variantField_7 = value;
   }
 
-  void set typeName_typeArguments(LinkedNodeBuilder value) {
+  set typeName_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeName);
     _variantField_7 = value;
   }
 
-  void set typeParameter_name(LinkedNodeBuilder value) {
+  set typeParameter_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.typeParameter);
     _variantField_7 = value;
   }
 
-  void set variableDeclaration_name(LinkedNodeBuilder value) {
+  set variableDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_7 = value;
   }
 
-  void set whileStatement_condition(LinkedNodeBuilder value) {
+  set whileStatement_condition(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     _variantField_7 = value;
   }
@@ -7763,83 +7778,82 @@
     return _variantField_8;
   }
 
-  void set annotation_name(LinkedNodeBuilder value) {
+  set annotation_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     _variantField_8 = value;
   }
 
-  void set catchClause_exceptionType(LinkedNodeBuilder value) {
+  set catchClause_exceptionType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_8 = value;
   }
 
-  void set classDeclaration_nativeClause(LinkedNodeBuilder value) {
+  set classDeclaration_nativeClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_8 = value;
   }
 
-  void set classTypeAlias_withClause(LinkedNodeBuilder value) {
+  set classTypeAlias_withClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_8 = value;
   }
 
-  void set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
+  set conditionalExpression_thenExpression(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     _variantField_8 = value;
   }
 
-  void set configuration_uri(LinkedNodeBuilder value) {
+  set configuration_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     _variantField_8 = value;
   }
 
-  void set constructorDeclaration_parameters(LinkedNodeBuilder value) {
+  set constructorDeclaration_parameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_8 = value;
   }
 
-  void set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
+  set fieldFormalParameter_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     _variantField_8 = value;
   }
 
-  void set functionExpression_typeParameters(LinkedNodeBuilder value) {
+  set functionExpression_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpression);
     _variantField_8 = value;
   }
 
-  void set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
+  set functionTypeAlias_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypeAlias);
     _variantField_8 = value;
   }
 
-  void set functionTypedFormalParameter_typeParameters(
-      LinkedNodeBuilder value) {
+  set functionTypedFormalParameter_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
     _variantField_8 = value;
   }
 
-  void set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
+  set genericFunctionType_formalParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_8 = value;
   }
 
-  void set ifElement_thenElement(LinkedNodeBuilder value) {
+  set ifElement_thenElement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifElement);
     _variantField_8 = value;
   }
 
-  void set ifStatement_thenStatement(LinkedNodeBuilder value) {
+  set ifStatement_thenStatement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifStatement);
     _variantField_8 = value;
   }
 
-  void set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
+  set instanceCreationExpression_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.instanceCreationExpression);
     _variantField_8 = value;
   }
 
-  void set methodDeclaration_returnType(LinkedNodeBuilder value) {
+  set methodDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_8 = value;
   }
@@ -8178,335 +8192,335 @@
     return _variantField_16 ??= 0;
   }
 
-  void set annotation_period(int value) {
+  set annotation_period(int value) {
     assert(kind == idl.LinkedNodeKind.annotation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set argumentList_rightParenthesis(int value) {
+  set argumentList_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.argumentList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assertInitializer_comma(int value) {
+  set assertInitializer_comma(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assertStatement_comma(int value) {
+  set assertStatement_comma(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set assignmentExpression_operator(int value) {
+  set assignmentExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.assignmentExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set binaryExpression_operator(int value) {
+  set binaryExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.binaryExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set block_rightBracket(int value) {
+  set block_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.block);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set blockFunctionBody_star(int value) {
+  set blockFunctionBody_star(int value) {
     assert(kind == idl.LinkedNodeKind.blockFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set breakStatement_semicolon(int value) {
+  set breakStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.breakStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set catchClause_comma(int value) {
+  set catchClause_comma(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set classDeclaration_classKeyword(int value) {
+  set classDeclaration_classKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set classTypeAlias_equals(int value) {
+  set classTypeAlias_equals(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set compilationUnit_endToken(int value) {
+  set compilationUnit_endToken(int value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set conditionalExpression_question(int value) {
+  set conditionalExpression_question(int value) {
     assert(kind == idl.LinkedNodeKind.conditionalExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set configuration_leftParenthesis(int value) {
+  set configuration_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorDeclaration_externalKeyword(int value) {
+  set constructorDeclaration_externalKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorFieldInitializer_period(int value) {
+  set constructorFieldInitializer_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set constructorName_period(int value) {
+  set constructorName_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorName);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set continueStatement_semicolon(int value) {
+  set continueStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.continueStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set doStatement_rightParenthesis(int value) {
+  set doStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set enumDeclaration_leftBracket(int value) {
+  set enumDeclaration_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set expressionFunctionBody_keyword(int value) {
+  set expressionFunctionBody_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set fieldDeclaration_semicolon(int value) {
+  set fieldDeclaration_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set fieldFormalParameter_period(int value) {
+  set fieldFormalParameter_period(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set formalParameterList_leftParenthesis(int value) {
+  set formalParameterList_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set forMixin_forKeyword(int value) {
+  set forMixin_forKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set forParts_rightSeparator(int value) {
+  set forParts_rightSeparator(int value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set functionDeclaration_propertyKeyword(int value) {
+  set functionDeclaration_propertyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.functionDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set genericFunctionType_question(int value) {
+  set genericFunctionType_question(int value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set genericTypeAlias_equals(int value) {
+  set genericTypeAlias_equals(int value) {
     assert(kind == idl.LinkedNodeKind.genericTypeAlias);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set ifMixin_ifKeyword(int value) {
+  set ifMixin_ifKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set importDirective_deferredKeyword(int value) {
+  set importDirective_deferredKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.importDirective);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set indexExpression_period(int value) {
+  set indexExpression_period(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set integerLiteral_value(int value) {
+  set integerLiteral_value(int value) {
     assert(kind == idl.LinkedNodeKind.integerLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set interpolationExpression_rightBracket(int value) {
+  set interpolationExpression_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.interpolationExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set isExpression_notOperator(int value) {
+  set isExpression_notOperator(int value) {
     assert(kind == idl.LinkedNodeKind.isExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set listLiteral_rightBracket(int value) {
+  set listLiteral_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set methodDeclaration_modifierKeyword(int value) {
+  set methodDeclaration_modifierKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set nativeFunctionBody_semicolon(int value) {
+  set nativeFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.nativeFunctionBody);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set parenthesizedExpression_rightParenthesis(int value) {
+  set parenthesizedExpression_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.parenthesizedExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set partOfDirective_ofKeyword(int value) {
+  set partOfDirective_ofKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.partOfDirective);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set postfixExpression_operator(int value) {
+  set postfixExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.postfixExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set prefixExpression_operator(int value) {
+  set prefixExpression_operator(int value) {
     assert(kind == idl.LinkedNodeKind.prefixExpression);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set redirectingConstructorInvocation_period(int value) {
+  set redirectingConstructorInvocation_period(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set returnStatement_semicolon(int value) {
+  set returnStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.returnStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set setOrMapLiteral_rightBracket(int value) {
+  set setOrMapLiteral_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set simpleIdentifier_token(int value) {
+  set simpleIdentifier_token(int value) {
     assert(kind == idl.LinkedNodeKind.simpleIdentifier);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set superConstructorInvocation_period(int value) {
+  set superConstructorInvocation_period(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set switchMember_colon(int value) {
+  set switchMember_colon(int value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set switchStatement_rightParenthesis(int value) {
+  set switchStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set tryStatement_tryKeyword(int value) {
+  set tryStatement_tryKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.tryStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set typeArgumentList_rightBracket(int value) {
+  set typeArgumentList_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeArgumentList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set typeParameterList_rightBracket(int value) {
+  set typeParameterList_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.typeParameterList);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set whileStatement_rightParenthesis(int value) {
+  set whileStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
   }
 
-  void set yieldStatement_star(int value) {
+  set yieldStatement_star(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_16 = value;
@@ -8640,129 +8654,129 @@
     return _variantField_17 ??= 0;
   }
 
-  void set assertInitializer_leftParenthesis(int value) {
+  set assertInitializer_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set assertStatement_leftParenthesis(int value) {
+  set assertStatement_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set catchClause_leftParenthesis(int value) {
+  set catchClause_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set configuration_rightParenthesis(int value) {
+  set configuration_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set constructorDeclaration_factoryKeyword(int value) {
+  set constructorDeclaration_factoryKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set constructorFieldInitializer_thisKeyword(int value) {
+  set constructorFieldInitializer_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.constructorFieldInitializer);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set doStatement_doKeyword(int value) {
+  set doStatement_doKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set enumDeclaration_rightBracket(int value) {
+  set enumDeclaration_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.enumDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set expressionFunctionBody_semicolon(int value) {
+  set expressionFunctionBody_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.expressionFunctionBody);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set fieldDeclaration_staticKeyword(int value) {
+  set fieldDeclaration_staticKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set fieldFormalParameter_thisKeyword(int value) {
+  set fieldFormalParameter_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set formalParameterList_rightDelimiter(int value) {
+  set formalParameterList_rightDelimiter(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set forMixin_leftParenthesis(int value) {
+  set forMixin_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set ifMixin_leftParenthesis(int value) {
+  set ifMixin_leftParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set indexExpression_leftBracket(int value) {
+  set indexExpression_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set methodDeclaration_operatorKeyword(int value) {
+  set methodDeclaration_operatorKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set redirectingConstructorInvocation_thisKeyword(int value) {
+  set redirectingConstructorInvocation_thisKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.redirectingConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set superConstructorInvocation_superKeyword(int value) {
+  set superConstructorInvocation_superKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.superConstructorInvocation);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set switchStatement_switchKeyword(int value) {
+  set switchStatement_switchKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set whileStatement_whileKeyword(int value) {
+  set whileStatement_whileKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.whileStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
   }
 
-  void set yieldStatement_semicolon(int value) {
+  set yieldStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.yieldStatement);
     assert(value == null || value >= 0);
     _variantField_17 = value;
@@ -8860,44 +8874,44 @@
     return _variantField_18 ??= 0;
   }
 
-  void set assertInitializer_rightParenthesis(int value) {
+  set assertInitializer_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertInitializer);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set assertStatement_rightParenthesis(int value) {
+  set assertStatement_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set catchClause_onKeyword(int value) {
+  set catchClause_onKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set classOrMixinDeclaration_rightBracket(int value) {
+  set classOrMixinDeclaration_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set configuration_equalToken(int value) {
+  set configuration_equalToken(int value) {
     assert(kind == idl.LinkedNodeKind.configuration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set constructorDeclaration_period(int value) {
+  set constructorDeclaration_period(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set directive_keyword(int value) {
+  set directive_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.libraryDirective ||
@@ -8907,44 +8921,44 @@
     _variantField_18 = value;
   }
 
-  void set doStatement_semicolon(int value) {
+  set doStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set formalParameterList_rightParenthesis(int value) {
+  set formalParameterList_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.formalParameterList);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set ifMixin_rightParenthesis(int value) {
+  set ifMixin_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.ifElement ||
         kind == idl.LinkedNodeKind.ifStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set indexExpression_rightBracket(int value) {
+  set indexExpression_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.indexExpression);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set methodDeclaration_propertyKeyword(int value) {
+  set methodDeclaration_propertyKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set switchStatement_leftBracket(int value) {
+  set switchStatement_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_18 = value;
   }
 
-  void set typeAlias_typedefKeyword(int value) {
+  set typeAlias_typedefKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9040,58 +9054,58 @@
     return _variantField_19 ??= 0;
   }
 
-  void set assertStatement_semicolon(int value) {
+  set assertStatement_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.assertStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set catchClause_rightParenthesis(int value) {
+  set catchClause_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set classOrMixinDeclaration_leftBracket(int value) {
+  set classOrMixinDeclaration_leftBracket(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set combinator_keyword(int value) {
+  set combinator_keyword(int value) {
     assert(kind == idl.LinkedNodeKind.hideCombinator ||
         kind == idl.LinkedNodeKind.showCombinator);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set constructorDeclaration_separator(int value) {
+  set constructorDeclaration_separator(int value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set doStatement_whileKeyword(int value) {
+  set doStatement_whileKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.doStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set forMixin_rightParenthesis(int value) {
+  set forMixin_rightParenthesis(int value) {
     assert(kind == idl.LinkedNodeKind.forElement ||
         kind == idl.LinkedNodeKind.forStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set methodDeclaration_actualProperty(int value) {
+  set methodDeclaration_actualProperty(int value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set normalFormalParameter_covariantKeyword(int value) {
+  set normalFormalParameter_covariantKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
@@ -9099,13 +9113,13 @@
     _variantField_19 = value;
   }
 
-  void set switchStatement_rightBracket(int value) {
+  set switchStatement_rightBracket(int value) {
     assert(kind == idl.LinkedNodeKind.switchStatement);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set typeAlias_semicolon(int value) {
+  set typeAlias_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.functionTypeAlias ||
         kind == idl.LinkedNodeKind.genericTypeAlias);
@@ -9113,14 +9127,14 @@
     _variantField_19 = value;
   }
 
-  void set typedLiteral_constKeyword(int value) {
+  set typedLiteral_constKeyword(int value) {
     assert(kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.setOrMapLiteral);
     assert(value == null || value >= 0);
     _variantField_19 = value;
   }
 
-  void set uriBasedDirective_uriElement(int value) {
+  set uriBasedDirective_uriElement(int value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.partDirective);
@@ -9129,131 +9143,6 @@
   }
 
   @override
-  LinkedNodeTypeBuilder get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get fieldFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionDeclaration_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionTypeAlias_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get functionTypedFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get genericFunctionType_returnType2 {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get methodDeclaration_returnType2 {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get simpleFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    return _variantField_24;
-  }
-
-  @override
-  LinkedNodeTypeBuilder get variableDeclaration_type2 {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    return _variantField_24;
-  }
-
-  void set binaryExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 = value;
-  }
-
-  void set fieldFormalParameter_type2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_24 = value;
-  }
-
-  void set functionDeclaration_returnType2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_24 = value;
-  }
-
-  void set functionTypeAlias_returnType2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_24 = value;
-  }
-
-  void set functionTypedFormalParameter_type2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_24 = value;
-  }
-
-  void set genericFunctionType_returnType2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_24 = value;
-  }
-
-  void set invocationExpression_invokeType(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 = value;
-  }
-
-  void set methodDeclaration_returnType2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 = value;
-  }
-
-  void set simpleFormalParameter_type2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_24 = value;
-  }
-
-  void set typeName_type(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_24 = value;
-  }
-
-  void set variableDeclaration_type2(LinkedNodeTypeBuilder value) {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 = value;
-  }
-
-  @override
   bool get booleanLiteral_value {
     assert(kind == idl.LinkedNodeKind.booleanLiteral);
     return _variantField_27 ??= false;
@@ -9285,29 +9174,29 @@
     return _variantField_27 ??= false;
   }
 
-  void set booleanLiteral_value(bool value) {
+  set booleanLiteral_value(bool value) {
     assert(kind == idl.LinkedNodeKind.booleanLiteral);
     _variantField_27 = value;
   }
 
-  void set classDeclaration_isDartObject(bool value) {
+  set classDeclaration_isDartObject(bool value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration);
     _variantField_27 = value;
   }
 
-  void set defaultFormalParameter_isNamed(bool value) {
+  set defaultFormalParameter_isNamed(bool value) {
     assert(kind == idl.LinkedNodeKind.defaultFormalParameter);
     _variantField_27 = value;
   }
 
-  void set normalFormalParameter_isCovariant(bool value) {
+  set normalFormalParameter_isCovariant(bool value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_27 = value;
   }
 
-  void set setOrMapLiteral_isMap(bool value) {
+  set setOrMapLiteral_isMap(bool value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     _variantField_27 = value;
   }
@@ -9342,28 +9231,27 @@
     return _variantField_9;
   }
 
-  void set catchClause_stackTraceParameter(LinkedNodeBuilder value) {
+  set catchClause_stackTraceParameter(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.catchClause);
     _variantField_9 = value;
   }
 
-  void set classTypeAlias_implementsClause(LinkedNodeBuilder value) {
+  set classTypeAlias_implementsClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classTypeAlias);
     _variantField_9 = value;
   }
 
-  void set constructorDeclaration_redirectedConstructor(
-      LinkedNodeBuilder value) {
+  set constructorDeclaration_redirectedConstructor(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_9 = value;
   }
 
-  void set ifElement_elseElement(LinkedNodeBuilder value) {
+  set ifElement_elseElement(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.ifElement);
     _variantField_9 = value;
   }
 
-  void set methodDeclaration_typeParameters(LinkedNodeBuilder value) {
+  set methodDeclaration_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_9 = value;
   }
@@ -9390,19 +9278,19 @@
     return _variantField_12;
   }
 
-  void set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
+  set classOrMixinDeclaration_implementsClause(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     _variantField_12 = value;
   }
 
-  void set invocationExpression_typeArguments(LinkedNodeBuilder value) {
+  set invocationExpression_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_12 = value;
   }
 
-  void set normalFormalParameter_identifier(LinkedNodeBuilder value) {
+  set normalFormalParameter_identifier(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
@@ -9423,13 +9311,13 @@
     return _variantField_5 ??= <LinkedNodeBuilder>[];
   }
 
-  void set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) {
+  set classOrMixinDeclaration_members(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     _variantField_5 = value;
   }
 
-  void set forParts_updaters(List<LinkedNodeBuilder> value) {
+  set forParts_updaters(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.forPartsWithDeclarations ||
         kind == idl.LinkedNodeKind.forPartsWithExpression);
     _variantField_5 = value;
@@ -9442,7 +9330,7 @@
     return _variantField_13;
   }
 
-  void set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) {
+  set classOrMixinDeclaration_typeParameters(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.mixinDeclaration);
     _variantField_13 = value;
@@ -9468,7 +9356,7 @@
     return _variantField_34 ??= 0;
   }
 
-  void set codeLength(int value) {
+  set codeLength(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -9518,7 +9406,7 @@
     return _variantField_33 ??= 0;
   }
 
-  void set codeOffset(int value) {
+  set codeOffset(int value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.constructorDeclaration ||
@@ -9538,7 +9426,7 @@
     _variantField_33 = value;
   }
 
-  void set directive_semicolon(int value) {
+  set directive_semicolon(int value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.libraryDirective ||
@@ -9560,13 +9448,13 @@
     return _variantField_28 ??= <int>[];
   }
 
-  void set comment_tokens(List<int> value) {
+  set comment_tokens(List<int> value) {
     assert(kind == idl.LinkedNodeKind.comment);
     assert(value == null || value.every((e) => e >= 0));
     _variantField_28 = value;
   }
 
-  void set symbolLiteral_components(List<int> value) {
+  set symbolLiteral_components(List<int> value) {
     assert(kind == idl.LinkedNodeKind.symbolLiteral);
     assert(value == null || value.every((e) => e >= 0));
     _variantField_28 = value;
@@ -9578,7 +9466,7 @@
     return _variantField_29 ??= idl.LinkedNodeCommentType.block;
   }
 
-  void set comment_type(idl.LinkedNodeCommentType value) {
+  set comment_type(idl.LinkedNodeCommentType value) {
     assert(kind == idl.LinkedNodeKind.comment);
     _variantField_29 = value;
   }
@@ -9603,18 +9491,18 @@
     return _variantField_3 ??= <LinkedNodeBuilder>[];
   }
 
-  void set compilationUnit_directives(List<LinkedNodeBuilder> value) {
+  set compilationUnit_directives(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.compilationUnit);
     _variantField_3 = value;
   }
 
-  void set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
+  set namespaceDirective_configurations(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective);
     _variantField_3 = value;
   }
 
-  void set switchMember_labels(List<LinkedNodeBuilder> value) {
+  set switchMember_labels(List<LinkedNodeBuilder> value) {
     assert(kind == idl.LinkedNodeKind.switchCase ||
         kind == idl.LinkedNodeKind.switchDefault);
     _variantField_3 = value;
@@ -9632,12 +9520,12 @@
     return _variantField_10;
   }
 
-  void set constructorDeclaration_returnType(LinkedNodeBuilder value) {
+  set constructorDeclaration_returnType(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.constructorDeclaration);
     _variantField_10 = value;
   }
 
-  void set methodDeclaration_name(LinkedNodeBuilder value) {
+  set methodDeclaration_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.methodDeclaration);
     _variantField_10 = value;
   }
@@ -9648,7 +9536,7 @@
     return _variantField_21 ??= 0.0;
   }
 
-  void set doubleLiteral_value(double value) {
+  set doubleLiteral_value(double value) {
     assert(kind == idl.LinkedNodeKind.doubleLiteral);
     _variantField_21 = value;
   }
@@ -9696,7 +9584,7 @@
     return _variantField_25;
   }
 
-  void set expression_type(LinkedNodeTypeBuilder value) {
+  set expression_type(LinkedNodeTypeBuilder value) {
     assert(kind == idl.LinkedNodeKind.adjacentStrings ||
         kind == idl.LinkedNodeKind.assignmentExpression ||
         kind == idl.LinkedNodeKind.asExpression ||
@@ -9732,7 +9620,7 @@
     _variantField_25 = value;
   }
 
-  void set genericFunctionType_type(LinkedNodeTypeBuilder value) {
+  set genericFunctionType_type(LinkedNodeTypeBuilder value) {
     assert(kind == idl.LinkedNodeKind.genericFunctionType);
     _variantField_25 = value;
   }
@@ -9745,7 +9633,7 @@
     return _variantField_26 ??= idl.LinkedNodeFormalParameterKind.required;
   }
 
-  void set formalParameter_kind(idl.LinkedNodeFormalParameterKind value) {
+  set formalParameter_kind(idl.LinkedNodeFormalParameterKind value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
@@ -9758,7 +9646,7 @@
     return _variantField_30 ??= '';
   }
 
-  void set interpolationString_value(String value) {
+  set interpolationString_value(String value) {
     assert(kind == idl.LinkedNodeKind.interpolationString);
     _variantField_30 = value;
   }
@@ -9805,13 +9693,13 @@
     return _variantField_14;
   }
 
-  void set invocationExpression_arguments(LinkedNodeBuilder value) {
+  set invocationExpression_arguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
         kind == idl.LinkedNodeKind.methodInvocation);
     _variantField_14 = value;
   }
 
-  void set namedCompilationUnitMember_name(LinkedNodeBuilder value) {
+  set namedCompilationUnitMember_name(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.classDeclaration ||
         kind == idl.LinkedNodeKind.classTypeAlias ||
         kind == idl.LinkedNodeKind.enumDeclaration ||
@@ -9822,20 +9710,20 @@
     _variantField_14 = value;
   }
 
-  void set normalFormalParameter_comment(LinkedNodeBuilder value) {
+  set normalFormalParameter_comment(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
         kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
         kind == idl.LinkedNodeKind.simpleFormalParameter);
     _variantField_14 = value;
   }
 
-  void set typedLiteral_typeArguments(LinkedNodeBuilder value) {
+  set typedLiteral_typeArguments(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.listLiteral ||
         kind == idl.LinkedNodeKind.setOrMapLiteral);
     _variantField_14 = value;
   }
 
-  void set uriBasedDirective_uri(LinkedNodeBuilder value) {
+  set uriBasedDirective_uri(LinkedNodeBuilder value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.partDirective);
@@ -9845,14 +9733,14 @@
   @override
   bool get isSynthetic => _isSynthetic ??= false;
 
-  void set isSynthetic(bool value) {
+  set isSynthetic(bool value) {
     this._isSynthetic = value;
   }
 
   @override
   idl.LinkedNodeKind get kind => _kind ??= idl.LinkedNodeKind.adjacentStrings;
 
-  void set kind(idl.LinkedNodeKind value) {
+  set kind(idl.LinkedNodeKind value) {
     this._kind = value;
   }
 
@@ -9865,7 +9753,7 @@
     return _variantField_23 ??= '';
   }
 
-  void set namespaceDirective_selectedUriContent(String value) {
+  set namespaceDirective_selectedUriContent(String value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.partDirective ||
@@ -9879,18 +9767,37 @@
     return _variantField_31 ??= false;
   }
 
-  void set setOrMapLiteral_isSet(bool value) {
+  @override
+  bool get simplyBoundable_isSimplyBounded {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.mixinDeclaration);
+    return _variantField_31 ??= false;
+  }
+
+  set setOrMapLiteral_isSet(bool value) {
     assert(kind == idl.LinkedNodeKind.setOrMapLiteral);
     _variantField_31 = value;
   }
 
+  set simplyBoundable_isSimplyBounded(bool value) {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_31 = value;
+  }
+
   @override
   String get simpleStringLiteral_value {
     assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
     return _variantField_20 ??= '';
   }
 
-  void set simpleStringLiteral_value(String value) {
+  set simpleStringLiteral_value(String value) {
     assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
     _variantField_20 = value;
   }
@@ -9903,7 +9810,7 @@
     return _variantField_22 ??= '';
   }
 
-  void set uriBasedDirective_uriContent(String value) {
+  set uriBasedDirective_uriContent(String value) {
     assert(kind == idl.LinkedNodeKind.exportDirective ||
         kind == idl.LinkedNodeKind.importDirective ||
         kind == idl.LinkedNodeKind.partDirective);
@@ -9916,12 +9823,285 @@
     return _variantField_32;
   }
 
-  void set variableDeclaration_declaration(
+  set variableDeclaration_declaration(
       LinkedNodeVariablesDeclarationBuilder value) {
     assert(kind == idl.LinkedNodeKind.variableDeclaration);
     _variantField_32 = value;
   }
 
+  LinkedNodeBuilder.functionDeclaration({
+    LinkedNodeTypeBuilder actualReturnType,
+    LinkedNodeBuilder annotatedNode_comment,
+    List<LinkedNodeBuilder> annotatedNode_metadata,
+    LinkedNodeBuilder functionDeclaration_functionExpression,
+    int functionDeclaration_externalKeyword,
+    LinkedNodeBuilder functionDeclaration_returnType,
+    int functionDeclaration_propertyKeyword,
+    int codeLength,
+    int codeOffset,
+    LinkedNodeBuilder namedCompilationUnitMember_name,
+  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
+        _variantField_24 = actualReturnType,
+        _variantField_11 = annotatedNode_comment,
+        _variantField_4 = annotatedNode_metadata,
+        _variantField_6 = functionDeclaration_functionExpression,
+        _variantField_15 = functionDeclaration_externalKeyword,
+        _variantField_7 = functionDeclaration_returnType,
+        _variantField_16 = functionDeclaration_propertyKeyword,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_14 = namedCompilationUnitMember_name;
+
+  LinkedNodeBuilder.functionExpression({
+    LinkedNodeTypeBuilder actualReturnType,
+    LinkedNodeBuilder functionExpression_body,
+    LinkedNodeBuilder functionExpression_formalParameters,
+    LinkedNodeBuilder functionExpression_typeParameters,
+  })  : _kind = idl.LinkedNodeKind.functionExpression,
+        _variantField_24 = actualReturnType,
+        _variantField_6 = functionExpression_body,
+        _variantField_7 = functionExpression_formalParameters,
+        _variantField_8 = functionExpression_typeParameters;
+
+  LinkedNodeBuilder.functionTypeAlias({
+    LinkedNodeTypeBuilder actualReturnType,
+    LinkedNodeBuilder annotatedNode_comment,
+    List<LinkedNodeBuilder> annotatedNode_metadata,
+    LinkedNodeBuilder functionTypeAlias_formalParameters,
+    LinkedNodeBuilder functionTypeAlias_returnType,
+    LinkedNodeBuilder functionTypeAlias_typeParameters,
+    int typeAlias_typedefKeyword,
+    int typeAlias_semicolon,
+    int codeLength,
+    int codeOffset,
+    LinkedNodeBuilder namedCompilationUnitMember_name,
+    bool simplyBoundable_isSimplyBounded,
+  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
+        _variantField_24 = actualReturnType,
+        _variantField_11 = annotatedNode_comment,
+        _variantField_4 = annotatedNode_metadata,
+        _variantField_6 = functionTypeAlias_formalParameters,
+        _variantField_7 = functionTypeAlias_returnType,
+        _variantField_8 = functionTypeAlias_typeParameters,
+        _variantField_18 = typeAlias_typedefKeyword,
+        _variantField_19 = typeAlias_semicolon,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_31 = simplyBoundable_isSimplyBounded;
+
+  LinkedNodeBuilder.genericFunctionType({
+    LinkedNodeTypeBuilder actualReturnType,
+    LinkedNodeBuilder genericFunctionType_typeParameters,
+    int genericFunctionType_functionKeyword,
+    LinkedNodeBuilder genericFunctionType_returnType,
+    LinkedNodeBuilder genericFunctionType_formalParameters,
+    int genericFunctionType_question,
+    LinkedNodeTypeBuilder genericFunctionType_type,
+  })  : _kind = idl.LinkedNodeKind.genericFunctionType,
+        _variantField_24 = actualReturnType,
+        _variantField_6 = genericFunctionType_typeParameters,
+        _variantField_15 = genericFunctionType_functionKeyword,
+        _variantField_7 = genericFunctionType_returnType,
+        _variantField_8 = genericFunctionType_formalParameters,
+        _variantField_16 = genericFunctionType_question,
+        _variantField_25 = genericFunctionType_type;
+
+  LinkedNodeBuilder.methodDeclaration({
+    LinkedNodeTypeBuilder actualReturnType,
+    LinkedNodeBuilder annotatedNode_comment,
+    List<LinkedNodeBuilder> annotatedNode_metadata,
+    LinkedNodeBuilder methodDeclaration_body,
+    int methodDeclaration_externalKeyword,
+    LinkedNodeBuilder methodDeclaration_formalParameters,
+    LinkedNodeBuilder methodDeclaration_returnType,
+    int methodDeclaration_modifierKeyword,
+    int methodDeclaration_operatorKeyword,
+    int methodDeclaration_propertyKeyword,
+    int methodDeclaration_actualProperty,
+    LinkedNodeBuilder methodDeclaration_typeParameters,
+    int codeLength,
+    int codeOffset,
+    LinkedNodeBuilder methodDeclaration_name,
+  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
+        _variantField_24 = actualReturnType,
+        _variantField_11 = annotatedNode_comment,
+        _variantField_4 = annotatedNode_metadata,
+        _variantField_6 = methodDeclaration_body,
+        _variantField_15 = methodDeclaration_externalKeyword,
+        _variantField_7 = methodDeclaration_formalParameters,
+        _variantField_8 = methodDeclaration_returnType,
+        _variantField_16 = methodDeclaration_modifierKeyword,
+        _variantField_17 = methodDeclaration_operatorKeyword,
+        _variantField_18 = methodDeclaration_propertyKeyword,
+        _variantField_19 = methodDeclaration_actualProperty,
+        _variantField_9 = methodDeclaration_typeParameters,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_10 = methodDeclaration_name;
+
+  LinkedNodeBuilder.fieldFormalParameter({
+    LinkedNodeTypeBuilder actualType,
+    List<LinkedNodeBuilder> normalFormalParameter_metadata,
+    LinkedNodeBuilder fieldFormalParameter_type,
+    int fieldFormalParameter_keyword,
+    LinkedNodeBuilder fieldFormalParameter_typeParameters,
+    LinkedNodeBuilder fieldFormalParameter_formalParameters,
+    int fieldFormalParameter_period,
+    int fieldFormalParameter_thisKeyword,
+    int normalFormalParameter_covariantKeyword,
+    bool normalFormalParameter_isCovariant,
+    LinkedNodeBuilder normalFormalParameter_identifier,
+    int codeLength,
+    int codeOffset,
+    idl.LinkedNodeFormalParameterKind formalParameter_kind,
+    LinkedNodeBuilder normalFormalParameter_comment,
+  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
+        _variantField_24 = actualType,
+        _variantField_4 = normalFormalParameter_metadata,
+        _variantField_6 = fieldFormalParameter_type,
+        _variantField_15 = fieldFormalParameter_keyword,
+        _variantField_7 = fieldFormalParameter_typeParameters,
+        _variantField_8 = fieldFormalParameter_formalParameters,
+        _variantField_16 = fieldFormalParameter_period,
+        _variantField_17 = fieldFormalParameter_thisKeyword,
+        _variantField_19 = normalFormalParameter_covariantKeyword,
+        _variantField_27 = normalFormalParameter_isCovariant,
+        _variantField_12 = normalFormalParameter_identifier,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_26 = formalParameter_kind,
+        _variantField_14 = normalFormalParameter_comment;
+
+  LinkedNodeBuilder.functionTypedFormalParameter({
+    LinkedNodeTypeBuilder actualType,
+    List<LinkedNodeBuilder> normalFormalParameter_metadata,
+    LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
+    LinkedNodeBuilder functionTypedFormalParameter_returnType,
+    LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
+    int normalFormalParameter_covariantKeyword,
+    bool normalFormalParameter_isCovariant,
+    LinkedNodeBuilder normalFormalParameter_identifier,
+    int codeLength,
+    int codeOffset,
+    idl.LinkedNodeFormalParameterKind formalParameter_kind,
+    LinkedNodeBuilder normalFormalParameter_comment,
+  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
+        _variantField_24 = actualType,
+        _variantField_4 = normalFormalParameter_metadata,
+        _variantField_6 = functionTypedFormalParameter_formalParameters,
+        _variantField_7 = functionTypedFormalParameter_returnType,
+        _variantField_8 = functionTypedFormalParameter_typeParameters,
+        _variantField_19 = normalFormalParameter_covariantKeyword,
+        _variantField_27 = normalFormalParameter_isCovariant,
+        _variantField_12 = normalFormalParameter_identifier,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_26 = formalParameter_kind,
+        _variantField_14 = normalFormalParameter_comment;
+
+  LinkedNodeBuilder.simpleFormalParameter({
+    LinkedNodeTypeBuilder actualType,
+    List<LinkedNodeBuilder> normalFormalParameter_metadata,
+    LinkedNodeBuilder simpleFormalParameter_type,
+    int simpleFormalParameter_keyword,
+    int normalFormalParameter_covariantKeyword,
+    bool normalFormalParameter_isCovariant,
+    LinkedNodeBuilder normalFormalParameter_identifier,
+    int codeLength,
+    int codeOffset,
+    idl.LinkedNodeFormalParameterKind formalParameter_kind,
+    LinkedNodeBuilder normalFormalParameter_comment,
+  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
+        _variantField_24 = actualType,
+        _variantField_4 = normalFormalParameter_metadata,
+        _variantField_6 = simpleFormalParameter_type,
+        _variantField_15 = simpleFormalParameter_keyword,
+        _variantField_19 = normalFormalParameter_covariantKeyword,
+        _variantField_27 = normalFormalParameter_isCovariant,
+        _variantField_12 = normalFormalParameter_identifier,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_26 = formalParameter_kind,
+        _variantField_14 = normalFormalParameter_comment;
+
+  LinkedNodeBuilder.variableDeclaration({
+    LinkedNodeTypeBuilder actualType,
+    LinkedNodeBuilder annotatedNode_comment,
+    List<LinkedNodeBuilder> annotatedNode_metadata,
+    LinkedNodeBuilder variableDeclaration_initializer,
+    int variableDeclaration_equals,
+    LinkedNodeBuilder variableDeclaration_name,
+    int codeLength,
+    int codeOffset,
+    LinkedNodeVariablesDeclarationBuilder variableDeclaration_declaration,
+  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
+        _variantField_24 = actualType,
+        _variantField_11 = annotatedNode_comment,
+        _variantField_4 = annotatedNode_metadata,
+        _variantField_6 = variableDeclaration_initializer,
+        _variantField_15 = variableDeclaration_equals,
+        _variantField_7 = variableDeclaration_name,
+        _variantField_34 = codeLength,
+        _variantField_33 = codeOffset,
+        _variantField_32 = variableDeclaration_declaration;
+
+  LinkedNodeBuilder.binaryExpression({
+    LinkedNodeTypeBuilder binaryExpression_invokeType,
+    LinkedNodeBuilder binaryExpression_leftOperand,
+    int binaryExpression_element,
+    LinkedNodeBuilder binaryExpression_rightOperand,
+    int binaryExpression_operator,
+    LinkedNodeTypeBuilder expression_type,
+  })  : _kind = idl.LinkedNodeKind.binaryExpression,
+        _variantField_24 = binaryExpression_invokeType,
+        _variantField_6 = binaryExpression_leftOperand,
+        _variantField_15 = binaryExpression_element,
+        _variantField_7 = binaryExpression_rightOperand,
+        _variantField_16 = binaryExpression_operator,
+        _variantField_25 = expression_type;
+
+  LinkedNodeBuilder.functionExpressionInvocation({
+    LinkedNodeTypeBuilder invocationExpression_invokeType,
+    LinkedNodeBuilder functionExpressionInvocation_function,
+    LinkedNodeBuilder invocationExpression_typeArguments,
+    LinkedNodeTypeBuilder expression_type,
+    LinkedNodeBuilder invocationExpression_arguments,
+  })  : _kind = idl.LinkedNodeKind.functionExpressionInvocation,
+        _variantField_24 = invocationExpression_invokeType,
+        _variantField_6 = functionExpressionInvocation_function,
+        _variantField_12 = invocationExpression_typeArguments,
+        _variantField_25 = expression_type,
+        _variantField_14 = invocationExpression_arguments;
+
+  LinkedNodeBuilder.methodInvocation({
+    LinkedNodeTypeBuilder invocationExpression_invokeType,
+    LinkedNodeBuilder methodInvocation_methodName,
+    int methodInvocation_operator,
+    LinkedNodeBuilder methodInvocation_target,
+    LinkedNodeBuilder invocationExpression_typeArguments,
+    LinkedNodeTypeBuilder expression_type,
+    LinkedNodeBuilder invocationExpression_arguments,
+  })  : _kind = idl.LinkedNodeKind.methodInvocation,
+        _variantField_24 = invocationExpression_invokeType,
+        _variantField_6 = methodInvocation_methodName,
+        _variantField_15 = methodInvocation_operator,
+        _variantField_7 = methodInvocation_target,
+        _variantField_12 = invocationExpression_typeArguments,
+        _variantField_25 = expression_type,
+        _variantField_14 = invocationExpression_arguments;
+
+  LinkedNodeBuilder.typeName({
+    LinkedNodeTypeBuilder typeName_type,
+    LinkedNodeBuilder typeName_name,
+    int typeName_question,
+    LinkedNodeBuilder typeName_typeArguments,
+  })  : _kind = idl.LinkedNodeKind.typeName,
+        _variantField_24 = typeName_type,
+        _variantField_6 = typeName_name,
+        _variantField_15 = typeName_question,
+        _variantField_7 = typeName_typeArguments;
+
   LinkedNodeBuilder.adjacentStrings({
     List<LinkedNodeBuilder> adjacentStrings_strings,
     LinkedNodeTypeBuilder expression_type,
@@ -10259,6 +10439,7 @@
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder namedCompilationUnitMember_name,
+    bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.classDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
@@ -10275,7 +10456,8 @@
         _variantField_13 = classOrMixinDeclaration_typeParameters,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
+        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.classTypeAlias({
     LinkedNodeBuilder annotatedNode_comment,
@@ -10291,6 +10473,7 @@
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder namedCompilationUnitMember_name,
+    bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.classTypeAlias,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
@@ -10304,7 +10487,8 @@
         _variantField_9 = classTypeAlias_implementsClause,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
+        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.declaredIdentifier({
     LinkedNodeBuilder annotatedNode_comment,
@@ -10343,54 +10527,6 @@
         _variantField_16 = fieldDeclaration_semicolon,
         _variantField_17 = fieldDeclaration_staticKeyword;
 
-  LinkedNodeBuilder.functionDeclaration({
-    LinkedNodeBuilder annotatedNode_comment,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionDeclaration_functionExpression,
-    int functionDeclaration_externalKeyword,
-    LinkedNodeBuilder functionDeclaration_returnType,
-    int functionDeclaration_propertyKeyword,
-    LinkedNodeTypeBuilder functionDeclaration_returnType2,
-    int codeLength,
-    int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
-  })  : _kind = idl.LinkedNodeKind.functionDeclaration,
-        _variantField_11 = annotatedNode_comment,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionDeclaration_functionExpression,
-        _variantField_15 = functionDeclaration_externalKeyword,
-        _variantField_7 = functionDeclaration_returnType,
-        _variantField_16 = functionDeclaration_propertyKeyword,
-        _variantField_24 = functionDeclaration_returnType2,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
-
-  LinkedNodeBuilder.functionTypeAlias({
-    LinkedNodeBuilder annotatedNode_comment,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder functionTypeAlias_formalParameters,
-    LinkedNodeBuilder functionTypeAlias_returnType,
-    LinkedNodeBuilder functionTypeAlias_typeParameters,
-    int typeAlias_typedefKeyword,
-    int typeAlias_semicolon,
-    LinkedNodeTypeBuilder functionTypeAlias_returnType2,
-    int codeLength,
-    int codeOffset,
-    LinkedNodeBuilder namedCompilationUnitMember_name,
-  })  : _kind = idl.LinkedNodeKind.functionTypeAlias,
-        _variantField_11 = annotatedNode_comment,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = functionTypeAlias_formalParameters,
-        _variantField_7 = functionTypeAlias_returnType,
-        _variantField_8 = functionTypeAlias_typeParameters,
-        _variantField_18 = typeAlias_typedefKeyword,
-        _variantField_19 = typeAlias_semicolon,
-        _variantField_24 = functionTypeAlias_returnType2,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
-
   LinkedNodeBuilder.genericTypeAlias({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
@@ -10402,6 +10538,7 @@
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder namedCompilationUnitMember_name,
+    bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.genericTypeAlias,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
@@ -10412,7 +10549,8 @@
         _variantField_19 = typeAlias_semicolon,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
+        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.libraryDirective({
     LinkedNodeBuilder annotatedNode_comment,
@@ -10427,39 +10565,6 @@
         _variantField_18 = directive_keyword,
         _variantField_33 = directive_semicolon;
 
-  LinkedNodeBuilder.methodDeclaration({
-    LinkedNodeBuilder annotatedNode_comment,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder methodDeclaration_body,
-    int methodDeclaration_externalKeyword,
-    LinkedNodeBuilder methodDeclaration_formalParameters,
-    LinkedNodeBuilder methodDeclaration_returnType,
-    int methodDeclaration_modifierKeyword,
-    int methodDeclaration_operatorKeyword,
-    int methodDeclaration_propertyKeyword,
-    int methodDeclaration_actualProperty,
-    LinkedNodeTypeBuilder methodDeclaration_returnType2,
-    LinkedNodeBuilder methodDeclaration_typeParameters,
-    int codeLength,
-    int codeOffset,
-    LinkedNodeBuilder methodDeclaration_name,
-  })  : _kind = idl.LinkedNodeKind.methodDeclaration,
-        _variantField_11 = annotatedNode_comment,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = methodDeclaration_body,
-        _variantField_15 = methodDeclaration_externalKeyword,
-        _variantField_7 = methodDeclaration_formalParameters,
-        _variantField_8 = methodDeclaration_returnType,
-        _variantField_16 = methodDeclaration_modifierKeyword,
-        _variantField_17 = methodDeclaration_operatorKeyword,
-        _variantField_18 = methodDeclaration_propertyKeyword,
-        _variantField_19 = methodDeclaration_actualProperty,
-        _variantField_24 = methodDeclaration_returnType2,
-        _variantField_9 = methodDeclaration_typeParameters,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_10 = methodDeclaration_name;
-
   LinkedNodeBuilder.mixinDeclaration({
     LinkedNodeBuilder annotatedNode_comment,
     List<LinkedNodeBuilder> annotatedNode_metadata,
@@ -10473,6 +10578,7 @@
     int codeLength,
     int codeOffset,
     LinkedNodeBuilder namedCompilationUnitMember_name,
+    bool simplyBoundable_isSimplyBounded,
   })  : _kind = idl.LinkedNodeKind.mixinDeclaration,
         _variantField_11 = annotatedNode_comment,
         _variantField_4 = annotatedNode_metadata,
@@ -10485,7 +10591,8 @@
         _variantField_13 = classOrMixinDeclaration_typeParameters,
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset,
-        _variantField_14 = namedCompilationUnitMember_name;
+        _variantField_14 = namedCompilationUnitMember_name,
+        _variantField_31 = simplyBoundable_isSimplyBounded;
 
   LinkedNodeBuilder.partDirective({
     LinkedNodeBuilder annotatedNode_comment,
@@ -10553,112 +10660,6 @@
         _variantField_34 = codeLength,
         _variantField_33 = codeOffset;
 
-  LinkedNodeBuilder.variableDeclaration({
-    LinkedNodeBuilder annotatedNode_comment,
-    List<LinkedNodeBuilder> annotatedNode_metadata,
-    LinkedNodeBuilder variableDeclaration_initializer,
-    int variableDeclaration_equals,
-    LinkedNodeBuilder variableDeclaration_name,
-    LinkedNodeTypeBuilder variableDeclaration_type2,
-    int codeLength,
-    int codeOffset,
-    LinkedNodeVariablesDeclarationBuilder variableDeclaration_declaration,
-  })  : _kind = idl.LinkedNodeKind.variableDeclaration,
-        _variantField_11 = annotatedNode_comment,
-        _variantField_4 = annotatedNode_metadata,
-        _variantField_6 = variableDeclaration_initializer,
-        _variantField_15 = variableDeclaration_equals,
-        _variantField_7 = variableDeclaration_name,
-        _variantField_24 = variableDeclaration_type2,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_32 = variableDeclaration_declaration;
-
-  LinkedNodeBuilder.fieldFormalParameter({
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder fieldFormalParameter_type,
-    int fieldFormalParameter_keyword,
-    LinkedNodeBuilder fieldFormalParameter_typeParameters,
-    LinkedNodeBuilder fieldFormalParameter_formalParameters,
-    int fieldFormalParameter_period,
-    int fieldFormalParameter_thisKeyword,
-    int normalFormalParameter_covariantKeyword,
-    LinkedNodeTypeBuilder fieldFormalParameter_type2,
-    bool normalFormalParameter_isCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
-    int codeLength,
-    int codeOffset,
-    idl.LinkedNodeFormalParameterKind formalParameter_kind,
-    LinkedNodeBuilder normalFormalParameter_comment,
-  })  : _kind = idl.LinkedNodeKind.fieldFormalParameter,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = fieldFormalParameter_type,
-        _variantField_15 = fieldFormalParameter_keyword,
-        _variantField_7 = fieldFormalParameter_typeParameters,
-        _variantField_8 = fieldFormalParameter_formalParameters,
-        _variantField_16 = fieldFormalParameter_period,
-        _variantField_17 = fieldFormalParameter_thisKeyword,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
-        _variantField_24 = fieldFormalParameter_type2,
-        _variantField_27 = normalFormalParameter_isCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_26 = formalParameter_kind,
-        _variantField_14 = normalFormalParameter_comment;
-
-  LinkedNodeBuilder.functionTypedFormalParameter({
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder functionTypedFormalParameter_formalParameters,
-    LinkedNodeBuilder functionTypedFormalParameter_returnType,
-    LinkedNodeBuilder functionTypedFormalParameter_typeParameters,
-    int normalFormalParameter_covariantKeyword,
-    LinkedNodeTypeBuilder functionTypedFormalParameter_type2,
-    bool normalFormalParameter_isCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
-    int codeLength,
-    int codeOffset,
-    idl.LinkedNodeFormalParameterKind formalParameter_kind,
-    LinkedNodeBuilder normalFormalParameter_comment,
-  })  : _kind = idl.LinkedNodeKind.functionTypedFormalParameter,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = functionTypedFormalParameter_formalParameters,
-        _variantField_7 = functionTypedFormalParameter_returnType,
-        _variantField_8 = functionTypedFormalParameter_typeParameters,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
-        _variantField_24 = functionTypedFormalParameter_type2,
-        _variantField_27 = normalFormalParameter_isCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_26 = formalParameter_kind,
-        _variantField_14 = normalFormalParameter_comment;
-
-  LinkedNodeBuilder.simpleFormalParameter({
-    List<LinkedNodeBuilder> normalFormalParameter_metadata,
-    LinkedNodeBuilder simpleFormalParameter_type,
-    int simpleFormalParameter_keyword,
-    int normalFormalParameter_covariantKeyword,
-    LinkedNodeTypeBuilder simpleFormalParameter_type2,
-    bool normalFormalParameter_isCovariant,
-    LinkedNodeBuilder normalFormalParameter_identifier,
-    int codeLength,
-    int codeOffset,
-    idl.LinkedNodeFormalParameterKind formalParameter_kind,
-    LinkedNodeBuilder normalFormalParameter_comment,
-  })  : _kind = idl.LinkedNodeKind.simpleFormalParameter,
-        _variantField_4 = normalFormalParameter_metadata,
-        _variantField_6 = simpleFormalParameter_type,
-        _variantField_15 = simpleFormalParameter_keyword,
-        _variantField_19 = normalFormalParameter_covariantKeyword,
-        _variantField_24 = simpleFormalParameter_type2,
-        _variantField_27 = normalFormalParameter_isCovariant,
-        _variantField_12 = normalFormalParameter_identifier,
-        _variantField_34 = codeLength,
-        _variantField_33 = codeOffset,
-        _variantField_26 = formalParameter_kind,
-        _variantField_14 = normalFormalParameter_comment;
-
   LinkedNodeBuilder.switchCase({
     List<LinkedNodeBuilder> switchMember_statements,
     LinkedNodeBuilder switchCase_expression,
@@ -10761,21 +10762,6 @@
         _variantField_15 = awaitExpression_awaitKeyword,
         _variantField_25 = expression_type;
 
-  LinkedNodeBuilder.binaryExpression({
-    LinkedNodeBuilder binaryExpression_leftOperand,
-    int binaryExpression_element,
-    LinkedNodeBuilder binaryExpression_rightOperand,
-    int binaryExpression_operator,
-    LinkedNodeTypeBuilder binaryExpression_invokeType,
-    LinkedNodeTypeBuilder expression_type,
-  })  : _kind = idl.LinkedNodeKind.binaryExpression,
-        _variantField_6 = binaryExpression_leftOperand,
-        _variantField_15 = binaryExpression_element,
-        _variantField_7 = binaryExpression_rightOperand,
-        _variantField_16 = binaryExpression_operator,
-        _variantField_24 = binaryExpression_invokeType,
-        _variantField_25 = expression_type;
-
   LinkedNodeBuilder.blockFunctionBody({
     LinkedNodeBuilder blockFunctionBody_block,
     int blockFunctionBody_keyword,
@@ -11016,47 +11002,6 @@
   })  : _kind = idl.LinkedNodeKind.functionDeclarationStatement,
         _variantField_6 = functionDeclarationStatement_functionDeclaration;
 
-  LinkedNodeBuilder.functionExpression({
-    LinkedNodeBuilder functionExpression_body,
-    LinkedNodeBuilder functionExpression_formalParameters,
-    LinkedNodeBuilder functionExpression_typeParameters,
-    LinkedNodeTypeBuilder functionDeclaration_returnType2,
-  })  : _kind = idl.LinkedNodeKind.functionExpression,
-        _variantField_6 = functionExpression_body,
-        _variantField_7 = functionExpression_formalParameters,
-        _variantField_8 = functionExpression_typeParameters,
-        _variantField_24 = functionDeclaration_returnType2;
-
-  LinkedNodeBuilder.functionExpressionInvocation({
-    LinkedNodeBuilder functionExpressionInvocation_function,
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.functionExpressionInvocation,
-        _variantField_6 = functionExpressionInvocation_function,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
-  LinkedNodeBuilder.genericFunctionType({
-    LinkedNodeBuilder genericFunctionType_typeParameters,
-    int genericFunctionType_functionKeyword,
-    LinkedNodeBuilder genericFunctionType_returnType,
-    LinkedNodeBuilder genericFunctionType_formalParameters,
-    int genericFunctionType_question,
-    LinkedNodeTypeBuilder genericFunctionType_returnType2,
-    LinkedNodeTypeBuilder genericFunctionType_type,
-  })  : _kind = idl.LinkedNodeKind.genericFunctionType,
-        _variantField_6 = genericFunctionType_typeParameters,
-        _variantField_15 = genericFunctionType_functionKeyword,
-        _variantField_7 = genericFunctionType_returnType,
-        _variantField_8 = genericFunctionType_formalParameters,
-        _variantField_16 = genericFunctionType_question,
-        _variantField_24 = genericFunctionType_returnType2,
-        _variantField_25 = genericFunctionType_type;
-
   LinkedNodeBuilder.ifElement({
     LinkedNodeBuilder ifMixin_condition,
     int ifMixin_elseKeyword,
@@ -11159,23 +11104,6 @@
         _variantField_15 = mapLiteralEntry_separator,
         _variantField_7 = mapLiteralEntry_value;
 
-  LinkedNodeBuilder.methodInvocation({
-    LinkedNodeBuilder methodInvocation_methodName,
-    int methodInvocation_operator,
-    LinkedNodeBuilder methodInvocation_target,
-    LinkedNodeTypeBuilder invocationExpression_invokeType,
-    LinkedNodeBuilder invocationExpression_typeArguments,
-    LinkedNodeTypeBuilder expression_type,
-    LinkedNodeBuilder invocationExpression_arguments,
-  })  : _kind = idl.LinkedNodeKind.methodInvocation,
-        _variantField_6 = methodInvocation_methodName,
-        _variantField_15 = methodInvocation_operator,
-        _variantField_7 = methodInvocation_target,
-        _variantField_24 = invocationExpression_invokeType,
-        _variantField_12 = invocationExpression_typeArguments,
-        _variantField_25 = expression_type,
-        _variantField_14 = invocationExpression_arguments;
-
   LinkedNodeBuilder.namedExpression({
     LinkedNodeBuilder namedExpression_expression,
     LinkedNodeBuilder namedExpression_name,
@@ -11307,17 +11235,6 @@
         _variantField_15 = throwExpression_throwKeyword,
         _variantField_25 = expression_type;
 
-  LinkedNodeBuilder.typeName({
-    LinkedNodeBuilder typeName_name,
-    int typeName_question,
-    LinkedNodeBuilder typeName_typeArguments,
-    LinkedNodeTypeBuilder typeName_type,
-  })  : _kind = idl.LinkedNodeKind.typeName,
-        _variantField_6 = typeName_name,
-        _variantField_15 = typeName_question,
-        _variantField_7 = typeName_typeArguments,
-        _variantField_24 = typeName_type;
-
   LinkedNodeBuilder.variableDeclarationStatement({
     LinkedNodeBuilder variableDeclarationStatement_variables,
     int variableDeclarationStatement_semicolon,
@@ -11460,17 +11377,15 @@
         _variantField_28 = comment_tokens,
         _variantField_29 = comment_type;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
+    _variantField_24?.flushInformative();
     _variantField_2?.forEach((b) => b.flushInformative());
     _variantField_11?.flushInformative();
     _variantField_4?.forEach((b) => b.flushInformative());
     _variantField_6?.flushInformative();
     _variantField_7?.flushInformative();
     _variantField_8?.flushInformative();
-    _variantField_24?.flushInformative();
     _variantField_9?.flushInformative();
     _variantField_12?.flushInformative();
     _variantField_5?.forEach((b) => b.flushInformative());
@@ -11482,9 +11397,7 @@
     _variantField_32?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._kind == null ? 0 : this._kind.index);
     signature.addBool(this._isSynthetic == true);
@@ -11573,13 +11486,13 @@
   }
 
   fb.Offset finish(fb.Builder fbBuilder) {
+    fb.Offset offset_variantField_24;
     fb.Offset offset_variantField_2;
     fb.Offset offset_variantField_11;
     fb.Offset offset_variantField_4;
     fb.Offset offset_variantField_6;
     fb.Offset offset_variantField_7;
     fb.Offset offset_variantField_8;
-    fb.Offset offset_variantField_24;
     fb.Offset offset_variantField_9;
     fb.Offset offset_variantField_12;
     fb.Offset offset_variantField_5;
@@ -11594,6 +11507,9 @@
     fb.Offset offset_variantField_20;
     fb.Offset offset_variantField_22;
     fb.Offset offset_variantField_32;
+    if (_variantField_24 != null) {
+      offset_variantField_24 = _variantField_24.finish(fbBuilder);
+    }
     if (!(_variantField_2 == null || _variantField_2.isEmpty)) {
       offset_variantField_2 = fbBuilder
           .writeList(_variantField_2.map((b) => b.finish(fbBuilder)).toList());
@@ -11614,9 +11530,6 @@
     if (_variantField_8 != null) {
       offset_variantField_8 = _variantField_8.finish(fbBuilder);
     }
-    if (_variantField_24 != null) {
-      offset_variantField_24 = _variantField_24.finish(fbBuilder);
-    }
     if (_variantField_9 != null) {
       offset_variantField_9 = _variantField_9.finish(fbBuilder);
     }
@@ -11662,6 +11575,9 @@
       offset_variantField_32 = _variantField_32.finish(fbBuilder);
     }
     fbBuilder.startTable();
+    if (offset_variantField_24 != null) {
+      fbBuilder.addOffset(24, offset_variantField_24);
+    }
     if (offset_variantField_2 != null) {
       fbBuilder.addOffset(2, offset_variantField_2);
     }
@@ -11695,9 +11611,6 @@
     if (_variantField_19 != null && _variantField_19 != 0) {
       fbBuilder.addUint32(19, _variantField_19);
     }
-    if (offset_variantField_24 != null) {
-      fbBuilder.addOffset(24, offset_variantField_24);
-    }
     if (_variantField_27 == true) {
       fbBuilder.addBool(27, true);
     }
@@ -11789,6 +11702,7 @@
 
   _LinkedNodeImpl(this._bc, this._bcOffset);
 
+  idl.LinkedNodeType _variantField_24;
   List<idl.LinkedNode> _variantField_2;
   idl.LinkedNode _variantField_11;
   List<idl.LinkedNode> _variantField_4;
@@ -11800,7 +11714,6 @@
   int _variantField_17;
   int _variantField_18;
   int _variantField_19;
-  idl.LinkedNodeType _variantField_24;
   bool _variantField_27;
   idl.LinkedNode _variantField_9;
   idl.LinkedNode _variantField_12;
@@ -11826,6 +11739,54 @@
   idl.LinkedNodeVariablesDeclaration _variantField_32;
 
   @override
+  idl.LinkedNodeType get actualReturnType {
+    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
+        kind == idl.LinkedNodeKind.functionExpression ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericFunctionType ||
+        kind == idl.LinkedNodeKind.methodDeclaration);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
+  idl.LinkedNodeType get actualType {
+    assert(kind == idl.LinkedNodeKind.fieldFormalParameter ||
+        kind == idl.LinkedNodeKind.functionTypedFormalParameter ||
+        kind == idl.LinkedNodeKind.simpleFormalParameter ||
+        kind == idl.LinkedNodeKind.variableDeclaration);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
+  idl.LinkedNodeType get binaryExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.binaryExpression);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
+  idl.LinkedNodeType get invocationExpression_invokeType {
+    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
+        kind == idl.LinkedNodeKind.methodInvocation);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
+  idl.LinkedNodeType get typeName_type {
+    assert(kind == idl.LinkedNodeKind.typeName);
+    _variantField_24 ??=
+        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
+    return _variantField_24;
+  }
+
+  @override
   List<idl.LinkedNode> get adjacentStrings_strings {
     assert(kind == idl.LinkedNodeKind.adjacentStrings);
     _variantField_2 ??=
@@ -14867,96 +14828,6 @@
   }
 
   @override
-  idl.LinkedNodeType get binaryExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.binaryExpression);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get fieldFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.fieldFormalParameter);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get functionDeclaration_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionDeclaration ||
-        kind == idl.LinkedNodeKind.functionExpression);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get functionTypeAlias_returnType2 {
-    assert(kind == idl.LinkedNodeKind.functionTypeAlias);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get functionTypedFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.functionTypedFormalParameter);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get genericFunctionType_returnType2 {
-    assert(kind == idl.LinkedNodeKind.genericFunctionType);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get invocationExpression_invokeType {
-    assert(kind == idl.LinkedNodeKind.functionExpressionInvocation ||
-        kind == idl.LinkedNodeKind.methodInvocation);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get methodDeclaration_returnType2 {
-    assert(kind == idl.LinkedNodeKind.methodDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get simpleFormalParameter_type2 {
-    assert(kind == idl.LinkedNodeKind.simpleFormalParameter);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get typeName_type {
-    assert(kind == idl.LinkedNodeKind.typeName);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
-  idl.LinkedNodeType get variableDeclaration_type2 {
-    assert(kind == idl.LinkedNodeKind.variableDeclaration);
-    _variantField_24 ??=
-        const _LinkedNodeTypeReader().vTableGet(_bc, _bcOffset, 24, null);
-    return _variantField_24;
-  }
-
-  @override
   bool get booleanLiteral_value {
     assert(kind == idl.LinkedNodeKind.booleanLiteral);
     _variantField_27 ??=
@@ -15378,6 +15249,18 @@
   }
 
   @override
+  bool get simplyBoundable_isSimplyBounded {
+    assert(kind == idl.LinkedNodeKind.classDeclaration ||
+        kind == idl.LinkedNodeKind.classTypeAlias ||
+        kind == idl.LinkedNodeKind.functionTypeAlias ||
+        kind == idl.LinkedNodeKind.genericTypeAlias ||
+        kind == idl.LinkedNodeKind.mixinDeclaration);
+    _variantField_31 ??=
+        const fb.BoolReader().vTableGet(_bc, _bcOffset, 31, false);
+    return _variantField_31;
+  }
+
+  @override
   String get simpleStringLiteral_value {
     assert(kind == idl.LinkedNodeKind.simpleStringLiteral);
     _variantField_20 ??=
@@ -15411,6 +15294,322 @@
     if (isSynthetic != false) _result["isSynthetic"] = isSynthetic;
     if (kind != idl.LinkedNodeKind.adjacentStrings)
       _result["kind"] = kind.toString().split('.')[1];
+    if (kind == idl.LinkedNodeKind.functionDeclaration) {
+      if (actualReturnType != null)
+        _result["actualReturnType"] = actualReturnType.toJson();
+      if (annotatedNode_comment != null)
+        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
+      if (annotatedNode_metadata.isNotEmpty)
+        _result["annotatedNode_metadata"] =
+            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
+      if (functionDeclaration_functionExpression != null)
+        _result["functionDeclaration_functionExpression"] =
+            functionDeclaration_functionExpression.toJson();
+      if (functionDeclaration_externalKeyword != 0)
+        _result["functionDeclaration_externalKeyword"] =
+            functionDeclaration_externalKeyword;
+      if (functionDeclaration_returnType != null)
+        _result["functionDeclaration_returnType"] =
+            functionDeclaration_returnType.toJson();
+      if (functionDeclaration_propertyKeyword != 0)
+        _result["functionDeclaration_propertyKeyword"] =
+            functionDeclaration_propertyKeyword;
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (namedCompilationUnitMember_name != null)
+        _result["namedCompilationUnitMember_name"] =
+            namedCompilationUnitMember_name.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.functionExpression) {
+      if (actualReturnType != null)
+        _result["actualReturnType"] = actualReturnType.toJson();
+      if (functionExpression_body != null)
+        _result["functionExpression_body"] = functionExpression_body.toJson();
+      if (functionExpression_formalParameters != null)
+        _result["functionExpression_formalParameters"] =
+            functionExpression_formalParameters.toJson();
+      if (functionExpression_typeParameters != null)
+        _result["functionExpression_typeParameters"] =
+            functionExpression_typeParameters.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
+      if (actualReturnType != null)
+        _result["actualReturnType"] = actualReturnType.toJson();
+      if (annotatedNode_comment != null)
+        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
+      if (annotatedNode_metadata.isNotEmpty)
+        _result["annotatedNode_metadata"] =
+            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
+      if (functionTypeAlias_formalParameters != null)
+        _result["functionTypeAlias_formalParameters"] =
+            functionTypeAlias_formalParameters.toJson();
+      if (functionTypeAlias_returnType != null)
+        _result["functionTypeAlias_returnType"] =
+            functionTypeAlias_returnType.toJson();
+      if (functionTypeAlias_typeParameters != null)
+        _result["functionTypeAlias_typeParameters"] =
+            functionTypeAlias_typeParameters.toJson();
+      if (typeAlias_typedefKeyword != 0)
+        _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
+      if (typeAlias_semicolon != 0)
+        _result["typeAlias_semicolon"] = typeAlias_semicolon;
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (namedCompilationUnitMember_name != null)
+        _result["namedCompilationUnitMember_name"] =
+            namedCompilationUnitMember_name.toJson();
+      if (simplyBoundable_isSimplyBounded != false)
+        _result["simplyBoundable_isSimplyBounded"] =
+            simplyBoundable_isSimplyBounded;
+    }
+    if (kind == idl.LinkedNodeKind.genericFunctionType) {
+      if (actualReturnType != null)
+        _result["actualReturnType"] = actualReturnType.toJson();
+      if (genericFunctionType_typeParameters != null)
+        _result["genericFunctionType_typeParameters"] =
+            genericFunctionType_typeParameters.toJson();
+      if (genericFunctionType_functionKeyword != 0)
+        _result["genericFunctionType_functionKeyword"] =
+            genericFunctionType_functionKeyword;
+      if (genericFunctionType_returnType != null)
+        _result["genericFunctionType_returnType"] =
+            genericFunctionType_returnType.toJson();
+      if (genericFunctionType_formalParameters != null)
+        _result["genericFunctionType_formalParameters"] =
+            genericFunctionType_formalParameters.toJson();
+      if (genericFunctionType_question != 0)
+        _result["genericFunctionType_question"] = genericFunctionType_question;
+      if (genericFunctionType_type != null)
+        _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.methodDeclaration) {
+      if (actualReturnType != null)
+        _result["actualReturnType"] = actualReturnType.toJson();
+      if (annotatedNode_comment != null)
+        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
+      if (annotatedNode_metadata.isNotEmpty)
+        _result["annotatedNode_metadata"] =
+            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
+      if (methodDeclaration_body != null)
+        _result["methodDeclaration_body"] = methodDeclaration_body.toJson();
+      if (methodDeclaration_externalKeyword != 0)
+        _result["methodDeclaration_externalKeyword"] =
+            methodDeclaration_externalKeyword;
+      if (methodDeclaration_formalParameters != null)
+        _result["methodDeclaration_formalParameters"] =
+            methodDeclaration_formalParameters.toJson();
+      if (methodDeclaration_returnType != null)
+        _result["methodDeclaration_returnType"] =
+            methodDeclaration_returnType.toJson();
+      if (methodDeclaration_modifierKeyword != 0)
+        _result["methodDeclaration_modifierKeyword"] =
+            methodDeclaration_modifierKeyword;
+      if (methodDeclaration_operatorKeyword != 0)
+        _result["methodDeclaration_operatorKeyword"] =
+            methodDeclaration_operatorKeyword;
+      if (methodDeclaration_propertyKeyword != 0)
+        _result["methodDeclaration_propertyKeyword"] =
+            methodDeclaration_propertyKeyword;
+      if (methodDeclaration_actualProperty != 0)
+        _result["methodDeclaration_actualProperty"] =
+            methodDeclaration_actualProperty;
+      if (methodDeclaration_typeParameters != null)
+        _result["methodDeclaration_typeParameters"] =
+            methodDeclaration_typeParameters.toJson();
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (methodDeclaration_name != null)
+        _result["methodDeclaration_name"] = methodDeclaration_name.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
+      if (actualType != null) _result["actualType"] = actualType.toJson();
+      if (normalFormalParameter_metadata.isNotEmpty)
+        _result["normalFormalParameter_metadata"] =
+            normalFormalParameter_metadata
+                .map((_value) => _value.toJson())
+                .toList();
+      if (fieldFormalParameter_type != null)
+        _result["fieldFormalParameter_type"] =
+            fieldFormalParameter_type.toJson();
+      if (fieldFormalParameter_keyword != 0)
+        _result["fieldFormalParameter_keyword"] = fieldFormalParameter_keyword;
+      if (fieldFormalParameter_typeParameters != null)
+        _result["fieldFormalParameter_typeParameters"] =
+            fieldFormalParameter_typeParameters.toJson();
+      if (fieldFormalParameter_formalParameters != null)
+        _result["fieldFormalParameter_formalParameters"] =
+            fieldFormalParameter_formalParameters.toJson();
+      if (fieldFormalParameter_period != 0)
+        _result["fieldFormalParameter_period"] = fieldFormalParameter_period;
+      if (fieldFormalParameter_thisKeyword != 0)
+        _result["fieldFormalParameter_thisKeyword"] =
+            fieldFormalParameter_thisKeyword;
+      if (normalFormalParameter_covariantKeyword != 0)
+        _result["normalFormalParameter_covariantKeyword"] =
+            normalFormalParameter_covariantKeyword;
+      if (normalFormalParameter_isCovariant != false)
+        _result["normalFormalParameter_isCovariant"] =
+            normalFormalParameter_isCovariant;
+      if (normalFormalParameter_identifier != null)
+        _result["normalFormalParameter_identifier"] =
+            normalFormalParameter_identifier.toJson();
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
+        _result["formalParameter_kind"] =
+            formalParameter_kind.toString().split('.')[1];
+      if (normalFormalParameter_comment != null)
+        _result["normalFormalParameter_comment"] =
+            normalFormalParameter_comment.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
+      if (actualType != null) _result["actualType"] = actualType.toJson();
+      if (normalFormalParameter_metadata.isNotEmpty)
+        _result["normalFormalParameter_metadata"] =
+            normalFormalParameter_metadata
+                .map((_value) => _value.toJson())
+                .toList();
+      if (functionTypedFormalParameter_formalParameters != null)
+        _result["functionTypedFormalParameter_formalParameters"] =
+            functionTypedFormalParameter_formalParameters.toJson();
+      if (functionTypedFormalParameter_returnType != null)
+        _result["functionTypedFormalParameter_returnType"] =
+            functionTypedFormalParameter_returnType.toJson();
+      if (functionTypedFormalParameter_typeParameters != null)
+        _result["functionTypedFormalParameter_typeParameters"] =
+            functionTypedFormalParameter_typeParameters.toJson();
+      if (normalFormalParameter_covariantKeyword != 0)
+        _result["normalFormalParameter_covariantKeyword"] =
+            normalFormalParameter_covariantKeyword;
+      if (normalFormalParameter_isCovariant != false)
+        _result["normalFormalParameter_isCovariant"] =
+            normalFormalParameter_isCovariant;
+      if (normalFormalParameter_identifier != null)
+        _result["normalFormalParameter_identifier"] =
+            normalFormalParameter_identifier.toJson();
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
+        _result["formalParameter_kind"] =
+            formalParameter_kind.toString().split('.')[1];
+      if (normalFormalParameter_comment != null)
+        _result["normalFormalParameter_comment"] =
+            normalFormalParameter_comment.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
+      if (actualType != null) _result["actualType"] = actualType.toJson();
+      if (normalFormalParameter_metadata.isNotEmpty)
+        _result["normalFormalParameter_metadata"] =
+            normalFormalParameter_metadata
+                .map((_value) => _value.toJson())
+                .toList();
+      if (simpleFormalParameter_type != null)
+        _result["simpleFormalParameter_type"] =
+            simpleFormalParameter_type.toJson();
+      if (simpleFormalParameter_keyword != 0)
+        _result["simpleFormalParameter_keyword"] =
+            simpleFormalParameter_keyword;
+      if (normalFormalParameter_covariantKeyword != 0)
+        _result["normalFormalParameter_covariantKeyword"] =
+            normalFormalParameter_covariantKeyword;
+      if (normalFormalParameter_isCovariant != false)
+        _result["normalFormalParameter_isCovariant"] =
+            normalFormalParameter_isCovariant;
+      if (normalFormalParameter_identifier != null)
+        _result["normalFormalParameter_identifier"] =
+            normalFormalParameter_identifier.toJson();
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
+        _result["formalParameter_kind"] =
+            formalParameter_kind.toString().split('.')[1];
+      if (normalFormalParameter_comment != null)
+        _result["normalFormalParameter_comment"] =
+            normalFormalParameter_comment.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.variableDeclaration) {
+      if (actualType != null) _result["actualType"] = actualType.toJson();
+      if (annotatedNode_comment != null)
+        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
+      if (annotatedNode_metadata.isNotEmpty)
+        _result["annotatedNode_metadata"] =
+            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
+      if (variableDeclaration_initializer != null)
+        _result["variableDeclaration_initializer"] =
+            variableDeclaration_initializer.toJson();
+      if (variableDeclaration_equals != 0)
+        _result["variableDeclaration_equals"] = variableDeclaration_equals;
+      if (variableDeclaration_name != null)
+        _result["variableDeclaration_name"] = variableDeclaration_name.toJson();
+      if (codeLength != 0) _result["codeLength"] = codeLength;
+      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
+      if (variableDeclaration_declaration != null)
+        _result["variableDeclaration_declaration"] =
+            variableDeclaration_declaration.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.binaryExpression) {
+      if (binaryExpression_invokeType != null)
+        _result["binaryExpression_invokeType"] =
+            binaryExpression_invokeType.toJson();
+      if (binaryExpression_leftOperand != null)
+        _result["binaryExpression_leftOperand"] =
+            binaryExpression_leftOperand.toJson();
+      if (binaryExpression_element != 0)
+        _result["binaryExpression_element"] = binaryExpression_element;
+      if (binaryExpression_rightOperand != null)
+        _result["binaryExpression_rightOperand"] =
+            binaryExpression_rightOperand.toJson();
+      if (binaryExpression_operator != 0)
+        _result["binaryExpression_operator"] = binaryExpression_operator;
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
+      if (invocationExpression_invokeType != null)
+        _result["invocationExpression_invokeType"] =
+            invocationExpression_invokeType.toJson();
+      if (functionExpressionInvocation_function != null)
+        _result["functionExpressionInvocation_function"] =
+            functionExpressionInvocation_function.toJson();
+      if (invocationExpression_typeArguments != null)
+        _result["invocationExpression_typeArguments"] =
+            invocationExpression_typeArguments.toJson();
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+      if (invocationExpression_arguments != null)
+        _result["invocationExpression_arguments"] =
+            invocationExpression_arguments.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.methodInvocation) {
+      if (invocationExpression_invokeType != null)
+        _result["invocationExpression_invokeType"] =
+            invocationExpression_invokeType.toJson();
+      if (methodInvocation_methodName != null)
+        _result["methodInvocation_methodName"] =
+            methodInvocation_methodName.toJson();
+      if (methodInvocation_operator != 0)
+        _result["methodInvocation_operator"] = methodInvocation_operator;
+      if (methodInvocation_target != null)
+        _result["methodInvocation_target"] = methodInvocation_target.toJson();
+      if (invocationExpression_typeArguments != null)
+        _result["invocationExpression_typeArguments"] =
+            invocationExpression_typeArguments.toJson();
+      if (expression_type != null)
+        _result["expression_type"] = expression_type.toJson();
+      if (invocationExpression_arguments != null)
+        _result["invocationExpression_arguments"] =
+            invocationExpression_arguments.toJson();
+    }
+    if (kind == idl.LinkedNodeKind.typeName) {
+      if (typeName_type != null)
+        _result["typeName_type"] = typeName_type.toJson();
+      if (typeName_name != null)
+        _result["typeName_name"] = typeName_name.toJson();
+      if (typeName_question != 0)
+        _result["typeName_question"] = typeName_question;
+      if (typeName_typeArguments != null)
+        _result["typeName_typeArguments"] = typeName_typeArguments.toJson();
+    }
     if (kind == idl.LinkedNodeKind.adjacentStrings) {
       if (adjacentStrings_strings.isNotEmpty)
         _result["adjacentStrings_strings"] =
@@ -15841,6 +16040,9 @@
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
+      if (simplyBoundable_isSimplyBounded != false)
+        _result["simplyBoundable_isSimplyBounded"] =
+            simplyBoundable_isSimplyBounded;
     }
     if (kind == idl.LinkedNodeKind.classTypeAlias) {
       if (annotatedNode_comment != null)
@@ -15874,6 +16076,9 @@
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
+      if (simplyBoundable_isSimplyBounded != false)
+        _result["simplyBoundable_isSimplyBounded"] =
+            simplyBoundable_isSimplyBounded;
     }
     if (kind == idl.LinkedNodeKind.declaredIdentifier) {
       if (annotatedNode_comment != null)
@@ -15916,61 +16121,6 @@
         _result["fieldDeclaration_staticKeyword"] =
             fieldDeclaration_staticKeyword;
     }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      if (annotatedNode_comment != null)
-        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
-      if (annotatedNode_metadata.isNotEmpty)
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (functionDeclaration_functionExpression != null)
-        _result["functionDeclaration_functionExpression"] =
-            functionDeclaration_functionExpression.toJson();
-      if (functionDeclaration_externalKeyword != 0)
-        _result["functionDeclaration_externalKeyword"] =
-            functionDeclaration_externalKeyword;
-      if (functionDeclaration_returnType != null)
-        _result["functionDeclaration_returnType"] =
-            functionDeclaration_returnType.toJson();
-      if (functionDeclaration_propertyKeyword != 0)
-        _result["functionDeclaration_propertyKeyword"] =
-            functionDeclaration_propertyKeyword;
-      if (functionDeclaration_returnType2 != null)
-        _result["functionDeclaration_returnType2"] =
-            functionDeclaration_returnType2.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      if (annotatedNode_comment != null)
-        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
-      if (annotatedNode_metadata.isNotEmpty)
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (functionTypeAlias_formalParameters != null)
-        _result["functionTypeAlias_formalParameters"] =
-            functionTypeAlias_formalParameters.toJson();
-      if (functionTypeAlias_returnType != null)
-        _result["functionTypeAlias_returnType"] =
-            functionTypeAlias_returnType.toJson();
-      if (functionTypeAlias_typeParameters != null)
-        _result["functionTypeAlias_typeParameters"] =
-            functionTypeAlias_typeParameters.toJson();
-      if (typeAlias_typedefKeyword != 0)
-        _result["typeAlias_typedefKeyword"] = typeAlias_typedefKeyword;
-      if (typeAlias_semicolon != 0)
-        _result["typeAlias_semicolon"] = typeAlias_semicolon;
-      if (functionTypeAlias_returnType2 != null)
-        _result["functionTypeAlias_returnType2"] =
-            functionTypeAlias_returnType2.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (namedCompilationUnitMember_name != null)
-        _result["namedCompilationUnitMember_name"] =
-            namedCompilationUnitMember_name.toJson();
-    }
     if (kind == idl.LinkedNodeKind.genericTypeAlias) {
       if (annotatedNode_comment != null)
         _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
@@ -15994,6 +16144,9 @@
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
+      if (simplyBoundable_isSimplyBounded != false)
+        _result["simplyBoundable_isSimplyBounded"] =
+            simplyBoundable_isSimplyBounded;
     }
     if (kind == idl.LinkedNodeKind.libraryDirective) {
       if (annotatedNode_comment != null)
@@ -16008,46 +16161,6 @@
       if (directive_semicolon != 0)
         _result["directive_semicolon"] = directive_semicolon;
     }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      if (annotatedNode_comment != null)
-        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
-      if (annotatedNode_metadata.isNotEmpty)
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (methodDeclaration_body != null)
-        _result["methodDeclaration_body"] = methodDeclaration_body.toJson();
-      if (methodDeclaration_externalKeyword != 0)
-        _result["methodDeclaration_externalKeyword"] =
-            methodDeclaration_externalKeyword;
-      if (methodDeclaration_formalParameters != null)
-        _result["methodDeclaration_formalParameters"] =
-            methodDeclaration_formalParameters.toJson();
-      if (methodDeclaration_returnType != null)
-        _result["methodDeclaration_returnType"] =
-            methodDeclaration_returnType.toJson();
-      if (methodDeclaration_modifierKeyword != 0)
-        _result["methodDeclaration_modifierKeyword"] =
-            methodDeclaration_modifierKeyword;
-      if (methodDeclaration_operatorKeyword != 0)
-        _result["methodDeclaration_operatorKeyword"] =
-            methodDeclaration_operatorKeyword;
-      if (methodDeclaration_propertyKeyword != 0)
-        _result["methodDeclaration_propertyKeyword"] =
-            methodDeclaration_propertyKeyword;
-      if (methodDeclaration_actualProperty != 0)
-        _result["methodDeclaration_actualProperty"] =
-            methodDeclaration_actualProperty;
-      if (methodDeclaration_returnType2 != null)
-        _result["methodDeclaration_returnType2"] =
-            methodDeclaration_returnType2.toJson();
-      if (methodDeclaration_typeParameters != null)
-        _result["methodDeclaration_typeParameters"] =
-            methodDeclaration_typeParameters.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (methodDeclaration_name != null)
-        _result["methodDeclaration_name"] = methodDeclaration_name.toJson();
-    }
     if (kind == idl.LinkedNodeKind.mixinDeclaration) {
       if (annotatedNode_comment != null)
         _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
@@ -16082,6 +16195,9 @@
       if (namedCompilationUnitMember_name != null)
         _result["namedCompilationUnitMember_name"] =
             namedCompilationUnitMember_name.toJson();
+      if (simplyBoundable_isSimplyBounded != false)
+        _result["simplyBoundable_isSimplyBounded"] =
+            simplyBoundable_isSimplyBounded;
     }
     if (kind == idl.LinkedNodeKind.partDirective) {
       if (annotatedNode_comment != null)
@@ -16152,140 +16268,6 @@
       if (codeLength != 0) _result["codeLength"] = codeLength;
       if (codeOffset != 0) _result["codeOffset"] = codeOffset;
     }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      if (annotatedNode_comment != null)
-        _result["annotatedNode_comment"] = annotatedNode_comment.toJson();
-      if (annotatedNode_metadata.isNotEmpty)
-        _result["annotatedNode_metadata"] =
-            annotatedNode_metadata.map((_value) => _value.toJson()).toList();
-      if (variableDeclaration_initializer != null)
-        _result["variableDeclaration_initializer"] =
-            variableDeclaration_initializer.toJson();
-      if (variableDeclaration_equals != 0)
-        _result["variableDeclaration_equals"] = variableDeclaration_equals;
-      if (variableDeclaration_name != null)
-        _result["variableDeclaration_name"] = variableDeclaration_name.toJson();
-      if (variableDeclaration_type2 != null)
-        _result["variableDeclaration_type2"] =
-            variableDeclaration_type2.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (variableDeclaration_declaration != null)
-        _result["variableDeclaration_declaration"] =
-            variableDeclaration_declaration.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      if (normalFormalParameter_metadata.isNotEmpty)
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      if (fieldFormalParameter_type != null)
-        _result["fieldFormalParameter_type"] =
-            fieldFormalParameter_type.toJson();
-      if (fieldFormalParameter_keyword != 0)
-        _result["fieldFormalParameter_keyword"] = fieldFormalParameter_keyword;
-      if (fieldFormalParameter_typeParameters != null)
-        _result["fieldFormalParameter_typeParameters"] =
-            fieldFormalParameter_typeParameters.toJson();
-      if (fieldFormalParameter_formalParameters != null)
-        _result["fieldFormalParameter_formalParameters"] =
-            fieldFormalParameter_formalParameters.toJson();
-      if (fieldFormalParameter_period != 0)
-        _result["fieldFormalParameter_period"] = fieldFormalParameter_period;
-      if (fieldFormalParameter_thisKeyword != 0)
-        _result["fieldFormalParameter_thisKeyword"] =
-            fieldFormalParameter_thisKeyword;
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
-      if (fieldFormalParameter_type2 != null)
-        _result["fieldFormalParameter_type2"] =
-            fieldFormalParameter_type2.toJson();
-      if (normalFormalParameter_isCovariant != false)
-        _result["normalFormalParameter_isCovariant"] =
-            normalFormalParameter_isCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
-        _result["formalParameter_kind"] =
-            formalParameter_kind.toString().split('.')[1];
-      if (normalFormalParameter_comment != null)
-        _result["normalFormalParameter_comment"] =
-            normalFormalParameter_comment.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      if (normalFormalParameter_metadata.isNotEmpty)
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      if (functionTypedFormalParameter_formalParameters != null)
-        _result["functionTypedFormalParameter_formalParameters"] =
-            functionTypedFormalParameter_formalParameters.toJson();
-      if (functionTypedFormalParameter_returnType != null)
-        _result["functionTypedFormalParameter_returnType"] =
-            functionTypedFormalParameter_returnType.toJson();
-      if (functionTypedFormalParameter_typeParameters != null)
-        _result["functionTypedFormalParameter_typeParameters"] =
-            functionTypedFormalParameter_typeParameters.toJson();
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
-      if (functionTypedFormalParameter_type2 != null)
-        _result["functionTypedFormalParameter_type2"] =
-            functionTypedFormalParameter_type2.toJson();
-      if (normalFormalParameter_isCovariant != false)
-        _result["normalFormalParameter_isCovariant"] =
-            normalFormalParameter_isCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
-        _result["formalParameter_kind"] =
-            formalParameter_kind.toString().split('.')[1];
-      if (normalFormalParameter_comment != null)
-        _result["normalFormalParameter_comment"] =
-            normalFormalParameter_comment.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      if (normalFormalParameter_metadata.isNotEmpty)
-        _result["normalFormalParameter_metadata"] =
-            normalFormalParameter_metadata
-                .map((_value) => _value.toJson())
-                .toList();
-      if (simpleFormalParameter_type != null)
-        _result["simpleFormalParameter_type"] =
-            simpleFormalParameter_type.toJson();
-      if (simpleFormalParameter_keyword != 0)
-        _result["simpleFormalParameter_keyword"] =
-            simpleFormalParameter_keyword;
-      if (normalFormalParameter_covariantKeyword != 0)
-        _result["normalFormalParameter_covariantKeyword"] =
-            normalFormalParameter_covariantKeyword;
-      if (simpleFormalParameter_type2 != null)
-        _result["simpleFormalParameter_type2"] =
-            simpleFormalParameter_type2.toJson();
-      if (normalFormalParameter_isCovariant != false)
-        _result["normalFormalParameter_isCovariant"] =
-            normalFormalParameter_isCovariant;
-      if (normalFormalParameter_identifier != null)
-        _result["normalFormalParameter_identifier"] =
-            normalFormalParameter_identifier.toJson();
-      if (codeLength != 0) _result["codeLength"] = codeLength;
-      if (codeOffset != 0) _result["codeOffset"] = codeOffset;
-      if (formalParameter_kind != idl.LinkedNodeFormalParameterKind.required)
-        _result["formalParameter_kind"] =
-            formalParameter_kind.toString().split('.')[1];
-      if (normalFormalParameter_comment != null)
-        _result["normalFormalParameter_comment"] =
-            normalFormalParameter_comment.toJson();
-    }
     if (kind == idl.LinkedNodeKind.switchCase) {
       if (switchMember_statements.isNotEmpty)
         _result["switchMember_statements"] =
@@ -16398,23 +16380,6 @@
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      if (binaryExpression_leftOperand != null)
-        _result["binaryExpression_leftOperand"] =
-            binaryExpression_leftOperand.toJson();
-      if (binaryExpression_element != 0)
-        _result["binaryExpression_element"] = binaryExpression_element;
-      if (binaryExpression_rightOperand != null)
-        _result["binaryExpression_rightOperand"] =
-            binaryExpression_rightOperand.toJson();
-      if (binaryExpression_operator != 0)
-        _result["binaryExpression_operator"] = binaryExpression_operator;
-      if (binaryExpression_invokeType != null)
-        _result["binaryExpression_invokeType"] =
-            binaryExpression_invokeType.toJson();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-    }
     if (kind == idl.LinkedNodeKind.blockFunctionBody) {
       if (blockFunctionBody_block != null)
         _result["blockFunctionBody_block"] = blockFunctionBody_block.toJson();
@@ -16664,56 +16629,6 @@
         _result["functionDeclarationStatement_functionDeclaration"] =
             functionDeclarationStatement_functionDeclaration.toJson();
     }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      if (functionExpression_body != null)
-        _result["functionExpression_body"] = functionExpression_body.toJson();
-      if (functionExpression_formalParameters != null)
-        _result["functionExpression_formalParameters"] =
-            functionExpression_formalParameters.toJson();
-      if (functionExpression_typeParameters != null)
-        _result["functionExpression_typeParameters"] =
-            functionExpression_typeParameters.toJson();
-      if (functionDeclaration_returnType2 != null)
-        _result["functionDeclaration_returnType2"] =
-            functionDeclaration_returnType2.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      if (functionExpressionInvocation_function != null)
-        _result["functionExpressionInvocation_function"] =
-            functionExpressionInvocation_function.toJson();
-      if (invocationExpression_invokeType != null)
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      if (invocationExpression_typeArguments != null)
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-      if (invocationExpression_arguments != null)
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      if (genericFunctionType_typeParameters != null)
-        _result["genericFunctionType_typeParameters"] =
-            genericFunctionType_typeParameters.toJson();
-      if (genericFunctionType_functionKeyword != 0)
-        _result["genericFunctionType_functionKeyword"] =
-            genericFunctionType_functionKeyword;
-      if (genericFunctionType_returnType != null)
-        _result["genericFunctionType_returnType"] =
-            genericFunctionType_returnType.toJson();
-      if (genericFunctionType_formalParameters != null)
-        _result["genericFunctionType_formalParameters"] =
-            genericFunctionType_formalParameters.toJson();
-      if (genericFunctionType_question != 0)
-        _result["genericFunctionType_question"] = genericFunctionType_question;
-      if (genericFunctionType_returnType2 != null)
-        _result["genericFunctionType_returnType2"] =
-            genericFunctionType_returnType2.toJson();
-      if (genericFunctionType_type != null)
-        _result["genericFunctionType_type"] = genericFunctionType_type.toJson();
-    }
     if (kind == idl.LinkedNodeKind.ifElement) {
       if (ifMixin_condition != null)
         _result["ifMixin_condition"] = ifMixin_condition.toJson();
@@ -16815,26 +16730,6 @@
       if (mapLiteralEntry_value != null)
         _result["mapLiteralEntry_value"] = mapLiteralEntry_value.toJson();
     }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      if (methodInvocation_methodName != null)
-        _result["methodInvocation_methodName"] =
-            methodInvocation_methodName.toJson();
-      if (methodInvocation_operator != 0)
-        _result["methodInvocation_operator"] = methodInvocation_operator;
-      if (methodInvocation_target != null)
-        _result["methodInvocation_target"] = methodInvocation_target.toJson();
-      if (invocationExpression_invokeType != null)
-        _result["invocationExpression_invokeType"] =
-            invocationExpression_invokeType.toJson();
-      if (invocationExpression_typeArguments != null)
-        _result["invocationExpression_typeArguments"] =
-            invocationExpression_typeArguments.toJson();
-      if (expression_type != null)
-        _result["expression_type"] = expression_type.toJson();
-      if (invocationExpression_arguments != null)
-        _result["invocationExpression_arguments"] =
-            invocationExpression_arguments.toJson();
-    }
     if (kind == idl.LinkedNodeKind.namedExpression) {
       if (namedExpression_expression != null)
         _result["namedExpression_expression"] =
@@ -16976,16 +16871,6 @@
       if (expression_type != null)
         _result["expression_type"] = expression_type.toJson();
     }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      if (typeName_name != null)
-        _result["typeName_name"] = typeName_name.toJson();
-      if (typeName_question != 0)
-        _result["typeName_question"] = typeName_question;
-      if (typeName_typeArguments != null)
-        _result["typeName_typeArguments"] = typeName_typeArguments.toJson();
-      if (typeName_type != null)
-        _result["typeName_type"] = typeName_type.toJson();
-    }
     if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
       if (variableDeclarationStatement_variables != null)
         _result["variableDeclarationStatement_variables"] =
@@ -17122,6 +17007,221 @@
 
   @override
   Map<String, Object> toMap() {
+    if (kind == idl.LinkedNodeKind.functionDeclaration) {
+      return {
+        "actualReturnType": actualReturnType,
+        "annotatedNode_comment": annotatedNode_comment,
+        "annotatedNode_metadata": annotatedNode_metadata,
+        "functionDeclaration_functionExpression":
+            functionDeclaration_functionExpression,
+        "functionDeclaration_externalKeyword":
+            functionDeclaration_externalKeyword,
+        "functionDeclaration_returnType": functionDeclaration_returnType,
+        "functionDeclaration_propertyKeyword":
+            functionDeclaration_propertyKeyword,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.functionExpression) {
+      return {
+        "actualReturnType": actualReturnType,
+        "functionExpression_body": functionExpression_body,
+        "functionExpression_formalParameters":
+            functionExpression_formalParameters,
+        "functionExpression_typeParameters": functionExpression_typeParameters,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
+      return {
+        "actualReturnType": actualReturnType,
+        "annotatedNode_comment": annotatedNode_comment,
+        "annotatedNode_metadata": annotatedNode_metadata,
+        "functionTypeAlias_formalParameters":
+            functionTypeAlias_formalParameters,
+        "functionTypeAlias_returnType": functionTypeAlias_returnType,
+        "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
+        "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
+        "typeAlias_semicolon": typeAlias_semicolon,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.genericFunctionType) {
+      return {
+        "actualReturnType": actualReturnType,
+        "genericFunctionType_typeParameters":
+            genericFunctionType_typeParameters,
+        "genericFunctionType_functionKeyword":
+            genericFunctionType_functionKeyword,
+        "genericFunctionType_returnType": genericFunctionType_returnType,
+        "genericFunctionType_formalParameters":
+            genericFunctionType_formalParameters,
+        "genericFunctionType_question": genericFunctionType_question,
+        "genericFunctionType_type": genericFunctionType_type,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.methodDeclaration) {
+      return {
+        "actualReturnType": actualReturnType,
+        "annotatedNode_comment": annotatedNode_comment,
+        "annotatedNode_metadata": annotatedNode_metadata,
+        "methodDeclaration_body": methodDeclaration_body,
+        "methodDeclaration_externalKeyword": methodDeclaration_externalKeyword,
+        "methodDeclaration_formalParameters":
+            methodDeclaration_formalParameters,
+        "methodDeclaration_returnType": methodDeclaration_returnType,
+        "methodDeclaration_modifierKeyword": methodDeclaration_modifierKeyword,
+        "methodDeclaration_operatorKeyword": methodDeclaration_operatorKeyword,
+        "methodDeclaration_propertyKeyword": methodDeclaration_propertyKeyword,
+        "methodDeclaration_actualProperty": methodDeclaration_actualProperty,
+        "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "methodDeclaration_name": methodDeclaration_name,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
+      return {
+        "actualType": actualType,
+        "normalFormalParameter_metadata": normalFormalParameter_metadata,
+        "fieldFormalParameter_type": fieldFormalParameter_type,
+        "fieldFormalParameter_keyword": fieldFormalParameter_keyword,
+        "fieldFormalParameter_typeParameters":
+            fieldFormalParameter_typeParameters,
+        "fieldFormalParameter_formalParameters":
+            fieldFormalParameter_formalParameters,
+        "fieldFormalParameter_period": fieldFormalParameter_period,
+        "fieldFormalParameter_thisKeyword": fieldFormalParameter_thisKeyword,
+        "normalFormalParameter_covariantKeyword":
+            normalFormalParameter_covariantKeyword,
+        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
+        "normalFormalParameter_identifier": normalFormalParameter_identifier,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "formalParameter_kind": formalParameter_kind,
+        "normalFormalParameter_comment": normalFormalParameter_comment,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
+      return {
+        "actualType": actualType,
+        "normalFormalParameter_metadata": normalFormalParameter_metadata,
+        "functionTypedFormalParameter_formalParameters":
+            functionTypedFormalParameter_formalParameters,
+        "functionTypedFormalParameter_returnType":
+            functionTypedFormalParameter_returnType,
+        "functionTypedFormalParameter_typeParameters":
+            functionTypedFormalParameter_typeParameters,
+        "normalFormalParameter_covariantKeyword":
+            normalFormalParameter_covariantKeyword,
+        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
+        "normalFormalParameter_identifier": normalFormalParameter_identifier,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "formalParameter_kind": formalParameter_kind,
+        "normalFormalParameter_comment": normalFormalParameter_comment,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
+      return {
+        "actualType": actualType,
+        "normalFormalParameter_metadata": normalFormalParameter_metadata,
+        "simpleFormalParameter_type": simpleFormalParameter_type,
+        "simpleFormalParameter_keyword": simpleFormalParameter_keyword,
+        "normalFormalParameter_covariantKeyword":
+            normalFormalParameter_covariantKeyword,
+        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
+        "normalFormalParameter_identifier": normalFormalParameter_identifier,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "formalParameter_kind": formalParameter_kind,
+        "normalFormalParameter_comment": normalFormalParameter_comment,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.variableDeclaration) {
+      return {
+        "actualType": actualType,
+        "annotatedNode_comment": annotatedNode_comment,
+        "annotatedNode_metadata": annotatedNode_metadata,
+        "variableDeclaration_initializer": variableDeclaration_initializer,
+        "variableDeclaration_equals": variableDeclaration_equals,
+        "variableDeclaration_name": variableDeclaration_name,
+        "codeLength": codeLength,
+        "codeOffset": codeOffset,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+        "variableDeclaration_declaration": variableDeclaration_declaration,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.binaryExpression) {
+      return {
+        "binaryExpression_invokeType": binaryExpression_invokeType,
+        "binaryExpression_leftOperand": binaryExpression_leftOperand,
+        "binaryExpression_element": binaryExpression_element,
+        "binaryExpression_rightOperand": binaryExpression_rightOperand,
+        "binaryExpression_operator": binaryExpression_operator,
+        "expression_type": expression_type,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
+      return {
+        "invocationExpression_invokeType": invocationExpression_invokeType,
+        "functionExpressionInvocation_function":
+            functionExpressionInvocation_function,
+        "invocationExpression_typeArguments":
+            invocationExpression_typeArguments,
+        "expression_type": expression_type,
+        "invocationExpression_arguments": invocationExpression_arguments,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.methodInvocation) {
+      return {
+        "invocationExpression_invokeType": invocationExpression_invokeType,
+        "methodInvocation_methodName": methodInvocation_methodName,
+        "methodInvocation_operator": methodInvocation_operator,
+        "methodInvocation_target": methodInvocation_target,
+        "invocationExpression_typeArguments":
+            invocationExpression_typeArguments,
+        "expression_type": expression_type,
+        "invocationExpression_arguments": invocationExpression_arguments,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
+    if (kind == idl.LinkedNodeKind.typeName) {
+      return {
+        "typeName_type": typeName_type,
+        "typeName_name": typeName_name,
+        "typeName_question": typeName_question,
+        "typeName_typeArguments": typeName_typeArguments,
+        "isSynthetic": isSynthetic,
+        "kind": kind,
+      };
+    }
     if (kind == idl.LinkedNodeKind.adjacentStrings) {
       return {
         "adjacentStrings_strings": adjacentStrings_strings,
@@ -17434,6 +17534,7 @@
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
+        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
     if (kind == idl.LinkedNodeKind.classTypeAlias) {
@@ -17453,6 +17554,7 @@
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
+        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
     if (kind == idl.LinkedNodeKind.declaredIdentifier) {
@@ -17487,43 +17589,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.functionDeclaration) {
-      return {
-        "annotatedNode_comment": annotatedNode_comment,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionDeclaration_functionExpression":
-            functionDeclaration_functionExpression,
-        "functionDeclaration_externalKeyword":
-            functionDeclaration_externalKeyword,
-        "functionDeclaration_returnType": functionDeclaration_returnType,
-        "functionDeclaration_propertyKeyword":
-            functionDeclaration_propertyKeyword,
-        "functionDeclaration_returnType2": functionDeclaration_returnType2,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypeAlias) {
-      return {
-        "annotatedNode_comment": annotatedNode_comment,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "functionTypeAlias_formalParameters":
-            functionTypeAlias_formalParameters,
-        "functionTypeAlias_returnType": functionTypeAlias_returnType,
-        "functionTypeAlias_typeParameters": functionTypeAlias_typeParameters,
-        "typeAlias_typedefKeyword": typeAlias_typedefKeyword,
-        "typeAlias_semicolon": typeAlias_semicolon,
-        "functionTypeAlias_returnType2": functionTypeAlias_returnType2,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.genericTypeAlias) {
       return {
         "annotatedNode_comment": annotatedNode_comment,
@@ -17538,6 +17603,7 @@
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
+        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
     if (kind == idl.LinkedNodeKind.libraryDirective) {
@@ -17551,28 +17617,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.methodDeclaration) {
-      return {
-        "annotatedNode_comment": annotatedNode_comment,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "methodDeclaration_body": methodDeclaration_body,
-        "methodDeclaration_externalKeyword": methodDeclaration_externalKeyword,
-        "methodDeclaration_formalParameters":
-            methodDeclaration_formalParameters,
-        "methodDeclaration_returnType": methodDeclaration_returnType,
-        "methodDeclaration_modifierKeyword": methodDeclaration_modifierKeyword,
-        "methodDeclaration_operatorKeyword": methodDeclaration_operatorKeyword,
-        "methodDeclaration_propertyKeyword": methodDeclaration_propertyKeyword,
-        "methodDeclaration_actualProperty": methodDeclaration_actualProperty,
-        "methodDeclaration_returnType2": methodDeclaration_returnType2,
-        "methodDeclaration_typeParameters": methodDeclaration_typeParameters,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "methodDeclaration_name": methodDeclaration_name,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.mixinDeclaration) {
       return {
         "annotatedNode_comment": annotatedNode_comment,
@@ -17593,6 +17637,7 @@
         "namedCompilationUnitMember_name": namedCompilationUnitMember_name,
         "isSynthetic": isSynthetic,
         "kind": kind,
+        "simplyBoundable_isSimplyBounded": simplyBoundable_isSimplyBounded,
       };
     }
     if (kind == idl.LinkedNodeKind.partDirective) {
@@ -17650,86 +17695,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.variableDeclaration) {
-      return {
-        "annotatedNode_comment": annotatedNode_comment,
-        "annotatedNode_metadata": annotatedNode_metadata,
-        "variableDeclaration_initializer": variableDeclaration_initializer,
-        "variableDeclaration_equals": variableDeclaration_equals,
-        "variableDeclaration_name": variableDeclaration_name,
-        "variableDeclaration_type2": variableDeclaration_type2,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-        "variableDeclaration_declaration": variableDeclaration_declaration,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.fieldFormalParameter) {
-      return {
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "fieldFormalParameter_type": fieldFormalParameter_type,
-        "fieldFormalParameter_keyword": fieldFormalParameter_keyword,
-        "fieldFormalParameter_typeParameters":
-            fieldFormalParameter_typeParameters,
-        "fieldFormalParameter_formalParameters":
-            fieldFormalParameter_formalParameters,
-        "fieldFormalParameter_period": fieldFormalParameter_period,
-        "fieldFormalParameter_thisKeyword": fieldFormalParameter_thisKeyword,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
-        "fieldFormalParameter_type2": fieldFormalParameter_type2,
-        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "formalParameter_kind": formalParameter_kind,
-        "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionTypedFormalParameter) {
-      return {
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "functionTypedFormalParameter_formalParameters":
-            functionTypedFormalParameter_formalParameters,
-        "functionTypedFormalParameter_returnType":
-            functionTypedFormalParameter_returnType,
-        "functionTypedFormalParameter_typeParameters":
-            functionTypedFormalParameter_typeParameters,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
-        "functionTypedFormalParameter_type2":
-            functionTypedFormalParameter_type2,
-        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "formalParameter_kind": formalParameter_kind,
-        "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.simpleFormalParameter) {
-      return {
-        "normalFormalParameter_metadata": normalFormalParameter_metadata,
-        "simpleFormalParameter_type": simpleFormalParameter_type,
-        "simpleFormalParameter_keyword": simpleFormalParameter_keyword,
-        "normalFormalParameter_covariantKeyword":
-            normalFormalParameter_covariantKeyword,
-        "simpleFormalParameter_type2": simpleFormalParameter_type2,
-        "normalFormalParameter_isCovariant": normalFormalParameter_isCovariant,
-        "normalFormalParameter_identifier": normalFormalParameter_identifier,
-        "codeLength": codeLength,
-        "codeOffset": codeOffset,
-        "formalParameter_kind": formalParameter_kind,
-        "normalFormalParameter_comment": normalFormalParameter_comment,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.switchCase) {
       return {
         "switchMember_statements": switchMember_statements,
@@ -17819,18 +17784,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.binaryExpression) {
-      return {
-        "binaryExpression_leftOperand": binaryExpression_leftOperand,
-        "binaryExpression_element": binaryExpression_element,
-        "binaryExpression_rightOperand": binaryExpression_rightOperand,
-        "binaryExpression_operator": binaryExpression_operator,
-        "binaryExpression_invokeType": binaryExpression_invokeType,
-        "expression_type": expression_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.blockFunctionBody) {
       return {
         "blockFunctionBody_block": blockFunctionBody_block,
@@ -18054,46 +18007,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.functionExpression) {
-      return {
-        "functionExpression_body": functionExpression_body,
-        "functionExpression_formalParameters":
-            functionExpression_formalParameters,
-        "functionExpression_typeParameters": functionExpression_typeParameters,
-        "functionDeclaration_returnType2": functionDeclaration_returnType2,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.functionExpressionInvocation) {
-      return {
-        "functionExpressionInvocation_function":
-            functionExpressionInvocation_function,
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
-    if (kind == idl.LinkedNodeKind.genericFunctionType) {
-      return {
-        "genericFunctionType_typeParameters":
-            genericFunctionType_typeParameters,
-        "genericFunctionType_functionKeyword":
-            genericFunctionType_functionKeyword,
-        "genericFunctionType_returnType": genericFunctionType_returnType,
-        "genericFunctionType_formalParameters":
-            genericFunctionType_formalParameters,
-        "genericFunctionType_question": genericFunctionType_question,
-        "genericFunctionType_returnType2": genericFunctionType_returnType2,
-        "genericFunctionType_type": genericFunctionType_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.ifElement) {
       return {
         "ifMixin_condition": ifMixin_condition,
@@ -18188,20 +18101,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.methodInvocation) {
-      return {
-        "methodInvocation_methodName": methodInvocation_methodName,
-        "methodInvocation_operator": methodInvocation_operator,
-        "methodInvocation_target": methodInvocation_target,
-        "invocationExpression_invokeType": invocationExpression_invokeType,
-        "invocationExpression_typeArguments":
-            invocationExpression_typeArguments,
-        "expression_type": expression_type,
-        "invocationExpression_arguments": invocationExpression_arguments,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.namedExpression) {
       return {
         "namedExpression_expression": namedExpression_expression,
@@ -18338,16 +18237,6 @@
         "kind": kind,
       };
     }
-    if (kind == idl.LinkedNodeKind.typeName) {
-      return {
-        "typeName_name": typeName_name,
-        "typeName_question": typeName_question,
-        "typeName_typeArguments": typeName_typeArguments,
-        "typeName_type": typeName_type,
-        "isSynthetic": isSynthetic,
-        "kind": kind,
-      };
-    }
     if (kind == idl.LinkedNodeKind.variableDeclarationStatement) {
       return {
         "variableDeclarationStatement_variables":
@@ -18519,7 +18408,7 @@
   List<LinkedNodeLibraryBuilder> get libraries =>
       _libraries ??= <LinkedNodeLibraryBuilder>[];
 
-  void set libraries(List<LinkedNodeLibraryBuilder> value) {
+  set libraries(List<LinkedNodeLibraryBuilder> value) {
     this._libraries = value;
   }
 
@@ -18527,7 +18416,7 @@
   LinkedNodeReferencesBuilder get references => _references;
 
   /// The shared list of references used in the [libraries].
-  void set references(LinkedNodeReferencesBuilder value) {
+  set references(LinkedNodeReferencesBuilder value) {
     this._references = value;
   }
 
@@ -18537,17 +18426,13 @@
       : _libraries = libraries,
         _references = references;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _libraries?.forEach((b) => b.flushInformative());
     _references?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addBool(this._references != null);
     this._references?.collectApiSignature(signature);
@@ -18661,7 +18546,7 @@
   @override
   List<int> get exports => _exports ??= <int>[];
 
-  void set exports(List<int> value) {
+  set exports(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._exports = value;
   }
@@ -18669,14 +18554,14 @@
   @override
   String get name => _name ??= '';
 
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
   @override
   int get nameLength => _nameLength ??= 0;
 
-  void set nameLength(int value) {
+  set nameLength(int value) {
     assert(value == null || value >= 0);
     this._nameLength = value;
   }
@@ -18684,7 +18569,7 @@
   @override
   int get nameOffset => _nameOffset ??= 0;
 
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -18692,14 +18577,14 @@
   @override
   List<LinkedNodeUnitBuilder> get units => _units ??= <LinkedNodeUnitBuilder>[];
 
-  void set units(List<LinkedNodeUnitBuilder> value) {
+  set units(List<LinkedNodeUnitBuilder> value) {
     this._units = value;
   }
 
   @override
   String get uriStr => _uriStr ??= '';
 
-  void set uriStr(String value) {
+  set uriStr(String value) {
     this._uriStr = value;
   }
 
@@ -18717,16 +18602,12 @@
         _units = units,
         _uriStr = uriStr;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _units?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uriStr ?? '');
     if (this._units == null) {
@@ -18891,14 +18772,14 @@
   @override
   List<String> get name => _name ??= <String>[];
 
-  void set name(List<String> value) {
+  set name(List<String> value) {
     this._name = value;
   }
 
   @override
   List<int> get parent => _parent ??= <int>[];
 
-  void set parent(List<int> value) {
+  set parent(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._parent = value;
   }
@@ -18907,14 +18788,10 @@
       : _name = name,
         _parent = parent;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._parent == null) {
       signature.addInt(0);
@@ -19026,7 +18903,7 @@
   List<LinkedNodeTypeFormalParameterBuilder> get functionFormalParameters =>
       _functionFormalParameters ??= <LinkedNodeTypeFormalParameterBuilder>[];
 
-  void set functionFormalParameters(
+  set functionFormalParameters(
       List<LinkedNodeTypeFormalParameterBuilder> value) {
     this._functionFormalParameters = value;
   }
@@ -19034,7 +18911,7 @@
   @override
   LinkedNodeTypeBuilder get functionReturnType => _functionReturnType;
 
-  void set functionReturnType(LinkedNodeTypeBuilder value) {
+  set functionReturnType(LinkedNodeTypeBuilder value) {
     this._functionReturnType = value;
   }
 
@@ -19042,7 +18919,7 @@
   List<int> get functionTypeParameters => _functionTypeParameters ??= <int>[];
 
   /// References to [LinkedNodeReferences].
-  void set functionTypeParameters(List<int> value) {
+  set functionTypeParameters(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._functionTypeParameters = value;
   }
@@ -19050,7 +18927,7 @@
   @override
   int get genericTypeAliasReference => _genericTypeAliasReference ??= 0;
 
-  void set genericTypeAliasReference(int value) {
+  set genericTypeAliasReference(int value) {
     assert(value == null || value >= 0);
     this._genericTypeAliasReference = value;
   }
@@ -19059,7 +18936,7 @@
   List<LinkedNodeTypeBuilder> get genericTypeAliasTypeArguments =>
       _genericTypeAliasTypeArguments ??= <LinkedNodeTypeBuilder>[];
 
-  void set genericTypeAliasTypeArguments(List<LinkedNodeTypeBuilder> value) {
+  set genericTypeAliasTypeArguments(List<LinkedNodeTypeBuilder> value) {
     this._genericTypeAliasTypeArguments = value;
   }
 
@@ -19067,7 +18944,7 @@
   int get interfaceClass => _interfaceClass ??= 0;
 
   /// Reference to a [LinkedNodeReferences].
-  void set interfaceClass(int value) {
+  set interfaceClass(int value) {
     assert(value == null || value >= 0);
     this._interfaceClass = value;
   }
@@ -19076,14 +18953,14 @@
   List<LinkedNodeTypeBuilder> get interfaceTypeArguments =>
       _interfaceTypeArguments ??= <LinkedNodeTypeBuilder>[];
 
-  void set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) {
+  set interfaceTypeArguments(List<LinkedNodeTypeBuilder> value) {
     this._interfaceTypeArguments = value;
   }
 
   @override
   idl.LinkedNodeTypeKind get kind => _kind ??= idl.LinkedNodeTypeKind.bottom;
 
-  void set kind(idl.LinkedNodeTypeKind value) {
+  set kind(idl.LinkedNodeTypeKind value) {
     this._kind = value;
   }
 
@@ -19091,7 +18968,7 @@
   int get typeParameterParameter => _typeParameterParameter ??= 0;
 
   /// Reference to a [LinkedNodeReferences].
-  void set typeParameterParameter(int value) {
+  set typeParameterParameter(int value) {
     assert(value == null || value >= 0);
     this._typeParameterParameter = value;
   }
@@ -19116,9 +18993,7 @@
         _kind = kind,
         _typeParameterParameter = typeParameterParameter;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _functionFormalParameters?.forEach((b) => b.flushInformative());
     _functionReturnType?.flushInformative();
@@ -19126,9 +19001,7 @@
     _interfaceTypeArguments?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._functionFormalParameters == null) {
       signature.addInt(0);
@@ -19381,21 +19254,21 @@
   idl.LinkedNodeFormalParameterKind get kind =>
       _kind ??= idl.LinkedNodeFormalParameterKind.required;
 
-  void set kind(idl.LinkedNodeFormalParameterKind value) {
+  set kind(idl.LinkedNodeFormalParameterKind value) {
     this._kind = value;
   }
 
   @override
   String get name => _name ??= '';
 
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
   @override
   LinkedNodeTypeBuilder get type => _type;
 
-  void set type(LinkedNodeTypeBuilder value) {
+  set type(LinkedNodeTypeBuilder value) {
     this._type = value;
   }
 
@@ -19407,16 +19280,12 @@
         _name = name,
         _type = type;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _type?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._kind == null ? 0 : this._kind.index);
     signature.addString(this._name ?? '');
@@ -19522,21 +19391,21 @@
   @override
   LinkedNodeBuilder get node => _node;
 
-  void set node(LinkedNodeBuilder value) {
+  set node(LinkedNodeBuilder value) {
     this._node = value;
   }
 
   @override
   UnlinkedTokensBuilder get tokens => _tokens;
 
-  void set tokens(UnlinkedTokensBuilder value) {
+  set tokens(UnlinkedTokensBuilder value) {
     this._tokens = value;
   }
 
   @override
   String get uriStr => _uriStr ??= '';
 
-  void set uriStr(String value) {
+  set uriStr(String value) {
     this._uriStr = value;
   }
 
@@ -19546,17 +19415,13 @@
         _tokens = tokens,
         _uriStr = uriStr;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _node?.flushInformative();
     _tokens?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uriStr ?? '');
     signature.addBool(this._tokens != null);
@@ -19665,35 +19530,35 @@
   @override
   LinkedNodeBuilder get comment => _comment;
 
-  void set comment(LinkedNodeBuilder value) {
+  set comment(LinkedNodeBuilder value) {
     this._comment = value;
   }
 
   @override
   bool get isConst => _isConst ??= false;
 
-  void set isConst(bool value) {
+  set isConst(bool value) {
     this._isConst = value;
   }
 
   @override
   bool get isCovariant => _isCovariant ??= false;
 
-  void set isCovariant(bool value) {
+  set isCovariant(bool value) {
     this._isCovariant = value;
   }
 
   @override
   bool get isFinal => _isFinal ??= false;
 
-  void set isFinal(bool value) {
+  set isFinal(bool value) {
     this._isFinal = value;
   }
 
   @override
   bool get isStatic => _isStatic ??= false;
 
-  void set isStatic(bool value) {
+  set isStatic(bool value) {
     this._isStatic = value;
   }
 
@@ -19709,16 +19574,12 @@
         _isFinal = isFinal,
         _isStatic = isStatic;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _comment?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addBool(this._comment != null);
     this._comment?.collectApiSignature(signature);
@@ -19856,7 +19717,7 @@
   /// Containing references must always point backward; that is, for all i, if
   /// LinkedUnit.references[i].containingReference != 0, then
   /// LinkedUnit.references[i].containingReference < i.
-  void set containingReference(int value) {
+  set containingReference(int value) {
     assert(value == null || value >= 0);
     this._containingReference = value;
   }
@@ -19869,7 +19730,7 @@
   ///
   /// Zero if this entity is contained within another entity (e.g. a class
   /// member), or if [kind] is [ReferenceKind.prefix].
-  void set dependency(int value) {
+  set dependency(int value) {
     assert(value == null || value >= 0);
     this._dependency = value;
   }
@@ -19879,7 +19740,7 @@
 
   /// The kind of the entity being referred to.  For the pseudo-types `dynamic`
   /// and `void`, the kind is [ReferenceKind.classOrEnum].
-  void set kind(idl.ReferenceKind value) {
+  set kind(idl.ReferenceKind value) {
     this._kind = value;
   }
 
@@ -19893,7 +19754,7 @@
   /// If this [LinkedReference] doesn't have an associated [UnlinkedReference],
   /// name of the entity being referred to.  For the pseudo-type `dynamic`, the
   /// string is "dynamic".  For the pseudo-type `void`, the string is "void".
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -19903,7 +19764,7 @@
   /// If the entity being referred to is generic, the number of type parameters
   /// it declares (does not include type parameters of enclosing entities).
   /// Otherwise zero.
-  void set numTypeParameters(int value) {
+  set numTypeParameters(int value) {
     assert(value == null || value >= 0);
     this._numTypeParameters = value;
   }
@@ -19918,7 +19779,7 @@
   ///
   /// Zero if this entity is contained within another entity (e.g. a class
   /// member).
-  void set unit(int value) {
+  set unit(int value) {
     assert(value == null || value >= 0);
     this._unit = value;
   }
@@ -19937,14 +19798,10 @@
         _numTypeParameters = numTypeParameters,
         _unit = unit;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._unit ?? 0);
     signature.addInt(this._dependency ?? 0);
@@ -20094,7 +19951,7 @@
 
   /// List of slot ids (referring to [UnlinkedExecutable.constCycleSlot])
   /// corresponding to const constructors that are part of cycles.
-  void set constCycles(List<int> value) {
+  set constCycles(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._constCycles = value;
   }
@@ -20105,7 +19962,7 @@
   /// List of slot ids (referring to [UnlinkedClass.notSimplyBoundedSlot] or
   /// [UnlinkedTypedef.notSimplyBoundedSlot]) corresponding to classes and
   /// typedefs that are not simply bounded.
-  void set notSimplyBounded(List<int> value) {
+  set notSimplyBounded(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._notSimplyBounded = value;
   }
@@ -20117,7 +19974,7 @@
   /// List of slot ids (referring to [UnlinkedParam.inheritsCovariantSlot] or
   /// [UnlinkedVariable.inheritsCovariantSlot]) corresponding to parameters
   /// that inherit `@covariant` behavior from a base class.
-  void set parametersInheritingCovariant(List<int> value) {
+  set parametersInheritingCovariant(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._parametersInheritingCovariant = value;
   }
@@ -20132,7 +19989,7 @@
   /// elements beyond the number of elements in [UnlinkedUnit.references], those
   /// additional elements are references that are only referred to implicitly
   /// (e.g. elements involved in inferred or propagated types).
-  void set references(List<LinkedReferenceBuilder> value) {
+  set references(List<LinkedReferenceBuilder> value) {
     this._references = value;
   }
 
@@ -20141,7 +19998,7 @@
       _topLevelInferenceErrors ??= <TopLevelInferenceErrorBuilder>[];
 
   /// The list of type inference errors.
-  void set topLevelInferenceErrors(List<TopLevelInferenceErrorBuilder> value) {
+  set topLevelInferenceErrors(List<TopLevelInferenceErrorBuilder> value) {
     this._topLevelInferenceErrors = value;
   }
 
@@ -20150,7 +20007,7 @@
 
   /// List associating slot ids found inside the unlinked summary for the
   /// compilation unit with propagated and inferred types.
-  void set types(List<EntityRefBuilder> value) {
+  set types(List<EntityRefBuilder> value) {
     this._types = value;
   }
 
@@ -20168,18 +20025,14 @@
         _topLevelInferenceErrors = topLevelInferenceErrors,
         _types = types;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _references?.forEach((b) => b.flushInformative());
     _topLevelInferenceErrors?.forEach((b) => b.flushInformative());
     _types?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._references == null) {
       signature.addInt(0);
@@ -20411,7 +20264,7 @@
       _linkedLibraries ??= <LinkedLibraryBuilder>[];
 
   /// Linked libraries.
-  void set linkedLibraries(List<LinkedLibraryBuilder> value) {
+  set linkedLibraries(List<LinkedLibraryBuilder> value) {
     this._linkedLibraries = value;
   }
 
@@ -20420,7 +20273,7 @@
 
   /// The list of URIs of items in [linkedLibraries], e.g. `dart:core` or
   /// `package:foo/bar.dart`.
-  void set linkedLibraryUris(List<String> value) {
+  set linkedLibraryUris(List<String> value) {
     this._linkedLibraryUris = value;
   }
 
@@ -20429,7 +20282,7 @@
 
   /// Major version of the summary format.  See
   /// [PackageBundleAssembler.currentMajorVersion].
-  void set majorVersion(int value) {
+  set majorVersion(int value) {
     assert(value == null || value >= 0);
     this._majorVersion = value;
   }
@@ -20439,7 +20292,7 @@
 
   /// Minor version of the summary format.  See
   /// [PackageBundleAssembler.currentMinorVersion].
-  void set minorVersion(int value) {
+  set minorVersion(int value) {
     assert(value == null || value >= 0);
     this._minorVersion = value;
   }
@@ -20453,7 +20306,7 @@
       _unlinkedUnits ??= <UnlinkedUnitBuilder>[];
 
   /// Unlinked information for the compilation units constituting the package.
-  void set unlinkedUnits(List<UnlinkedUnitBuilder> value) {
+  set unlinkedUnits(List<UnlinkedUnitBuilder> value) {
     this._unlinkedUnits = value;
   }
 
@@ -20461,7 +20314,7 @@
   List<String> get unlinkedUnitUris => _unlinkedUnitUris ??= <String>[];
 
   /// The list of URIs of items in [unlinkedUnits], e.g. `dart:core/bool.dart`.
-  void set unlinkedUnitUris(List<String> value) {
+  set unlinkedUnitUris(List<String> value) {
     this._unlinkedUnitUris = value;
   }
 
@@ -20479,17 +20332,13 @@
         _unlinkedUnits = unlinkedUnits,
         _unlinkedUnitUris = unlinkedUnitUris;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _linkedLibraries?.forEach((b) => b.flushInformative());
     _unlinkedUnits?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._linkedLibraries == null) {
       signature.addInt(0);
@@ -20711,7 +20560,7 @@
 
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the kind of the synthetic element.
-  void set elementKinds(List<idl.IndexSyntheticElementKind> value) {
+  set elementKinds(List<idl.IndexSyntheticElementKind> value) {
     this._elementKinds = value;
   }
 
@@ -20724,7 +20573,7 @@
   /// is a top-level element.  The list is sorted in ascending order, so that
   /// the client can quickly check whether an element is referenced in this
   /// [PackageIndex].
-  void set elementNameClassMemberIds(List<int> value) {
+  set elementNameClassMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameClassMemberIds = value;
   }
@@ -20737,7 +20586,7 @@
   /// not a named parameter.  The list is sorted in ascending order, so that the
   /// client can quickly check whether an element is referenced in this
   /// [PackageIndex].
-  void set elementNameParameterIds(List<int> value) {
+  set elementNameParameterIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameParameterIds = value;
   }
@@ -20750,7 +20599,7 @@
   /// the identifier of the top-level element name, or `null` if the element is
   /// the unit.  The list is sorted in ascending order, so that the client can
   /// quickly check whether an element is referenced in this [PackageIndex].
-  void set elementNameUnitMemberIds(List<int> value) {
+  set elementNameUnitMemberIds(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementNameUnitMemberIds = value;
   }
@@ -20761,7 +20610,7 @@
   /// Each item of this list corresponds to a unique referenced element.  It is
   /// the index into [unitLibraryUris] and [unitUnitUris] for the library
   /// specific unit where the element is declared.
-  void set elementUnits(List<int> value) {
+  set elementUnits(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._elementUnits = value;
   }
@@ -20772,7 +20621,7 @@
   /// List of unique element strings used in this [PackageIndex].  The list is
   /// sorted in ascending order, so that the client can quickly check the
   /// presence of a string in this [PackageIndex].
-  void set strings(List<String> value) {
+  set strings(List<String> value) {
     this._strings = value;
   }
 
@@ -20782,7 +20631,7 @@
   /// Each item of this list corresponds to the library URI of a unique library
   /// specific unit referenced in the [PackageIndex].  It is an index into
   /// [strings] list.
-  void set unitLibraryUris(List<int> value) {
+  set unitLibraryUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitLibraryUris = value;
   }
@@ -20791,7 +20640,7 @@
   List<UnitIndexBuilder> get units => _units ??= <UnitIndexBuilder>[];
 
   /// List of indexes of each unit in this [PackageIndex].
-  void set units(List<UnitIndexBuilder> value) {
+  set units(List<UnitIndexBuilder> value) {
     this._units = value;
   }
 
@@ -20801,7 +20650,7 @@
   /// Each item of this list corresponds to the unit URI of a unique library
   /// specific unit referenced in the [PackageIndex].  It is an index into
   /// [strings] list.
-  void set unitUnitUris(List<int> value) {
+  set unitUnitUris(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._unitUnitUris = value;
   }
@@ -20826,16 +20675,12 @@
         _units = units,
         _unitUnitUris = unitUnitUris;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _units?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._elementUnits == null) {
       signature.addInt(0);
@@ -21142,7 +20987,7 @@
   List<String> get arguments => _arguments ??= <String>[];
 
   /// The [kind] specific arguments.
-  void set arguments(List<String> value) {
+  set arguments(List<String> value) {
     this._arguments = value;
   }
 
@@ -21151,7 +20996,7 @@
       _kind ??= idl.TopLevelInferenceErrorKind.assignment;
 
   /// The kind of the error.
-  void set kind(idl.TopLevelInferenceErrorKind value) {
+  set kind(idl.TopLevelInferenceErrorKind value) {
     this._kind = value;
   }
 
@@ -21161,7 +21006,7 @@
   /// The slot id (which is unique within the compilation unit) identifying the
   /// target of type inference with which this [TopLevelInferenceError] is
   /// associated.
-  void set slot(int value) {
+  set slot(int value) {
     assert(value == null || value >= 0);
     this._slot = value;
   }
@@ -21172,14 +21017,10 @@
         _kind = kind,
         _slot = slot;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._slot ?? 0);
     signature.addInt(this._kind == null ? 0 : this._kind.index);
@@ -21300,7 +21141,7 @@
       _definedNameKinds ??= <idl.IndexNameKind>[];
 
   /// Each item of this list is the kind of an element defined in this unit.
-  void set definedNameKinds(List<idl.IndexNameKind> value) {
+  set definedNameKinds(List<idl.IndexNameKind> value) {
     this._definedNameKinds = value;
   }
 
@@ -21309,7 +21150,7 @@
 
   /// Each item of this list is the name offset of an element defined in this
   /// unit relative to the beginning of the file.
-  void set definedNameOffsets(List<int> value) {
+  set definedNameOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._definedNameOffsets = value;
   }
@@ -21321,7 +21162,7 @@
   /// is an index into [PackageIndex.strings] list.  The list is sorted in
   /// ascending order, so that the client can quickly find name definitions in
   /// this [UnitIndex].
-  void set definedNames(List<int> value) {
+  set definedNames(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._definedNames = value;
   }
@@ -21331,7 +21172,7 @@
 
   /// Index into [PackageIndex.unitLibraryUris] and [PackageIndex.unitUnitUris]
   /// for the library specific unit that corresponds to this [UnitIndex].
-  void set unit(int value) {
+  set unit(int value) {
     assert(value == null || value >= 0);
     this._unit = value;
   }
@@ -21342,7 +21183,7 @@
 
   /// Each item of this list is the `true` if the corresponding element usage
   /// is qualified with some prefix.
-  void set usedElementIsQualifiedFlags(List<bool> value) {
+  set usedElementIsQualifiedFlags(List<bool> value) {
     this._usedElementIsQualifiedFlags = value;
   }
 
@@ -21351,7 +21192,7 @@
       _usedElementKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the element usage.
-  void set usedElementKinds(List<idl.IndexRelationKind> value) {
+  set usedElementKinds(List<idl.IndexRelationKind> value) {
     this._usedElementKinds = value;
   }
 
@@ -21359,7 +21200,7 @@
   List<int> get usedElementLengths => _usedElementLengths ??= <int>[];
 
   /// Each item of this list is the length of the element usage.
-  void set usedElementLengths(List<int> value) {
+  set usedElementLengths(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementLengths = value;
   }
@@ -21369,7 +21210,7 @@
 
   /// Each item of this list is the offset of the element usage relative to the
   /// beginning of the file.
-  void set usedElementOffsets(List<int> value) {
+  set usedElementOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElementOffsets = value;
   }
@@ -21380,7 +21221,7 @@
   /// Each item of this list is the index into [PackageIndex.elementUnits] and
   /// [PackageIndex.elementOffsets].  The list is sorted in ascending order, so
   /// that the client can quickly find element references in this [UnitIndex].
-  void set usedElements(List<int> value) {
+  set usedElements(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedElements = value;
   }
@@ -21391,7 +21232,7 @@
 
   /// Each item of this list is the `true` if the corresponding name usage
   /// is qualified with some prefix.
-  void set usedNameIsQualifiedFlags(List<bool> value) {
+  set usedNameIsQualifiedFlags(List<bool> value) {
     this._usedNameIsQualifiedFlags = value;
   }
 
@@ -21400,7 +21241,7 @@
       _usedNameKinds ??= <idl.IndexRelationKind>[];
 
   /// Each item of this list is the kind of the name usage.
-  void set usedNameKinds(List<idl.IndexRelationKind> value) {
+  set usedNameKinds(List<idl.IndexRelationKind> value) {
     this._usedNameKinds = value;
   }
 
@@ -21409,7 +21250,7 @@
 
   /// Each item of this list is the offset of the name usage relative to the
   /// beginning of the file.
-  void set usedNameOffsets(List<int> value) {
+  set usedNameOffsets(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNameOffsets = value;
   }
@@ -21420,7 +21261,7 @@
   /// Each item of this list is the index into [PackageIndex.strings] for a
   /// used name.  The list is sorted in ascending order, so that the client can
   /// quickly find name uses in this [UnitIndex].
-  void set usedNames(List<int> value) {
+  set usedNames(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._usedNames = value;
   }
@@ -21453,14 +21294,10 @@
         _usedNameOffsets = usedNameOffsets,
         _usedNames = usedNames;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addInt(this._unit ?? 0);
     if (this._usedElementLengths == null) {
@@ -21870,7 +21707,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this class.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -21878,7 +21715,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the class.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -21888,7 +21725,7 @@
 
   /// Documentation comment for the class, or `null` if there is no
   /// documentation comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -21897,7 +21734,7 @@
       _executables ??= <UnlinkedExecutableBuilder>[];
 
   /// Executable objects (methods, getters, and setters) contained in the class.
-  void set executables(List<UnlinkedExecutableBuilder> value) {
+  set executables(List<UnlinkedExecutableBuilder> value) {
     this._executables = value;
   }
 
@@ -21906,7 +21743,7 @@
       _fields ??= <UnlinkedVariableBuilder>[];
 
   /// Field declarations contained in the class.
-  void set fields(List<UnlinkedVariableBuilder> value) {
+  set fields(List<UnlinkedVariableBuilder> value) {
     this._fields = value;
   }
 
@@ -21915,7 +21752,7 @@
 
   /// Indicates whether this class is the core "Object" class (and hence has no
   /// supertype)
-  void set hasNoSupertype(bool value) {
+  set hasNoSupertype(bool value) {
     this._hasNoSupertype = value;
   }
 
@@ -21923,7 +21760,7 @@
   List<EntityRefBuilder> get interfaces => _interfaces ??= <EntityRefBuilder>[];
 
   /// Interfaces appearing in an `implements` clause, if any.
-  void set interfaces(List<EntityRefBuilder> value) {
+  set interfaces(List<EntityRefBuilder> value) {
     this._interfaces = value;
   }
 
@@ -21931,7 +21768,7 @@
   bool get isAbstract => _isAbstract ??= false;
 
   /// Indicates whether the class is declared with the `abstract` keyword.
-  void set isAbstract(bool value) {
+  set isAbstract(bool value) {
     this._isAbstract = value;
   }
 
@@ -21939,7 +21776,7 @@
   bool get isMixinApplication => _isMixinApplication ??= false;
 
   /// Indicates whether the class is declared using mixin application syntax.
-  void set isMixinApplication(bool value) {
+  set isMixinApplication(bool value) {
     this._isMixinApplication = value;
   }
 
@@ -21947,7 +21784,7 @@
   List<EntityRefBuilder> get mixins => _mixins ??= <EntityRefBuilder>[];
 
   /// Mixins appearing in a `with` clause, if any.
-  void set mixins(List<EntityRefBuilder> value) {
+  set mixins(List<EntityRefBuilder> value) {
     this._mixins = value;
   }
 
@@ -21955,7 +21792,7 @@
   String get name => _name ??= '';
 
   /// Name of the class.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -21963,7 +21800,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the class name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -21978,7 +21815,7 @@
   /// type when specifying the bound of a type parameter.
   ///
   /// Otherwise, zero.
-  void set notSimplyBoundedSlot(int value) {
+  set notSimplyBoundedSlot(int value) {
     assert(value == null || value >= 0);
     this._notSimplyBoundedSlot = value;
   }
@@ -21990,7 +21827,7 @@
   /// Superclass constraints for this mixin declaration. The list will be empty
   /// if this class is not a mixin declaration, or if the declaration does not
   /// have an `on` clause (in which case the type `Object` is implied).
-  void set superclassConstraints(List<EntityRefBuilder> value) {
+  set superclassConstraints(List<EntityRefBuilder> value) {
     this._superclassConstraints = value;
   }
 
@@ -22000,7 +21837,7 @@
   /// Names of methods, getters, setters, and operators that this mixin
   /// declaration super-invokes.  For setters this includes the trailing "=".
   /// The list will be empty if this class is not a mixin declaration.
-  void set superInvokedNames(List<String> value) {
+  set superInvokedNames(List<String> value) {
     this._superInvokedNames = value;
   }
 
@@ -22010,7 +21847,7 @@
   /// Supertype of the class, or `null` if either (a) the class doesn't
   /// explicitly declare a supertype (and hence has supertype `Object`), or (b)
   /// the class *is* `Object` (and hence has no supertype).
-  void set supertype(EntityRefBuilder value) {
+  set supertype(EntityRefBuilder value) {
     this._supertype = value;
   }
 
@@ -22019,7 +21856,7 @@
       _typeParameters ??= <UnlinkedTypeParamBuilder>[];
 
   /// Type parameters of the class, if any.
-  void set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
     this._typeParameters = value;
   }
 
@@ -22059,9 +21896,7 @@
         _supertype = supertype,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -22076,9 +21911,7 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     if (this._executables == null) {
@@ -22498,7 +22331,7 @@
 
   /// If this is a `show` combinator, offset of the end of the list of shown
   /// names.  Otherwise zero.
-  void set end(int value) {
+  set end(int value) {
     assert(value == null || value >= 0);
     this._end = value;
   }
@@ -22507,7 +22340,7 @@
   List<String> get hides => _hides ??= <String>[];
 
   /// List of names which are hidden.  Empty if this is a `show` combinator.
-  void set hides(List<String> value) {
+  set hides(List<String> value) {
     this._hides = value;
   }
 
@@ -22516,7 +22349,7 @@
 
   /// If this is a `show` combinator, offset of the `show` keyword.  Otherwise
   /// zero.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -22525,7 +22358,7 @@
   List<String> get shows => _shows ??= <String>[];
 
   /// List of names which are shown.  Empty if this is a `hide` combinator.
-  void set shows(List<String> value) {
+  set shows(List<String> value) {
     this._shows = value;
   }
 
@@ -22536,17 +22369,13 @@
         _offset = offset,
         _shows = shows;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _end = null;
     _offset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._shows == null) {
       signature.addInt(0);
@@ -22678,7 +22507,7 @@
 
   /// The name of the declared variable whose value is being used in the
   /// condition.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -22686,7 +22515,7 @@
   String get uri => _uri ??= '';
 
   /// The URI of the implementation library to be used if the condition is true.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -22695,7 +22524,7 @@
 
   /// The value to which the value of the declared variable will be compared,
   /// or `true` if the condition does not include an equality test.
-  void set value(String value) {
+  set value(String value) {
     this._value = value;
   }
 
@@ -22704,14 +22533,10 @@
         _uri = uri,
         _value = value;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addString(this._value ?? '');
@@ -22822,7 +22647,7 @@
   /// If there are `m` [arguments] and `n` [argumentNames], then each argument
   /// from [arguments] with index `i` such that `n + i - m >= 0`, should be used
   /// with the name at `n + i - m`.
-  void set argumentNames(List<String> value) {
+  set argumentNames(List<String> value) {
     this._argumentNames = value;
   }
 
@@ -22832,7 +22657,7 @@
 
   /// If [kind] is `thisInvocation` or `superInvocation`, the arguments of the
   /// invocation.  Otherwise empty.
-  void set arguments(List<UnlinkedExprBuilder> value) {
+  set arguments(List<UnlinkedExprBuilder> value) {
     this._arguments = value;
   }
 
@@ -22841,7 +22666,7 @@
 
   /// If [kind] is `field`, the expression of the field initializer.
   /// Otherwise `null`.
-  void set expression(UnlinkedExprBuilder value) {
+  set expression(UnlinkedExprBuilder value) {
     this._expression = value;
   }
 
@@ -22850,7 +22675,7 @@
       _kind ??= idl.UnlinkedConstructorInitializerKind.field;
 
   /// The kind of the constructor initializer (field, redirect, super).
-  void set kind(idl.UnlinkedConstructorInitializerKind value) {
+  set kind(idl.UnlinkedConstructorInitializerKind value) {
     this._kind = value;
   }
 
@@ -22861,7 +22686,7 @@
   /// [kind] is `thisInvocation`, the name of the constructor, declared in this
   /// class, to redirect to.  If [kind] is `superInvocation`, the name of the
   /// constructor, declared in the superclass, to invoke.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -22877,17 +22702,13 @@
         _kind = kind,
         _name = name;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _arguments?.forEach((b) => b.flushInformative());
     _expression?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addBool(this._expression != null);
@@ -23060,20 +22881,16 @@
   ///
   /// References appearing within the doc comment in square brackets are not
   /// specially encoded.
-  void set text(String value) {
+  set text(String value) {
     this._text = value;
   }
 
   UnlinkedDocumentationCommentBuilder({String text}) : _text = text;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._text ?? '');
   }
@@ -23159,7 +22976,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this enum.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -23167,7 +22984,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the enum.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -23177,7 +22994,7 @@
 
   /// Documentation comment for the enum, or `null` if there is no documentation
   /// comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -23185,7 +23002,7 @@
   String get name => _name ??= '';
 
   /// Name of the enum type.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -23193,7 +23010,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the enum name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -23203,7 +23020,7 @@
       _values ??= <UnlinkedEnumValueBuilder>[];
 
   /// Values listed in the enum declaration, in declaration order.
-  void set values(List<UnlinkedEnumValueBuilder> value) {
+  set values(List<UnlinkedEnumValueBuilder> value) {
     this._values = value;
   }
 
@@ -23221,9 +23038,7 @@
         _nameOffset = nameOffset,
         _values = values;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -23232,9 +23047,7 @@
     _values?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     if (this._values == null) {
@@ -23410,7 +23223,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this value.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -23420,7 +23233,7 @@
 
   /// Documentation comment for the enum value, or `null` if there is no
   /// documentation comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -23428,7 +23241,7 @@
   String get name => _name ??= '';
 
   /// Name of the enumerated value.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -23436,7 +23249,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the enum value name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -23451,18 +23264,14 @@
         _name = name,
         _nameOffset = nameOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _documentationComment = null;
     _nameOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     if (this._annotations == null) {
@@ -23618,7 +23427,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this executable.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -23628,7 +23437,7 @@
   /// If this executable's function body is declared using `=>`, the expression
   /// to the right of the `=>`.  May be omitted if neither type inference nor
   /// constant evaluation depends on the function body.
-  void set bodyExpr(UnlinkedExprBuilder value) {
+  set bodyExpr(UnlinkedExprBuilder value) {
     this._bodyExpr = value;
   }
 
@@ -23636,7 +23445,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the executable.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -23646,8 +23455,7 @@
 
   /// If a constant [UnlinkedExecutableKind.constructor], the constructor
   /// initializers.  Otherwise empty.
-  void set constantInitializers(
-      List<UnlinkedConstructorInitializerBuilder> value) {
+  set constantInitializers(List<UnlinkedConstructorInitializerBuilder> value) {
     this._constantInitializers = value;
   }
 
@@ -23660,7 +23468,7 @@
   /// a cycle.
   ///
   /// Otherwise, zero.
-  void set constCycleSlot(int value) {
+  set constCycleSlot(int value) {
     assert(value == null || value >= 0);
     this._constCycleSlot = value;
   }
@@ -23671,7 +23479,7 @@
 
   /// Documentation comment for the executable, or `null` if there is no
   /// documentation comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -23683,7 +23491,7 @@
   /// return type.  If there is no matching entry in [LinkedUnit.types], then
   /// no return type was inferred for this variable, so its static type is
   /// `dynamic`.
-  void set inferredReturnTypeSlot(int value) {
+  set inferredReturnTypeSlot(int value) {
     assert(value == null || value >= 0);
     this._inferredReturnTypeSlot = value;
   }
@@ -23692,7 +23500,7 @@
   bool get isAbstract => _isAbstract ??= false;
 
   /// Indicates whether the executable is declared using the `abstract` keyword.
-  void set isAbstract(bool value) {
+  set isAbstract(bool value) {
     this._isAbstract = value;
   }
 
@@ -23700,7 +23508,7 @@
   bool get isAsynchronous => _isAsynchronous ??= false;
 
   /// Indicates whether the executable has body marked as being asynchronous.
-  void set isAsynchronous(bool value) {
+  set isAsynchronous(bool value) {
     this._isAsynchronous = value;
   }
 
@@ -23708,7 +23516,7 @@
   bool get isConst => _isConst ??= false;
 
   /// Indicates whether the executable is declared using the `const` keyword.
-  void set isConst(bool value) {
+  set isConst(bool value) {
     this._isConst = value;
   }
 
@@ -23716,7 +23524,7 @@
   bool get isExternal => _isExternal ??= false;
 
   /// Indicates whether the executable is declared using the `external` keyword.
-  void set isExternal(bool value) {
+  set isExternal(bool value) {
     this._isExternal = value;
   }
 
@@ -23724,7 +23532,7 @@
   bool get isFactory => _isFactory ??= false;
 
   /// Indicates whether the executable is declared using the `factory` keyword.
-  void set isFactory(bool value) {
+  set isFactory(bool value) {
     this._isFactory = value;
   }
 
@@ -23732,7 +23540,7 @@
   bool get isGenerator => _isGenerator ??= false;
 
   /// Indicates whether the executable has body marked as being a generator.
-  void set isGenerator(bool value) {
+  set isGenerator(bool value) {
     this._isGenerator = value;
   }
 
@@ -23740,7 +23548,7 @@
   bool get isRedirectedConstructor => _isRedirectedConstructor ??= false;
 
   /// Indicates whether the executable is a redirected constructor.
-  void set isRedirectedConstructor(bool value) {
+  set isRedirectedConstructor(bool value) {
     this._isRedirectedConstructor = value;
   }
 
@@ -23752,7 +23560,7 @@
   /// Note that for top level executables, this flag is false, since they are
   /// not declared using the `static` keyword (even though they are considered
   /// static for semantic purposes).
-  void set isStatic(bool value) {
+  set isStatic(bool value) {
     this._isStatic = value;
   }
 
@@ -23762,7 +23570,7 @@
 
   /// The kind of the executable (function/method, getter, setter, or
   /// constructor).
-  void set kind(idl.UnlinkedExecutableKind value) {
+  set kind(idl.UnlinkedExecutableKind value) {
     this._kind = value;
   }
 
@@ -23771,7 +23579,7 @@
       _localFunctions ??= <UnlinkedExecutableBuilder>[];
 
   /// The list of local functions.
-  void set localFunctions(List<UnlinkedExecutableBuilder> value) {
+  set localFunctions(List<UnlinkedExecutableBuilder> value) {
     this._localFunctions = value;
   }
 
@@ -23789,7 +23597,7 @@
   /// Name of the executable.  For setters, this includes the trailing "=".  For
   /// named constructors, this excludes the class name and excludes the ".".
   /// For unnamed constructors, this is the empty string.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -23798,7 +23606,7 @@
 
   /// If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
   /// the offset of the end of the constructor name.  Otherwise zero.
-  void set nameEnd(int value) {
+  set nameEnd(int value) {
     assert(value == null || value >= 0);
     this._nameEnd = value;
   }
@@ -23810,7 +23618,7 @@
   /// named constructors, this excludes the class name and excludes the ".".
   /// For unnamed constructors, this is the offset of the class name (i.e. the
   /// offset of the second "C" in "class C { C(); }").
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -23822,7 +23630,7 @@
   /// Parameters of the executable, if any.  Note that getters have no
   /// parameters (hence this will be the empty list), and setters have a single
   /// parameter.
-  void set parameters(List<UnlinkedParamBuilder> value) {
+  set parameters(List<UnlinkedParamBuilder> value) {
     this._parameters = value;
   }
 
@@ -23831,7 +23639,7 @@
 
   /// If [kind] is [UnlinkedExecutableKind.constructor] and [name] is not empty,
   /// the offset of the period before the constructor name.  Otherwise zero.
-  void set periodOffset(int value) {
+  set periodOffset(int value) {
     assert(value == null || value >= 0);
     this._periodOffset = value;
   }
@@ -23841,7 +23649,7 @@
 
   /// If [isRedirectedConstructor] and [isFactory] are both `true`, the
   /// constructor to which this constructor redirects; otherwise empty.
-  void set redirectedConstructor(EntityRefBuilder value) {
+  set redirectedConstructor(EntityRefBuilder value) {
     this._redirectedConstructor = value;
   }
 
@@ -23851,7 +23659,7 @@
   /// If [isRedirectedConstructor] is `true` and [isFactory] is `false`, the
   /// name of the constructor that this constructor redirects to; otherwise
   /// empty.
-  void set redirectedConstructorName(String value) {
+  set redirectedConstructorName(String value) {
     this._redirectedConstructorName = value;
   }
 
@@ -23863,7 +23671,7 @@
   /// associated with variable initializers and closures, since these
   /// executables may have return types that are not accessible via direct
   /// imports.
-  void set returnType(EntityRefBuilder value) {
+  set returnType(EntityRefBuilder value) {
     this._returnType = value;
   }
 
@@ -23873,7 +23681,7 @@
 
   /// Type parameters of the executable, if any.  Empty if support for generic
   /// method syntax is disabled.
-  void set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
     this._typeParameters = value;
   }
 
@@ -23881,7 +23689,7 @@
   int get visibleLength => _visibleLength ??= 0;
 
   /// If a local function, the length of the visible range; zero otherwise.
-  void set visibleLength(int value) {
+  set visibleLength(int value) {
     assert(value == null || value >= 0);
     this._visibleLength = value;
   }
@@ -23890,7 +23698,7 @@
   int get visibleOffset => _visibleOffset ??= 0;
 
   /// If a local function, the beginning of the visible range; zero otherwise.
-  void set visibleOffset(int value) {
+  set visibleOffset(int value) {
     assert(value == null || value >= 0);
     this._visibleOffset = value;
   }
@@ -23953,9 +23761,7 @@
         _visibleLength = visibleLength,
         _visibleOffset = visibleOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _bodyExpr?.flushInformative();
@@ -23976,9 +23782,7 @@
     _visibleOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     if (this._parameters == null) {
@@ -24527,7 +24331,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this export directive.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -24535,7 +24339,7 @@
   int get offset => _offset ??= 0;
 
   /// Offset of the "export" keyword.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -24545,7 +24349,7 @@
 
   /// End of the URI string (including quotes) relative to the beginning of the
   /// file.
-  void set uriEnd(int value) {
+  set uriEnd(int value) {
     assert(value == null || value >= 0);
     this._uriEnd = value;
   }
@@ -24555,7 +24359,7 @@
 
   /// Offset of the URI string (including quotes) relative to the beginning of
   /// the file.
-  void set uriOffset(int value) {
+  set uriOffset(int value) {
     assert(value == null || value >= 0);
     this._uriOffset = value;
   }
@@ -24570,9 +24374,7 @@
         _uriEnd = uriEnd,
         _uriOffset = uriOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _offset = null;
@@ -24580,9 +24382,7 @@
     _uriOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._annotations == null) {
       signature.addInt(0);
@@ -24704,7 +24504,7 @@
       _combinators ??= <UnlinkedCombinatorBuilder>[];
 
   /// Combinators contained in this export declaration.
-  void set combinators(List<UnlinkedCombinatorBuilder> value) {
+  set combinators(List<UnlinkedCombinatorBuilder> value) {
     this._combinators = value;
   }
 
@@ -24714,7 +24514,7 @@
 
   /// Configurations used to control which library will actually be loaded at
   /// run-time.
-  void set configurations(List<UnlinkedConfigurationBuilder> value) {
+  set configurations(List<UnlinkedConfigurationBuilder> value) {
     this._configurations = value;
   }
 
@@ -24722,7 +24522,7 @@
   String get uri => _uri ??= '';
 
   /// URI used in the source code to reference the exported library.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -24734,17 +24534,13 @@
         _configurations = configurations,
         _uri = uri;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _combinators?.forEach((b) => b.flushInformative());
     _configurations?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._combinators == null) {
@@ -24880,7 +24676,7 @@
       _assignmentOperators ??= <idl.UnlinkedExprAssignOperator>[];
 
   /// Sequence of operators used by assignment operations.
-  void set assignmentOperators(List<idl.UnlinkedExprAssignOperator> value) {
+  set assignmentOperators(List<idl.UnlinkedExprAssignOperator> value) {
     this._assignmentOperators = value;
   }
 
@@ -24888,7 +24684,7 @@
   List<double> get doubles => _doubles ??= <double>[];
 
   /// Sequence of 64-bit doubles consumed by the operation `pushDouble`.
-  void set doubles(List<double> value) {
+  set doubles(List<double> value) {
     this._doubles = value;
   }
 
@@ -24898,7 +24694,7 @@
   /// Sequence of unsigned 32-bit integers consumed by the operations
   /// `pushArgument`, `pushInt`, `shiftOr`, `concatenate`, `invokeConstructor`,
   /// `makeList`, and `makeMap`.
-  void set ints(List<int> value) {
+  set ints(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._ints = value;
   }
@@ -24908,7 +24704,7 @@
 
   /// Indicates whether the expression is a valid potentially constant
   /// expression.
-  void set isValidConst(bool value) {
+  set isValidConst(bool value) {
     this._isValidConst = value;
   }
 
@@ -24918,7 +24714,7 @@
 
   /// Sequence of operations to execute (starting with an empty stack) to form
   /// the constant value.
-  void set operations(List<idl.UnlinkedExprOperation> value) {
+  set operations(List<idl.UnlinkedExprOperation> value) {
     this._operations = value;
   }
 
@@ -24929,7 +24725,7 @@
   /// `pushReference`, `invokeConstructor`, `makeList`, and `makeMap`.  Note
   /// that in the case of `pushReference` (and sometimes `invokeConstructor` the
   /// actual entity being referred to may be something other than a type.
-  void set references(List<EntityRefBuilder> value) {
+  set references(List<EntityRefBuilder> value) {
     this._references = value;
   }
 
@@ -24938,7 +24734,7 @@
 
   /// String representation of the expression in a form suitable to be tokenized
   /// and parsed.
-  void set sourceRepresentation(String value) {
+  set sourceRepresentation(String value) {
     this._sourceRepresentation = value;
   }
 
@@ -24947,7 +24743,7 @@
 
   /// Sequence of strings consumed by the operations `pushString` and
   /// `invokeConstructor`.
-  void set strings(List<String> value) {
+  set strings(List<String> value) {
     this._strings = value;
   }
 
@@ -24969,16 +24765,12 @@
         _sourceRepresentation = sourceRepresentation,
         _strings = strings;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _references?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._operations == null) {
       signature.addInt(0);
@@ -25242,7 +25034,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this import declaration.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -25251,7 +25043,7 @@
       _combinators ??= <UnlinkedCombinatorBuilder>[];
 
   /// Combinators contained in this import declaration.
-  void set combinators(List<UnlinkedCombinatorBuilder> value) {
+  set combinators(List<UnlinkedCombinatorBuilder> value) {
     this._combinators = value;
   }
 
@@ -25261,7 +25053,7 @@
 
   /// Configurations used to control which library will actually be loaded at
   /// run-time.
-  void set configurations(List<UnlinkedConfigurationBuilder> value) {
+  set configurations(List<UnlinkedConfigurationBuilder> value) {
     this._configurations = value;
   }
 
@@ -25269,7 +25061,7 @@
   bool get isDeferred => _isDeferred ??= false;
 
   /// Indicates whether the import declaration uses the `deferred` keyword.
-  void set isDeferred(bool value) {
+  set isDeferred(bool value) {
     this._isDeferred = value;
   }
 
@@ -25277,7 +25069,7 @@
   bool get isImplicit => _isImplicit ??= false;
 
   /// Indicates whether the import declaration is implicit.
-  void set isImplicit(bool value) {
+  set isImplicit(bool value) {
     this._isImplicit = value;
   }
 
@@ -25286,7 +25078,7 @@
 
   /// If [isImplicit] is false, offset of the "import" keyword.  If [isImplicit]
   /// is true, zero.
-  void set offset(int value) {
+  set offset(int value) {
     assert(value == null || value >= 0);
     this._offset = value;
   }
@@ -25296,7 +25088,7 @@
 
   /// Offset of the prefix name relative to the beginning of the file, or zero
   /// if there is no prefix.
-  void set prefixOffset(int value) {
+  set prefixOffset(int value) {
     assert(value == null || value >= 0);
     this._prefixOffset = value;
   }
@@ -25308,7 +25100,7 @@
   /// import declaration, or zero if this import declaration declares no prefix.
   ///
   /// Note that multiple imports can declare the same prefix.
-  void set prefixReference(int value) {
+  set prefixReference(int value) {
     assert(value == null || value >= 0);
     this._prefixReference = value;
   }
@@ -25317,7 +25109,7 @@
   String get uri => _uri ??= '';
 
   /// URI used in the source code to reference the imported library.
-  void set uri(String value) {
+  set uri(String value) {
     this._uri = value;
   }
 
@@ -25326,7 +25118,7 @@
 
   /// End of the URI string (including quotes) relative to the beginning of the
   /// file.  If [isImplicit] is true, zero.
-  void set uriEnd(int value) {
+  set uriEnd(int value) {
     assert(value == null || value >= 0);
     this._uriEnd = value;
   }
@@ -25336,7 +25128,7 @@
 
   /// Offset of the URI string (including quotes) relative to the beginning of
   /// the file.  If [isImplicit] is true, zero.
-  void set uriOffset(int value) {
+  set uriOffset(int value) {
     assert(value == null || value >= 0);
     this._uriOffset = value;
   }
@@ -25365,9 +25157,7 @@
         _uriEnd = uriEnd,
         _uriOffset = uriOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _combinators?.forEach((b) => b.flushInformative());
@@ -25378,9 +25168,7 @@
     _uriOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._uri ?? '');
     if (this._combinators == null) {
@@ -25641,7 +25429,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this parameter.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -25649,7 +25437,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the parameter.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -25658,7 +25446,7 @@
 
   /// If the parameter has a default value, the source text of the constant
   /// expression in the default value.  Otherwise the empty string.
-  void set defaultValueCode(String value) {
+  set defaultValueCode(String value) {
     this._defaultValueCode = value;
   }
 
@@ -25674,7 +25462,7 @@
   /// inferable, they are not marked as such in the summary; if their type is
   /// not specified, they always inherit the static type of the corresponding
   /// field.
-  void set inferredTypeSlot(int value) {
+  set inferredTypeSlot(int value) {
     assert(value == null || value >= 0);
     this._inferredTypeSlot = value;
   }
@@ -25688,7 +25476,7 @@
   /// `@covariant` behavior from a base class.
   ///
   /// Otherwise, zero.
-  void set inheritsCovariantSlot(int value) {
+  set inheritsCovariantSlot(int value) {
     assert(value == null || value >= 0);
     this._inheritsCovariantSlot = value;
   }
@@ -25698,7 +25486,7 @@
 
   /// The synthetic initializer function of the parameter.  Absent if the
   /// variable does not have an initializer.
-  void set initializer(UnlinkedExecutableBuilder value) {
+  set initializer(UnlinkedExecutableBuilder value) {
     this._initializer = value;
   }
 
@@ -25706,7 +25494,7 @@
   bool get isExplicitlyCovariant => _isExplicitlyCovariant ??= false;
 
   /// Indicates whether this parameter is explicitly marked as being covariant.
-  void set isExplicitlyCovariant(bool value) {
+  set isExplicitlyCovariant(bool value) {
     this._isExplicitlyCovariant = value;
   }
 
@@ -25714,7 +25502,7 @@
   bool get isFinal => _isFinal ??= false;
 
   /// Indicates whether the parameter is declared using the `final` keyword.
-  void set isFinal(bool value) {
+  set isFinal(bool value) {
     this._isFinal = value;
   }
 
@@ -25729,7 +25517,7 @@
   /// ```
   /// but is not function-typed if it does not, even if the type of the
   /// parameter is a function type.
-  void set isFunctionTyped(bool value) {
+  set isFunctionTyped(bool value) {
     this._isFunctionTyped = value;
   }
 
@@ -25738,7 +25526,7 @@
 
   /// Indicates whether this is an initializing formal parameter (i.e. it is
   /// declared using `this.` syntax).
-  void set isInitializingFormal(bool value) {
+  set isInitializingFormal(bool value) {
     this._isInitializingFormal = value;
   }
 
@@ -25746,7 +25534,7 @@
   idl.UnlinkedParamKind get kind => _kind ??= idl.UnlinkedParamKind.required;
 
   /// Kind of the parameter.
-  void set kind(idl.UnlinkedParamKind value) {
+  set kind(idl.UnlinkedParamKind value) {
     this._kind = value;
   }
 
@@ -25754,7 +25542,7 @@
   String get name => _name ??= '';
 
   /// Name of the parameter.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -25762,7 +25550,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the parameter name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -25772,7 +25560,7 @@
       _parameters ??= <UnlinkedParamBuilder>[];
 
   /// If [isFunctionTyped] is `true`, the parameters of the function type.
-  void set parameters(List<UnlinkedParamBuilder> value) {
+  set parameters(List<UnlinkedParamBuilder> value) {
     this._parameters = value;
   }
 
@@ -25782,7 +25570,7 @@
   /// If [isFunctionTyped] is `true`, the declared return type.  If
   /// [isFunctionTyped] is `false`, the declared type.  Absent if the type is
   /// implicit.
-  void set type(EntityRefBuilder value) {
+  set type(EntityRefBuilder value) {
     this._type = value;
   }
 
@@ -25790,7 +25578,7 @@
   int get visibleLength => _visibleLength ??= 0;
 
   /// The length of the visible range.
-  void set visibleLength(int value) {
+  set visibleLength(int value) {
     assert(value == null || value >= 0);
     this._visibleLength = value;
   }
@@ -25799,7 +25587,7 @@
   int get visibleOffset => _visibleOffset ??= 0;
 
   /// The beginning of the visible range.
-  void set visibleOffset(int value) {
+  set visibleOffset(int value) {
     assert(value == null || value >= 0);
     this._visibleOffset = value;
   }
@@ -25840,9 +25628,7 @@
         _visibleLength = visibleLength,
         _visibleOffset = visibleOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -25855,9 +25641,7 @@
     _visibleOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addInt(this._inferredTypeSlot ?? 0);
@@ -26194,7 +25978,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this part declaration.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -26203,7 +25987,7 @@
 
   /// End of the URI string (including quotes) relative to the beginning of the
   /// file.
-  void set uriEnd(int value) {
+  set uriEnd(int value) {
     assert(value == null || value >= 0);
     this._uriEnd = value;
   }
@@ -26213,7 +25997,7 @@
 
   /// Offset of the URI string (including quotes) relative to the beginning of
   /// the file.
-  void set uriOffset(int value) {
+  set uriOffset(int value) {
     assert(value == null || value >= 0);
     this._uriOffset = value;
   }
@@ -26224,18 +26008,14 @@
         _uriEnd = uriEnd,
         _uriOffset = uriOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _uriEnd = null;
     _uriOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._annotations == null) {
       signature.addInt(0);
@@ -26343,7 +26123,7 @@
   idl.ReferenceKind get kind => _kind ??= idl.ReferenceKind.classOrEnum;
 
   /// The kind of object referred to by the name.
-  void set kind(idl.ReferenceKind value) {
+  set kind(idl.ReferenceKind value) {
     this._kind = value;
   }
 
@@ -26357,7 +26137,7 @@
   ///
   /// Unnamed constructors are not included since they do not constitute a
   /// separate name added to any namespace.
-  void set members(List<UnlinkedPublicNameBuilder> value) {
+  set members(List<UnlinkedPublicNameBuilder> value) {
     this._members = value;
   }
 
@@ -26365,7 +26145,7 @@
   String get name => _name ??= '';
 
   /// The name itself.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -26374,7 +26154,7 @@
 
   /// If the entity being referred to is generic, the number of type parameters
   /// it accepts.  Otherwise zero.
-  void set numTypeParameters(int value) {
+  set numTypeParameters(int value) {
     assert(value == null || value >= 0);
     this._numTypeParameters = value;
   }
@@ -26389,16 +26169,12 @@
         _name = name,
         _numTypeParameters = numTypeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _members?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addInt(this._kind == null ? 0 : this._kind.index);
@@ -26529,7 +26305,7 @@
       _exports ??= <UnlinkedExportPublicBuilder>[];
 
   /// Export declarations in the compilation unit.
-  void set exports(List<UnlinkedExportPublicBuilder> value) {
+  set exports(List<UnlinkedExportPublicBuilder> value) {
     this._exports = value;
   }
 
@@ -26541,7 +26317,7 @@
   ///
   /// TODO(paulberry): consider sorting these names to reduce unnecessary
   /// relinking.
-  void set names(List<UnlinkedPublicNameBuilder> value) {
+  set names(List<UnlinkedPublicNameBuilder> value) {
     this._names = value;
   }
 
@@ -26549,7 +26325,7 @@
   List<String> get parts => _parts ??= <String>[];
 
   /// URIs referenced by part declarations in the compilation unit.
-  void set parts(List<String> value) {
+  set parts(List<String> value) {
     this._parts = value;
   }
 
@@ -26561,17 +26337,13 @@
         _names = names,
         _parts = parts;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _exports?.forEach((b) => b.flushInformative());
     _names?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._names == null) {
       signature.addInt(0);
@@ -26720,7 +26492,7 @@
   /// Name of the entity being referred to.  For the pseudo-type `dynamic`, the
   /// string is "dynamic".  For the pseudo-type `void`, the string is "void".
   /// For the pseudo-type `bottom`, the string is "*bottom*".
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -26733,7 +26505,7 @@
   /// Prefix references must always point backward; that is, for all i, if
   /// UnlinkedUnit.references[i].prefixReference != 0, then
   /// UnlinkedUnit.references[i].prefixReference < i.
-  void set prefixReference(int value) {
+  set prefixReference(int value) {
     assert(value == null || value >= 0);
     this._prefixReference = value;
   }
@@ -26742,14 +26514,10 @@
       : _name = name,
         _prefixReference = prefixReference;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addInt(this._prefixReference ?? 0);
@@ -26841,7 +26609,7 @@
 
   /// The token that corresponds to this token, or `0` if this token is not
   /// the first of a pair of matching tokens (such as parentheses).
-  void set endGroup(List<int> value) {
+  set endGroup(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._endGroup = value;
   }
@@ -26852,21 +26620,21 @@
   /// Return `true` if this token is a synthetic token. A synthetic token is a
   /// token that was introduced by the parser in order to recover from an error
   /// in the code.
-  void set isSynthetic(List<bool> value) {
+  set isSynthetic(List<bool> value) {
     this._isSynthetic = value;
   }
 
   @override
   List<idl.UnlinkedTokenKind> get kind => _kind ??= <idl.UnlinkedTokenKind>[];
 
-  void set kind(List<idl.UnlinkedTokenKind> value) {
+  set kind(List<idl.UnlinkedTokenKind> value) {
     this._kind = value;
   }
 
   @override
   List<int> get length => _length ??= <int>[];
 
-  void set length(List<int> value) {
+  set length(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._length = value;
   }
@@ -26874,7 +26642,7 @@
   @override
   List<String> get lexeme => _lexeme ??= <String>[];
 
-  void set lexeme(List<String> value) {
+  set lexeme(List<String> value) {
     this._lexeme = value;
   }
 
@@ -26883,7 +26651,7 @@
 
   /// The next token in the token stream, `0` for [UnlinkedTokenType.EOF] or
   /// the last comment token.
-  void set next(List<int> value) {
+  set next(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._next = value;
   }
@@ -26891,7 +26659,7 @@
   @override
   List<int> get offset => _offset ??= <int>[];
 
-  void set offset(List<int> value) {
+  set offset(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._offset = value;
   }
@@ -26903,7 +26671,7 @@
   /// or `0` if there are no comments preceding this token. Additional comments
   /// can be reached by following the token stream using [next] until `0` is
   /// reached.
-  void set precedingComment(List<int> value) {
+  set precedingComment(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._precedingComment = value;
   }
@@ -26911,7 +26679,7 @@
   @override
   List<idl.UnlinkedTokenType> get type => _type ??= <idl.UnlinkedTokenType>[];
 
-  void set type(List<idl.UnlinkedTokenType> value) {
+  set type(List<idl.UnlinkedTokenType> value) {
     this._type = value;
   }
 
@@ -26935,14 +26703,10 @@
         _precedingComment = precedingComment,
         _type = type;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {}
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     if (this._endGroup == null) {
       signature.addInt(0);
@@ -27239,7 +27003,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this typedef.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -27247,7 +27011,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the typedef.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -27257,7 +27021,7 @@
 
   /// Documentation comment for the typedef, or `null` if there is no
   /// documentation comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -27265,7 +27029,7 @@
   String get name => _name ??= '';
 
   /// Name of the typedef.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -27273,7 +27037,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the typedef name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -27288,7 +27052,7 @@
   /// raw type when specifying the bound of a type parameter.
   ///
   /// Otherwise, zero.
-  void set notSimplyBoundedSlot(int value) {
+  set notSimplyBoundedSlot(int value) {
     assert(value == null || value >= 0);
     this._notSimplyBoundedSlot = value;
   }
@@ -27298,7 +27062,7 @@
       _parameters ??= <UnlinkedParamBuilder>[];
 
   /// Parameters of the executable, if any.
-  void set parameters(List<UnlinkedParamBuilder> value) {
+  set parameters(List<UnlinkedParamBuilder> value) {
     this._parameters = value;
   }
 
@@ -27308,7 +27072,7 @@
   /// If [style] is [TypedefStyle.functionType], the return type of the typedef.
   /// If [style] is [TypedefStyle.genericFunctionType], the function type being
   /// defined.
-  void set returnType(EntityRefBuilder value) {
+  set returnType(EntityRefBuilder value) {
     this._returnType = value;
   }
 
@@ -27316,7 +27080,7 @@
   idl.TypedefStyle get style => _style ??= idl.TypedefStyle.functionType;
 
   /// The style of the typedef.
-  void set style(idl.TypedefStyle value) {
+  set style(idl.TypedefStyle value) {
     this._style = value;
   }
 
@@ -27325,7 +27089,7 @@
       _typeParameters ??= <UnlinkedTypeParamBuilder>[];
 
   /// Type parameters of the typedef, if any.
-  void set typeParameters(List<UnlinkedTypeParamBuilder> value) {
+  set typeParameters(List<UnlinkedTypeParamBuilder> value) {
     this._typeParameters = value;
   }
 
@@ -27351,9 +27115,7 @@
         _style = style,
         _typeParameters = typeParameters;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -27364,9 +27126,7 @@
     _typeParameters?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addBool(this._returnType != null);
@@ -27621,7 +27381,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this type parameter.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -27630,7 +27390,7 @@
 
   /// Bound of the type parameter, if a bound is explicitly declared.  Otherwise
   /// null.
-  void set bound(EntityRefBuilder value) {
+  set bound(EntityRefBuilder value) {
     this._bound = value;
   }
 
@@ -27638,7 +27398,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the type parameter.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -27646,7 +27406,7 @@
   String get name => _name ??= '';
 
   /// Name of the type parameter.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -27654,7 +27414,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the type parameter name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -27671,9 +27431,7 @@
         _name = name,
         _nameOffset = nameOffset;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _bound?.flushInformative();
@@ -27681,9 +27439,7 @@
     _nameOffset = null;
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addBool(this._bound != null);
@@ -27848,7 +27604,7 @@
   /// MD5 hash of the non-informative fields of the [UnlinkedUnit] (not
   /// including this one) as 16 unsigned 8-bit integer values.  This can be used
   /// to identify when the API of a unit may have changed.
-  void set apiSignature(List<int> value) {
+  set apiSignature(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._apiSignature = value;
   }
@@ -27858,7 +27614,7 @@
       _classes ??= <UnlinkedClassBuilder>[];
 
   /// Classes declared in the compilation unit.
-  void set classes(List<UnlinkedClassBuilder> value) {
+  set classes(List<UnlinkedClassBuilder> value) {
     this._classes = value;
   }
 
@@ -27866,7 +27622,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the unit.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -27874,7 +27630,7 @@
   List<UnlinkedEnumBuilder> get enums => _enums ??= <UnlinkedEnumBuilder>[];
 
   /// Enums declared in the compilation unit.
-  void set enums(List<UnlinkedEnumBuilder> value) {
+  set enums(List<UnlinkedEnumBuilder> value) {
     this._enums = value;
   }
 
@@ -27884,7 +27640,7 @@
 
   /// Top level executable objects (functions, getters, and setters) declared in
   /// the compilation unit.
-  void set executables(List<UnlinkedExecutableBuilder> value) {
+  set executables(List<UnlinkedExecutableBuilder> value) {
     this._executables = value;
   }
 
@@ -27893,7 +27649,7 @@
       _exports ??= <UnlinkedExportNonPublicBuilder>[];
 
   /// Export declarations in the compilation unit.
-  void set exports(List<UnlinkedExportNonPublicBuilder> value) {
+  set exports(List<UnlinkedExportNonPublicBuilder> value) {
     this._exports = value;
   }
 
@@ -27906,7 +27662,7 @@
       _imports ??= <UnlinkedImportBuilder>[];
 
   /// Import declarations in the compilation unit.
-  void set imports(List<UnlinkedImportBuilder> value) {
+  set imports(List<UnlinkedImportBuilder> value) {
     this._imports = value;
   }
 
@@ -27914,7 +27670,7 @@
   bool get isPartOf => _isPartOf ??= false;
 
   /// Indicates whether the unit contains a "part of" declaration.
-  void set isPartOf(bool value) {
+  set isPartOf(bool value) {
     this._isPartOf = value;
   }
 
@@ -27924,7 +27680,7 @@
 
   /// Annotations for the library declaration, or the empty list if there is no
   /// library declaration.
-  void set libraryAnnotations(List<UnlinkedExprBuilder> value) {
+  set libraryAnnotations(List<UnlinkedExprBuilder> value) {
     this._libraryAnnotations = value;
   }
 
@@ -27934,8 +27690,7 @@
 
   /// Documentation comment for the library, or `null` if there is no
   /// documentation comment.
-  void set libraryDocumentationComment(
-      UnlinkedDocumentationCommentBuilder value) {
+  set libraryDocumentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._libraryDocumentationComment = value;
   }
 
@@ -27943,7 +27698,7 @@
   String get libraryName => _libraryName ??= '';
 
   /// Name of the library (from a "library" declaration, if present).
-  void set libraryName(String value) {
+  set libraryName(String value) {
     this._libraryName = value;
   }
 
@@ -27952,7 +27707,7 @@
 
   /// Length of the library name as it appears in the source code (or 0 if the
   /// library has no name).
-  void set libraryNameLength(int value) {
+  set libraryNameLength(int value) {
     assert(value == null || value >= 0);
     this._libraryNameLength = value;
   }
@@ -27962,7 +27717,7 @@
 
   /// Offset of the library name relative to the beginning of the file (or 0 if
   /// the library has no name).
-  void set libraryNameOffset(int value) {
+  set libraryNameOffset(int value) {
     assert(value == null || value >= 0);
     this._libraryNameOffset = value;
   }
@@ -27971,7 +27726,7 @@
   List<int> get lineStarts => _lineStarts ??= <int>[];
 
   /// Offsets of the first character of each line in the source code.
-  void set lineStarts(List<int> value) {
+  set lineStarts(List<int> value) {
     assert(value == null || value.every((e) => e >= 0));
     this._lineStarts = value;
   }
@@ -27980,7 +27735,7 @@
   List<UnlinkedClassBuilder> get mixins => _mixins ??= <UnlinkedClassBuilder>[];
 
   /// Mixins declared in the compilation unit.
-  void set mixins(List<UnlinkedClassBuilder> value) {
+  set mixins(List<UnlinkedClassBuilder> value) {
     this._mixins = value;
   }
 
@@ -27988,7 +27743,7 @@
   List<UnlinkedPartBuilder> get parts => _parts ??= <UnlinkedPartBuilder>[];
 
   /// Part declarations in the compilation unit.
-  void set parts(List<UnlinkedPartBuilder> value) {
+  set parts(List<UnlinkedPartBuilder> value) {
     this._parts = value;
   }
 
@@ -27996,7 +27751,7 @@
   UnlinkedPublicNamespaceBuilder get publicNamespace => _publicNamespace;
 
   /// Unlinked public namespace of this compilation unit.
-  void set publicNamespace(UnlinkedPublicNamespaceBuilder value) {
+  set publicNamespace(UnlinkedPublicNamespaceBuilder value) {
     this._publicNamespace = value;
   }
 
@@ -28009,7 +27764,7 @@
   /// the absence of a reference in places where a reference is optional (for
   /// example [UnlinkedReference.prefixReference or
   /// UnlinkedImport.prefixReference]).
-  void set references(List<UnlinkedReferenceBuilder> value) {
+  set references(List<UnlinkedReferenceBuilder> value) {
     this._references = value;
   }
 
@@ -28018,7 +27773,7 @@
       _typedefs ??= <UnlinkedTypedefBuilder>[];
 
   /// Typedefs declared in the compilation unit.
-  void set typedefs(List<UnlinkedTypedefBuilder> value) {
+  set typedefs(List<UnlinkedTypedefBuilder> value) {
     this._typedefs = value;
   }
 
@@ -28027,7 +27782,7 @@
       _variables ??= <UnlinkedVariableBuilder>[];
 
   /// Top level variables declared in the compilation unit.
-  void set variables(List<UnlinkedVariableBuilder> value) {
+  set variables(List<UnlinkedVariableBuilder> value) {
     this._variables = value;
   }
 
@@ -28073,9 +27828,7 @@
         _typedefs = typedefs,
         _variables = variables;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _classes?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -28096,9 +27849,7 @@
     _variables?.forEach((b) => b.flushInformative());
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addBool(this._publicNamespace != null);
     this._publicNamespace?.collectApiSignature(signature);
@@ -28646,7 +28397,7 @@
       _annotations ??= <UnlinkedExprBuilder>[];
 
   /// Annotations for this variable.
-  void set annotations(List<UnlinkedExprBuilder> value) {
+  set annotations(List<UnlinkedExprBuilder> value) {
     this._annotations = value;
   }
 
@@ -28654,7 +28405,7 @@
   CodeRangeBuilder get codeRange => _codeRange;
 
   /// Code range of the variable.
-  void set codeRange(CodeRangeBuilder value) {
+  set codeRange(CodeRangeBuilder value) {
     this._codeRange = value;
   }
 
@@ -28664,7 +28415,7 @@
 
   /// Documentation comment for the variable, or `null` if there is no
   /// documentation comment.
-  void set documentationComment(UnlinkedDocumentationCommentBuilder value) {
+  set documentationComment(UnlinkedDocumentationCommentBuilder value) {
     this._documentationComment = value;
   }
 
@@ -28675,7 +28426,7 @@
   /// [LinkedLibrary.types] contains the inferred type for this variable.  If
   /// there is no matching entry in [LinkedLibrary.types], then no type was
   /// inferred for this variable, so its static type is `dynamic`.
-  void set inferredTypeSlot(int value) {
+  set inferredTypeSlot(int value) {
     assert(value == null || value >= 0);
     this._inferredTypeSlot = value;
   }
@@ -28689,7 +28440,7 @@
   /// synthetic setter inherits `@covariant` behavior from a base class.
   ///
   /// Otherwise, zero.
-  void set inheritsCovariantSlot(int value) {
+  set inheritsCovariantSlot(int value) {
     assert(value == null || value >= 0);
     this._inheritsCovariantSlot = value;
   }
@@ -28699,7 +28450,7 @@
 
   /// The synthetic initializer function of the variable.  Absent if the
   /// variable does not have an initializer.
-  void set initializer(UnlinkedExecutableBuilder value) {
+  set initializer(UnlinkedExecutableBuilder value) {
     this._initializer = value;
   }
 
@@ -28707,7 +28458,7 @@
   bool get isConst => _isConst ??= false;
 
   /// Indicates whether the variable is declared using the `const` keyword.
-  void set isConst(bool value) {
+  set isConst(bool value) {
     this._isConst = value;
   }
 
@@ -28716,7 +28467,7 @@
 
   /// Indicates whether this variable is declared using the `covariant` keyword.
   /// This should be false for everything except instance fields.
-  void set isCovariant(bool value) {
+  set isCovariant(bool value) {
     this._isCovariant = value;
   }
 
@@ -28724,7 +28475,7 @@
   bool get isFinal => _isFinal ??= false;
 
   /// Indicates whether the variable is declared using the `final` keyword.
-  void set isFinal(bool value) {
+  set isFinal(bool value) {
     this._isFinal = value;
   }
 
@@ -28736,7 +28487,7 @@
   /// Note that for top level variables, this flag is false, since they are not
   /// declared using the `static` keyword (even though they are considered
   /// static for semantic purposes).
-  void set isStatic(bool value) {
+  set isStatic(bool value) {
     this._isStatic = value;
   }
 
@@ -28744,7 +28495,7 @@
   String get name => _name ??= '';
 
   /// Name of the variable.
-  void set name(String value) {
+  set name(String value) {
     this._name = value;
   }
 
@@ -28752,7 +28503,7 @@
   int get nameOffset => _nameOffset ??= 0;
 
   /// Offset of the variable name relative to the beginning of the file.
-  void set nameOffset(int value) {
+  set nameOffset(int value) {
     assert(value == null || value >= 0);
     this._nameOffset = value;
   }
@@ -28766,7 +28517,7 @@
   /// propagated type is the same as its declared type.
   ///
   /// Non-propagable variables have a [propagatedTypeSlot] of zero.
-  void set propagatedTypeSlot(int value) {
+  set propagatedTypeSlot(int value) {
     assert(value == null || value >= 0);
     this._propagatedTypeSlot = value;
   }
@@ -28775,7 +28526,7 @@
   EntityRefBuilder get type => _type;
 
   /// Declared type of the variable.  Absent if the type is implicit.
-  void set type(EntityRefBuilder value) {
+  set type(EntityRefBuilder value) {
     this._type = value;
   }
 
@@ -28817,9 +28568,7 @@
         _propagatedTypeSlot = propagatedTypeSlot,
         _type = type;
 
-  /**
-   * Flush [informative] data recursively.
-   */
+  /// Flush [informative] data recursively.
   void flushInformative() {
     _annotations?.forEach((b) => b.flushInformative());
     _codeRange = null;
@@ -28829,9 +28578,7 @@
     _type?.flushInformative();
   }
 
-  /**
-   * Accumulate non-[informative] data into [signature].
-   */
+  /// Accumulate non-[informative] data into [signature].
   void collectApiSignature(api_sig.ApiSignature signature) {
     signature.addString(this._name ?? '');
     signature.addInt(this._propagatedTypeSlot ?? 0);
diff --git a/pkg/analyzer/lib/src/summary/format.fbs b/pkg/analyzer/lib/src/summary/format.fbs
index bab0ccd..bb86ffb 100644
--- a/pkg/analyzer/lib/src/summary/format.fbs
+++ b/pkg/analyzer/lib/src/summary/format.fbs
@@ -1547,40 +1547,38 @@
 
 /// Information about a single declaration.
 table AvailableDeclaration {
-  defaultArgumentListString:string (id: 0);
+  children:[AvailableDeclaration] (id: 0);
 
-  defaultArgumentListTextRanges:[uint] (id: 1);
+  defaultArgumentListString:string (id: 1);
 
-  docComplete:string (id: 2);
+  defaultArgumentListTextRanges:[uint] (id: 2);
 
-  docSummary:string (id: 3);
+  docComplete:string (id: 3);
 
-  fieldMask:uint (id: 4);
+  docSummary:string (id: 4);
 
-  isAbstract:bool (id: 5);
+  fieldMask:uint (id: 5);
 
-  isConst:bool (id: 6);
+  isAbstract:bool (id: 6);
 
-  isDeprecated:bool (id: 7);
+  isConst:bool (id: 7);
 
-  isFinal:bool (id: 8);
+  isDeprecated:bool (id: 8);
+
+  isFinal:bool (id: 9);
 
   /// The kind of the declaration.
-  kind:AvailableDeclarationKind (id: 9);
+  kind:AvailableDeclarationKind (id: 10);
 
-  locationOffset:uint (id: 10);
+  locationOffset:uint (id: 11);
 
-  locationStartColumn:uint (id: 11);
+  locationStartColumn:uint (id: 12);
 
-  locationStartLine:uint (id: 12);
+  locationStartLine:uint (id: 13);
 
   /// The first part of the declaration name, usually the only one, for example
   /// the name of a class like `MyClass`, or a function like `myFunction`.
-  name:string (id: 13);
-
-  /// The second, optional, part of the declaration name.  For example enum
-  /// constants all have the same [name], but their own [name2].
-  name2:string (id: 14);
+  name:string (id: 14);
 
   parameterNames:[string] (id: 15);
 
@@ -1603,12 +1601,12 @@
 
 /// Information about an available, even if not yet imported file.
 table AvailableFile {
-  /// The Dartdoc directives in the file.
-  directiveInfo:DirectiveInfo (id: 5);
-
   /// Declarations of the file.
   declarations:[AvailableDeclaration] (id: 0);
 
+  /// The Dartdoc directives in the file.
+  directiveInfo:DirectiveInfo (id: 5);
+
   /// Exports directives of the file.
   exports:[AvailableFileExport] (id: 1);
 
@@ -1838,6 +1836,9 @@
 
 /// Information about a linked AST node.
 table LinkedNode {
+  /// The explicit or inferred return type of a function typed node.
+  variantField_24:LinkedNodeType (id: 24);
+
   variantField_2:[LinkedNode] (id: 2);
 
   variantField_11:LinkedNode (id: 11);
@@ -1860,8 +1861,6 @@
 
   variantField_19:uint (id: 19);
 
-  variantField_24:LinkedNodeType (id: 24);
-
   variantField_27:bool (id: 27);
 
   variantField_9:LinkedNode (id: 9);
diff --git a/pkg/analyzer/lib/src/summary/idl.dart b/pkg/analyzer/lib/src/summary/idl.dart
index 60284a3..4b897bc 100644
--- a/pkg/analyzer/lib/src/summary/idl.dart
+++ b/pkg/analyzer/lib/src/summary/idl.dart
@@ -288,54 +288,52 @@
 /// Information about a single declaration.
 abstract class AvailableDeclaration extends base.SummaryClass {
   @Id(0)
-  String get defaultArgumentListString;
+  List<AvailableDeclaration> get children;
 
   @Id(1)
-  List<int> get defaultArgumentListTextRanges;
+  String get defaultArgumentListString;
 
   @Id(2)
-  String get docComplete;
+  List<int> get defaultArgumentListTextRanges;
 
   @Id(3)
-  String get docSummary;
+  String get docComplete;
 
   @Id(4)
-  int get fieldMask;
+  String get docSummary;
 
   @Id(5)
-  bool get isAbstract;
+  int get fieldMask;
 
   @Id(6)
-  bool get isConst;
+  bool get isAbstract;
 
   @Id(7)
-  bool get isDeprecated;
+  bool get isConst;
 
   @Id(8)
+  bool get isDeprecated;
+
+  @Id(9)
   bool get isFinal;
 
   /// The kind of the declaration.
-  @Id(9)
+  @Id(10)
   AvailableDeclarationKind get kind;
 
-  @Id(10)
+  @Id(11)
   int get locationOffset;
 
-  @Id(11)
+  @Id(12)
   int get locationStartColumn;
 
-  @Id(12)
+  @Id(13)
   int get locationStartLine;
 
   /// The first part of the declaration name, usually the only one, for example
   /// the name of a class like `MyClass`, or a function like `myFunction`.
-  @Id(13)
-  String get name;
-
-  /// The second, optional, part of the declaration name.  For example enum
-  /// constants all have the same [name], but their own [name2].
   @Id(14)
-  String get name2;
+  String get name;
 
   @Id(15)
   List<String> get parameterNames;
@@ -384,14 +382,14 @@
   factory AvailableFile.fromBuffer(List<int> buffer) =>
       generated.readAvailableFile(buffer);
 
-  /// The Dartdoc directives in the file.
-  @Id(5)
-  DirectiveInfo get directiveInfo;
-
   /// Declarations of the file.
   @Id(0)
   List<AvailableDeclaration> get declarations;
 
+  /// The Dartdoc directives in the file.
+  @Id(5)
+  DirectiveInfo get directiveInfo;
+
   /// Exports directives of the file.
   @Id(1)
   List<AvailableFileExport> get exports;
@@ -770,6 +768,25 @@
 /// Information about a linked AST node.
 @Variant('kind')
 abstract class LinkedNode extends base.SummaryClass {
+  /// The explicit or inferred return type of a function typed node.
+  @VariantId(24, variantList: [
+    LinkedNodeKind.functionDeclaration,
+    LinkedNodeKind.functionExpression,
+    LinkedNodeKind.functionTypeAlias,
+    LinkedNodeKind.genericFunctionType,
+    LinkedNodeKind.methodDeclaration,
+  ])
+  LinkedNodeType get actualReturnType;
+
+  /// The explicit or inferred type of a variable.
+  @VariantId(24, variantList: [
+    LinkedNodeKind.fieldFormalParameter,
+    LinkedNodeKind.functionTypedFormalParameter,
+    LinkedNodeKind.simpleFormalParameter,
+    LinkedNodeKind.variableDeclaration,
+  ])
+  LinkedNodeType get actualType;
+
   @VariantId(2, variant: LinkedNodeKind.adjacentStrings)
   List<LinkedNode> get adjacentStrings_strings;
 
@@ -1407,9 +1424,6 @@
   @VariantId(6, variant: LinkedNodeKind.fieldFormalParameter)
   LinkedNode get fieldFormalParameter_type;
 
-  @VariantId(24, variant: LinkedNodeKind.fieldFormalParameter)
-  LinkedNodeType get fieldFormalParameter_type2;
-
   @VariantId(7, variant: LinkedNodeKind.fieldFormalParameter)
   LinkedNode get fieldFormalParameter_typeParameters;
 
@@ -1531,12 +1545,6 @@
   @VariantId(7, variant: LinkedNodeKind.functionDeclaration)
   LinkedNode get functionDeclaration_returnType;
 
-  @VariantId(24, variantList: [
-    LinkedNodeKind.functionDeclaration,
-    LinkedNodeKind.functionExpression,
-  ])
-  LinkedNodeType get functionDeclaration_returnType2;
-
   @VariantId(6, variant: LinkedNodeKind.functionDeclarationStatement)
   LinkedNode get functionDeclarationStatement_functionDeclaration;
 
@@ -1558,9 +1566,6 @@
   @VariantId(7, variant: LinkedNodeKind.functionTypeAlias)
   LinkedNode get functionTypeAlias_returnType;
 
-  @VariantId(24, variant: LinkedNodeKind.functionTypeAlias)
-  LinkedNodeType get functionTypeAlias_returnType2;
-
   @VariantId(8, variant: LinkedNodeKind.functionTypeAlias)
   LinkedNode get functionTypeAlias_typeParameters;
 
@@ -1570,9 +1575,6 @@
   @VariantId(7, variant: LinkedNodeKind.functionTypedFormalParameter)
   LinkedNode get functionTypedFormalParameter_returnType;
 
-  @VariantId(24, variant: LinkedNodeKind.functionTypedFormalParameter)
-  LinkedNodeType get functionTypedFormalParameter_type2;
-
   @VariantId(8, variant: LinkedNodeKind.functionTypedFormalParameter)
   LinkedNode get functionTypedFormalParameter_typeParameters;
 
@@ -1588,9 +1590,6 @@
   @VariantId(7, variant: LinkedNodeKind.genericFunctionType)
   LinkedNode get genericFunctionType_returnType;
 
-  @VariantId(24, variant: LinkedNodeKind.genericFunctionType)
-  LinkedNodeType get genericFunctionType_returnType2;
-
   @VariantId(25, variant: LinkedNodeKind.genericFunctionType)
   LinkedNodeType get genericFunctionType_type;
 
@@ -1816,9 +1815,6 @@
   @VariantId(8, variant: LinkedNodeKind.methodDeclaration)
   LinkedNode get methodDeclaration_returnType;
 
-  @VariantId(24, variant: LinkedNodeKind.methodDeclaration)
-  LinkedNodeType get methodDeclaration_returnType2;
-
   @VariantId(9, variant: LinkedNodeKind.methodDeclaration)
   LinkedNode get methodDeclaration_typeParameters;
 
@@ -2041,9 +2037,6 @@
   @VariantId(6, variant: LinkedNodeKind.simpleFormalParameter)
   LinkedNode get simpleFormalParameter_type;
 
-  @VariantId(24, variant: LinkedNodeKind.simpleFormalParameter)
-  LinkedNodeType get simpleFormalParameter_type2;
-
   @VariantId(15, variant: LinkedNodeKind.simpleIdentifier)
   int get simpleIdentifier_element;
 
@@ -2056,6 +2049,15 @@
   @VariantId(20, variant: LinkedNodeKind.simpleStringLiteral)
   String get simpleStringLiteral_value;
 
+  @VariantId(31, variantList: [
+    LinkedNodeKind.classDeclaration,
+    LinkedNodeKind.classTypeAlias,
+    LinkedNodeKind.functionTypeAlias,
+    LinkedNodeKind.genericTypeAlias,
+    LinkedNodeKind.mixinDeclaration,
+  ])
+  bool get simplyBoundable_isSimplyBounded;
+
   @VariantId(6, variant: LinkedNodeKind.spreadElement)
   LinkedNode get spreadElement_expression;
 
@@ -2265,9 +2267,6 @@
   @VariantId(7, variant: LinkedNodeKind.variableDeclaration)
   LinkedNode get variableDeclaration_name;
 
-  @VariantId(24, variant: LinkedNodeKind.variableDeclaration)
-  LinkedNodeType get variableDeclaration_type2;
-
   @VariantId(15, variant: LinkedNodeKind.variableDeclarationList)
   int get variableDeclarationList_keyword;
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
index 5c35451..e08c4f6 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_reader.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
@@ -24,16 +25,26 @@
   int _localRefNextId;
   List<ParameterElement> _localParameters;
 
+  /// Set to `true` when this reader is used to lazily read its unit.
+  bool isLazy = false;
+
   AstBinaryReader(this._unitContext);
 
   AstNode readNode(LinkedNode data) {
     var node = _readNode(data);
     if (node == null) return null;
 
-    _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken);
+    if (!isLazy) {
+      _unitContext.tokensContext.linkTokens(node.beginToken, node.endToken);
+    }
+
     return node;
   }
 
+  DartType readType(LinkedNodeType data) {
+    return _readType(data);
+  }
+
   /// Run [f] that reads nodes with local declarations, making sure that
   /// [_localRef] is ready for adding local references.
   T withLocalScope<T>(ElementImpl enclosingElement, T f()) {
@@ -223,36 +234,41 @@
   }
 
   ClassDeclaration _read_classDeclaration(LinkedNode data) {
-    return astFactory.classDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.classDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.classDeclaration_abstractKeyword),
       _getToken(data.classDeclaration_classKeyword),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.classOrMixinDeclaration_typeParameters),
-      _readNode(data.classDeclaration_extendsClause),
-      _readNode(data.classDeclaration_withClause),
-      _readNode(data.classOrMixinDeclaration_implementsClause),
+      _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+      _readNodeLazy(data.classDeclaration_extendsClause),
+      _readNodeLazy(data.classDeclaration_withClause),
+      _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
       _getToken(data.classOrMixinDeclaration_leftBracket),
-      _readNodeList(data.classOrMixinDeclaration_members),
+      _readNodeListLazy(data.classOrMixinDeclaration_members),
       _getToken(data.classOrMixinDeclaration_rightBracket),
-    )..nativeClause = _readNode(data.classDeclaration_nativeClause);
+    );
+    node.nativeClause = _readNodeLazy(data.classDeclaration_nativeClause);
+    LazyClassDeclaration.setData(node, data);
+    return node;
   }
 
   ClassTypeAlias _read_classTypeAlias(LinkedNode data) {
-    return astFactory.classTypeAlias(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.classTypeAlias(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.typeAlias_typedefKeyword),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.classTypeAlias_typeParameters),
+      _readNodeLazy(data.classTypeAlias_typeParameters),
       _getToken(data.classTypeAlias_equals),
       _getToken(data.classTypeAlias_abstractKeyword),
-      _readNode(data.classTypeAlias_superclass),
-      _readNode(data.classTypeAlias_withClause),
-      _readNode(data.classTypeAlias_implementsClause),
+      _readNodeLazy(data.classTypeAlias_superclass),
+      _readNodeLazy(data.classTypeAlias_withClause),
+      _readNodeLazy(data.classTypeAlias_implementsClause),
       _getToken(data.typeAlias_semicolon),
     );
+    LazyClassTypeAlias.setData(node, data);
+    return node;
   }
 
   Comment _read_comment(LinkedNode data) {
@@ -309,21 +325,23 @@
   }
 
   ConstructorDeclaration _read_constructorDeclaration(LinkedNode data) {
-    return astFactory.constructorDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.constructorDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.constructorDeclaration_externalKeyword),
       _getToken(data.constructorDeclaration_constKeyword),
       _getToken(data.constructorDeclaration_factoryKeyword),
       _readNode(data.constructorDeclaration_returnType),
       _getToken(data.constructorDeclaration_period),
       _readNode(data.constructorDeclaration_name),
-      _readNode(data.constructorDeclaration_parameters),
+      _readNodeLazy(data.constructorDeclaration_parameters),
       _getToken(data.constructorDeclaration_separator),
-      _readNodeList(data.constructorDeclaration_initializers),
-      _readNode(data.constructorDeclaration_redirectedConstructor),
-      _readNode(data.constructorDeclaration_body),
+      _readNodeListLazy(data.constructorDeclaration_initializers),
+      _readNodeLazy(data.constructorDeclaration_redirectedConstructor),
+      _readNodeLazy(data.constructorDeclaration_body),
     );
+    LazyConstructorDeclaration.setData(node, data);
+    return node;
   }
 
   ConstructorFieldInitializer _read_constructorFieldInitializer(
@@ -364,14 +382,16 @@
   }
 
   DefaultFormalParameter _read_defaultFormalParameter(LinkedNode data) {
-    return astFactory.defaultFormalParameter(
+    var node = astFactory.defaultFormalParameter(
       _readNode(data.defaultFormalParameter_parameter),
       data.defaultFormalParameter_isNamed
           ? ParameterKind.NAMED
           : ParameterKind.POSITIONAL,
       _getToken(data.defaultFormalParameter_separator),
-      _readNode(data.defaultFormalParameter_defaultValue),
+      _readNodeLazy(data.defaultFormalParameter_defaultValue),
     );
+    LazyFormalParameter.setData(node, data);
+    return node;
   }
 
   DoStatement _read_doStatement(LinkedNode data) {
@@ -412,35 +432,41 @@
   }
 
   EnumConstantDeclaration _read_enumConstantDeclaration(LinkedNode data) {
-    return astFactory.enumConstantDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.enumConstantDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _readNode(data.enumConstantDeclaration_name),
     );
+    LazyEnumConstantDeclaration.setData(node, data);
+    return node;
   }
 
   EnumDeclaration _read_enumDeclaration(LinkedNode data) {
-    return astFactory.enumDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.enumDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.enumDeclaration_enumKeyword),
       _readNode(data.namedCompilationUnitMember_name),
       _getToken(data.enumDeclaration_leftBracket),
-      _readNodeList(data.enumDeclaration_constants),
+      _readNodeListLazy(data.enumDeclaration_constants),
       _getToken(data.enumDeclaration_rightBracket),
     );
+    LazyEnumDeclaration.setData(node, data);
+    return node;
   }
 
   ExportDirective _read_exportDirective(LinkedNode data) {
-    return astFactory.exportDirective(
+    var node = astFactory.exportDirective(
       _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.directive_keyword),
       _readNode(data.uriBasedDirective_uri),
       _readNodeList(data.namespaceDirective_configurations),
       _readNodeList(data.namespaceDirective_combinators),
       _getToken(data.directive_semicolon),
     );
+    LazyDirective.setData(node, data);
+    return node;
   }
 
   ExpressionFunctionBody _read_expressionFunctionBody(LinkedNode data) {
@@ -467,18 +493,20 @@
   }
 
   FieldDeclaration _read_fieldDeclaration(LinkedNode data) {
-    return astFactory.fieldDeclaration2(
-      comment: _readNode(data.annotatedNode_comment),
+    var node = astFactory.fieldDeclaration2(
+      comment: _readNodeLazy(data.annotatedNode_comment),
       covariantKeyword: _getToken(data.fieldDeclaration_covariantKeyword),
       fieldList: _readNode(data.fieldDeclaration_fields),
-      metadata: _readNodeList(data.annotatedNode_metadata),
+      metadata: _readNodeListLazy(data.annotatedNode_metadata),
       semicolon: _getToken(data.fieldDeclaration_semicolon),
       staticKeyword: _getToken(data.fieldDeclaration_staticKeyword),
     );
+    LazyFieldDeclaration.setData(node, data);
+    return node;
   }
 
   FieldFormalParameter _read_fieldFormalParameter(LinkedNode data) {
-    return astFactory.fieldFormalParameter2(
+    var node = astFactory.fieldFormalParameter2(
       identifier: _readNode(data.normalFormalParameter_identifier),
       period: _getToken(data.fieldFormalParameter_period),
       thisKeyword: _getToken(data.fieldFormalParameter_thisKeyword),
@@ -490,6 +518,8 @@
       type: _readNode(data.fieldFormalParameter_type),
       parameters: _readNode(data.fieldFormalParameter_formalParameters),
     );
+    LazyFormalParameter.setData(node, data);
+    return node;
   }
 
   ForEachPartsWithDeclaration _read_forEachPartsWithDeclaration(
@@ -562,15 +592,17 @@
   }
 
   FunctionDeclaration _read_functionDeclaration(LinkedNode data) {
-    return astFactory.functionDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.functionDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.functionDeclaration_externalKeyword),
-      _readNode(data.functionDeclaration_returnType),
+      _readNodeLazy(data.functionDeclaration_returnType),
       _getToken(data.functionDeclaration_propertyKeyword),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.functionDeclaration_functionExpression),
+      _readNodeLazy(data.functionDeclaration_functionExpression),
     );
+    LazyFunctionDeclaration.setData(node, data);
+    return node;
   }
 
   FunctionDeclarationStatement _read_functionDeclarationStatement(
@@ -586,31 +618,33 @@
     _localParameters = thisLocalParameters;
 
     var node = astFactory.functionExpression(
-      _readNode(data.functionExpression_typeParameters),
-      _readNode(data.functionExpression_formalParameters),
-      _readNode(data.functionExpression_body),
+      _readNodeLazy(data.functionExpression_typeParameters),
+      _readNodeLazy(data.functionExpression_formalParameters),
+      _readNodeLazy(data.functionExpression_body),
     );
     _localParameters = prevLocalParameters;
 
     if (_localRef != null) {
-      var element = FunctionElementImpl.forLinkedNode(
-        _enclosingElement,
-        _localRef.getChild('${_localRefNextId++}'),
-        data,
-      );
-      element.parameters = thisLocalParameters;
-
-      var body = node.body;
-      if (body.isAsynchronous) {
-        element.asynchronous = true;
-      }
-      if (body.isGenerator) {
-        element.generator = true;
-      }
-
-      element.type = new FunctionTypeImpl(element);
-      (node as FunctionExpressionImpl).declaredElement = element;
+      throw UnimplementedError();
+//      var element = FunctionElementImpl.forLinkedNode(
+//        _enclosingElement,
+//        _localRef.getChild('${_localRefNextId++}'),
+//        data,
+//      );
+//      element.parameters = thisLocalParameters;
+//
+//      var body = node.body;
+//      if (body.isAsynchronous) {
+//        element.asynchronous = true;
+//      }
+//      if (body.isGenerator) {
+//        element.generator = true;
+//      }
+//
+//      element.type = new FunctionTypeImpl(element);
+//      (node as FunctionExpressionImpl).declaredElement = element;
     }
+    LazyFunctionExpression.setData(node, data);
     return node;
   }
 
@@ -624,16 +658,18 @@
   }
 
   FunctionTypeAlias _read_functionTypeAlias(LinkedNode data) {
-    return astFactory.functionTypeAlias(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.functionTypeAlias(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.typeAlias_typedefKeyword),
-      _readNode(data.functionTypeAlias_returnType),
+      _readNodeLazy(data.functionTypeAlias_returnType),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.functionTypeAlias_typeParameters),
-      _readNode(data.functionTypeAlias_formalParameters),
+      _readNodeLazy(data.functionTypeAlias_typeParameters),
+      _readNodeLazy(data.functionTypeAlias_formalParameters),
       _getToken(data.typeAlias_semicolon),
     );
+    LazyFunctionTypeAlias.setData(node, data);
+    return node;
   }
 
   FunctionTypedFormalParameter _read_functionTypedFormalParameter(
@@ -650,40 +686,47 @@
     );
 
     if (_localRef != null) {
-      var name = node.identifier.name;
-      var element = ParameterElementImpl.forLinkedNodeFactory(
-        _enclosingElement,
-        _localRef.getChild('${_localRefNextId++}').getChild(name),
-        data,
-      );
-      _localParameters.add(element);
-      node.identifier.staticElement = element;
+      throw UnimplementedError();
+//      var name = node.identifier.name;
+//      var element = ParameterElementImpl.forLinkedNodeFactory(
+//        _enclosingElement,
+//        _localRef.getChild('${_localRefNextId++}').getChild(name),
+//        data,
+//      );
+//      _localParameters.add(element);
+//      node.identifier.staticElement = element;
     }
 
+    LazyFormalParameter.setData(node, data);
     return node;
   }
 
   GenericFunctionType _read_genericFunctionType(LinkedNode data) {
-    return astFactory.genericFunctionType(
-      _readNode(data.genericFunctionType_returnType),
+    GenericFunctionTypeImpl node = astFactory.genericFunctionType(
+      _readNodeLazy(data.genericFunctionType_returnType),
       _getToken(data.genericFunctionType_functionKeyword),
-      _readNode(data.genericFunctionType_typeParameters),
-      _readNode(data.genericFunctionType_formalParameters),
+      _readNodeLazy(data.genericFunctionType_typeParameters),
+      _readNodeLazy(data.genericFunctionType_formalParameters),
       question: _getToken(data.genericFunctionType_question),
     );
+    node.type = _readType(data.genericFunctionType_type);
+    LazyGenericFunctionType.setData(node, data);
+    return node;
   }
 
   GenericTypeAlias _read_genericTypeAlias(LinkedNode data) {
-    return astFactory.genericTypeAlias(
-      _readNode(data.annotatedNode_comment),
+    var node = astFactory.genericTypeAlias(
+      _readNodeLazy(data.annotatedNode_comment),
       _readNodeList(data.annotatedNode_metadata),
       _getToken(data.typeAlias_typedefKeyword),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.genericTypeAlias_typeParameters),
+      _readNodeLazy(data.genericTypeAlias_typeParameters),
       _getToken(data.genericTypeAlias_equals),
-      _readNode(data.genericTypeAlias_functionType),
+      _readNodeLazy(data.genericTypeAlias_functionType),
       _getToken(data.typeAlias_semicolon),
     );
+    LazyGenericTypeAlias.setData(node, data);
+    return node;
   }
 
   HideCombinator _read_hideCombinator(LinkedNode data) {
@@ -725,9 +768,9 @@
   }
 
   ImportDirective _read_importDirective(LinkedNode data) {
-    return astFactory.importDirective(
+    var node = astFactory.importDirective(
       _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.directive_keyword),
       _readNode(data.uriBasedDirective_uri),
       _readNodeList(data.namespaceDirective_configurations),
@@ -737,6 +780,8 @@
       _readNodeList(data.namespaceDirective_combinators),
       _getToken(data.directive_semicolon),
     );
+    LazyDirective.setData(node, data);
+    return node;
   }
 
   IndexExpression _read_indexExpression(LinkedNode data) {
@@ -806,13 +851,15 @@
   }
 
   LibraryDirective _read_libraryDirective(LinkedNode data) {
-    return astFactory.libraryDirective(
+    var node = astFactory.libraryDirective(
       _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.directive_keyword),
       _readNode(data.libraryDirective_name),
       _getToken(data.directive_semicolon),
     );
+    LazyDirective.setData(node, data);
+    return node;
   }
 
   LibraryIdentifier _read_libraryIdentifier(LinkedNode data) {
@@ -840,19 +887,21 @@
   }
 
   MethodDeclaration _read_methodDeclaration(LinkedNode data) {
-    return astFactory.methodDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.methodDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.methodDeclaration_externalKeyword),
       _getToken(data.methodDeclaration_modifierKeyword),
-      _readNode(data.methodDeclaration_returnType),
+      _readNodeLazy(data.methodDeclaration_returnType),
       _getToken(data.methodDeclaration_propertyKeyword),
       _getToken(data.methodDeclaration_operatorKeyword),
       _readNode(data.methodDeclaration_name),
-      _readNode(data.methodDeclaration_typeParameters),
-      _readNode(data.methodDeclaration_formalParameters),
-      _readNode(data.methodDeclaration_body),
+      _readNodeLazy(data.methodDeclaration_typeParameters),
+      _readNodeLazy(data.methodDeclaration_formalParameters),
+      _readNodeLazy(data.methodDeclaration_body),
     );
+    LazyMethodDeclaration.setData(node, data);
+    return node;
   }
 
   MethodInvocation _read_methodInvocation(LinkedNode data) {
@@ -866,18 +915,20 @@
   }
 
   MixinDeclaration _read_mixinDeclaration(LinkedNode data) {
-    return astFactory.mixinDeclaration(
-      _readNode(data.annotatedNode_comment),
+    var node = astFactory.mixinDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
       _readNodeList(data.annotatedNode_metadata),
       _getToken(data.mixinDeclaration_mixinKeyword),
       _readNode(data.namedCompilationUnitMember_name),
-      _readNode(data.classOrMixinDeclaration_typeParameters),
-      _readNode(data.mixinDeclaration_onClause),
-      _readNode(data.classOrMixinDeclaration_implementsClause),
+      _readNodeLazy(data.classOrMixinDeclaration_typeParameters),
+      _readNodeLazy(data.mixinDeclaration_onClause),
+      _readNodeLazy(data.classOrMixinDeclaration_implementsClause),
       _getToken(data.classOrMixinDeclaration_leftBracket),
-      _readNodeList(data.classOrMixinDeclaration_members),
+      _readNodeListLazy(data.classOrMixinDeclaration_members),
       _getToken(data.classOrMixinDeclaration_rightBracket),
     );
+    LazyMixinDeclaration.setData(node, data);
+    return node;
   }
 
   NamedExpression _read_namedExpression(LinkedNode data) {
@@ -924,17 +975,19 @@
   }
 
   PartDirective _read_partDirective(LinkedNode data) {
-    return astFactory.partDirective(
+    var node = astFactory.partDirective(
       _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.directive_keyword),
       _readNode(data.uriBasedDirective_uri),
       _getToken(data.directive_semicolon),
     );
+    LazyDirective.setData(node, data);
+    return node;
   }
 
   PartOfDirective _read_partOfDirective(LinkedNode data) {
-    return astFactory.partOfDirective(
+    var node = astFactory.partOfDirective(
       _readNode(data.annotatedNode_comment),
       _readNodeList(data.annotatedNode_metadata),
       _getToken(data.directive_keyword),
@@ -943,6 +996,8 @@
       _readNode(data.partOfDirective_libraryName),
       _getToken(data.directive_semicolon),
     );
+    LazyDirective.setData(node, data);
+    return node;
   }
 
   PostfixExpression _read_postfixExpression(LinkedNode data) {
@@ -1044,17 +1099,19 @@
     );
 
     if (_localRef != null) {
-      var name = node.identifier.name;
-      var element = ParameterElementImpl.forLinkedNodeFactory(
-        _enclosingElement,
-        _localRef.getChild('${_localRefNextId++}').getChild(name),
-        data,
-      );
-      _localParameters.add(element);
-      node.identifier.staticElement = element;
-      node.declaredElement = element;
+      throw UnimplementedError();
+//      var name = node.identifier.name;
+//      var element = ParameterElementImpl.forLinkedNodeFactory(
+//        _enclosingElement,
+//        _localRef.getChild('${_localRefNextId++}').getChild(name),
+//        data,
+//      );
+//      _localParameters.add(element);
+//      node.identifier.staticElement = element;
+//      node.declaredElement = element;
     }
 
+    LazyFormalParameter.setData(node, data);
     return node;
   }
 
@@ -1154,12 +1211,14 @@
 
   TopLevelVariableDeclaration _read_topLevelVariableDeclaration(
       LinkedNode data) {
-    return astFactory.topLevelVariableDeclaration(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.topLevelVariableDeclaration(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _readNode(data.topLevelVariableDeclaration_variableList),
       _getToken(data.topLevelVariableDeclaration_semicolon),
     );
+    LazyTopLevelVariableDeclaration.setData(node, data);
+    return node;
   }
 
   TryStatement _read_tryStatement(LinkedNode data) {
@@ -1189,13 +1248,15 @@
   }
 
   TypeParameter _read_typeParameter(LinkedNode data) {
-    return astFactory.typeParameter(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+    var node = astFactory.typeParameter(
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _readNode(data.typeParameter_name),
       _getToken(data.typeParameter_extendsKeyword),
-      _readNode(data.typeParameter_bound),
+      _readNodeLazy(data.typeParameter_bound),
     );
+    LazyTypeParameter.setData(node, data);
+    return node;
   }
 
   TypeParameterList _read_typeParameterList(LinkedNode data) {
@@ -1207,19 +1268,21 @@
   }
 
   VariableDeclaration _read_variableDeclaration(LinkedNode data) {
-    return astFactory.variableDeclaration(
+    var node = astFactory.variableDeclaration(
       _readNode(data.variableDeclaration_name),
       _getToken(data.variableDeclaration_equals),
-      _readNode(data.variableDeclaration_initializer),
+      _readNodeLazy(data.variableDeclaration_initializer),
     );
+    LazyVariableDeclaration.setData(node, data);
+    return node;
   }
 
   VariableDeclarationList _read_variableDeclarationList(LinkedNode data) {
     return astFactory.variableDeclarationList(
-      _readNode(data.annotatedNode_comment),
-      _readNodeList(data.annotatedNode_metadata),
+      _readNodeLazy(data.annotatedNode_comment),
+      _readNodeListLazy(data.annotatedNode_metadata),
       _getToken(data.variableDeclarationList_keyword),
-      _readNode(data.variableDeclarationList_type),
+      _readNodeLazy(data.variableDeclarationList_type),
       _readNodeList(data.variableDeclarationList_variables),
     );
   }
@@ -1503,6 +1566,11 @@
     }
   }
 
+  AstNode _readNodeLazy(LinkedNode data) {
+    if (isLazy) return null;
+    return _readNode(data);
+  }
+
   List<T> _readNodeList<T>(List<LinkedNode> nodeList) {
     var result = List<T>.filled(nodeList.length, null);
     for (var i = 0; i < nodeList.length; ++i) {
@@ -1512,6 +1580,13 @@
     return result;
   }
 
+  List<T> _readNodeListLazy<T>(List<LinkedNode> nodeList) {
+    if (isLazy) {
+      return List<T>.filled(nodeList.length, null);
+    }
+    return _readNodeList(nodeList);
+  }
+
   DartType _readType(LinkedNodeType data) {
     if (data == null) return null;
 
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index 634e7da..0766c24 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -12,6 +12,7 @@
 import 'package:analyzer/src/dart/element/member.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/tokens_context.dart';
 
@@ -555,6 +556,7 @@
       functionDeclaration_returnType: node.returnType?.accept(this),
     );
     _storeNamedCompilationUnitMember(builder, node);
+    _writeActualReturnType(builder, node);
     return builder;
   }
 
@@ -594,6 +596,7 @@
       functionTypeAlias_typeParameters: node.typeParameters?.accept(this),
     );
     _storeTypeAlias(builder, node);
+    _writeActualReturnType(builder, node);
     return builder;
   }
 
@@ -613,13 +616,16 @@
 
   @override
   LinkedNodeBuilder visitGenericFunctionType(GenericFunctionType node) {
-    return LinkedNodeBuilder.genericFunctionType(
+    var builder = LinkedNodeBuilder.genericFunctionType(
       genericFunctionType_formalParameters: node.parameters.accept(this),
       genericFunctionType_functionKeyword: _getToken(node.functionKeyword),
       genericFunctionType_question: _getToken(node.question),
       genericFunctionType_returnType: node.returnType?.accept(this),
+      genericFunctionType_type: _writeType(node.type),
       genericFunctionType_typeParameters: node.typeParameters?.accept(this),
     );
+    _writeActualReturnType(builder, node);
+    return builder;
   }
 
   @override
@@ -710,6 +716,7 @@
       instanceCreationExpression_keyword: _getToken(node.keyword),
       instanceCreationExpression_typeArguments:
           nodeImpl.typeArguments?.accept(this),
+      expression_type: _writeType(node.staticType),
     );
   }
 
@@ -819,6 +826,7 @@
     );
     _storeClassMember(builder, node);
     _storeCodeOffsetLength(builder, node);
+    _writeActualReturnType(builder, node);
     return builder;
   }
 
@@ -1228,12 +1236,14 @@
 
   @override
   LinkedNodeBuilder visitVariableDeclaration(VariableDeclaration node) {
-    return LinkedNodeBuilder.variableDeclaration(
+    var builder = LinkedNodeBuilder.variableDeclaration(
       variableDeclaration_equals: _getToken(node.equals),
       variableDeclaration_initializer: node.initializer?.accept(this),
       variableDeclaration_name: node.name.accept(this),
       variableDeclaration_declaration: _variablesDeclaration,
     );
+    _writeActualType(builder, node);
+    return builder;
   }
 
   @override
@@ -1409,6 +1419,7 @@
     builder.formalParameter_kind = kind;
 
     _storeCodeOffsetLength(builder, node);
+    _writeActualType(builder, node);
   }
 
   void _storeForMixin(LinkedNodeBuilder builder, ForMixin node) {
@@ -1509,6 +1520,18 @@
       ..uriBasedDirective_uriElement = _getReferenceIndex(node.uriElement);
   }
 
+  void _writeActualReturnType(LinkedNodeBuilder builder, AstNode node) {
+    var type = LazyAst.getReturnType(node);
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    builder.actualReturnType = _writeType(type);
+  }
+
+  void _writeActualType(LinkedNodeBuilder builder, AstNode node) {
+    var type = LazyAst.getType(node);
+    // TODO(scheglov) Check for `null` when writing resolved AST.
+    builder.actualType = _writeType(type);
+  }
+
   List<LinkedNodeBuilder> _writeNodeList(List<AstNode> nodeList) {
     var result = List<LinkedNodeBuilder>.filled(
       nodeList.length,
diff --git a/pkg/analyzer/lib/src/summary2/ast_resolver.dart b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
index 09f12b4..ab43e11 100644
--- a/pkg/analyzer/lib/src/summary2/ast_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_resolver.dart
@@ -7,10 +7,7 @@
 import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/src/generated/resolver.dart';
 import 'package:analyzer/src/generated/source.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
 
 /// Used to resolve some AST nodes - variable initializers, and annotations.
 class AstResolver {
@@ -20,8 +17,7 @@
 
   AstResolver(this._linker, this._library, this._nameScope);
 
-  LinkedNode resolve(
-    LinkedUnitContext context,
+  void resolve(
     AstNode node, {
     ClassElement enclosingClassElement,
     ExecutableElement enclosingExecutableElement,
@@ -51,12 +47,6 @@
     );
 
     node.accept(resolverVisitor);
-
-    var writer = AstBinaryWriter(
-      _linker.linkingBundleContext,
-      context.tokensContext,
-    );
-    return writer.writeNode(node);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
index 6c2acdc..be3a93a 100644
--- a/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/builder/source_library_builder.dart
@@ -3,69 +3,62 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart' as ast;
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart' show LibraryScope;
 import 'package:analyzer/src/generated/source.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/combinator.dart';
 import 'package:analyzer/src/summary2/constructor_initializer_resolver.dart';
+import 'package:analyzer/src/summary2/default_value_resolver.dart';
 import 'package:analyzer/src/summary2/export.dart';
 import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/metadata_resolver.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/reference_resolver.dart';
 import 'package:analyzer/src/summary2/scope.dart';
-import 'package:analyzer/src/summary2/tokens_writer.dart';
 import 'package:analyzer/src/summary2/top_level_inference.dart';
+import 'package:analyzer/src/summary2/type_builder.dart';
 
 class SourceLibraryBuilder {
   final Linker linker;
   final Uri uri;
   final Reference reference;
   final LinkedNodeLibraryBuilder node;
-  final List<UnitBuilder> units = [];
 
-  /// The import scope of the library.
-  final Scope importScope;
+  LinkedLibraryContext context;
 
-  /// Local declarations, enclosed by [importScope].
-  final Scope scope;
+  LibraryElement element;
+  LibraryScope libraryScope;
+
+  /// Local declarations.
+  final Scope localScope = Scope.top();
 
   /// The export scope of the library.
   final Scope exportScope = Scope.top();
 
   final List<Export> exporters = [];
 
-  SourceLibraryBuilder(Linker linker, Uri uri, Reference reference,
-      LinkedNodeLibraryBuilder node)
-      : this._(linker, uri, reference, node, Scope.top());
-
-  SourceLibraryBuilder._(
-      this.linker, this.uri, this.reference, this.node, this.importScope)
-      : scope = Scope(importScope, <String, Reference>{});
+  SourceLibraryBuilder(this.linker, this.uri, this.reference, this.node);
 
   void addExporters() {
-    var unitContext = units[0].context;
-    for (var directive in units[0].node.compilationUnit_directives) {
-      if (directive.kind == LinkedNodeKind.exportDirective) {
-        var relativeUriStr = unitContext.getStringContent(
-          directive.uriBasedDirective_uri,
-        );
+    var unitContext = context.units[0];
+    for (var directive in unitContext.unit_withDirectives.directives) {
+      if (directive is ast.ExportDirective) {
+        var relativeUriStr = directive.uri.stringValue;
         var relativeUri = Uri.parse(relativeUriStr);
         var uri = resolveRelativeUri(this.uri, relativeUri);
         var exported = linker.builders[uri];
         if (exported != null) {
-          var combinatorNodeList = directive.namespaceDirective_combinators;
-          var combinators = combinatorNodeList.map((node) {
-            if (node.kind == LinkedNodeKind.showCombinator) {
-              var nodeList = node.showCombinator_shownNames;
-              var nameList = unitContext.getSimpleNameList(nodeList);
+          var combinators = directive.combinators.map((node) {
+            if (node is ast.ShowCombinator) {
+              var nameList = node.shownNames.map((i) => i.name).toList();
               return Combinator.show(nameList);
-            } else {
-              var nodeList = node.hideCombinator_hiddenNames;
-              var nameList = unitContext.getSimpleNameList(nodeList);
+            } else if (node is ast.HideCombinator) {
+              var nameList = node.hiddenNames.map((i) => i.name).toList();
               return Combinator.hide(nameList);
             }
           }).toList();
@@ -76,64 +69,10 @@
     }
   }
 
-  void addImportsToScope() {
-    var hasDartCore = false;
-    var unitContext = units[0].context;
-    for (var directive in units[0].node.compilationUnit_directives) {
-      if (directive.kind == LinkedNodeKind.importDirective) {
-        var relativeUriStr = unitContext.getStringContent(
-          directive.uriBasedDirective_uri,
-        );
-        var relativeUri = Uri.parse(relativeUriStr);
-        var uri = resolveRelativeUri(this.uri, relativeUri);
-        var builder = linker.builders[uri];
-
-        Scope targetScope = importScope;
-
-        var prefixNode = directive.importDirective_prefix;
-        if (prefixNode != null) {
-          var prefixName = unitContext.getSimpleName(prefixNode);
-          var prefixContainer = reference.getChild('@prefix');
-          var prefixReference = prefixContainer[prefixName];
-
-          if (prefixReference == null) {
-            prefixReference = prefixContainer.getChild(prefixName);
-            prefixReference.prefixScope = Scope.top();
-            importScope.declare(prefixName, prefixReference);
-          }
-
-          targetScope = prefixReference.prefixScope;
-        }
-
-        if (builder != null) {
-          builder.exportScope.forEach((name, reference) {
-            targetScope.declare(name, reference);
-          });
-        } else {
-          var references = linker.elementFactory.exportsOfLibrary('$uri');
-          _declareReferences(targetScope, references);
-        }
-        // TODO(scheglov) combinators
-      }
-    }
-    if (!hasDartCore) {
-      var importDartCore = LinkedNodeBuilder.importDirective(
-        uriBasedDirective_uri: LinkedNodeBuilder.simpleStringLiteral(
-          simpleStringLiteral_value: 'dart:core',
-        ),
-      )..isSynthetic = true;
-      units[0].node.compilationUnit_directives.add(importDartCore);
-
-      // TODO(scheglov) This works only when dart:core is linked
-      var references = linker.elementFactory.exportsOfLibrary('dart:core');
-      _declareReferences(importScope, references);
-    }
-  }
-
   /// Add top-level declaration of the library units to the local scope.
   void addLocalDeclarations() {
-    for (var unit in units) {
-      var unitRef = reference.getChild('@unit').getChild('${unit.uri}');
+    for (var unitContext in context.units) {
+      var unitRef = reference.getChild('@unit').getChild(unitContext.uriStr);
       var classRef = unitRef.getChild('@class');
       var enumRef = unitRef.getChild('@enum');
       var functionRef = unitRef.getChild('@function');
@@ -141,77 +80,155 @@
       var getterRef = unitRef.getChild('@getter');
       var setterRef = unitRef.getChild('@setter');
       var variableRef = unitRef.getChild('@variable');
-      for (var node in unit.node.compilationUnit_declarations) {
-        if (node.kind == LinkedNodeKind.classDeclaration ||
-            node.kind == LinkedNodeKind.classTypeAlias ||
-            node.kind == LinkedNodeKind.mixinDeclaration) {
-          var name = unit.context.getUnitMemberName(node);
+      for (var node in unitContext.unit.declarations) {
+        if (node is ast.ClassDeclaration) {
+          var name = node.name.name;
           var reference = classRef.getChild(name);
-          reference.node = node;
-          scope.declare(name, reference);
-        } else if (node.kind == LinkedNodeKind.enumDeclaration) {
-          var name = unit.context.getUnitMemberName(node);
+          reference.node2 = node;
+          localScope.declare(name, reference);
+        } else if (node is ast.ClassTypeAlias) {
+          var name = node.name.name;
+          var reference = classRef.getChild(name);
+          reference.node2 = node;
+          localScope.declare(name, reference);
+        } else if (node is ast.EnumDeclaration) {
+          var name = node.name.name;
           var reference = enumRef.getChild(name);
-          reference.node = node;
-          scope.declare(name, reference);
-        } else if (node.kind == LinkedNodeKind.functionDeclaration) {
-          var name = unit.context.getUnitMemberName(node);
+          reference.node2 = node;
+          localScope.declare(name, reference);
+        } else if (node is ast.FunctionDeclaration) {
+          var name = node.name.name;
 
           Reference containerRef;
-          if (unit.context.isGetterFunction(node)) {
+          if (node.isGetter) {
             containerRef = getterRef;
-          } else if (unit.context.isSetterFunction(node)) {
+          } else if (node.isSetter) {
             containerRef = setterRef;
           } else {
             containerRef = functionRef;
           }
 
           var reference = containerRef.getChild(name);
-          reference.node = node;
-
-          scope.declare(name, reference);
-        } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
-          var name = unit.context.getUnitMemberName(node);
+          reference.node2 = node;
+          localScope.declare(name, reference);
+        } else if (node is ast.FunctionTypeAlias) {
+          var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
-          reference.node = node;
+          reference.node2 = node;
 
-          scope.declare(name, reference);
-        } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
-          var name = unit.context.getUnitMemberName(node);
+          localScope.declare(name, reference);
+        } else if (node is ast.GenericTypeAlias) {
+          var name = node.name.name;
           var reference = typeAliasRef.getChild(name);
-          reference.node = node;
+          reference.node2 = node;
 
-          scope.declare(name, reference);
-        } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) {
-          var variableList = node.topLevelVariableDeclaration_variableList;
-          for (var variable in variableList.variableDeclarationList_variables) {
-            var name = unit.context.getVariableName(variable);
+          localScope.declare(name, reference);
+        } else if (node is ast.MixinDeclaration) {
+          var name = node.name.name;
+          var reference = classRef.getChild(name);
+          reference.node2 = node;
+          localScope.declare(name, reference);
+        } else if (node is ast.TopLevelVariableDeclaration) {
+          for (var variable in node.variables.variables) {
+            var name = variable.name.name;
 
             var reference = variableRef.getChild(name);
-            reference.node = node;
+            reference.node2 = node;
 
             var getter = getterRef.getChild(name);
-            scope.declare(name, getter);
+            localScope.declare(name, getter);
 
-            if (!unit.context.isConst(variable) &&
-                !unit.context.isFinal(variable)) {
+            if (!variable.isConst && !variable.isFinal) {
               var setter = setterRef.getChild(name);
-              scope.declare('$name=', setter);
+              localScope.declare('$name=', setter);
             }
           }
         } else {
           // TODO(scheglov) implement
-          throw UnimplementedError('${node.kind}');
+          throw UnimplementedError('${node.runtimeType}');
         }
       }
     }
+//    for (var unit in units) {
+//      var unitRef = reference.getChild('@unit').getChild('${unit.uri}');
+//      var classRef = unitRef.getChild('@class');
+//      var enumRef = unitRef.getChild('@enum');
+//      var functionRef = unitRef.getChild('@function');
+//      var typeAliasRef = unitRef.getChild('@typeAlias');
+//      var getterRef = unitRef.getChild('@getter');
+//      var setterRef = unitRef.getChild('@setter');
+//      var variableRef = unitRef.getChild('@variable');
+//      for (var node in unit.node.compilationUnit_declarations) {
+//        if (node.kind == LinkedNodeKind.classDeclaration ||
+//            node.kind == LinkedNodeKind.classTypeAlias ||
+//            node.kind == LinkedNodeKind.mixinDeclaration) {
+//          var name = unit.context.getUnitMemberName(node);
+//          var reference = classRef.getChild(name);
+//          reference.node = node;
+//          scope.declare(name, reference);
+//        } else if (node.kind == LinkedNodeKind.enumDeclaration) {
+//          var name = unit.context.getUnitMemberName(node);
+//          var reference = enumRef.getChild(name);
+//          reference.node = node;
+//          scope.declare(name, reference);
+//        } else if (node.kind == LinkedNodeKind.functionDeclaration) {
+//          var name = unit.context.getUnitMemberName(node);
+//
+//          Reference containerRef;
+//          if (unit.context.isGetterFunction(node)) {
+//            containerRef = getterRef;
+//          } else if (unit.context.isSetterFunction(node)) {
+//            containerRef = setterRef;
+//          } else {
+//            containerRef = functionRef;
+//          }
+//
+//          var reference = containerRef.getChild(name);
+//          reference.node = node;
+//
+//          scope.declare(name, reference);
+//        } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
+//          var name = unit.context.getUnitMemberName(node);
+//          var reference = typeAliasRef.getChild(name);
+//          reference.node = node;
+//
+//          scope.declare(name, reference);
+//        } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
+//          var name = unit.context.getUnitMemberName(node);
+//          var reference = typeAliasRef.getChild(name);
+//          reference.node = node;
+//
+//          scope.declare(name, reference);
+//        } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) {
+//          var variableList = node.topLevelVariableDeclaration_variableList;
+//          for (var variable in variableList.variableDeclarationList_variables) {
+//            var name = unit.context.getVariableName(variable);
+//
+//            var reference = variableRef.getChild(name);
+//            reference.node = node;
+//
+//            var getter = getterRef.getChild(name);
+//            scope.declare(name, getter);
+//
+//            if (!unit.context.isConst(variable) &&
+//                !unit.context.isFinal(variable)) {
+//              var setter = setterRef.getChild(name);
+//              scope.declare('$name=', setter);
+//            }
+//          }
+//        } else {
+//          // TODO(scheglov) implement
+//          throw UnimplementedError('${node.kind}');
+//        }
+//      }
+//    }
     if ('$uri' == 'dart:core') {
-      scope.declare('dynamic', reference.getChild('dynamic'));
+      localScope.declare('dynamic', reference.getChild('dynamic'));
     }
   }
 
   void addSyntheticConstructors() {
-    for (var reference in scope.map.values) {
+    for (var reference in localScope.map.values) {
       var node = reference.node;
       if (node == null) continue;
       if (node.kind != LinkedNodeKind.classDeclaration) continue;
@@ -247,8 +264,13 @@
     return true;
   }
 
+  void buildElement() {
+    element = linker.elementFactory.libraryOfUri('$uri');
+    libraryScope = LibraryScope(element);
+  }
+
   void buildInitialExportScope() {
-    scope.forEach((name, reference) {
+    localScope.forEach((name, reference) {
       addToExportScope(name, reference);
     });
   }
@@ -261,23 +283,29 @@
     ConstructorInitializerResolver(linker, reference).resolve();
   }
 
+  void resolveDefaultValues() {
+    DefaultValueResolver(linker, reference).resolve();
+  }
+
   void resolveMetadata() {
-    var metadataResolver = MetadataResolver(linker, reference);
-    for (var unit in units) {
-      metadataResolver.resolve(unit);
+    var metadataResolver = MetadataResolver(linker, element);
+    for (var unitContext in context.units) {
+      unitContext.unit.accept(metadataResolver);
     }
   }
 
-  void resolveTypes(TypesToBuild typesToBuild) {
-    for (var unit in units) {
-      var unitReference = reference.getChild('@unit').getChild('${unit.uri}');
-      ReferenceResolver(
-        linker.linkingBundleContext,
-        typesToBuild,
-        unit,
-        scope,
+  void resolveTypes(NodesToBuildType nodesToBuildType) {
+    for (var unitContext in context.units) {
+      var unitRef = reference.getChild('@unit');
+      var unitReference = unitRef.getChild(unitContext.uriStr);
+      var resolver = ReferenceResolver(
+        nodesToBuildType,
+        linker.elementFactory,
+        element,
         unitReference,
-      ).resolve();
+        libraryScope,
+      );
+      unitContext.unit.accept(resolver);
     }
   }
 
@@ -306,50 +334,31 @@
       libraryReference,
       libraryNode,
     );
+    linker.builders[builder.uri] = builder;
 
+    var unitMap = <String, ast.CompilationUnit>{};
     ast.CompilationUnit definingUnit;
     for (var unitSource in libraryUnits.keys) {
       var unit = libraryUnits[unitSource];
       definingUnit ??= unit;
-
-      var tokensResult = TokensWriter().writeTokens(
-        unit.beginToken,
-        unit.endToken,
-      );
-      var tokensContext = tokensResult.toContext();
-
-      var unitContext = LinkedUnitContext(
-        linker.bundleContext,
-        tokensContext,
-      );
-
-      var writer = AstBinaryWriter(linker.linkingBundleContext, tokensContext);
-      var unitNode = writer.writeNode(unit);
-
-      builder.units.add(
-        UnitBuilder(unitSource.uri, unitContext, unitNode),
-      );
-
-      libraryNode.units.add(
-        LinkedNodeUnitBuilder(
-          uriStr: '${unitSource.uri}',
-          tokens: tokensResult.tokens,
-          node: unitNode,
-        ),
-      );
-
-      if (libraryUriStr == 'dart:core') {
-        for (var declaration in unitNode.compilationUnit_declarations) {
-          if (declaration.kind == LinkedNodeKind.classDeclaration) {
-            var nameNode = declaration.namedCompilationUnitMember_name;
-            if (unitContext.getSimpleName(nameNode) == 'Object') {
-              declaration.classDeclaration_isDartObject = true;
-            }
-          }
-        }
-      }
+      unitMap['${unitSource.uri}'] = unit;
     }
 
+    builder.context = linker.bundleContext
+        .addLinkingLibrary(libraryUriStr, libraryNode, unitMap);
+
+//      if (libraryUriStr == 'dart:core') {
+//        for (var declaration in unitNode.compilationUnit_declarations) {
+//          if (declaration.kind == LinkedNodeKind.classDeclaration) {
+//            var nameNode = declaration.namedCompilationUnitMember_name;
+//            if (unitContext.getSimpleName(nameNode) == 'Object') {
+//              declaration.classDeclaration_isDartObject = true;
+//            }
+//          }
+//        }
+//      }
+//    }
+
     for (var directive in definingUnit.directives) {
       if (directive is ast.LibraryDirective) {
         var name = directive.name;
@@ -359,16 +368,6 @@
         break;
       }
     }
-
-    linker.linkingLibraries.add(libraryNode);
-    linker.builders[builder.uri] = builder;
-  }
-
-  static void _declareReferences(Scope target, List<Reference> references) {
-    for (var reference in references) {
-      var name = reference.name;
-      target.declare(name, reference);
-    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
index 9c7fc99..a0cc02e 100644
--- a/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/constructor_initializer_resolver.dart
@@ -6,8 +6,6 @@
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/ast_resolver.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
@@ -46,66 +44,70 @@
   void _constructor(ConstructorElementImpl constructorElement) {
     if (constructorElement.isSynthetic) return;
 
-    _constructorElement = constructorElement;
-    _constructorNode = constructorElement.linkedNode;
-
-    var functionScope = FunctionScope(_classScope, constructorElement);
-    functionScope.defineParameters();
-
-    var nameScope = ConstructorInitializerScope(
-      functionScope,
-      constructorElement,
-    );
-
-    _astResolver = AstResolver(_linker, _libraryElement, nameScope);
-
-    _initializers();
-    _redirectedConstructor();
+//    _constructorElement = constructorElement;
+//    _constructorNode = constructorElement.linkedNode;
+//
+//    var functionScope = FunctionScope(_classScope, constructorElement);
+//    functionScope.defineParameters();
+//
+//    var nameScope = ConstructorInitializerScope(
+//      functionScope,
+//      constructorElement,
+//    );
+//
+//    _astResolver = AstResolver(_linker, _libraryElement, nameScope);
+//
+//    _initializers();
+//    _redirectedConstructor();
   }
 
   void _initializers() {
-    bool isConst = _constructorNode.constructorDeclaration_constKeyword != 0;
+    throw UnimplementedError();
 
-    var initializers = _constructorNode.constructorDeclaration_initializers;
-    var resolvedList = List<LinkedNodeBuilder>();
-    for (var i = 0; i < initializers.length; ++i) {
-      var unresolvedNode = initializers[i];
-
-      // Keep only initializers of constant constructors; or redirects.
-      if (!isConst &&
-          unresolvedNode.kind !=
-              LinkedNodeKind.redirectingConstructorInvocation) {
-        continue;
-      }
-
-      var reader = AstBinaryReader(_linkedContext);
-      var unresolvedAst = reader.readNode(unresolvedNode);
-
-      var resolvedNode = _astResolver.resolve(
-        _linkedContext,
-        unresolvedAst,
-        enclosingClassElement: _constructorElement.enclosingElement,
-        enclosingExecutableElement: _constructorElement,
-      );
-      resolvedList.add(resolvedNode);
-    }
-    _constructorNode.constructorDeclaration_initializers = resolvedList;
+//    bool isConst = _constructorNode.constructorDeclaration_constKeyword != 0;
+//
+//    var initializers = _constructorNode.constructorDeclaration_initializers;
+//    var resolvedList = List<LinkedNodeBuilder>();
+//    for (var i = 0; i < initializers.length; ++i) {
+//      var unresolvedNode = initializers[i];
+//
+//      // Keep only initializers of constant constructors; or redirects.
+//      if (!isConst &&
+//          unresolvedNode.kind !=
+//              LinkedNodeKind.redirectingConstructorInvocation) {
+//        continue;
+//      }
+//
+//      var reader = AstBinaryReader(_linkedContext);
+//      var unresolvedAst = reader.readNode(unresolvedNode);
+//
+//      var resolvedNode = _astResolver.resolve(
+//        _linkedContext,
+//        unresolvedAst,
+//        enclosingClassElement: _constructorElement.enclosingElement,
+//        enclosingExecutableElement: _constructorElement,
+//      );
+//      resolvedList.add(resolvedNode);
+//    }
+//    _constructorNode.constructorDeclaration_initializers = resolvedList;
   }
 
   void _redirectedConstructor() {
-    var redirectedConstructorNode =
-        _constructorNode.constructorDeclaration_redirectedConstructor;
-    if (redirectedConstructorNode == null) return;
+    throw UnimplementedError();
 
-    var reader = AstBinaryReader(_linkedContext);
-    var unresolvedAst = reader.readNode(redirectedConstructorNode);
-    var resolvedNode = _astResolver.resolve(
-      _linkedContext,
-      unresolvedAst,
-      enclosingClassElement: _constructorElement.enclosingElement,
-      enclosingExecutableElement: _constructorElement,
-    );
-    _constructorNode.constructorDeclaration_redirectedConstructor =
-        resolvedNode;
+//    var redirectedConstructorNode =
+//        _constructorNode.constructorDeclaration_redirectedConstructor;
+//    if (redirectedConstructorNode == null) return;
+//
+//    var reader = AstBinaryReader(_linkedContext);
+//    var unresolvedAst = reader.readNode(redirectedConstructorNode);
+//    var resolvedNode = _astResolver.resolve(
+//      _linkedContext,
+//      unresolvedAst,
+//      enclosingClassElement: _constructorElement.enclosingElement,
+//      enclosingExecutableElement: _constructorElement,
+//    );
+//    _constructorNode.constructorDeclaration_redirectedConstructor =
+//        resolvedNode;
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/default_value_resolver.dart b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
new file mode 100644
index 0000000..4ee405d
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/default_value_resolver.dart
@@ -0,0 +1,130 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
+import 'package:analyzer/src/generated/resolver.dart';
+import 'package:analyzer/src/summary2/ast_resolver.dart';
+import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+
+class DefaultValueResolver {
+  Linker _linker;
+  LibraryElementImpl _libraryElement;
+  LinkedUnitContext _linkedContext;
+
+  ClassElement _enclosingClassElement;
+  ExecutableElement _enclosingExecutableElement;
+
+  Scope _libraryScope;
+  Scope _classScope;
+
+  AstResolver _astResolver;
+
+  DefaultValueResolver(this._linker, Reference libraryRef) {
+    _libraryElement = _linker.elementFactory.elementOfReference(libraryRef);
+    _libraryScope = LibraryScope(_libraryElement);
+  }
+
+  void resolve() {
+    for (CompilationUnitElementImpl unit in _libraryElement.units) {
+      _linkedContext = unit.linkedContext;
+
+      for (var classElement in unit.types) {
+        _enclosingClassElement = classElement;
+        _classScope = TypeParameterScope(_libraryScope, classElement);
+
+        for (var element in classElement.constructors) {
+          _constructor(element);
+        }
+
+        for (var element in classElement.methods) {
+          _method(element);
+        }
+
+        _enclosingClassElement = null;
+        _classScope = null;
+      }
+
+      for (var element in unit.functions) {
+        _function(element);
+      }
+    }
+  }
+
+  void _constructor(ConstructorElementImpl element) {
+    if (element.isSynthetic) return;
+
+    _astResolver = null;
+    _enclosingExecutableElement = element;
+
+    _parameters(element.parameters);
+  }
+
+  void _function(FunctionElementImpl element) {
+    _astResolver = null;
+    _enclosingExecutableElement = element;
+
+    _parameters(element.parameters);
+  }
+
+  void _method(MethodElementImpl element) {
+    _astResolver = null;
+    _enclosingExecutableElement = element;
+
+    _parameters(element.parameters);
+  }
+
+  void _parameter(ParameterElementImpl parameter) {
+    if (parameter.isNotOptional) return;
+
+//    LinkedNodeBuilder node = parameter.linkedNode;
+//    var unresolvedNode = node.defaultFormalParameter_defaultValue;
+//    if (unresolvedNode == null) return;
+//
+//    var reader = AstBinaryReader(_linkedContext);
+//    var unresolvedAst = reader.readNode(unresolvedNode);
+//
+//    if (_astResolver == null) {
+//      var scope = FunctionScope(
+//        _classScope ?? _libraryScope,
+//        _enclosingExecutableElement,
+//      );
+//      _astResolver = AstResolver(_linker, _libraryElement, scope);
+//    }
+//
+//    var contextType = TypeVariableEliminator(_linker.typeProvider)
+//        .substituteType(parameter.type);
+//    InferenceContext.setType(unresolvedAst, contextType);
+//
+//    var resolvedNode = _astResolver.resolve(
+//      _linkedContext,
+//      unresolvedAst,
+//      enclosingClassElement: _enclosingClassElement,
+//      enclosingExecutableElement: _enclosingExecutableElement,
+//    );
+//    node.defaultFormalParameter_defaultValue = resolvedNode;
+  }
+
+  void _parameters(List<ParameterElement> parameters) {
+    for (var parameter in parameters) {
+      _parameter(parameter);
+    }
+  }
+}
+
+class TypeVariableEliminator extends Substitution {
+  final TypeProvider _typeProvider;
+
+  TypeVariableEliminator(this._typeProvider);
+
+  @override
+  DartType getSubstitute(TypeParameterElement parameter, bool upperBound) {
+    return upperBound ? _typeProvider.nullType : _typeProvider.objectType;
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
new file mode 100644
index 0000000..d4f01c5
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -0,0 +1,1234 @@
+// 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/dart/ast/ast.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/ast/ast.dart';
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary2/ast_binary_reader.dart';
+
+/// Accessor for reading AST lazily, or read data that is stored in IDL, but
+/// cannot be stored in AST, like inferred types.
+class LazyAst {
+  static const _returnTypeKey = 'lazyAst_returnType';
+  static const _typeKey = 'lazyAst_type';
+
+  final LinkedNode data;
+
+  LazyAst(this.data);
+
+  static DartType getReturnType(AstNode node) {
+    return node.getProperty(_returnTypeKey);
+  }
+
+  static DartType getType(AstNode node) {
+    return node.getProperty(_typeKey);
+  }
+
+  static void setReturnType(AstNode node, DartType type) {
+    node.setProperty(_returnTypeKey, type);
+  }
+
+  static void setType(AstNode node, DartType type) {
+    node.setProperty(_typeKey, type);
+  }
+}
+
+class LazyClassDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasExtendsClause = false;
+  bool _hasImplementsClause = false;
+  bool _hasMembers = false;
+  bool _hasMetadata = false;
+  bool _hasTypeParameters = false;
+  bool _hasWithClause = false;
+
+  LazyClassDeclaration(this.data);
+
+  static LazyClassDeclaration get(ClassDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readExtendsClause(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasExtendsClause) {
+      node.extendsClause = reader.readNode(
+        lazy.data.classDeclaration_extendsClause,
+      );
+      lazy._hasExtendsClause = true;
+    }
+  }
+
+  static void readImplementsClause(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasImplementsClause) {
+      node.implementsClause = reader.readNode(
+        lazy.data.classOrMixinDeclaration_implementsClause,
+      );
+      lazy._hasImplementsClause = true;
+    }
+  }
+
+  static void readMembers(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasMembers) {
+      var dataList = lazy.data.classOrMixinDeclaration_members;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.members[i] = reader.readNode(data);
+      }
+      lazy._hasMembers = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.classOrMixinDeclaration_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void readWithClause(
+    AstBinaryReader reader,
+    ClassDeclaration node,
+  ) {
+    var lazy = LazyClassDeclaration.get(node);
+    if (lazy != null && !lazy._hasWithClause) {
+      node.withClause = reader.readNode(
+        lazy.data.classDeclaration_withClause,
+      );
+      lazy._hasWithClause = true;
+    }
+  }
+
+  static void setData(ClassDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyClassDeclaration(data));
+  }
+}
+
+class LazyClassTypeAlias {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasImplementsClause = false;
+  bool _hasMetadata = false;
+  bool _hasSuperclass = false;
+  bool _hasTypeParameters = false;
+  bool _hasWithClause = false;
+
+  LazyClassTypeAlias(this.data);
+
+  static LazyClassTypeAlias get(ClassTypeAlias node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    var lazy = LazyClassTypeAlias.get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readImplementsClause(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    var lazy = LazyClassTypeAlias.get(node);
+    if (lazy != null && !lazy._hasImplementsClause) {
+      node.implementsClause = reader.readNode(
+        lazy.data.classTypeAlias_implementsClause,
+      );
+      lazy._hasImplementsClause = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void readSuperclass(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasSuperclass) {
+        node.superclass = reader.readNode(
+          lazy.data.classTypeAlias_superclass,
+        );
+        lazy._hasSuperclass = true;
+      }
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.classTypeAlias_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void readWithClause(
+    AstBinaryReader reader,
+    ClassTypeAlias node,
+  ) {
+    var lazy = LazyClassTypeAlias.get(node);
+    if (lazy != null && !lazy._hasWithClause) {
+      node.withClause = reader.readNode(
+        lazy.data.classTypeAlias_withClause,
+      );
+      lazy._hasWithClause = true;
+    }
+  }
+
+  static void setData(ClassTypeAlias node, LinkedNode data) {
+    node.setProperty(_key, LazyClassTypeAlias(data));
+  }
+}
+
+class LazyConstructorDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasBody = false;
+  bool _hasDocumentationComment = false;
+  bool _hasFormalParameters = false;
+  bool _hasMetadata = false;
+
+  LazyConstructorDeclaration(this.data);
+
+  static LazyConstructorDeclaration get(ConstructorDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readBody(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasBody) {
+      node.body = reader.readNode(
+        lazy.data.constructorDeclaration_body,
+      );
+      lazy._hasBody = true;
+    }
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    var lazy = LazyConstructorDeclaration.get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    var lazy = LazyConstructorDeclaration.get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      node.parameters = reader.readNode(
+        lazy.data.constructorDeclaration_parameters,
+      );
+      lazy._hasFormalParameters = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    ConstructorDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(ConstructorDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyConstructorDeclaration(data));
+  }
+}
+
+class LazyDirective {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasMetadata = false;
+
+  LazyDirective(this.data);
+
+  static LazyDirective get(Directive node) {
+    return node.getProperty(_key);
+  }
+
+  static void readMetadata(AstBinaryReader reader, Directive node) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(Directive node, LinkedNode data) {
+    node.setProperty(_key, LazyDirective(data));
+  }
+}
+
+class LazyEnumConstantDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasMetadata = false;
+
+  LazyEnumConstantDeclaration(this.data);
+
+  static LazyEnumConstantDeclaration get(EnumConstantDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    EnumConstantDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    EnumConstantDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(EnumConstantDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyEnumConstantDeclaration(data));
+  }
+}
+
+class LazyEnumDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasConstants = false;
+  bool _hasDocumentationComment = false;
+  bool _hasMetadata = false;
+
+  LazyEnumDeclaration(this.data);
+
+  static LazyEnumDeclaration get(EnumDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readConstants(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasConstants) {
+      var dataList = lazy.data.enumDeclaration_constants;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.constants[i] = reader.readNode(data);
+      }
+      lazy._hasConstants = true;
+    }
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    EnumDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(EnumDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyEnumDeclaration(data));
+  }
+}
+
+class LazyFieldDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasMetadata = false;
+
+  LazyFieldDeclaration(this.data);
+
+  static LazyFieldDeclaration get(FieldDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    FieldDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    FieldDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(FieldDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyFieldDeclaration(data));
+  }
+}
+
+class LazyFormalParameter {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDefaultValue = false;
+  bool _hasMetadata = false;
+  bool _hasType = false;
+
+  LazyFormalParameter(this.data);
+
+  static LazyFormalParameter get(FormalParameter node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getType(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasType) {
+        var type = reader.readType(lazy.data.actualType);
+        LazyAst.setType(node, type);
+        lazy._hasType = true;
+      }
+    }
+    return LazyAst.getType(node);
+  }
+
+  static void readDefaultValue(
+    AstBinaryReader reader,
+    DefaultFormalParameter node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = LazyFormalParameter.get(node);
+      if (lazy != null && !lazy._hasDefaultValue) {
+        node.defaultValue = reader.readNode(
+          lazy.data.defaultFormalParameter_defaultValue,
+        );
+        lazy._hasDefaultValue = true;
+      }
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.normalFormalParameter_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(FormalParameter node, LinkedNode data) {
+    node.setProperty(_key, LazyFormalParameter(data));
+  }
+}
+
+class LazyFunctionDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasMetadata = false;
+  bool _hasReturnType = false;
+
+  LazyFunctionDeclaration(this.data);
+
+  static LazyFunctionDeclaration get(FunctionDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getReturnType(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasReturnType) {
+        var type = reader.readType(lazy.data.actualReturnType);
+        LazyAst.setReturnType(node, type);
+        lazy._hasReturnType = true;
+      }
+    }
+    return LazyAst.getReturnType(node);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    var lazy = LazyFunctionDeclaration.get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readFunctionExpression(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    if (node.functionExpression == null) {
+      var lazy = LazyFunctionDeclaration.get(node);
+      node.functionExpression = reader.readNode(
+        lazy.data.functionDeclaration_functionExpression,
+      );
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    FunctionDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(FunctionDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyFunctionDeclaration(data));
+  }
+}
+
+class LazyFunctionExpression {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasBody = false;
+  bool _hasFormalParameters = false;
+  bool _hasTypeParameters = false;
+
+  LazyFunctionExpression(this.data);
+
+  static LazyFunctionExpression get(FunctionExpression node) {
+    return node.getProperty(_key);
+  }
+
+  static void readBody(
+    AstBinaryReader reader,
+    FunctionExpression node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasBody) {
+      node.body = reader.readNode(
+        lazy.data.functionExpression_body,
+      );
+      lazy._hasBody = true;
+    }
+  }
+
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    FunctionExpression node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      node.parameters = reader.readNode(
+        lazy.data.functionExpression_formalParameters,
+      );
+      lazy._hasFormalParameters = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    FunctionExpression node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.functionExpression_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void setData(FunctionExpression node, LinkedNode data) {
+    node.setProperty(_key, LazyFunctionExpression(data));
+  }
+}
+
+class LazyFunctionTypeAlias {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasFormalParameters = false;
+  bool _hasMetadata = false;
+  bool _hasReturnType = false;
+  bool _hasTypeParameters = false;
+
+  LazyFunctionTypeAlias(this.data);
+
+  static LazyFunctionTypeAlias get(FunctionTypeAlias node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getReturnType(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasReturnType) {
+        var type = reader.readType(lazy.data.actualReturnType);
+        LazyAst.setReturnType(node, type);
+        lazy._hasReturnType = true;
+      }
+    }
+    return LazyAst.getReturnType(node);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    var lazy = LazyFunctionTypeAlias.get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      node.parameters = reader.readNode(
+        lazy.data.functionTypeAlias_formalParameters,
+      );
+      lazy._hasFormalParameters = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    FunctionTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.functionTypeAlias_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void setData(FunctionTypeAlias node, LinkedNode data) {
+    node.setProperty(_key, LazyFunctionTypeAlias(data));
+  }
+}
+
+class LazyGenericFunctionType {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasFormalParameters = false;
+  bool _hasReturnType = false;
+
+  LazyGenericFunctionType(this.data);
+
+  static LazyGenericFunctionType get(GenericFunctionType node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getReturnType(
+    AstBinaryReader reader,
+    GenericFunctionType node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasReturnType) {
+        var type = reader.readType(lazy.data.actualReturnType);
+        LazyAst.setReturnType(node, type);
+        lazy._hasReturnType = true;
+      }
+    }
+    return LazyAst.getReturnType(node);
+  }
+
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    GenericFunctionType node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      node.parameters = reader.readNode(
+        lazy.data.genericFunctionType_formalParameters,
+      );
+      lazy._hasFormalParameters = true;
+    }
+  }
+
+  static void setData(GenericFunctionType node, LinkedNode data) {
+    node.setProperty(_key, LazyGenericFunctionType(data));
+  }
+}
+
+class LazyGenericTypeAlias {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasFunction = false;
+  bool _hasTypeParameters = false;
+
+  LazyGenericTypeAlias(this.data);
+
+  static LazyGenericTypeAlias get(GenericTypeAlias node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readFunctionType(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasFunction) {
+      node.functionType = reader.readNode(
+        lazy.data.genericTypeAlias_functionType,
+      );
+      lazy._hasFunction = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    GenericTypeAlias node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.genericTypeAlias_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void setData(GenericTypeAlias node, LinkedNode data) {
+    node.setProperty(_key, LazyGenericTypeAlias(data));
+  }
+}
+
+class LazyMethodDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasBody = false;
+  bool _hasDocumentationComment = false;
+  bool _hasFormalParameters = false;
+  bool _hasMetadata = false;
+  bool _hasReturnType = false;
+  bool _hasTypeParameters = false;
+
+  LazyMethodDeclaration(this.data);
+
+  static LazyMethodDeclaration get(MethodDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getReturnType(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasReturnType) {
+        var type = reader.readType(lazy.data.actualReturnType);
+        LazyAst.setReturnType(node, type);
+        lazy._hasReturnType = true;
+      }
+    }
+    return LazyAst.getReturnType(node);
+  }
+
+  static void readBody(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasBody) {
+      node.body = reader.readNode(
+        lazy.data.methodDeclaration_body,
+      );
+      lazy._hasBody = true;
+    }
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    var lazy = LazyMethodDeclaration.get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    var lazy = LazyMethodDeclaration.get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      node.parameters = reader.readNode(
+        lazy.data.methodDeclaration_formalParameters,
+      );
+      lazy._hasFormalParameters = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    MethodDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.methodDeclaration_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void setData(MethodDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyMethodDeclaration(data));
+  }
+}
+
+class LazyMixinDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasOnClause = false;
+  bool _hasImplementsClause = false;
+  bool _hasMembers = false;
+  bool _hasTypeParameters = false;
+
+  LazyMixinDeclaration(this.data);
+
+  static LazyMixinDeclaration get(MixinDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readImplementsClause(
+    AstBinaryReader reader,
+    MixinDeclarationImpl node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasImplementsClause) {
+      node.implementsClause = reader.readNode(
+        lazy.data.classOrMixinDeclaration_implementsClause,
+      );
+      lazy._hasImplementsClause = true;
+    }
+  }
+
+  static void readMembers(
+    AstBinaryReader reader,
+    MixinDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMembers) {
+      var dataList = lazy.data.classOrMixinDeclaration_members;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.members[i] = reader.readNode(data);
+      }
+      lazy._hasMembers = true;
+    }
+  }
+
+  static void readOnClause(
+    AstBinaryReader reader,
+    MixinDeclarationImpl node,
+  ) {
+    var lazy = get(node);
+    if (!lazy._hasOnClause) {
+      node.onClause = reader.readNode(
+        lazy.data.mixinDeclaration_onClause,
+      );
+      lazy._hasOnClause = true;
+    }
+  }
+
+  static void readTypeParameters(
+    AstBinaryReader reader,
+    MixinDeclarationImpl node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasTypeParameters) {
+      node.typeParameters = reader.readNode(
+        lazy.data.classOrMixinDeclaration_typeParameters,
+      );
+      lazy._hasTypeParameters = true;
+    }
+  }
+
+  static void setData(MixinDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyMixinDeclaration(data));
+  }
+}
+
+class LazyTopLevelVariableDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasDocumentationComment = false;
+  bool _hasMetadata = false;
+
+  LazyTopLevelVariableDeclaration(this.data);
+
+  static LazyTopLevelVariableDeclaration get(TopLevelVariableDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static void readDocumentationComment(
+    AstBinaryReader reader,
+    TopLevelVariableDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasDocumentationComment) {
+      node.documentationComment = reader.readNode(
+        lazy.data.annotatedNode_comment,
+      );
+      lazy._hasDocumentationComment = true;
+    }
+  }
+
+  static void readMetadata(
+    AstBinaryReader reader,
+    TopLevelVariableDeclaration node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasMetadata) {
+      var dataList = lazy.data.annotatedNode_metadata;
+      for (var i = 0; i < dataList.length; ++i) {
+        var data = dataList[i];
+        node.metadata[i] = reader.readNode(data);
+      }
+      lazy._hasMetadata = true;
+    }
+  }
+
+  static void setData(TopLevelVariableDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyTopLevelVariableDeclaration(data));
+  }
+}
+
+class LazyTypeParameter {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasBound = false;
+
+  LazyTypeParameter(this.data);
+
+  static LazyTypeParameter get(TypeParameter node) {
+    return node.getProperty(_key);
+  }
+
+  static void readBound(AstBinaryReader reader, TypeParameter node) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasBound) {
+      node.bound = reader.readNode(lazy.data.typeParameter_bound);
+      lazy._hasBound = true;
+    }
+  }
+
+  static void setData(TypeParameter node, LinkedNode data) {
+    node.setProperty(_key, LazyTypeParameter(data));
+  }
+}
+
+class LazyVariableDeclaration {
+  static const _key = 'lazyAst';
+
+  final LinkedNode data;
+
+  bool _hasInitializer = false;
+  bool _hasType = false;
+
+  LazyVariableDeclaration(this.data);
+
+  static LazyVariableDeclaration get(VariableDeclaration node) {
+    return node.getProperty(_key);
+  }
+
+  static DartType getType(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (!lazy._hasType) {
+        var type = reader.readType(lazy.data.actualType);
+        LazyAst.setType(node, type);
+        lazy._hasType = true;
+      }
+    }
+    return LazyAst.getType(node);
+  }
+
+  static void readInitializer(
+    AstBinaryReader reader,
+    VariableDeclaration node,
+  ) {
+    if (reader.isLazy) {
+      var lazy = get(node);
+      if (lazy != null && !lazy._hasInitializer) {
+        node.initializer = reader.readNode(
+          lazy.data.variableDeclaration_initializer,
+        );
+        lazy._hasInitializer = true;
+      }
+    }
+  }
+
+  static void setData(VariableDeclaration node, LinkedNode data) {
+    node.setProperty(_key, LazyVariableDeclaration(data));
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/link.dart b/pkg/analyzer/lib/src/summary2/link.dart
index 4edc6cd..989a7f4 100644
--- a/pkg/analyzer/lib/src/summary2/link.dart
+++ b/pkg/analyzer/lib/src/summary2/link.dart
@@ -14,12 +14,13 @@
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
+import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/reference_resolver.dart';
+import 'package:analyzer/src/summary2/tokens_writer.dart';
 import 'package:analyzer/src/summary2/type_builder.dart';
 
 LinkResult link(
@@ -37,10 +38,9 @@
   final Reference rootReference = Reference.root();
   LinkedElementFactory elementFactory;
 
-  LinkingBundleContext linkingBundleContext;
-  List<LinkedNodeLibraryBuilder> linkingLibraries = [];
   LinkedNodeBundleBuilder linkingBundle;
   LinkedBundleContext bundleContext;
+  LinkingBundleContext linkingBundleContext;
 
   /// Libraries that are being linked.
   final Map<Uri, SourceLibraryBuilder> builders = {};
@@ -67,32 +67,28 @@
       rootReference,
     );
 
-    linkingBundle = LinkedNodeBundleBuilder(
-      references: linkingBundleContext.referencesBuilder,
-      libraries: linkingLibraries,
-    );
-
-    bundleContext = LinkedBundleContext(
+    bundleContext = LinkedBundleContext.forAst(
       elementFactory,
-      linkingBundle.references,
+      linkingBundleContext.references,
     );
-    bundleContext.linking = linkingBundleContext;
   }
 
   void link(List<LinkedNodeBundle> inputs,
       Map<Source, Map<Source, CompilationUnit>> unitMap) {
     for (var input in inputs) {
-      elementFactory.addBundle(input);
+      var inputBundleContext = LinkedBundleContext(elementFactory, input);
+      elementFactory.addBundle(inputBundleContext);
     }
 
     for (var librarySource in unitMap.keys) {
       SourceLibraryBuilder.build(this, librarySource, unitMap[librarySource]);
     }
-
-    // Add libraries being linked, so we can ask for their elements as well.
-    elementFactory.addBundle(linkingBundle, context: bundleContext);
+    // TODO(scheglov) do in build() ?
+    elementFactory.addBundle(bundleContext);
 
     _buildOutlines();
+
+    _createLinkingBundle();
   }
 
   void _addExporters() {
@@ -115,6 +111,7 @@
     _resolveTypes();
     _performTopLevelInference();
     _resolveConstructors();
+    _resolveDefaultValues();
     _resolveMetadata();
   }
 
@@ -161,14 +158,44 @@
     }
 
     for (var library in builders.values) {
-      library.addImportsToScope();
+      library.storeExportScope();
     }
 
     for (var library in builders.values) {
-      library.storeExportScope();
+      library.buildElement();
     }
   }
 
+  void _createLinkingBundle() {
+    var linkingLibraries = <LinkedNodeLibraryBuilder>[];
+    for (var builder in builders.values) {
+      linkingLibraries.add(builder.node);
+
+      for (var unit2 in builder.context.units) {
+        var unit = unit2.unit;
+        var tokensResult = TokensWriter().writeTokens(
+          unit.beginToken,
+          unit.endToken,
+        );
+        var tokensContext = tokensResult.toContext();
+
+        var writer = new AstBinaryWriter(linkingBundleContext, tokensContext);
+        var unitLinkedNode = writer.writeNode(unit);
+        builder.node.units.add(
+          LinkedNodeUnitBuilder(
+            uriStr: unit2.uriStr,
+            tokens: tokensResult.tokens,
+            node: unitLinkedNode,
+          ),
+        );
+      }
+    }
+    linkingBundle = LinkedNodeBundleBuilder(
+      references: linkingBundleContext.referencesBuilder,
+      libraries: linkingLibraries,
+    );
+  }
+
   void _createTypeSystem() {
     var coreRef = rootReference.getChild('dart:core');
     var coreLib = elementFactory.elementOfReference(coreRef);
@@ -194,9 +221,15 @@
   }
 
   void _resolveConstructors() {
-    for (var library in builders.values) {
-      library.resolveConstructors();
-    }
+//    for (var library in builders.values) {
+//      library.resolveConstructors();
+//    }
+  }
+
+  void _resolveDefaultValues() {
+//    for (var library in builders.values) {
+//      library.resolveDefaultValues();
+//    }
   }
 
   void _resolveMetadata() {
@@ -206,11 +239,12 @@
   }
 
   void _resolveTypes() {
-    var typesToBuild = TypesToBuild();
+    var nodesToBuildType = NodesToBuildType();
     for (var library in builders.values) {
-      library.resolveTypes(typesToBuild);
+      library.resolveTypes(nodesToBuildType);
     }
-    TypeBuilder(bundleContext).build(typesToBuild);
+//    computeSimplyBounded(bundleContext, builders.values);
+    TypeBuilder(linkingBundleContext).build(nodesToBuildType);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
index 8ecb51f..88f8655 100644
--- a/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_bundle_context.dart
@@ -2,29 +2,71 @@
 // for details. All 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/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/generated/utilities_dart.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 
 /// The context of a linked bundle, with shared references.
 class LinkedBundleContext {
   final LinkedElementFactory elementFactory;
-  final LinkedNodeReferences referencesData;
+  final LinkedNodeBundle _bundle;
   final List<Reference> _references;
+  final Map<String, LinkedLibraryContext> libraryMap = {};
 
-  /// If the bundle is being linked, the reference to the linking context.
-  /// Otherwise `null`, and we are not expected to access it.
-  LinkingBundleContext linking;
+  LinkedBundleContext(this.elementFactory, this._bundle)
+      : _references = List<Reference>(_bundle.references.name.length) {
+    for (var library in _bundle.libraries) {
+      var libraryContext = LinkedLibraryContext(library.uriStr, this, library);
+      libraryMap[library.uriStr] = libraryContext;
 
-  LinkedBundleContext(this.elementFactory, this.referencesData)
-      : _references = List<Reference>.filled(referencesData.name.length, null,
-            growable: true);
+      var units = library.units;
+      for (var unitIndex = 0; unitIndex < units.length; ++unitIndex) {
+        var unit = units[unitIndex];
+        var unitContext = LinkedUnitContext(
+          this,
+          libraryContext,
+          unitIndex,
+          unit.uriStr,
+          unit,
+        );
+        libraryContext.units.add(unitContext);
+      }
+    }
+  }
+
+  LinkedBundleContext.forAst(this.elementFactory, this._references)
+      : _bundle = null;
+
+  LinkedLibraryContext addLinkingLibrary(String uriStr,
+      LinkedNodeLibraryBuilder data, Map<String, CompilationUnit> unitMap) {
+    var uriStr = data.uriStr;
+    var libraryContext = LinkedLibraryContext(uriStr, this, data);
+    libraryMap[uriStr] = libraryContext;
+
+    var uriUriStrList = unitMap.keys.toList();
+    for (var unitIndex = 0; unitIndex < uriUriStrList.length; ++unitIndex) {
+      var unitUriStr = uriUriStrList[unitIndex];
+      var unit = unitMap[unitUriStr];
+      var unitContext = LinkedUnitContext(
+        this,
+        libraryContext,
+        unitIndex,
+        unitUriStr,
+        null,
+        unit: unit,
+      );
+      libraryContext.units.add(unitContext);
+    }
+    return libraryContext;
+  }
 
   T elementOfIndex<T extends Element>(int index) {
     var reference = referenceOfIndex(index);
@@ -87,14 +129,6 @@
   }
 
   Reference referenceOfIndex(int index) {
-    // When we are linking a bundle, we add new references.
-    // So, grow the list of references when we have data for them.
-    if (index >= _references.length) {
-      if (referencesData.name.length > _references.length) {
-        _references.length = referencesData.name.length;
-      }
-    }
-
     var reference = _references[index];
     if (reference != null) return reference;
 
@@ -104,10 +138,10 @@
       return reference;
     }
 
-    var parentIndex = referencesData.parent[index];
+    var parentIndex = _bundle.references.parent[index];
     var parent = referenceOfIndex(parentIndex);
 
-    var name = referencesData.name[index];
+    var name = _bundle.references.name[index];
     reference = parent.getChild(name);
     _references[index] = reference;
 
@@ -124,3 +158,14 @@
     return ParameterKind.REQUIRED;
   }
 }
+
+class LinkedLibraryContext {
+  final String uriStr;
+  final LinkedBundleContext context;
+  final LinkedNodeLibrary node;
+  final List<LinkedUnitContext> units = [];
+
+  LinkedLibraryContext(this.uriStr, this.context, this.node);
+
+  LinkedUnitContext get definingUnit => units.first;
+}
diff --git a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
index 13197b8..e16238f 100644
--- a/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_element_factory.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/analysis/session.dart';
+import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
@@ -11,22 +12,18 @@
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/tokens_context.dart';
 
 class LinkedElementFactory {
   final AnalysisContext analysisContext;
   final AnalysisSession analysisSession;
   final Reference rootReference;
-  final Map<String, _Library> libraryMap = {};
+  final Map<String, LinkedLibraryContext> libraryMap = {};
 
   LinkedElementFactory(
       this.analysisContext, this.analysisSession, this.rootReference);
 
-  void addBundle(LinkedNodeBundle bundle, {LinkedBundleContext context}) {
-    context ??= LinkedBundleContext(this, bundle.references);
-    for (var library in bundle.libraries) {
-      libraryMap[library.uriStr] = _Library(context, library);
-    }
+  void addBundle(LinkedBundleContext context) {
+    libraryMap.addAll(context.libraryMap);
   }
 
   Namespace buildExportNamespace(Uri uri) {
@@ -70,28 +67,28 @@
   }
 
   LinkedNode nodeOfReference(Reference reference) {
-    if (reference.node != null) {
-      return reference.node;
-    }
-
-    var unitRef = reference.parent?.parent;
-    var unitContainer = unitRef?.parent;
-    if (unitContainer?.name == '@unit') {
-      var libraryUriStr = unitContainer.parent.name;
-      var libraryData = libraryMap[libraryUriStr];
-      for (var unitData in libraryData.node.units) {
-        var definingUnitContext = LinkedUnitContext(
-          libraryData.context,
-          TokensContext(unitData.tokens),
-        );
-        _ElementRequest._indexUnitDeclarations(
-          definingUnitContext,
-          unitRef,
-          unitData.node,
-        );
-        return reference.node;
-      }
-    }
+//    if (reference.node != null) {
+//      return reference.node;
+//    }
+//
+//    var unitRef = reference.parent?.parent;
+//    var unitContainer = unitRef?.parent;
+//    if (unitContainer?.name == '@unit') {
+//      var libraryUriStr = unitContainer.parent.name;
+//      var libraryData = libraryMap[libraryUriStr];
+//      for (var unitData in libraryData.node.units) {
+//        var definingUnitContext = LinkedUnitContext(
+//          libraryData.context,
+//          TokensContext(unitData.tokens),
+//        );
+//        _ElementRequest._indexUnitDeclarations(
+//          definingUnitContext,
+//          unitRef,
+//          unitData.node,
+//        );
+//        return reference.node;
+//      }
+//    }
 
     throw UnimplementedError('$reference');
   }
@@ -191,24 +188,20 @@
 
   ClassElementImpl _class(
       CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
+    if (reference.node2 == null) {
       _indexUnitElementDeclarations(unit);
-      assert(reference.node != 0, '$reference');
+      assert(reference.node2 != null, '$reference');
     }
-    return reference.element = ClassElementImpl.forLinkedNode(
-      unit,
-      reference,
-      reference.node,
-    );
+    ClassElementImpl.forLinkedNode(unit, reference, reference.node2);
+    return reference.element;
   }
 
   ConstructorElementImpl _constructor(
-      ClassElementImpl class_, Reference reference) {
-    return reference.element = ConstructorElementImpl.forLinkedNode(
-      reference,
-      reference.node,
-      class_,
-    );
+      ClassElementImpl enclosing, Reference reference) {
+    enclosing.constructors;
+    // Requesting constructors sets elements for all of them.
+    assert(reference.element != null);
+    return reference.element;
   }
 
   LibraryElementImpl _createLibraryElement(Reference reference) {
@@ -217,42 +210,40 @@
     var sourceFactory = elementFactory.analysisContext.sourceFactory;
     var librarySource = sourceFactory.forUri(uriStr);
 
-    var libraryData = elementFactory.libraryMap[uriStr];
-    var node = libraryData.node;
-    var hasName = node.name.isNotEmpty;
+    var libraryContext = elementFactory.libraryMap[uriStr];
+    // TODO(scheglov) don't use node
+    var node2 = libraryContext.node;
+    var hasName = node2.name.isNotEmpty;
 
-    var definingUnitData = node.units[0];
-    var definingUnitContext = LinkedUnitContext(
-      libraryData.context,
-      TokensContext(definingUnitData.tokens),
-    );
+    var definingUnitContext = libraryContext.definingUnit;
 
     var libraryElement = LibraryElementImpl.forLinkedNode(
       elementFactory.analysisContext,
       elementFactory.analysisSession,
-      node.name,
-      hasName ? node.nameOffset : -1,
-      node.name.length,
+      node2.name,
+      hasName ? node2.nameOffset : -1,
+      node2.name.length,
       definingUnitContext,
       reference,
-      definingUnitData.node,
+      definingUnitContext.unit_withDeclarations,
     );
 
     var units = <CompilationUnitElementImpl>[];
     var unitContainerRef = reference.getChild('@unit');
-    for (var unitData in node.units) {
-      var unitSource = sourceFactory.forUri(unitData.uriStr);
-      var tokensContext = TokensContext(unitData.tokens);
+    for (var unitContext in libraryContext.units) {
+      var unitNode = unitContext.unit_withDeclarations;
+
+      var unitSource = sourceFactory.forUri(unitContext.uriStr);
       var unitElement = CompilationUnitElementImpl.forLinkedNode(
         libraryElement,
-        LinkedUnitContext(libraryData.context, tokensContext),
-        unitContainerRef.getChild(unitData.uriStr),
-        unitData.node,
+        unitContext,
+        unitContainerRef.getChild(unitContext.uriStr),
+        unitNode,
       );
       unitElement.source = unitSource;
       unitElement.librarySource = librarySource;
       units.add(unitElement);
-      unitContainerRef.getChild(unitData.uriStr).element = unitElement;
+      unitContainerRef.getChild(unitContext.uriStr).element = unitElement;
     }
 
     libraryElement.definingCompilationUnit = units[0];
@@ -261,15 +252,12 @@
   }
 
   EnumElementImpl _enum(CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
+    if (reference.node2 == null) {
       _indexUnitElementDeclarations(unit);
-      assert(reference.node != 0, '$reference');
+      assert(reference.node2 != null, '$reference');
     }
-    return reference.element = EnumElementImpl.forLinkedNode(
-      unit,
-      reference,
-      reference.node,
-    );
+    EnumElementImpl.forLinkedNode(unit, reference, reference.node2);
+    return reference.element;
   }
 
   Element _function(CompilationUnitElementImpl enclosing, Reference reference) {
@@ -300,15 +288,12 @@
 
   GenericTypeAliasElementImpl _typeAlias(
       CompilationUnitElementImpl unit, Reference reference) {
-    if (reference.node == null) {
+    if (reference.node2 == null) {
       _indexUnitElementDeclarations(unit);
-      assert(reference.node != 0, '$reference');
+      assert(reference.node2 != null, '$reference');
     }
-    return reference.element = GenericTypeAliasElementImpl.forLinkedNode(
-      unit,
-      reference,
-      reference.node,
-    );
+    GenericTypeAliasElementImpl.forLinkedNode(unit, reference, reference.node2);
+    return reference.element;
   }
 
   Element _typeParameter(
@@ -319,48 +304,31 @@
     return reference.element;
   }
 
+  /// Index nodes for which we choose to create elements individually,
+  /// for example [ClassDeclaration], so that its [Reference] has the node,
+  /// and we can call the [ClassElementImpl] constructor.
   static void _indexUnitDeclarations(
     LinkedUnitContext unitContext,
     Reference unitRef,
-    LinkedNode unitNode,
+    CompilationUnit unitNode,
   ) {
     var classRef = unitRef.getChild('@class');
     var enumRef = unitRef.getChild('@enum');
-    var functionRef = unitRef.getChild('@function');
     var typeAliasRef = unitRef.getChild('@typeAlias');
-    var variableRef = unitRef.getChild('@variable');
-    for (var declaration in unitNode.compilationUnit_declarations) {
-      var kind = declaration.kind;
-      if (kind == LinkedNodeKind.classDeclaration ||
-          kind == LinkedNodeKind.classTypeAlias) {
-        var name = unitContext.getUnitMemberName(declaration);
-        classRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.enumDeclaration) {
-        var name = unitContext.getUnitMemberName(declaration);
-        enumRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.functionDeclaration) {
-        var name = unitContext.getUnitMemberName(declaration);
-        functionRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.functionTypeAlias) {
-        var name = unitContext.getUnitMemberName(declaration);
-        typeAliasRef.getChild(name).node = declaration;
-      } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) {
-        var variables = declaration.topLevelVariableDeclaration_variableList;
-        for (var variable in variables.variableDeclarationList_variables) {
-          var name =
-              unitContext.getSimpleName(variable.variableDeclaration_name);
-          variableRef.getChild(name).node = variable;
-        }
-      } else {
-        throw UnimplementedError('$kind');
+    for (var declaration in unitNode.declarations) {
+      if (declaration is ClassDeclaration) {
+        var name = declaration.name.name;
+        classRef.getChild(name).node2 = declaration;
+      } else if (declaration is EnumDeclaration) {
+        var name = declaration.name.name;
+        enumRef.getChild(name).node2 = declaration;
+      } else if (declaration is FunctionTypeAlias) {
+        var name = declaration.name.name;
+        typeAliasRef.getChild(name).node2 = declaration;
+      } else if (declaration is GenericTypeAlias) {
+        var name = declaration.name.name;
+        typeAliasRef.getChild(name).node2 = declaration;
       }
     }
   }
 }
-
-class _Library {
-  final LinkedBundleContext context;
-  final LinkedNodeLibrary node;
-
-  _Library(this.context, this.node);
-}
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 7f2a591..0451be4 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -5,35 +5,107 @@
 import 'package:analyzer/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/type.dart';
 import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
 import 'package:analyzer/src/summary2/tokens_context.dart';
 
 /// The context of a unit - the context of the bundle, and the unit tokens.
 class LinkedUnitContext {
   final LinkedBundleContext bundleContext;
+  final LinkedLibraryContext libraryContext;
+  final int indexInLibrary;
+  final String uriStr;
+  final LinkedNodeUnit data;
   final TokensContext tokensContext;
 
-  LinkedUnitContext(this.bundleContext, this.tokensContext);
+  AstBinaryReader _astReader;
 
-  Iterable<LinkedNode> classFields(LinkedNode class_) sync* {
-    for (var declaration in class_.classOrMixinDeclaration_members) {
-      if (declaration.kind == LinkedNodeKind.fieldDeclaration) {
-        var variableList = declaration.fieldDeclaration_fields;
-        for (var field in variableList.variableDeclarationList_variables) {
-          yield field;
-        }
-      }
-    }
+  CompilationUnit _unit;
+  bool _hasDirectivesRead = false;
+
+  LinkedUnitContext(this.bundleContext, this.libraryContext,
+      this.indexInLibrary, this.uriStr, this.data,
+      {CompilationUnit unit})
+      : tokensContext = data != null ? TokensContext(data.tokens) : null {
+    _astReader = AstBinaryReader(this);
+    _astReader.isLazy = unit == null;
+
+    _unit = unit;
+    _hasDirectivesRead = _unit != null;
   }
 
-  String getCommentText(LinkedNode comment) {
-    if (comment == null) return null;
+  CompilationUnit get unit => _unit;
 
-    return comment.comment_tokens.map(getTokenLexeme).join('\n');
+  CompilationUnit get unit_withDeclarations {
+    if (_unit == null) {
+      _unit = _astReader.readNode(data.node);
+    }
+    return _unit;
+  }
+
+  CompilationUnit get unit_withDirectives {
+    if (!_hasDirectivesRead) {
+      var directiveDataList = data.node.compilationUnit_directives;
+      for (var i = 0; i < directiveDataList.length; ++i) {
+        var directiveData = directiveDataList[i];
+        _unit.directives[i] = _astReader.readNode(directiveData);
+      }
+      _hasDirectivesRead = true;
+    }
+    return _unit;
+  }
+
+  /// Return the absolute URI referenced in the [directive].
+  Uri directiveUri(Uri libraryUri, UriBasedDirective directive) {
+    var relativeUriStr = directive.uri.stringValue;
+    var relativeUri = Uri.parse(relativeUriStr);
+    return resolveRelativeUri(libraryUri, relativeUri);
+  }
+
+  int getCodeLength(AstNode node) {
+    if (node is ClassDeclaration) {
+      return LazyClassDeclaration.get(node).data.codeLength;
+    } else if (node is ClassTypeAlias) {
+      return LazyClassTypeAlias.get(node).data.codeLength;
+    } else if (node is ConstructorDeclaration) {
+      return LazyConstructorDeclaration.get(node).data.codeLength;
+    } else if (node is FormalParameter) {
+      return LazyFormalParameter.get(node).data.codeLength;
+    } else if (node is FunctionDeclaration) {
+      return LazyFunctionDeclaration.get(node).data.codeLength;
+    } else if (node is MethodDeclaration) {
+      return LazyMethodDeclaration.get(node).data.codeLength;
+    } else if (node is TypeParameter) {
+      return LazyTypeParameter.get(node).data.codeLength;
+    } else if (node is VariableDeclaration) {
+      return LazyVariableDeclaration.get(node).data.codeLength;
+    }
+    throw UnimplementedError('${node.runtimeType}');
+  }
+
+  int getCodeOffset(AstNode node) {
+    if (node is ClassDeclaration) {
+      return LazyClassDeclaration.get(node).data.codeOffset;
+    } else if (node is ClassTypeAlias) {
+      return LazyClassTypeAlias.get(node).data.codeOffset;
+    } else if (node is ConstructorDeclaration) {
+      return LazyConstructorDeclaration.get(node).data.codeOffset;
+    } else if (node is FormalParameter) {
+      return LazyFormalParameter.get(node).data.codeOffset;
+    } else if (node is FunctionDeclaration) {
+      return LazyFunctionDeclaration.get(node).data.codeOffset;
+    } else if (node is MethodDeclaration) {
+      return LazyMethodDeclaration.get(node).data.codeOffset;
+    } else if (node is TypeParameter) {
+      return LazyTypeParameter.get(node).data.codeOffset;
+    } else if (node is VariableDeclaration) {
+      return LazyVariableDeclaration.get(node).data.codeOffset;
+    }
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   String getConstructorDeclarationName(LinkedNode node) {
@@ -44,58 +116,143 @@
     return '';
   }
 
+  Iterable<ConstructorDeclaration> getConstructors(AstNode node) sync* {
+    if (node is ClassOrMixinDeclaration) {
+      var members = _getClassOrMixinMembers(node);
+      for (var member in members) {
+        if (member is ConstructorDeclaration) {
+          yield member;
+        }
+      }
+    }
+  }
+
+  Comment getDocumentationComment(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is ConstructorDeclaration) {
+      LazyConstructorDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is EnumConstantDeclaration) {
+      LazyEnumConstantDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is EnumDeclaration) {
+      LazyEnumDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is FunctionTypeAlias) {
+      LazyFunctionTypeAlias.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is GenericTypeAlias) {
+      LazyGenericTypeAlias.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is MethodDeclaration) {
+      LazyMethodDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is MixinDeclaration) {
+      LazyMixinDeclaration.readDocumentationComment(_astReader, node);
+      return node.documentationComment;
+    } else if (node is VariableDeclaration) {
+      var parent2 = node.parent.parent;
+      if (parent2 is FieldDeclaration) {
+        LazyFieldDeclaration.readDocumentationComment(_astReader, parent2);
+        return parent2.documentationComment;
+      } else if (parent2 is TopLevelVariableDeclaration) {
+        LazyTopLevelVariableDeclaration.readDocumentationComment(
+          _astReader,
+          parent2,
+        );
+        return parent2.documentationComment;
+      } else {
+        throw UnimplementedError('${parent2.runtimeType}');
+      }
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
+    }
+  }
+
+  List<EnumConstantDeclaration> getEnumConstants(EnumDeclaration node) {
+    LazyEnumDeclaration.readConstants(_astReader, node);
+    return node.constants;
+  }
+
+  Iterable<VariableDeclaration> getFields(ClassOrMixinDeclaration node) sync* {
+    var members = _getClassOrMixinMembers(node);
+    for (var member in members) {
+      if (member is FieldDeclaration) {
+        for (var field in member.fields.variables) {
+          yield field;
+        }
+      }
+    }
+  }
+
   String getFormalParameterName(LinkedNode node) {
     return getSimpleName(node.normalFormalParameter_identifier);
   }
 
-  List<LinkedNode> getFormalParameters(LinkedNode node) {
-    LinkedNode parameterList;
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.constructorDeclaration) {
-      parameterList = node.constructorDeclaration_parameters;
-    } else if (kind == LinkedNodeKind.functionDeclaration) {
-      return getFormalParameters(node.functionDeclaration_functionExpression);
-    } else if (kind == LinkedNodeKind.functionExpression) {
-      parameterList = node.functionExpression_formalParameters;
-    } else if (kind == LinkedNodeKind.functionTypeAlias) {
-      parameterList = node.functionTypeAlias_formalParameters;
-    } else if (kind == LinkedNodeKind.genericFunctionType) {
-      parameterList = node.genericFunctionType_formalParameters;
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      parameterList = node.methodDeclaration_formalParameters;
+  List<FormalParameter> getFormalParameters(AstNode node) {
+    if (node is ConstructorDeclaration) {
+      LazyConstructorDeclaration.readFormalParameters(_astReader, node);
+      return node.parameters.parameters;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      return getFormalParameters(node.functionExpression);
+    } else if (node is FunctionExpression) {
+      LazyFunctionExpression.readFormalParameters(_astReader, node);
+      return node.parameters?.parameters;
+    } else if (node is FunctionTypeAlias) {
+      LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
+      return node.parameters.parameters;
+    } else if (node is GenericFunctionType) {
+      LazyGenericFunctionType.readFormalParameters(_astReader, node);
+      return node.parameters.parameters;
+    } else if (node is MethodDeclaration) {
+      LazyMethodDeclaration.readFormalParameters(_astReader, node);
+      return node.parameters?.parameters;
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
-    return parameterList?.formalParameterList_parameters;
+//    if (kind == LinkedNodeKind.constructorDeclaration) {
+//      parameterList = node.constructorDeclaration_parameters;
+//    } else if (kind == LinkedNodeKind.functionDeclaration) {
+//      return getFormalParameters(node.functionDeclaration_functionExpression);
+//    } else if (kind == LinkedNodeKind.functionExpression) {
+//      parameterList = node.functionExpression_formalParameters;
+//    } else if (kind == LinkedNodeKind.functionTypeAlias) {
+//      parameterList = node.functionTypeAlias_formalParameters;
+//    } else if (kind == LinkedNodeKind.genericFunctionType) {
+//      parameterList = node.genericFunctionType_formalParameters;
+//    } else if (kind == LinkedNodeKind.methodDeclaration) {
+//      parameterList = node.methodDeclaration_formalParameters;
+//    } else {
+//      throw UnimplementedError('$kind');
+//    }
   }
 
-  DartType getFormalParameterType(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.defaultFormalParameter) {
-      return getFormalParameterType(node.defaultFormalParameter_parameter);
-    }
-    if (kind == LinkedNodeKind.fieldFormalParameter) {
-      return getType(node.fieldFormalParameter_type2);
-    }
-    if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-      return getType(node.functionTypedFormalParameter_type2);
-    }
-    if (kind == LinkedNodeKind.simpleFormalParameter) {
-      return getType(node.simpleFormalParameter_type2);
-    }
-    throw UnimplementedError('$kind');
+  GenericFunctionType getGeneticTypeAliasFunction(GenericTypeAlias node) {
+    LazyGenericTypeAlias.readFunctionType(_astReader, node);
+    return node.functionType;
   }
 
-  LinkedNode getImplementsClause(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.classDeclaration) {
-      return node.classOrMixinDeclaration_implementsClause;
-    } else if (kind == LinkedNodeKind.classTypeAlias) {
-      return node.classTypeAlias_implementsClause;
-    } else if (kind == LinkedNodeKind.mixinDeclaration) {
-      return node.classOrMixinDeclaration_implementsClause;
+  ImplementsClause getImplementsClause(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readImplementsClause(_astReader, node);
+      return node.implementsClause;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readImplementsClause(_astReader, node);
+      return node.implementsClause;
+    } else if (node is MixinDeclaration) {
+      LazyMixinDeclaration.readImplementsClause(_astReader, node);
+      return node.implementsClause;
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
@@ -103,61 +260,135 @@
     return bundleContext.getInterfaceType(linkedType);
   }
 
-  List<LinkedNode> getLibraryMetadataOrEmpty(LinkedNode unit) {
-    for (var directive in unit.compilationUnit_directives) {
-      if (directive.kind == LinkedNodeKind.libraryDirective) {
-        return getMetadataOrEmpty(directive);
+  List<Annotation> getLibraryMetadata(CompilationUnit unit) {
+    for (var directive in unit.directives) {
+      if (directive is LibraryDirective) {
+        return getMetadata(directive);
       }
     }
-    return const <LinkedNode>[];
+    return const <Annotation>[];
   }
 
-  List<LinkedNode> getMetadataOrEmpty(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.classDeclaration ||
-        kind == LinkedNodeKind.classTypeAlias ||
-        kind == LinkedNodeKind.constructorDeclaration ||
-        kind == LinkedNodeKind.enumConstantDeclaration ||
-        kind == LinkedNodeKind.enumDeclaration ||
-        kind == LinkedNodeKind.exportDirective ||
-        kind == LinkedNodeKind.functionDeclaration ||
-        kind == LinkedNodeKind.functionTypeAlias ||
-        kind == LinkedNodeKind.libraryDirective ||
-        kind == LinkedNodeKind.importDirective ||
-        kind == LinkedNodeKind.methodDeclaration ||
-        kind == LinkedNodeKind.mixinDeclaration ||
-        kind == LinkedNodeKind.partDirective ||
-        kind == LinkedNodeKind.partOfDirective ||
-        kind == LinkedNodeKind.variableDeclaration) {
-      return node.annotatedNode_metadata;
+  List<Annotation> getMetadata(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is CompilationUnit) {
+      assert(node == _unit);
+      return _getPartDirectiveAnnotation();
+    } else if (node is ConstructorDeclaration) {
+      LazyConstructorDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is DefaultFormalParameter) {
+      return getMetadata(node.parameter);
+    } else if (node is Directive) {
+      LazyDirective.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is EnumConstantDeclaration) {
+      LazyEnumConstantDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is EnumDeclaration) {
+      LazyEnumDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is FormalParameter) {
+      LazyFormalParameter.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is FunctionTypeAlias) {
+      LazyFunctionTypeAlias.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is MethodDeclaration) {
+      LazyMethodDeclaration.readMetadata(_astReader, node);
+      return node.metadata;
+    } else if (node is VariableDeclaration) {
+      var parent2 = node.parent.parent;
+      if (parent2 is FieldDeclaration) {
+        LazyFieldDeclaration.readMetadata(_astReader, parent2);
+        return parent2.metadata;
+      } else if (parent2 is TopLevelVariableDeclaration) {
+        LazyTopLevelVariableDeclaration.readMetadata(_astReader, parent2);
+        return parent2.metadata;
+      }
     }
-    if (kind == LinkedNodeKind.defaultFormalParameter) {
-      return getMetadataOrEmpty(node.defaultFormalParameter_parameter);
-    }
-    if (kind == LinkedNodeKind.fieldFormalParameter ||
-        kind == LinkedNodeKind.functionTypedFormalParameter ||
-        kind == LinkedNodeKind.simpleFormalParameter) {
-      return node.normalFormalParameter_metadata;
-    }
-    return const <LinkedNode>[];
+//    var kind = node.kind;
+//    if (kind == LinkedNodeKind.classDeclaration ||
+//        kind == LinkedNodeKind.classTypeAlias ||
+//        kind == LinkedNodeKind.constructorDeclaration ||
+//        kind == LinkedNodeKind.enumConstantDeclaration ||
+//        kind == LinkedNodeKind.enumDeclaration ||
+//        kind == LinkedNodeKind.exportDirective ||
+//        kind == LinkedNodeKind.functionDeclaration ||
+//        kind == LinkedNodeKind.functionTypeAlias ||
+//        kind == LinkedNodeKind.libraryDirective ||
+//        kind == LinkedNodeKind.importDirective ||
+//        kind == LinkedNodeKind.methodDeclaration ||
+//        kind == LinkedNodeKind.mixinDeclaration ||
+//        kind == LinkedNodeKind.partDirective ||
+//        kind == LinkedNodeKind.partOfDirective ||
+//        kind == LinkedNodeKind.variableDeclaration) {
+//      return node.annotatedNode_metadata;
+//    }
+//    if (kind == LinkedNodeKind.defaultFormalParameter) {
+//      return getMetadataOrEmpty(node.defaultFormalParameter_parameter);
+//    }
+//    if (kind == LinkedNodeKind.fieldFormalParameter ||
+//        kind == LinkedNodeKind.functionTypedFormalParameter ||
+//        kind == LinkedNodeKind.simpleFormalParameter) {
+//      return node.normalFormalParameter_metadata;
+//    }
+    return const <Annotation>[];
   }
 
   String getMethodName(LinkedNode node) {
     return getSimpleName(node.methodDeclaration_name);
   }
 
-  DartType getReturnType(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.functionDeclaration) {
-      return getType(node.functionDeclaration_returnType2);
-    } else if (kind == LinkedNodeKind.functionTypeAlias) {
-      return getType(node.functionTypeAlias_returnType2);
-    } else if (kind == LinkedNodeKind.genericFunctionType) {
-      return getType(node.genericFunctionType_returnType2);
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      return getType(node.methodDeclaration_returnType2);
+  Iterable<MethodDeclaration> getMethods(AstNode node) sync* {
+    if (node is ClassOrMixinDeclaration) {
+      var members = _getClassOrMixinMembers(node);
+      for (var member in members) {
+        if (member is MethodDeclaration) {
+          yield member;
+        }
+      }
+    }
+  }
+
+  int getNameOffset(AstNode node) {
+    if (node is NamedCompilationUnitMember) {
+      return node.name.offset;
+    } else if (node is EnumConstantDeclaration) {
+      return node.name.offset;
+    } else if (node is FormalParameter) {
+      return node.identifier.offset;
+    } else if (node is VariableDeclaration) {
+      return node.name.offset;
+    }
+    throw UnimplementedError('${node.runtimeType}');
+  }
+
+  OnClause getOnClause(MixinDeclaration node) {
+    LazyMixinDeclaration.readOnClause(_astReader, node);
+    return node.onClause;
+  }
+
+  /// Return the actual return type for the [node] - explicit or inferred.
+  DartType getReturnType(AstNode node) {
+    if (node is FunctionDeclaration) {
+      return LazyFunctionDeclaration.getReturnType(_astReader, node);
+    } else if (node is FunctionTypeAlias) {
+      return LazyFunctionTypeAlias.getReturnType(_astReader, node);
+    } else if (node is GenericFunctionType) {
+      return LazyGenericFunctionType.getReturnType(_astReader, node);
+    } else if (node is MethodDeclaration) {
+      return LazyMethodDeclaration.getReturnType(_astReader, node);
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
@@ -177,6 +408,18 @@
     return node.simpleStringLiteral_value;
   }
 
+  TypeName getSuperclass(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readExtendsClause(_astReader, node);
+      return node.extendsClause?.superclass;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readSuperclass(_astReader, node);
+      return node.superclass;
+    } else {
+      throw StateError('${node.runtimeType}');
+    }
+  }
+
   String getTokenLexeme(int token) {
     return tokensContext.lexeme(token);
   }
@@ -185,16 +428,55 @@
     return tokensContext.offset(token);
   }
 
-  DartType getType(LinkedNodeType linkedType) {
-    return bundleContext.getType(linkedType);
+  /// Return the actual type for the [node] - explicit or inferred.
+  DartType getType(AstNode node) {
+    if (node is DefaultFormalParameter) {
+      return getType(node.parameter);
+    } else if (node is FormalParameter) {
+      return LazyFormalParameter.getType(_astReader, node);
+    } else if (node is VariableDeclaration) {
+      return LazyVariableDeclaration.getType(_astReader, node);
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
+    }
   }
 
-  DartType getTypeAnnotationType(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.typeName) {
-      return getType(node.typeName_type);
+  TypeAnnotation getTypeParameterBound(TypeParameter node) {
+    LazyTypeParameter.readBound(_astReader, node);
+    return node.bound;
+  }
+
+  TypeParameterList getTypeParameters2(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is ConstructorDeclaration) {
+      return null;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      return getTypeParameters2(node.functionExpression);
+    } else if (node is FunctionExpression) {
+      LazyFunctionExpression.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is FunctionTypeAlias) {
+      LazyFunctionTypeAlias.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is GenericFunctionType) {
+      return node.typeParameters;
+    } else if (node is GenericTypeAlias) {
+      LazyGenericTypeAlias.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is MethodDeclaration) {
+      LazyMethodDeclaration.readTypeParameters(_astReader, node);
+      return node.typeParameters;
+    } else if (node is MixinDeclaration) {
+      LazyMixinDeclaration.readTypeParameters(_astReader, node);
+      return node.typeParameters;
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
@@ -206,38 +488,59 @@
     return getSimpleName(node.variableDeclaration_name);
   }
 
-  bool isAbstract(LinkedNode node) {
-    return node.kind == LinkedNodeKind.methodDeclaration &&
-        node.methodDeclaration_body.kind == LinkedNodeKind.emptyFunctionBody;
+  WithClause getWithClause(AstNode node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readWithClause(_astReader, node);
+      return node.withClause;
+    } else if (node is ClassTypeAlias) {
+      LazyClassTypeAlias.readWithClause(_astReader, node);
+      return node.withClause;
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
+    }
   }
 
-  bool isAsynchronous(LinkedNode node) {
-    LinkedNode body = _getFunctionBody(node);
-    if (body.kind == LinkedNodeKind.blockFunctionBody) {
-      return isAsyncKeyword(body.blockFunctionBody_keyword);
-    } else if (body.kind == LinkedNodeKind.emptyFunctionBody) {
+  bool isAbstract(AstNode node) {
+    if (node is ClassDeclaration) {
+      return node.abstractKeyword != null;
+    } else if (node is ClassTypeAlias) {
+      return node.abstractKeyword != null;
+    } else if (node is FunctionDeclaration) {
       return false;
-    } else {
-      return isAsyncKeyword(body.expressionFunctionBody_keyword);
+    } else if (node is MethodDeclaration) {
+      return node.isAbstract;
     }
+    throw UnimplementedError('${node.runtimeType}');
+  }
+
+  bool isAsynchronous(AstNode node) {
+    var body = _getFunctionBody(node);
+    return body.isAsynchronous;
   }
 
   bool isAsyncKeyword(int token) {
     return tokensContext.type(token) == UnlinkedTokenType.ASYNC;
   }
 
-  bool isConst(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.defaultFormalParameter) {
-      return isConst(node.defaultFormalParameter_parameter);
+  bool isConst(AstNode node) {
+    if (node is FormalParameter) {
+      return node.isConst;
     }
-    if (kind == LinkedNodeKind.simpleFormalParameter) {
-      return isConstKeyword(node.simpleFormalParameter_keyword);
+    if (node is VariableDeclaration) {
+      VariableDeclarationList parent = node.parent;
+      return parent.isConst;
     }
-    if (kind == LinkedNodeKind.variableDeclaration) {
-      return node.variableDeclaration_declaration.isConst;
-    }
-    throw UnimplementedError('$kind');
+//    var kind = node.kind;
+//    if (kind == LinkedNodeKind.defaultFormalParameter) {
+//      return isConst(node.defaultFormalParameter_parameter);
+//    }
+//    if (kind == LinkedNodeKind.simpleFormalParameter) {
+//      return isConstKeyword(node.simpleFormalParameter_keyword);
+//    }
+//    if (kind == LinkedNodeKind.variableDeclaration) {
+//      return node.variableDeclaration_declaration.isConst;
+//    }
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   bool isConstKeyword(int token) {
@@ -248,40 +551,35 @@
     return isConstKeyword(node.variableDeclarationList_keyword);
   }
 
-  bool isExternal(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.constructorDeclaration) {
-      return node.constructorDeclaration_externalKeyword != 0;
-    } else if (kind == LinkedNodeKind.functionDeclaration) {
-      return node.functionDeclaration_externalKeyword != 0;
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      return node.methodDeclaration_externalKeyword != 0;
+  bool isCovariantField(AstNode node) {
+    if (node is VariableDeclaration) {
+      var parent2 = node.parent.parent;
+      return parent2 is FieldDeclaration && parent2.covariantKeyword != null;
+    }
+    return false;
+  }
+
+  bool isExternal(AstNode node) {
+    if (node is ConstructorDeclaration) {
+      return node.externalKeyword != null;
+    } else if (node is FunctionDeclaration) {
+      return node.externalKeyword != null;
+    } else if (node is MethodDeclaration) {
+      return node.externalKeyword != null;
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  bool isFinal(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.defaultFormalParameter) {
-      return isFinal(node.defaultFormalParameter_parameter);
-    }
-    if (kind == LinkedNodeKind.enumConstantDeclaration) {
+  bool isFinal(AstNode node) {
+    if (node is EnumConstantDeclaration) {
       return false;
     }
-    if (kind == LinkedNodeKind.fieldFormalParameter) {
-      return isFinalKeyword(node.fieldFormalParameter_keyword);
+    if (node is VariableDeclaration) {
+      VariableDeclarationList parent = node.parent;
+      return parent.isFinal;
     }
-    if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-      return false;
-    }
-    if (kind == LinkedNodeKind.simpleFormalParameter) {
-      return isFinalKeyword(node.simpleFormalParameter_keyword);
-    }
-    if (kind == LinkedNodeKind.variableDeclaration) {
-      return node.variableDeclaration_declaration.isFinal;
-    }
-    throw UnimplementedError('$kind');
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   bool isFinalKeyword(int token) {
@@ -296,26 +594,19 @@
     return node.kind == LinkedNodeKind.functionDeclaration;
   }
 
-  bool isGenerator(LinkedNode node) {
-    LinkedNode body = _getFunctionBody(node);
-    if (body.kind == LinkedNodeKind.blockFunctionBody) {
-      return body.blockFunctionBody_star != 0;
+  bool isGenerator(AstNode node) {
+    var body = _getFunctionBody(node);
+    return body.isGenerator;
+  }
+
+  bool isGetter(AstNode node) {
+    if (node is FunctionDeclaration) {
+      return node.isGetter;
+    } else if (node is MethodDeclaration) {
+      return node.isGetter;
+    } else {
+      throw StateError('${node.runtimeType}');
     }
-    return false;
-  }
-
-  bool isGetter(LinkedNode node) {
-    return isGetterMethod(node) || isGetterFunction(node);
-  }
-
-  bool isGetterFunction(LinkedNode node) {
-    return isFunction(node) &&
-        _isGetToken(node.functionDeclaration_propertyKeyword);
-  }
-
-  bool isGetterMethod(LinkedNode node) {
-    return isMethod(node) &&
-        _isGetToken(node.methodDeclaration_propertyKeyword);
   }
 
   bool isLibraryKeyword(int token) {
@@ -326,131 +617,115 @@
     return node.kind == LinkedNodeKind.methodDeclaration;
   }
 
-  bool isSetter(LinkedNode node) {
-    return isSetterMethod(node) || isSetterFunction(node);
-  }
-
-  bool isSetterFunction(LinkedNode node) {
-    return isFunction(node) &&
-        _isSetToken(node.functionDeclaration_propertyKeyword);
-  }
-
-  bool isSetterMethod(LinkedNode node) {
-    return isMethod(node) &&
-        _isSetToken(node.methodDeclaration_propertyKeyword);
-  }
-
-  bool isStatic(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.functionDeclaration) {
-      return true;
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      return node.methodDeclaration_modifierKeyword != 0;
-    } else if (kind == LinkedNodeKind.variableDeclaration) {
-      return node.variableDeclaration_declaration.isStatic;
+  bool isSetter(AstNode node) {
+    if (node is FunctionDeclaration) {
+      return node.isSetter;
+    } else if (node is MethodDeclaration) {
+      return node.isSetter;
+    } else {
+      throw StateError('${node.runtimeType}');
     }
-    throw UnimplementedError('$kind');
+  }
+
+  bool isStatic(AstNode node) {
+    if (node is FunctionDeclaration) {
+      return true;
+    } else if (node is MethodDeclaration) {
+      return node.modifierKeyword != null;
+    } else if (node is VariableDeclaration) {
+      var parent2 = node.parent.parent;
+      return parent2 is FieldDeclaration && parent2.isStatic;
+    }
+    throw UnimplementedError('${node.runtimeType}');
   }
 
   bool isSyncKeyword(int token) {
     return tokensContext.type(token) == UnlinkedTokenType.SYNC;
   }
 
-  void loadClassMemberReferences(Reference reference) {
-    var node = reference.node;
-    if (node.kind != LinkedNodeKind.classDeclaration &&
-        node.kind != LinkedNodeKind.mixinDeclaration) {
-      return;
+  Expression readInitializer(ElementImpl enclosing, AstNode node) {
+    if (node is DefaultFormalParameter) {
+      LazyFormalParameter.readDefaultValue(_astReader, node);
+      return node.defaultValue;
+    } else if (node is VariableDeclaration) {
+      LazyVariableDeclaration.readInitializer(_astReader, node);
+      return node.initializer;
+    } else {
+      throw StateError('${node.runtimeType}');
     }
-
-    var constructorContainerRef = reference.getChild('@constructor');
-    var fieldContainerRef = reference.getChild('@field');
-    var methodContainerRef = reference.getChild('@method');
-    var getterContainerRef = reference.getChild('@getter');
-    var setterContainerRef = reference.getChild('@setter');
-    for (var member in node.classOrMixinDeclaration_members) {
-      if (member.kind == LinkedNodeKind.constructorDeclaration) {
-        var name = getConstructorDeclarationName(member);
-        constructorContainerRef.getChild(name).node = member;
-      } else if (member.kind == LinkedNodeKind.fieldDeclaration) {
-        var variableList = member.fieldDeclaration_fields;
-        for (var field in variableList.variableDeclarationList_variables) {
-          var name = getSimpleName(field.variableDeclaration_name);
-          fieldContainerRef.getChild(name).node = field;
-        }
-      } else if (member.kind == LinkedNodeKind.methodDeclaration) {
-        var name = getSimpleName(member.methodDeclaration_name);
-        var propertyKeyword = member.methodDeclaration_propertyKeyword;
-        if (_isGetToken(propertyKeyword)) {
-          getterContainerRef.getChild(name).node = member;
-        } else if (_isSetToken(propertyKeyword)) {
-          setterContainerRef.getChild(name).node = member;
-        } else {
-          methodContainerRef.getChild(name).node = member;
-        }
-      }
-    }
-  }
-
-  Expression readInitializer(ElementImpl enclosing, LinkedNode linkedNode) {
-    var reader = AstBinaryReader(this);
-    return reader.withLocalScope(enclosing, () {
-      if (linkedNode.kind == LinkedNodeKind.defaultFormalParameter) {
-        var data = linkedNode.defaultFormalParameter_defaultValue;
-        return reader.readNode(data);
-      }
-      var data = linkedNode.variableDeclaration_initializer;
-      return reader.readNode(data);
-    });
   }
 
   AstNode readNode(LinkedNode linkedNode) {
-    var reader = AstBinaryReader(this);
-    return reader.readNode(linkedNode);
+    return _astReader.readNode(linkedNode);
   }
 
   void setReturnType(LinkedNodeBuilder node, DartType type) {
-    var typeData = bundleContext.linking.writeType(type);
-    node.functionDeclaration_returnType2 = typeData;
+    throw UnimplementedError();
+//    var typeData = bundleContext.linking.writeType(type);
+//    node.functionDeclaration_returnType2 = typeData;
   }
 
   void setVariableType(LinkedNodeBuilder node, DartType type) {
-    var typeData = bundleContext.linking.writeType(type);
-    node.simpleFormalParameter_type2 = typeData;
+    throw UnimplementedError();
+//    var typeData = bundleContext.linking.writeType(type);
+//    node.simpleFormalParameter_type2 = typeData;
   }
 
-  Iterable<LinkedNode> topLevelVariables(LinkedNode unit) sync* {
-    for (var declaration in unit.compilationUnit_declarations) {
-      if (declaration.kind == LinkedNodeKind.topLevelVariableDeclaration) {
-        var variableList = declaration.topLevelVariableDeclaration_variableList;
-        for (var variable in variableList.variableDeclarationList_variables) {
+  Iterable<VariableDeclaration> topLevelVariables(CompilationUnit unit) sync* {
+    for (var declaration in unit.declarations) {
+      if (declaration is TopLevelVariableDeclaration) {
+        for (var variable in declaration.variables.variables) {
           yield variable;
         }
       }
     }
   }
 
-  LinkedNode _getFunctionBody(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.constructorDeclaration) {
-      return node.constructorDeclaration_body;
-    } else if (kind == LinkedNodeKind.functionDeclaration) {
-      return _getFunctionBody(node.functionDeclaration_functionExpression);
-    } else if (kind == LinkedNodeKind.functionExpression) {
-      return node.functionExpression_body;
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      return node.methodDeclaration_body;
+  List<ClassMember> _getClassOrMixinMembers(ClassOrMixinDeclaration node) {
+    if (node is ClassDeclaration) {
+      LazyClassDeclaration.readMembers(_astReader, node);
+    } else if (node is MixinDeclaration) {
+      LazyMixinDeclaration.readMembers(_astReader, node);
     } else {
-      throw UnimplementedError('$kind');
+      throw StateError('${node.runtimeType}');
+    }
+    return node.members;
+  }
+
+  FunctionBody _getFunctionBody(AstNode node) {
+    if (node is ConstructorDeclaration) {
+      LazyConstructorDeclaration.readBody(_astReader, node);
+      return node.body;
+    } else if (node is FunctionDeclaration) {
+      LazyFunctionDeclaration.readFunctionExpression(_astReader, node);
+      return _getFunctionBody(node.functionExpression);
+    } else if (node is FunctionExpression) {
+      LazyFunctionExpression.readBody(_astReader, node);
+      return node.body;
+    } else if (node is MethodDeclaration) {
+      LazyMethodDeclaration.readBody(_astReader, node);
+      return node.body;
+    } else {
+      throw UnimplementedError('${node.runtimeType}');
     }
   }
 
-  bool _isGetToken(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.GET;
-  }
-
-  bool _isSetToken(int token) {
-    return tokensContext.type(token) == UnlinkedTokenType.SET;
+  NodeList<Annotation> _getPartDirectiveAnnotation() {
+    if (indexInLibrary != 0) {
+      var definingContext = libraryContext.definingUnit;
+      var unit = definingContext.unit;
+      var partDirectiveIndex = 0;
+      for (var directive in unit.directives) {
+        if (directive is PartDirective) {
+          partDirectiveIndex++;
+          if (partDirectiveIndex == indexInLibrary) {
+            LazyDirective.readMetadata(definingContext._astReader, directive);
+            return directive.metadata;
+          }
+        }
+      }
+    }
+    throw StateError('Expected to find $indexInLibrary part directive.');
   }
 
   static List<LinkedNode> getTypeParameters(LinkedNode node) {
diff --git a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
index 6eb82be..e089151 100644
--- a/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/metadata_resolver.dart
@@ -3,153 +3,171 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:analyzer/dart/ast/standard_ast_factory.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/element.dart';
 import 'package:analyzer/src/generated/resolver.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/ast_resolver.dart';
-import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
 import 'package:analyzer/src/summary2/link.dart';
-import 'package:analyzer/src/summary2/reference.dart';
 
-class MetadataResolver {
-  AstResolver _astResolver;
+class MetadataResolver extends ThrowingAstVisitor<void> {
+  final Linker _linker;
+  final LibraryElement _libraryElement;
 
-  MetadataResolver(Linker linker, Reference libraryRef) {
-    var libraryElement = linker.elementFactory.elementOfReference(libraryRef);
-    var libraryScope = LibraryScope(libraryElement);
-    _astResolver = AstResolver(linker, libraryElement, libraryScope);
+  Scope scope;
+
+  MetadataResolver(this._linker, this._libraryElement);
+
+  @override
+  void visitAnnotation(Annotation node) {
+    // TODO(scheglov) get rid of?
+    node.elementAnnotation = ElementAnnotationImpl(null);
+
+    var astResolver = AstResolver(_linker, _libraryElement, scope);
+    // TODO(scheglov) enclosing elements?
+    astResolver.resolve(node);
   }
 
-  void resolve(UnitBuilder unit) {
-    var unitDirectives = unit.node.compilationUnit_directives;
-    for (var directive in unitDirectives) {
-      _annotatedNode(unit, directive);
-    }
-
-    var unitDeclarations = unit.node.compilationUnit_declarations;
-    for (LinkedNodeBuilder unitDeclaration in unitDeclarations) {
-      var kind = unitDeclaration.kind;
-      if (_isAnnotatedNode(kind)) {
-        _annotatedNode(unit, unitDeclaration);
-      }
-      if (kind == LinkedNodeKind.classDeclaration) {
-        _class(unit, unitDeclaration);
-      } else if (kind == LinkedNodeKind.enumDeclaration) {
-        _enumDeclaration(unit, unitDeclaration);
-      } else if (kind == LinkedNodeKind.functionDeclaration) {
-        var function = unitDeclaration.functionDeclaration_functionExpression;
-        _formalParameterList(
-          unit,
-          function.functionExpression_formalParameters,
-        );
-      } else if (kind == LinkedNodeKind.topLevelVariableDeclaration) {
-        _variables(
-          unit,
-          unitDeclaration,
-          unitDeclaration.topLevelVariableDeclaration_variableList,
-        );
-      }
-    }
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    node.metadata.accept(this);
+    node.typeParameters?.accept(this);
+    node.members.accept(this);
   }
 
-  void _annotatedNode(UnitBuilder unit, LinkedNodeBuilder node) {
-    var unresolved = node.annotatedNode_metadata;
-    var resolved = _list(unit, unresolved);
-    node.annotatedNode_metadata = resolved;
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    node.metadata.accept(this);
+    node.typeParameters?.accept(this);
   }
 
-  void _class(UnitBuilder unit, LinkedNodeBuilder unitDeclaration) {
-    var members = unitDeclaration.classOrMixinDeclaration_members;
-    for (var classMember in members) {
-      var kind = classMember.kind;
-      if (_isAnnotatedNode(kind)) {
-        _annotatedNode(unit, classMember);
-      }
-      if (kind == LinkedNodeKind.constructorDeclaration) {
-        _formalParameterList(
-          unit,
-          classMember.constructorDeclaration_parameters,
-        );
-      } else if (kind == LinkedNodeKind.fieldDeclaration) {
-        _variables(
-          unit,
-          classMember,
-          classMember.fieldDeclaration_fields,
-        );
-      } else if (kind == LinkedNodeKind.methodDeclaration) {
-        _formalParameterList(
-          unit,
-          classMember.methodDeclaration_formalParameters,
-        );
-      }
-    }
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    node.directives.accept(this);
+    node.declarations.accept(this);
   }
 
-  void _enumDeclaration(UnitBuilder unit, LinkedNodeBuilder node) {
-    for (var constant in node.enumDeclaration_constants) {
-      var kind = constant.kind;
-      if (kind == LinkedNodeKind.enumConstantDeclaration) {
-        _annotatedNode(unit, constant);
-      }
-    }
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.metadata.accept(this);
+    node.parameters.accept(this);
   }
 
-  void _formalParameterList(UnitBuilder unit, LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    for (var parameter in node.formalParameterList_parameters) {
-      if (parameter.kind == LinkedNodeKind.defaultFormalParameter) {
-        var actual = parameter.defaultFormalParameter_parameter;
-        var unresolved = actual.normalFormalParameter_metadata;
-        var resolved = _list(unit, unresolved);
-        actual.normalFormalParameter_metadata = resolved;
-      } else {
-        var unresolved = parameter.normalFormalParameter_metadata;
-        var resolved = _list(unit, unresolved);
-        parameter.normalFormalParameter_metadata = resolved;
-      }
-    }
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    node.parameter.accept(this);
   }
 
-  List<LinkedNodeBuilder> _list(UnitBuilder unit, List<LinkedNode> unresolved) {
-    var resolved = List<LinkedNodeBuilder>(unresolved.length);
-    for (var i = 0; i < unresolved.length; ++i) {
-      var unresolvedNode = unresolved[i];
-
-      var reader = AstBinaryReader(unit.context);
-      var ast = reader.readNode(unresolvedNode) as Annotation;
-      ast.elementAnnotation = ElementAnnotationImpl(null);
-
-      // Set some parent, so that resolver does not bail out.
-      astFactory.libraryDirective(null, [ast], null, null, null);
-
-      var resolvedNode = _astResolver.resolve(unit.context, ast);
-      resolved[i] = resolvedNode;
-    }
-    return resolved;
+  @override
+  void visitEnumConstantDeclaration(EnumConstantDeclaration node) {
+    node.metadata.accept(this);
   }
 
-  /// Resolve annotations of the [declaration] (field or top-level variable),
-  /// and set them as metadata for each variable in the [variableList].
-  void _variables(UnitBuilder unit, LinkedNodeBuilder declaration,
-      LinkedNodeBuilder variableList) {
-    for (var variable in variableList.variableDeclarationList_variables) {
-      var unresolved = declaration.annotatedNode_metadata;
-      var resolved = _list(unit, unresolved);
-      variable.annotatedNode_metadata = resolved;
-    }
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {
+    node.metadata.accept(this);
+    node.constants.accept(this);
   }
 
-  static bool _isAnnotatedNode(LinkedNodeKind kind) {
-    return kind == LinkedNodeKind.classDeclaration ||
-        kind == LinkedNodeKind.classTypeAlias ||
-        kind == LinkedNodeKind.constructorDeclaration ||
-        kind == LinkedNodeKind.enumDeclaration ||
-        kind == LinkedNodeKind.functionDeclaration ||
-        kind == LinkedNodeKind.functionTypeAlias ||
-        kind == LinkedNodeKind.methodDeclaration;
+  @override
+  void visitExportDirective(ExportDirective node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    node.metadata.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    node.parameters.accept(this);
+  }
+
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    node.metadata.accept(this);
+    node.functionExpression.accept(this);
+  }
+
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    node.metadata.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
+  }
+
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    node.metadata.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
+  }
+
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    // TODO: implement visitGenericTypeAlias
+//    super.visitGenericTypeAlias(node);
+  }
+
+  @override
+  void visitImportDirective(ImportDirective node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitLibraryDirective(LibraryDirective node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    node.metadata.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
+  }
+
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    // TODO: implement visitMixinDeclaration
+//    super.visitMixinDeclaration(node);
+  }
+
+  @override
+  void visitPartDirective(PartDirective node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitPartOfDirective(PartOfDirective node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.metadata.accept(this);
+  }
+
+  @override
+  void visitTypeParameterList(TypeParameterList node) {
+    // TODO: implement visitTypeParameterList
+//    super.visitTypeParameterList(node);
   }
 }
diff --git a/pkg/analyzer/lib/src/summary2/reference.dart b/pkg/analyzer/lib/src/summary2/reference.dart
index 234ed5d..7f8af39 100644
--- a/pkg/analyzer/lib/src/summary2/reference.dart
+++ b/pkg/analyzer/lib/src/summary2/reference.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/dart/ast/ast.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/scope.dart';
@@ -35,6 +36,9 @@
   /// The corresponding [LinkedNode], or `null` if a named container.
   LinkedNode node;
 
+  /// The corresponding [AstNode], or `null` if a named container.
+  AstNode node2;
+
   /// The corresponding [Element], or `null` if a named container.
   Element element;
 
@@ -50,16 +54,23 @@
 
   Reference._(this.parent, this.name);
 
+  Iterable<Reference> get children {
+    if (_children != null) {
+      return _children.values;
+    }
+    return const [];
+  }
+
   bool get isClass => parent != null && parent.name == '@class';
 
   bool get isDynamic => name == 'dynamic' && parent?.name == 'dart:core';
 
   bool get isEnum => parent != null && parent.name == '@enum';
 
-  bool get isGenericTypeAlias => parent != null && parent.name == '@typeAlias';
-
   bool get isPrefix => parent != null && parent.name == '@prefix';
 
+  bool get isTypeAlias => parent != null && parent.name == '@typeAlias';
+
   bool get isTypeParameter => parent != null && parent.name == '@typeParameter';
 
   int get numOfChildren => _children != null ? _children.length : 0;
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index c76cd0b..4d27523e 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -2,12 +2,523 @@
 // for details. All 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/summary/format.dart';
+import 'package:analyzer/dart/ast/ast.dart';
+import 'package:analyzer/dart/ast/visitor.dart';
+import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/resolver/scope.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
-import 'package:analyzer/src/summary2/linking_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/scope.dart';
+import 'package:analyzer/src/summary2/type_builder.dart';
+
+// TODO(scheglov) This class is not used, not [get] yet.
+class LinkingNodeContext {
+  static const _key = 'linkingNodeContext';
+
+  final Scope scope;
+
+  LinkingNodeContext(this.scope);
+
+  static LinkingNodeContext get(AstNode node) {
+    LinkingNodeContext context = node.getProperty(_key);
+    if (context == null) {
+      throw StateError('No context for: $node');
+    }
+    return context;
+  }
+
+  static void set(AstNode node, LinkingNodeContext context) {
+    node.setProperty(_key, context);
+  }
+}
+
+//class ReferenceResolver {
+//  final LinkingBundleContext linkingBundleContext;
+//  final TypesToBuild typesToBuild;
+//  final UnitBuilder unit;
+//
+//  /// TODO(scheglov) Update scope with local scopes (formal / type parameters).
+//  Scope scope;
+//
+//  Reference reference;
+//
+//  ReferenceResolver(
+//    this.linkingBundleContext,
+//    this.typesToBuild,
+//    this.unit,
+//    this.scope,
+//    this.reference,
+//  );
+//
+//  LinkedNodeTypeBuilder get _dynamicType {
+//    return LinkedNodeTypeBuilder(
+//      kind: LinkedNodeTypeKind.dynamic_,
+//    );
+//  }
+//
+//  void resolve() {
+//    _node(unit.node);
+//  }
+//
+//  void _classDeclaration(LinkedNodeBuilder node) {
+//    var name = unit.context.getUnitMemberName(node);
+//    reference = reference.getChild('@class').getChild(name);
+//
+//    var typeParameters = node.classOrMixinDeclaration_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      _extendsClause(node.classDeclaration_extendsClause);
+//      _withClause(node.classDeclaration_withClause);
+//      _implementsClause(node.classOrMixinDeclaration_implementsClause);
+//
+//      for (var member in node.classOrMixinDeclaration_members) {
+//        if (member.kind != LinkedNodeKind.constructorDeclaration) {
+//          _node(member);
+//        }
+//      }
+//      for (var member in node.classOrMixinDeclaration_members) {
+//        if (member.kind == LinkedNodeKind.constructorDeclaration) {
+//          _node(member);
+//        }
+//      }
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _classTypeAlias(LinkedNodeBuilder node) {
+//    var name = unit.context.getUnitMemberName(node);
+//    reference = reference.getChild('@class').getChild(name);
+//
+//    var typeParameters = node.classTypeAlias_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      _typeName(node.classTypeAlias_superclass);
+//      _withClause(node.classTypeAlias_withClause);
+//      _implementsClause(node.classTypeAlias_implementsClause);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _compilationUnit(LinkedNodeBuilder node) {
+//    _nodeList(node.compilationUnit_directives);
+//    _nodeList(node.compilationUnit_declarations);
+//  }
+//
+//  void _constructorDeclaration(LinkedNodeBuilder node) {
+//    _node(node.constructorDeclaration_parameters);
+//  }
+//
+//  void _enumConstantDeclaration(LinkedNodeBuilder node) {}
+//
+//  void _enumDeclaration(LinkedNodeBuilder node) {
+//    _nodeList(node.enumDeclaration_constants);
+//  }
+//
+//  void _exportDirective(LinkedNodeBuilder node) {}
+//
+//  void _extendsClause(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    _typeName(node.extendsClause_superclass);
+//  }
+//
+//  void _fieldDeclaration(LinkedNodeBuilder node) {
+//    _node(node.fieldDeclaration_fields);
+//  }
+//
+//  void _fieldFormalParameter(LinkedNodeBuilder node) {
+//    var typeNode = node.fieldFormalParameter_type;
+//    if (typeNode != null) {
+//      _node(typeNode);
+//    }
+//
+//    var formalParameters = node.fieldFormalParameter_formalParameters;
+//    if (formalParameters != null) {
+//      _formalParameters(formalParameters);
+//    }
+//
+//    if (typeNode != null || formalParameters != null) {
+//      typesToBuild.declarations.add(node);
+//    }
+//  }
+//
+//  void _formalParameters(LinkedNodeBuilder node) {
+//    for (var parameter in node.formalParameterList_parameters) {
+//      _node(parameter);
+//    }
+//  }
+//
+//  void _functionDeclaration(LinkedNodeBuilder node) {
+//    var name = unit.context.getUnitMemberName(node);
+//    reference = reference.getChild('@function').getChild(name);
+//
+//    var function = node.functionDeclaration_functionExpression;
+//    var typeParameters = function.functionExpression_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      var returnType = node.functionDeclaration_returnType;
+//      if (returnType != null) {
+//        _node(returnType);
+//        typesToBuild.declarations.add(node);
+//      } else {
+//        node.functionDeclaration_returnType2 = _dynamicType;
+//      }
+//
+//      _node(function.functionExpression_formalParameters);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _functionExpression(LinkedNodeBuilder node) {
+//    var typeParameters = node.functionExpression_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      _node(node.functionExpression_formalParameters);
+//    });
+//  }
+//
+//  void _functionTypeAlias(LinkedNodeBuilder node) {
+//    var name = unit.context.getUnitMemberName(node);
+//    reference = reference.getChild('@typeAlias').getChild(name);
+//
+//    var typeParameters = node.functionTypeAlias_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      var returnType = node.functionTypeAlias_returnType;
+//      if (returnType != null) {
+//        _node(returnType);
+//        typesToBuild.declarations.add(node);
+//      } else {
+//        node.functionTypeAlias_returnType2 = _dynamicType;
+//      }
+//
+//      _node(node.functionTypeAlias_formalParameters);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _functionTypedFormalParameter(LinkedNodeBuilder node) {
+//    var typeParameters = node.functionTypedFormalParameter_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      var typeNode = node.functionTypedFormalParameter_returnType;
+//      if (typeNode != null) {
+//        _node(typeNode);
+//      }
+//
+//      _formalParameters(node.functionTypedFormalParameter_formalParameters);
+//      typesToBuild.declarations.add(node);
+//    });
+//  }
+//
+//  void _genericFunctionType(LinkedNodeBuilder node) {
+//    reference = reference.getChild('@function');
+//
+//    var name = '${reference.numOfChildren}';
+//    reference = reference.getChild(name);
+//
+//    var typeParameters = node.genericFunctionType_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      var returnType = node.genericFunctionType_returnType;
+//      if (returnType != null) {
+//        _node(returnType);
+//        typesToBuild.declarations.add(node);
+//      }
+//
+//      _formalParameters(node.genericFunctionType_formalParameters);
+//
+//      typesToBuild.typeAnnotations.add(node);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _genericTypeAlias(LinkedNodeBuilder node) {
+//    var name = unit.context.getSimpleName(
+//      node.namedCompilationUnitMember_name,
+//    );
+//    reference = reference.getChild('@typeAlias').getChild(name);
+//
+//    var typeParameters = node.genericTypeAlias_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      _node(node.genericTypeAlias_functionType);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _implementsClause(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    _typeNameList(node.implementsClause_interfaces);
+//  }
+//
+//  void _importDirective(LinkedNodeBuilder node) {}
+//
+//  void _libraryDirective(LinkedNodeBuilder node) {}
+//
+//  void _methodDeclaration(LinkedNodeBuilder node) {
+//    var name = unit.context.getMethodName(node);
+//    reference = reference.getChild('@method').getChild(name);
+//
+//    var typeParameters = node.methodDeclaration_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      var returnType = node.methodDeclaration_returnType;
+//      if (returnType != null) {
+//        _node(returnType);
+//        typesToBuild.declarations.add(node);
+//      }
+//
+//      _node(node.methodDeclaration_formalParameters);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _mixinDeclaration(LinkedNodeBuilder node) {
+//    var name = unit.context.getUnitMemberName(node);
+//    reference = reference.getChild('@class').getChild(name);
+//
+//    var typeParameters = node.classOrMixinDeclaration_typeParameters;
+//    _withTypeParameters(typeParameters, () {
+//      _onClause(node.mixinDeclaration_onClause);
+//      _implementsClause(node.classOrMixinDeclaration_implementsClause);
+//      _nodeList(node.classOrMixinDeclaration_members);
+//    });
+//
+//    reference = reference.parent.parent;
+//  }
+//
+//  void _node(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    if (node.kind == LinkedNodeKind.classDeclaration) {
+//      _classDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.classTypeAlias) {
+//      _classTypeAlias(node);
+//    } else if (node.kind == LinkedNodeKind.compilationUnit) {
+//      _compilationUnit(node);
+//    } else if (node.kind == LinkedNodeKind.constructorDeclaration) {
+//      _constructorDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.defaultFormalParameter) {
+//      _node(node.defaultFormalParameter_parameter);
+//    } else if (node.kind == LinkedNodeKind.enumDeclaration) {
+//      _enumDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.enumConstantDeclaration) {
+//      _enumConstantDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.exportDirective) {
+//      _exportDirective(node);
+//    } else if (node.kind == LinkedNodeKind.fieldDeclaration) {
+//      _fieldDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.fieldFormalParameter) {
+//      _fieldFormalParameter(node);
+//    } else if (node.kind == LinkedNodeKind.formalParameterList) {
+//      _formalParameters(node);
+//    } else if (node.kind == LinkedNodeKind.functionDeclaration) {
+//      _functionDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.functionExpression) {
+//      _functionExpression(node);
+//    } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
+//      _functionTypeAlias(node);
+//    } else if (node.kind == LinkedNodeKind.functionTypedFormalParameter) {
+//      _functionTypedFormalParameter(node);
+//    } else if (node.kind == LinkedNodeKind.genericFunctionType) {
+//      _genericFunctionType(node);
+//    } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
+//      _genericTypeAlias(node);
+//    } else if (node.kind == LinkedNodeKind.importDirective) {
+//      _importDirective(node);
+//    } else if (node.kind == LinkedNodeKind.libraryDirective) {
+//      _libraryDirective(node);
+//    } else if (node.kind == LinkedNodeKind.methodDeclaration) {
+//      _methodDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.mixinDeclaration) {
+//      _mixinDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.partDirective) {
+//      _partDirective(node);
+//    } else if (node.kind == LinkedNodeKind.partOfDirective) {
+//      _partOfDirective(node);
+//    } else if (node.kind == LinkedNodeKind.simpleFormalParameter) {
+//      _simpleFormalParameter(node);
+//    } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) {
+//      _topLevelVariableDeclaration(node);
+//    } else if (node.kind == LinkedNodeKind.typeArgumentList) {
+//      _typeArgumentList(node);
+//    } else if (node.kind == LinkedNodeKind.typeName) {
+//      _typeName(node);
+//    } else if (node.kind == LinkedNodeKind.typeParameter) {
+//      _typeParameter(node);
+//    } else if (node.kind == LinkedNodeKind.typeParameterList) {
+//      _typeParameterList(node);
+//    } else if (node.kind == LinkedNodeKind.variableDeclarationList) {
+//      _variableDeclarationList(node);
+//    } else {
+//      // TODO(scheglov) implement
+//      throw UnimplementedError('${node.kind}');
+//    }
+//  }
+//
+//  void _nodeList(List<LinkedNode> nodeList) {
+//    if (nodeList == null) return;
+//
+//    for (var i = 0; i < nodeList.length; ++i) {
+//      var node = nodeList[i];
+//      _node(node);
+//    }
+//  }
+//
+//  void _onClause(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    _typeNameList(node.onClause_superclassConstraints);
+//  }
+//
+//  void _partDirective(LinkedNodeBuilder node) {}
+//
+//  void _partOfDirective(LinkedNodeBuilder node) {}
+//
+//  void _setSimpleElement(LinkedNodeBuilder identifier, Reference reference) {
+//    var referenceIndex = linkingBundleContext.indexOfReference(reference);
+//    identifier.simpleIdentifier_element = referenceIndex;
+//  }
+//
+//  void _simpleFormalParameter(LinkedNodeBuilder node) {
+//    var typeNode = node.simpleFormalParameter_type;
+//    if (typeNode != null) {
+//      _node(typeNode);
+//      typesToBuild.declarations.add(node);
+//    } else {
+//      // TODO(scheglov) might be inferred
+//      node.simpleFormalParameter_type2 = _dynamicType;
+//    }
+//
+//    if (node.normalFormalParameter_covariantKeyword != 0) {
+//      node.normalFormalParameter_isCovariant = true;
+//    } else {
+//      // TODO(scheglov) might be inferred
+//    }
+//  }
+//
+//  void _topLevelVariableDeclaration(LinkedNodeBuilder node) {
+//    _node(node.topLevelVariableDeclaration_variableList);
+//  }
+//
+//  void _typeArgumentList(LinkedNodeBuilder node) {
+//    for (var typeArgument in node.typeArgumentList_arguments) {
+//      _typeName(typeArgument);
+//    }
+//  }
+//
+//  void _typeName(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    var identifier = node.typeName_name;
+//    Reference reference;
+//
+//    if (identifier.kind == LinkedNodeKind.simpleIdentifier) {
+//      var name = unit.context.getSimpleName(identifier);
+//
+//      if (name == 'void') {
+//        node.typeName_type = LinkedNodeTypeBuilder(
+//          kind: LinkedNodeTypeKind.void_,
+//        );
+//        return;
+//      }
+//
+//      reference = scope.lookup(name);
+//    } else {
+//      var prefixNode = identifier.prefixedIdentifier_prefix;
+//      var prefixName = unit.context.getSimpleName(prefixNode);
+//      var prefixReference = scope.lookup(prefixName);
+//      _setSimpleElement(prefixNode, prefixReference);
+//
+//      identifier = identifier.prefixedIdentifier_identifier;
+//      var name = unit.context.getSimpleName(identifier);
+//
+//      if (prefixReference != null && prefixReference.isPrefix) {
+//        var prefixScope = prefixReference.prefixScope;
+//        reference = prefixScope.lookup(name);
+//      } else {
+//        identifier.simpleIdentifier_element = 0;
+//        node.typeName_type = _dynamicType;
+//        return;
+//      }
+//    }
+//
+//    if (reference == null) {
+//      identifier.simpleIdentifier_element = 0;
+//      node.typeName_type = _dynamicType;
+//      return;
+//    }
+//
+//    _setSimpleElement(identifier, reference);
+//
+//    var typeArgumentList = node.typeName_typeArguments;
+//    if (typeArgumentList != null) {
+//      _node(typeArgumentList);
+//    }
+//
+//    typesToBuild.typeAnnotations.add(node);
+//  }
+//
+//  void _typeNameList(List<LinkedNode> nodeList) {
+//    for (var i = 0; i < nodeList.length; ++i) {
+//      var node = nodeList[i];
+//      _typeName(node);
+//    }
+//  }
+//
+//  void _typeParameter(LinkedNodeBuilder node) {
+//    _node(node.typeParameter_bound);
+//    // TODO(scheglov) set Object bound if no explicit?
+//  }
+//
+//  void _typeParameterList(LinkedNodeBuilder node) {
+//    for (var typeParameter in node.typeParameterList_typeParameters) {
+//      _node(typeParameter);
+//    }
+//  }
+//
+//  void _variableDeclarationList(LinkedNodeBuilder node) {
+//    var typeNode = node.variableDeclarationList_type;
+//    if (typeNode != null) {
+//      _node(typeNode);
+//      typesToBuild.declarations.add(node);
+//    }
+//  }
+//
+//  void _withClause(LinkedNodeBuilder node) {
+//    if (node == null) return;
+//
+//    _typeNameList(node.withClause_mixinTypes);
+//  }
+//
+//  /// Enter the type parameters scope, visit them, and run [f].
+//  void _withTypeParameters(LinkedNode typeParameterList, void f()) {
+//    if (typeParameterList == null) {
+//      f();
+//      return;
+//    }
+//
+//    scope = Scope(this.scope, {});
+//
+//    var containerRef = this.reference.getChild('@typeParameter');
+//    var typeParameters = typeParameterList.typeParameterList_typeParameters;
+//    for (var typeParameter in typeParameters) {
+//      var name = unit.context.getSimpleName(typeParameter.typeParameter_name);
+//      var reference = containerRef.getChild(name);
+//      reference.node = typeParameter;
+//      scope.declare(name, reference);
+//    }
+//
+//    _node(typeParameterList);
+//    f();
+//
+//    if (typeParameterList != null) {
+//      scope = scope.parent;
+//    }
+//  }
+//}
 
 /// Recursive visitor of [LinkedNode]s that resolves explicit type annotations
 /// in outlines.  This includes resolving element references in identifiers
@@ -18,512 +529,355 @@
 /// the corresponding type set (so, if there is an explicit type annotation,
 /// the type is set, otherwise we keep it empty, so we will attempt to infer
 /// it later).
-class ReferenceResolver {
-  final LinkingBundleContext linkingBundleContext;
-  final TypesToBuild typesToBuild;
-  final UnitBuilder unit;
-
-  /// TODO(scheglov) Update scope with local scopes (formal / type parameters).
-  Scope scope;
+class ReferenceResolver extends ThrowingAstVisitor<void> {
+  final NodesToBuildType nodesToBuildType;
+  final LinkedElementFactory elementFactory;
+  final LibraryElement _libraryElement;
 
   Reference reference;
+  Scope scope;
 
   ReferenceResolver(
-    this.linkingBundleContext,
-    this.typesToBuild,
-    this.unit,
-    this.scope,
+    this.nodesToBuildType,
+    this.elementFactory,
+    this._libraryElement,
     this.reference,
+    this.scope,
   );
 
-  LinkedNodeTypeBuilder get _dynamicType {
-    return LinkedNodeTypeBuilder(
-      kind: LinkedNodeTypeKind.dynamic_,
+  @override
+  void visitBlockFunctionBody(BlockFunctionBody node) {}
+
+  @override
+  void visitClassDeclaration(ClassDeclaration node) {
+    var outerScope = scope;
+    var outerReference = reference;
+
+    var name = node.name.name;
+    reference = reference.getChild('@class').getChild(name);
+
+    var element = ClassElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
     );
+    node.name.staticElement = element;
+    scope = new TypeParameterScope(scope, element);
+    scope = new ClassScope(scope, element);
+    LinkingNodeContext.set(node, LinkingNodeContext(scope));
+
+    node.typeParameters?.accept(this);
+    node.extendsClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.withClause?.accept(this);
+    node.members.accept(this);
+
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void resolve() {
-    _node(unit.node);
-  }
+  @override
+  void visitClassTypeAlias(ClassTypeAlias node) {
+    var outerScope = scope;
+    var outerReference = reference;
 
-  void _classDeclaration(LinkedNodeBuilder node) {
-    var name = unit.context.getUnitMemberName(node);
+    var name = node.name.name;
     reference = reference.getChild('@class').getChild(name);
 
-    var typeParameters = node.classOrMixinDeclaration_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      _extendsClause(node.classDeclaration_extendsClause);
-      _withClause(node.classDeclaration_withClause);
-      _implementsClause(node.classOrMixinDeclaration_implementsClause);
+    var element = ClassElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = new TypeParameterScope(scope, element);
+    scope = new ClassScope(scope, element);
+    LinkingNodeContext.set(node, LinkingNodeContext(scope));
 
-      for (var member in node.classOrMixinDeclaration_members) {
-        if (member.kind != LinkedNodeKind.constructorDeclaration) {
-          _node(member);
-        }
-      }
-      for (var member in node.classOrMixinDeclaration_members) {
-        if (member.kind == LinkedNodeKind.constructorDeclaration) {
-          _node(member);
-        }
-      }
-    });
+    node.typeParameters?.accept(this);
+    node.superclass?.accept(this);
+    node.withClause?.accept(this);
+    node.implementsClause?.accept(this);
 
-    reference = reference.parent.parent;
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _classTypeAlias(LinkedNodeBuilder node) {
-    var name = unit.context.getUnitMemberName(node);
-    reference = reference.getChild('@class').getChild(name);
-
-    var typeParameters = node.classTypeAlias_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      _typeName(node.classTypeAlias_superclass);
-      _withClause(node.classTypeAlias_withClause);
-      _implementsClause(node.classTypeAlias_implementsClause);
-    });
-
-    reference = reference.parent.parent;
+  @override
+  void visitCompilationUnit(CompilationUnit node) {
+    LinkingNodeContext.set(node, LinkingNodeContext(scope));
+    node.declarations.accept(this);
   }
 
-  void _compilationUnit(LinkedNodeBuilder node) {
-    _nodeList(node.compilationUnit_directives);
-    _nodeList(node.compilationUnit_declarations);
+  @override
+  void visitConstructorDeclaration(ConstructorDeclaration node) {
+    node.parameters?.accept(this);
   }
 
-  void _constructorDeclaration(LinkedNodeBuilder node) {
-    _node(node.constructorDeclaration_parameters);
+  @override
+  void visitDefaultFormalParameter(DefaultFormalParameter node) {
+    node.parameter.accept(this);
   }
 
-  void _enumConstantDeclaration(LinkedNodeBuilder node) {}
+  @override
+  void visitEnumDeclaration(EnumDeclaration node) {}
 
-  void _enumDeclaration(LinkedNodeBuilder node) {
-    _nodeList(node.enumDeclaration_constants);
+  @override
+  void visitExpressionFunctionBody(ExpressionFunctionBody node) {}
+
+  @override
+  void visitExtendsClause(ExtendsClause node) {
+    node.superclass.accept(this);
   }
 
-  void _exportDirective(LinkedNodeBuilder node) {}
-
-  void _extendsClause(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    _typeName(node.extendsClause_superclass);
+  @override
+  void visitFieldDeclaration(FieldDeclaration node) {
+    node.fields.accept(this);
   }
 
-  void _fieldDeclaration(LinkedNodeBuilder node) {
-    _node(node.fieldDeclaration_fields);
+  @override
+  void visitFieldFormalParameter(FieldFormalParameter node) {
+    node.type?.accept(this);
+    node.parameters?.accept(this);
+    nodesToBuildType.addDeclaration(node);
   }
 
-  void _fieldFormalParameter(LinkedNodeBuilder node) {
-    var typeNode = node.fieldFormalParameter_type;
-    if (typeNode != null) {
-      _node(typeNode);
-    }
-
-    var formalParameters = node.fieldFormalParameter_formalParameters;
-    if (formalParameters != null) {
-      _formalParameters(formalParameters);
-    }
-
-    if (typeNode != null || formalParameters != null) {
-      typesToBuild.declarations.add(node);
-    }
+  @override
+  void visitFormalParameterList(FormalParameterList node) {
+    node.parameters.accept(this);
   }
 
-  void _formalParameters(LinkedNodeBuilder node) {
-    for (var parameter in node.formalParameterList_parameters) {
-      _node(parameter);
-    }
-  }
+  @override
+  void visitFunctionDeclaration(FunctionDeclaration node) {
+    var outerScope = scope;
+    var outerReference = reference;
 
-  void _functionDeclaration(LinkedNodeBuilder node) {
-    var name = unit.context.getUnitMemberName(node);
+    var name = node.name.name;
     reference = reference.getChild('@function').getChild(name);
 
-    var function = node.functionDeclaration_functionExpression;
-    var typeParameters = function.functionExpression_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      var returnType = node.functionDeclaration_returnType;
-      if (returnType != null) {
-        _node(returnType);
-        typesToBuild.declarations.add(node);
-      } else {
-        node.functionDeclaration_returnType2 = _dynamicType;
-      }
+    var element = FunctionElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = new FunctionScope(scope, element);
+    LinkingNodeContext.set(node, LinkingNodeContext(scope));
 
-      _node(function.functionExpression_formalParameters);
-    });
+    node.returnType?.accept(this);
+    node.functionExpression.accept(this);
+    nodesToBuildType.addDeclaration(node);
 
-    reference = reference.parent.parent;
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _functionExpression(LinkedNodeBuilder node) {
-    var typeParameters = node.functionExpression_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      _node(node.functionExpression_formalParameters);
-    });
+  @override
+  void visitFunctionExpression(FunctionExpression node) {
+    node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
   }
 
-  void _functionTypeAlias(LinkedNodeBuilder node) {
-    var name = unit.context.getUnitMemberName(node);
+  @override
+  void visitFunctionTypeAlias(FunctionTypeAlias node) {
+    var outerScope = scope;
+    var outerReference = reference;
+
+    var name = node.name.name;
     reference = reference.getChild('@typeAlias').getChild(name);
 
-    var typeParameters = node.functionTypeAlias_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      var returnType = node.functionTypeAlias_returnType;
-      if (returnType != null) {
-        _node(returnType);
-        typesToBuild.declarations.add(node);
-      } else {
-        node.functionTypeAlias_returnType2 = _dynamicType;
-      }
+    var element = GenericTypeAliasElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = FunctionTypeScope(outerScope, element);
 
-      _node(node.functionTypeAlias_formalParameters);
-    });
+    node.returnType?.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
+    nodesToBuildType.addDeclaration(node);
 
-    reference = reference.parent.parent;
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _functionTypedFormalParameter(LinkedNodeBuilder node) {
-    var typeParameters = node.functionTypedFormalParameter_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      var typeNode = node.functionTypedFormalParameter_returnType;
-      if (typeNode != null) {
-        _node(typeNode);
-      }
+  @override
+  void visitFunctionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    node.returnType?.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
 
-      _formalParameters(node.functionTypedFormalParameter_formalParameters);
-      typesToBuild.declarations.add(node);
-    });
+    nodesToBuildType.addDeclaration(node);
   }
 
-  void _genericFunctionType(LinkedNodeBuilder node) {
-    reference = reference.getChild('@function');
+  @override
+  void visitGenericFunctionType(GenericFunctionType node) {
+    var outerScope = scope;
+    var outerReference = reference;
 
-    var name = '${reference.numOfChildren}';
+    var name = '${outerReference.numOfChildren}';
     reference = reference.getChild(name);
 
-    var typeParameters = node.genericFunctionType_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      var returnType = node.genericFunctionType_returnType;
-      if (returnType != null) {
-        _node(returnType);
-        typesToBuild.declarations.add(node);
-      }
+    var element = GenericFunctionTypeElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    scope = TypeParameterScope(outerScope, element);
 
-      _formalParameters(node.genericFunctionType_formalParameters);
+    node.returnType?.accept(this);
+    node.typeParameters?.accept(this);
+    node.parameters.accept(this);
+    nodesToBuildType.addTypeAnnotation(node);
+    nodesToBuildType.addDeclaration(node);
 
-      typesToBuild.typeAnnotations.add(node);
-    });
-
-    reference = reference.parent.parent;
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _genericTypeAlias(LinkedNodeBuilder node) {
-    var name = unit.context.getSimpleName(
-      node.namedCompilationUnitMember_name,
-    );
+  @override
+  void visitGenericTypeAlias(GenericTypeAlias node) {
+    var outerScope = scope;
+    var outerReference = reference;
+
+    var name = node.name.name;
     reference = reference.getChild('@typeAlias').getChild(name);
 
-    var typeParameters = node.genericTypeAlias_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      _node(node.genericTypeAlias_functionType);
-    });
+    var element = GenericTypeAliasElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = TypeParameterScope(outerScope, element);
 
-    reference = reference.parent.parent;
+    node.typeParameters?.accept(this);
+    node.functionType.accept(this);
+
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _implementsClause(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    _typeNameList(node.implementsClause_interfaces);
+  @override
+  void visitImplementsClause(ImplementsClause node) {
+    node.interfaces.accept(this);
   }
 
-  void _importDirective(LinkedNodeBuilder node) {}
+  @override
+  void visitMethodDeclaration(MethodDeclaration node) {
+    var outerScope = scope;
+    var outerReference = reference;
 
-  void _libraryDirective(LinkedNodeBuilder node) {}
-
-  void _methodDeclaration(LinkedNodeBuilder node) {
-    var name = unit.context.getMethodName(node);
+    var name = node.name.name;
     reference = reference.getChild('@method').getChild(name);
 
-    var typeParameters = node.methodDeclaration_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      var returnType = node.methodDeclaration_returnType;
-      if (returnType != null) {
-        _node(returnType);
-        typesToBuild.declarations.add(node);
-      }
+    var element = MethodElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = new FunctionScope(scope, element);
+    LinkingNodeContext.set(node, LinkingNodeContext(scope));
 
-      _node(node.methodDeclaration_formalParameters);
-    });
+    node.returnType?.accept(this);
+    node.parameters?.accept(this);
+    node.typeParameters?.accept(this);
+    nodesToBuildType.addDeclaration(node);
 
-    reference = reference.parent.parent;
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _mixinDeclaration(LinkedNodeBuilder node) {
-    var name = unit.context.getUnitMemberName(node);
+  @override
+  void visitMixinDeclaration(MixinDeclaration node) {
+    var outerScope = scope;
+    var outerReference = reference;
+
+    var name = node.name.name;
     reference = reference.getChild('@class').getChild(name);
 
-    var typeParameters = node.classOrMixinDeclaration_typeParameters;
-    _withTypeParameters(typeParameters, () {
-      _onClause(node.mixinDeclaration_onClause);
-      _implementsClause(node.classOrMixinDeclaration_implementsClause);
-      _nodeList(node.classOrMixinDeclaration_members);
-    });
+    var element = ClassElementImpl.forLinkedNode(
+      outerReference.element,
+      reference,
+      node,
+    );
+    node.name.staticElement = element;
+    scope = new TypeParameterScope(scope, element);
+    scope = new ClassScope(scope, element);
 
-    reference = reference.parent.parent;
+    node.typeParameters?.accept(this);
+    node.onClause?.accept(this);
+    node.implementsClause?.accept(this);
+    node.members.accept(this);
+
+    scope = outerScope;
+    reference = outerReference;
   }
 
-  void _node(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    if (node.kind == LinkedNodeKind.classDeclaration) {
-      _classDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.classTypeAlias) {
-      _classTypeAlias(node);
-    } else if (node.kind == LinkedNodeKind.compilationUnit) {
-      _compilationUnit(node);
-    } else if (node.kind == LinkedNodeKind.constructorDeclaration) {
-      _constructorDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.defaultFormalParameter) {
-      _node(node.defaultFormalParameter_parameter);
-    } else if (node.kind == LinkedNodeKind.enumDeclaration) {
-      _enumDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.enumConstantDeclaration) {
-      _enumConstantDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.exportDirective) {
-      _exportDirective(node);
-    } else if (node.kind == LinkedNodeKind.fieldDeclaration) {
-      _fieldDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.fieldFormalParameter) {
-      _fieldFormalParameter(node);
-    } else if (node.kind == LinkedNodeKind.formalParameterList) {
-      _formalParameters(node);
-    } else if (node.kind == LinkedNodeKind.functionDeclaration) {
-      _functionDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.functionExpression) {
-      _functionExpression(node);
-    } else if (node.kind == LinkedNodeKind.functionTypeAlias) {
-      _functionTypeAlias(node);
-    } else if (node.kind == LinkedNodeKind.functionTypedFormalParameter) {
-      _functionTypedFormalParameter(node);
-    } else if (node.kind == LinkedNodeKind.genericFunctionType) {
-      _genericFunctionType(node);
-    } else if (node.kind == LinkedNodeKind.genericTypeAlias) {
-      _genericTypeAlias(node);
-    } else if (node.kind == LinkedNodeKind.importDirective) {
-      _importDirective(node);
-    } else if (node.kind == LinkedNodeKind.libraryDirective) {
-      _libraryDirective(node);
-    } else if (node.kind == LinkedNodeKind.methodDeclaration) {
-      _methodDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.mixinDeclaration) {
-      _mixinDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.partDirective) {
-      _partDirective(node);
-    } else if (node.kind == LinkedNodeKind.partOfDirective) {
-      _partOfDirective(node);
-    } else if (node.kind == LinkedNodeKind.simpleFormalParameter) {
-      _simpleFormalParameter(node);
-    } else if (node.kind == LinkedNodeKind.topLevelVariableDeclaration) {
-      _topLevelVariableDeclaration(node);
-    } else if (node.kind == LinkedNodeKind.typeArgumentList) {
-      _typeArgumentList(node);
-    } else if (node.kind == LinkedNodeKind.typeName) {
-      _typeName(node);
-    } else if (node.kind == LinkedNodeKind.typeParameter) {
-      _typeParameter(node);
-    } else if (node.kind == LinkedNodeKind.typeParameterList) {
-      _typeParameterList(node);
-    } else if (node.kind == LinkedNodeKind.variableDeclarationList) {
-      _variableDeclarationList(node);
-    } else {
-      // TODO(scheglov) implement
-      throw UnimplementedError('${node.kind}');
-    }
+  @override
+  void visitOnClause(OnClause node) {
+    node.superclassConstraints.accept(this);
   }
 
-  void _nodeList(List<LinkedNode> nodeList) {
-    if (nodeList == null) return;
-
-    for (var i = 0; i < nodeList.length; ++i) {
-      var node = nodeList[i];
-      _node(node);
-    }
+  @override
+  void visitSimpleFormalParameter(SimpleFormalParameter node) {
+    node.type?.accept(this);
+    nodesToBuildType.addDeclaration(node);
   }
 
-  void _onClause(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    _typeNameList(node.onClause_superclassConstraints);
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    node.variables.accept(this);
   }
 
-  void _partDirective(LinkedNodeBuilder node) {}
-
-  void _partOfDirective(LinkedNodeBuilder node) {}
-
-  void _setSimpleElement(LinkedNodeBuilder identifier, Reference reference) {
-    var referenceIndex = linkingBundleContext.indexOfReference(reference);
-    identifier.simpleIdentifier_element = referenceIndex;
+  @override
+  void visitTypeArgumentList(TypeArgumentList node) {
+    node.arguments.accept(this);
   }
 
-  void _simpleFormalParameter(LinkedNodeBuilder node) {
-    var typeNode = node.simpleFormalParameter_type;
-    if (typeNode != null) {
-      _node(typeNode);
-      typesToBuild.declarations.add(node);
-    } else {
-      // TODO(scheglov) might be inferred
-      node.simpleFormalParameter_type2 = _dynamicType;
-    }
-
-    if (node.normalFormalParameter_covariantKeyword != 0) {
-      node.normalFormalParameter_isCovariant = true;
-    } else {
-      // TODO(scheglov) might be inferred
-    }
-  }
-
-  void _topLevelVariableDeclaration(LinkedNodeBuilder node) {
-    _node(node.topLevelVariableDeclaration_variableList);
-  }
-
-  void _typeArgumentList(LinkedNodeBuilder node) {
-    for (var typeArgument in node.typeArgumentList_arguments) {
-      _typeName(typeArgument);
-    }
-  }
-
-  void _typeName(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    var identifier = node.typeName_name;
-    Reference reference;
-
-    if (identifier.kind == LinkedNodeKind.simpleIdentifier) {
-      var name = unit.context.getSimpleName(identifier);
-
-      if (name == 'void') {
-        node.typeName_type = LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.void_,
-        );
-        return;
-      }
-
-      reference = scope.lookup(name);
-    } else {
-      var prefixNode = identifier.prefixedIdentifier_prefix;
-      var prefixName = unit.context.getSimpleName(prefixNode);
-      var prefixReference = scope.lookup(prefixName);
-      _setSimpleElement(prefixNode, prefixReference);
-
-      identifier = identifier.prefixedIdentifier_identifier;
-      var name = unit.context.getSimpleName(identifier);
-
-      if (prefixReference != null && prefixReference.isPrefix) {
-        var prefixScope = prefixReference.prefixScope;
-        reference = prefixScope.lookup(name);
-      } else {
-        identifier.simpleIdentifier_element = 0;
-        node.typeName_type = _dynamicType;
-        return;
-      }
-    }
-
-    if (reference == null) {
-      identifier.simpleIdentifier_element = 0;
-      node.typeName_type = _dynamicType;
+  @override
+  void visitTypeName(TypeName node) {
+    var typeName = node.name;
+    if (typeName is SimpleIdentifier && typeName.name == 'void') {
+      node.type = VoidTypeImpl.instance;
       return;
     }
 
-    _setSimpleElement(identifier, reference);
-
-    var typeArgumentList = node.typeName_typeArguments;
-    if (typeArgumentList != null) {
-      _node(typeArgumentList);
+    var element = scope.lookup(typeName, _libraryElement);
+    if (typeName is SimpleIdentifier) {
+      typeName.staticElement = element;
+    } else if (typeName is PrefixedIdentifier) {
+      typeName.identifier.staticElement = element;
+      SimpleIdentifier prefix = typeName.prefix;
+      prefix.staticElement = scope.lookup(prefix, _libraryElement);
     }
 
-    typesToBuild.typeAnnotations.add(node);
+    node.typeArguments?.accept(this);
+
+    nodesToBuildType.addTypeAnnotation(node);
   }
 
-  void _typeNameList(List<LinkedNode> nodeList) {
-    for (var i = 0; i < nodeList.length; ++i) {
-      var node = nodeList[i];
-      _typeName(node);
-    }
+  @override
+  void visitTypeParameter(TypeParameter node) {
+    node.bound?.accept(this);
   }
 
-  void _typeParameter(LinkedNodeBuilder node) {
-    _node(node.typeParameter_bound);
-    // TODO(scheglov) set Object bound if no explicit?
+  @override
+  void visitTypeParameterList(TypeParameterList node) {
+    node.typeParameters.accept(this);
   }
 
-  void _typeParameterList(LinkedNodeBuilder node) {
-    for (var typeParameter in node.typeParameterList_typeParameters) {
-      _node(typeParameter);
-    }
+  @override
+  void visitVariableDeclarationList(VariableDeclarationList node) {
+    node.type?.accept(this);
+    nodesToBuildType.addDeclaration(node);
   }
 
-  void _variableDeclarationList(LinkedNodeBuilder node) {
-    var typeNode = node.variableDeclarationList_type;
-    if (typeNode != null) {
-      _node(typeNode);
-      typesToBuild.declarations.add(node);
-    }
+  @override
+  void visitWithClause(WithClause node) {
+    node.mixinTypes.accept(this);
   }
-
-  void _withClause(LinkedNodeBuilder node) {
-    if (node == null) return;
-
-    _typeNameList(node.withClause_mixinTypes);
-  }
-
-  /// Enter the type parameters scope, visit them, and run [f].
-  void _withTypeParameters(LinkedNode typeParameterList, void f()) {
-    if (typeParameterList == null) {
-      f();
-      return;
-    }
-
-    scope = Scope(this.scope, {});
-
-    var containerRef = this.reference.getChild('@typeParameter');
-    var typeParameters = typeParameterList.typeParameterList_typeParameters;
-    for (var typeParameter in typeParameters) {
-      var name = unit.context.getSimpleName(typeParameter.typeParameter_name);
-      var reference = containerRef.getChild(name);
-      reference.node = typeParameter;
-      scope.declare(name, reference);
-    }
-
-    _node(typeParameterList);
-    f();
-
-    if (typeParameterList != null) {
-      scope = scope.parent;
-    }
-  }
-}
-
-/// Type annotations and declarations to build types for.
-///
-/// Not all types can be build during reference resolution phase.
-/// For example `A` means `A<num>` if `class A<T extends num>`, but we don't
-/// know this until we resolved `A` declaration, and we might have not yet.
-/// So, we remember [LinkedNodeKind.typeName] nodes to resolve them later.
-class TypesToBuild {
-  /// Nodes with [LinkedNodeKind.typeName] (with type arguments, and without
-  /// them), and [LinkedNodeKind.genericFunctionType].  These nodes will be
-  /// resolved by [ReferenceResolver], so that they have their references set,
-  /// but their types will not be set yet.
-  ///
-  /// Types arguments, return types, and types of formal parameters must be
-  /// before the types that use them in this list.
-  final List<LinkedNodeBuilder> typeAnnotations = [];
-
-  /// Nodes with type annotations, where we want not just resolve these types
-  /// annotations, but also set additional types.  For example instance method
-  /// return types might be specified, and then the method has the specified
-  /// return type.  But if the return type is not specified explicitly, the
-  /// method still might have a return type, inferred from a superclass.
-  final List<LinkedNodeBuilder> declarations = [];
 }
diff --git a/pkg/analyzer/lib/src/summary2/simply_bounded.dart b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
new file mode 100644
index 0000000..13a6dc4
--- /dev/null
+++ b/pkg/analyzer/lib/src/summary2/simply_bounded.dart
@@ -0,0 +1,313 @@
+// 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/summary/format.dart';
+import 'package:analyzer/src/summary/idl.dart' show LinkedNode;
+import 'package:analyzer/src/summary/idl.dart';
+import 'package:analyzer/src/summary/link.dart' as graph
+    show DependencyWalker, Node;
+import 'package:analyzer/src/summary2/builder/source_library_builder.dart';
+import 'package:analyzer/src/summary2/linked_bundle_context.dart';
+import 'package:analyzer/src/summary2/linked_unit_context.dart';
+import 'package:analyzer/src/summary2/reference.dart';
+import 'package:analyzer/src/summary2/type_builder.dart';
+
+/// Compute simple-boundedness for all classes and generic types aliases in
+/// the source [libraryBuilders].  There might be dependencies between them,
+/// so they all should be processed simultaneously.
+void computeSimplyBounded(
+  LinkedBundleContext bundleContext,
+  Iterable<SourceLibraryBuilder> libraryBuilders,
+) {
+  var walker = SimplyBoundedDependencyWalker(bundleContext);
+  var nodes = <SimplyBoundedNode>[];
+  for (var libraryBuilder in libraryBuilders) {
+    var unitsRef = libraryBuilder.reference.getChild('@unit');
+    for (var unitRef in unitsRef.children) {
+      for (var classRef in unitRef.getChild('@class').children) {
+        var node = walker.getNode(classRef);
+        nodes.add(node);
+      }
+      for (var ref in unitRef.getChild('@typeAlias').children) {
+        var node = walker.getNode(ref);
+        nodes.add(node);
+      }
+    }
+  }
+
+  for (var node in nodes) {
+    if (!node.isEvaluated) {
+      walker.walk(node);
+    }
+    LinkedNodeBuilder builder = node._reference.node;
+    builder.simplyBoundable_isSimplyBounded = node.isSimplyBounded;
+  }
+}
+
+/// The graph walker for evaluating whether types are simply bounded.
+class SimplyBoundedDependencyWalker
+    extends graph.DependencyWalker<SimplyBoundedNode> {
+  final LinkedBundleContext bundleContext;
+  final Map<Reference, SimplyBoundedNode> nodeMap = {};
+
+  SimplyBoundedDependencyWalker(this.bundleContext);
+
+  @override
+  void evaluate(SimplyBoundedNode v) {
+    v._evaluate();
+  }
+
+  @override
+  void evaluateScc(List<SimplyBoundedNode> scc) {
+    for (var node in scc) {
+      node._markCircular();
+    }
+  }
+
+  SimplyBoundedNode getNode(Reference reference) {
+    var node = nodeMap[reference];
+    if (node == null) {
+      if (reference.isClass) {
+        var parameters = LinkedUnitContext.getTypeParameters(reference.node);
+        node = SimplyBoundedNode(
+          this,
+          reference,
+          parameters ?? const <LinkedNode>[],
+          const <LinkedNode>[],
+        );
+      } else if (reference.isTypeAlias) {
+        var parameters = LinkedUnitContext.getTypeParameters(reference.node);
+        node = SimplyBoundedNode(
+          this,
+          reference,
+          parameters ?? const <LinkedNode>[],
+          _collectTypedefRhsTypes(reference.node),
+        );
+      } else {
+        throw UnimplementedError('$reference');
+      }
+      nodeMap[reference] = node;
+    }
+    return node;
+  }
+
+  /// Collects all the type references appearing on the "right hand side" of a
+  /// typedef.
+  ///
+  /// The "right hand side" of a typedef is the type appearing after the "="
+  /// in a new style typedef declaration, or for an old style typedef
+  /// declaration, the type that *would* appear after the "=" if it were
+  /// converted to a new style typedef declaration.  This means that type
+  /// parameter declarations and their bounds are not included.
+  static List<LinkedNode> _collectTypedefRhsTypes(LinkedNode node) {
+    var kind = node.kind;
+    if (kind == LinkedNodeKind.functionTypeAlias) {
+      var types = <LinkedNode>[];
+      _TypeCollector.addType(
+        types,
+        node.functionTypeAlias_returnType,
+      );
+      _TypeCollector.visitParameters(
+        types,
+        node.functionTypeAlias_formalParameters,
+      );
+      return types;
+    } else if (kind == LinkedNodeKind.genericTypeAlias) {
+      var types = <LinkedNode>[];
+      var function = node.genericTypeAlias_functionType;
+      _TypeCollector.addType(
+        types,
+        function.genericFunctionType_returnType,
+      );
+      _TypeCollector.visitParameters(
+        types,
+        function.genericFunctionType_formalParameters,
+      );
+      return types;
+    } else {
+      throw StateError('$kind');
+    }
+  }
+}
+
+/// The graph node used to construct the dependency graph for evaluating
+/// whether types are simply bounded.
+class SimplyBoundedNode extends graph.Node<SimplyBoundedNode> {
+  final SimplyBoundedDependencyWalker _walker;
+  final Reference _reference;
+
+  /// The type parameters of the type whose simple-boundedness we check.
+  final List<LinkedNode> _typeParameters;
+
+  /// If the type whose simple-boundedness we check is a typedef, the types
+  /// appearing in its "right hand side".
+  final List<LinkedNode> _rhsTypes;
+
+  @override
+  bool isEvaluated = false;
+
+  /// After execution of [_evaluate], indicates whether the type is
+  /// simply bounded.
+  ///
+  /// Prior to execution of [computeDependencies], `true`.
+  ///
+  /// Between execution of [computeDependencies] and [_evaluate], `true`
+  /// indicates that the type is simply bounded only if all of its dependencies
+  /// are simply bounded; `false` indicates that the type is not simply bounded.
+  bool isSimplyBounded = true;
+
+  SimplyBoundedNode(
+    this._walker,
+    this._reference,
+    this._typeParameters,
+    this._rhsTypes,
+  );
+
+  @override
+  List<SimplyBoundedNode> computeDependencies() {
+    var dependencies = <SimplyBoundedNode>[];
+    for (var typeParameter in _typeParameters) {
+      var bound = typeParameter.typeParameter_bound;
+      if (bound != null) {
+        if (!_visitType(dependencies, bound, false)) {
+          // Note: we might consider setting isEvaluated=true here to prevent an
+          // unnecessary call to SimplyBoundedDependencyWalker.evaluate.
+          // However, we'd have to be careful to make sure this doesn't violate
+          // an invariant of the DependencyWalker algorithm, since normally it
+          // only expects isEvaluated to change during a call to .evaluate or
+          // .evaluateScc.
+          isSimplyBounded = false;
+          return const [];
+        }
+      }
+    }
+    for (var type in _rhsTypes) {
+      if (!_visitType(dependencies, type, true)) {
+        // Note: we might consider setting isEvaluated=true here to prevent an
+        // unnecessary call to SimplyBoundedDependencyWalker.evaluate.
+        // However, we'd have to be careful to make sure this doesn't violate
+        // an invariant of the DependencyWalker algorithm, since normally it
+        // only expects isEvaluated to change during a call to .evaluate or
+        // .evaluateScc.
+        isSimplyBounded = false;
+        return const [];
+      }
+    }
+    return dependencies;
+  }
+
+  void _evaluate() {
+    for (var dependency in graph.Node.getDependencies(this)) {
+      if (!dependency.isSimplyBounded) {
+        isSimplyBounded = false;
+        break;
+      }
+    }
+    isEvaluated = true;
+  }
+
+  void _markCircular() {
+    isSimplyBounded = false;
+    isEvaluated = true;
+  }
+
+  /// Visits the type specified by [type], storing the [SimplyBoundedNode] for
+  /// any types it references in [dependencies].
+  ///
+  /// Return `false` if a type that is known to be not simply bound is found.
+  ///
+  /// Return `false` if a reference to a type parameter is found, and
+  /// [allowTypeParameters] is `false`.
+  ///
+  /// If `false` is returned, further visiting is short-circuited.
+  ///
+  /// Otherwise `true` is returned.
+  bool _visitType(List<SimplyBoundedNode> dependencies, LinkedNode type,
+      bool allowTypeParameters) {
+    if (type == null) return true;
+
+    if (type.kind == LinkedNodeKind.typeName) {
+      var element = TypeBuilder.typeNameElementIndex(type.typeName_name);
+      var reference = _walker.bundleContext.referenceOfIndex(element);
+
+      if (reference.isTypeParameter) {
+        return allowTypeParameters;
+      }
+
+      var arguments = type.typeName_typeArguments;
+      if (arguments == null) {
+        var graphNode = _walker.nodeMap[reference];
+
+        // If not a node being linked, then the flag is already set.
+        if (graphNode == null) {
+          if (reference.isClass || reference.isTypeAlias) {
+            var elementFactory = _walker.bundleContext.elementFactory;
+            var node = elementFactory.nodeOfReference(reference);
+            return node.simplyBoundable_isSimplyBounded;
+          }
+          return true;
+        }
+
+        dependencies.add(graphNode);
+      } else {
+        for (var argument in arguments.typeArgumentList_arguments) {
+          if (!_visitType(dependencies, argument, allowTypeParameters)) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+
+    if (type.kind == LinkedNodeKind.genericFunctionType) {
+      var types = <LinkedNode>[];
+      _TypeCollector.addType(types, type.genericFunctionType_returnType);
+      _TypeCollector.visitParameters(
+        types,
+        type.genericFunctionType_formalParameters,
+      );
+      for (var type in types) {
+        if (!_visitType(dependencies, type, allowTypeParameters)) {
+          return false;
+        }
+      }
+      return true;
+    }
+
+    throw UnimplementedError('${type.kind}');
+  }
+}
+
+/// Helper for collecting type annotations in formal parameters.
+class _TypeCollector {
+  static void addType(List<LinkedNode> types, LinkedNode type) {
+    if (type != null) {
+      types.add(type);
+    }
+  }
+
+  static void visitParameter(List<LinkedNode> types, LinkedNode parameter) {
+    var kind = parameter.kind;
+    if (kind == LinkedNodeKind.defaultFormalParameter) {
+      visitParameter(types, parameter.defaultFormalParameter_parameter);
+    } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
+      addType(types, parameter.functionTypedFormalParameter_returnType);
+      visitParameters(
+        types,
+        parameter.functionTypedFormalParameter_formalParameters,
+      );
+    } else if (kind == LinkedNodeKind.simpleFormalParameter) {
+      addType(types, parameter.simpleFormalParameter_type);
+    } else {
+      throw UnimplementedError('$kind');
+    }
+  }
+
+  static void visitParameters(List<LinkedNode> types, LinkedNode parameters) {
+    assert(parameters.kind == LinkedNodeKind.formalParameterList);
+    for (var parameter in parameters.formalParameterList_parameters) {
+      visitParameter(types, parameter);
+    }
+  }
+}
diff --git a/pkg/analyzer/lib/src/summary2/top_level_inference.dart b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
index 4779752..c5b38e4 100644
--- a/pkg/analyzer/lib/src/summary2/top_level_inference.dart
+++ b/pkg/analyzer/lib/src/summary2/top_level_inference.dart
@@ -2,15 +2,14 @@
 // for details. All 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/ast/standard_ast_factory.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/src/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/type.dart';
 import 'package:analyzer/src/dart/resolver/scope.dart';
-import 'package:analyzer/src/summary/format.dart';
-import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_resolver.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
 import 'package:analyzer/src/summary2/link.dart';
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
@@ -44,6 +43,12 @@
     _nameScope = _libraryScope;
   }
 
+  DynamicTypeImpl get _dynamicType {
+    return DynamicTypeImpl.instance;
+  }
+
+  VoidTypeImpl get _voidType => VoidTypeImpl.instance;
+
   void infer() {
     _setOmittedReturnTypes();
     _inferFieldsTemporary();
@@ -56,12 +61,12 @@
       _linkedContext = unit.linkedContext;
 
       for (var class_ in unit.types) {
-        var fields = <String, LinkedNodeType>{};
+        var fields = <String, DartType>{};
         for (FieldElementImpl field in class_.fields) {
           if (field.isSynthetic) continue;
 
           var name = field.name;
-          var type = field.linkedNode.variableDeclaration_type2;
+          var type = field.type;
           if (type == null) {
             throw StateError('Field $name should have a type.');
           }
@@ -71,20 +76,18 @@
         for (ConstructorElementImpl constructor in class_.constructors) {
           for (ParameterElementImpl parameter in constructor.parameters) {
             if (parameter is FieldFormalParameterElement) {
-              LinkedNodeBuilder parameterNode = parameter.linkedNode;
-              if (parameterNode.kind == LinkedNodeKind.defaultFormalParameter) {
-                parameterNode = parameterNode.defaultFormalParameter_parameter;
+              FormalParameter node = parameter.linkedNode;
+              if (node is DefaultFormalParameter) {
+                var defaultParameter = node as DefaultFormalParameter;
+                node = defaultParameter.parameter;
               }
 
-              if (parameterNode.fieldFormalParameter_type2 == null) {
+              if (node is FieldFormalParameter &&
+                  node.type == null &&
+                  node.parameters == null) {
                 var name = parameter.name;
-                var type = fields[name];
-                if (type == null) {
-                  type = LinkedNodeTypeBuilder(
-                    kind: LinkedNodeTypeKind.dynamic_,
-                  );
-                }
-                parameterNode.fieldFormalParameter_type2 = type;
+                var type = fields[name] ?? _dynamicType;
+                LazyAst.setType(node, type);
               }
             }
           }
@@ -108,10 +111,10 @@
 
       for (TopLevelVariableElementImpl variable in unit.topLevelVariables) {
         if (variable.isSynthetic) continue;
-        LinkedNodeBuilder variableNode = variable.linkedNode;
-        if (variableNode.variableDeclaration_type2 == null ||
-            _linkedContext.isConst(variableNode)) {
-          _inferVariableTypeFromInitializerTemporary(variableNode);
+        VariableDeclaration node = variable.linkedNode;
+        VariableDeclarationList parent = node.parent;
+        if (parent.type == null || _linkedContext.isConst(node)) {
+          _inferVariableTypeFromInitializerTemporary(node);
         }
       }
     }
@@ -125,43 +128,34 @@
 
     for (FieldElementImpl field in class_.fields) {
       if (field.isSynthetic) continue;
-      var fieldNode = field.linkedNode;
-
+      VariableDeclaration node = field.linkedNode;
+      VariableDeclarationList parent = node.parent;
       // TODO(scheglov) Use inheritance
       // TODO(scheglov) infer in the correct order
-      if (fieldNode.variableDeclaration_type2 == null) {
-        _inferVariableTypeFromInitializerTemporary(fieldNode);
+      if (parent.type == null || parent.isConst) {
+        _inferVariableTypeFromInitializerTemporary(node);
       }
     }
 
     _nameScope = prevScope;
   }
 
-  void _inferVariableTypeFromInitializerTemporary(LinkedNodeBuilder node) {
-    var unresolvedNode = node.variableDeclaration_initializer;
+  void _inferVariableTypeFromInitializerTemporary(VariableDeclaration node) {
+    var initializer = node.initializer;
 
-    if (unresolvedNode == null) {
-      node.variableDeclaration_type2 = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
+    if (initializer == null) {
+      LazyAst.setType(node, _dynamicType);
       return;
     }
 
-    var expression = _linkedContext.readInitializer(unitElement, node);
-    astFactory.expressionFunctionBody(null, null, expression, null);
-
     var astResolver = AstResolver(linker, _libraryElement, _nameScope);
-    var resolvedNode = astResolver.resolve(_linkedContext, expression);
-    node.variableDeclaration_initializer = resolvedNode;
+    astResolver.resolve(initializer);
 
-    if (node.variableDeclaration_type2 == null) {
-      var initializerType = expression.staticType;
+    VariableDeclarationList parent = node.parent;
+    if (parent.type == null) {
+      var initializerType = initializer.staticType;
       initializerType = _dynamicIfNull(initializerType);
-
-      var linkingBundleContext = linker.linkingBundleContext;
-      node.variableDeclaration_type2 = linkingBundleContext.writeType(
-        initializerType,
-      );
+      LazyAst.setType(node, initializerType);
     }
   }
 
@@ -179,23 +173,16 @@
       }
 
       for (FunctionElementImpl function in unit.functions) {
-        LinkedNodeBuilder functionNode = function.linkedNode;
-        if (functionNode.functionDeclaration_returnType == null) {
-          functionNode.functionDeclaration_returnType2 = LinkedNodeTypeBuilder(
-            kind: LinkedNodeTypeKind.dynamic_,
-          );
+        FunctionDeclaration node = function.linkedNode;
+        if (node.returnType == null) {
+          LazyAst.setReturnType(node, _dynamicType);
         }
       }
 
       for (PropertyAccessorElementImpl accessor in unit.accessors) {
         if (accessor.isSynthetic) continue;
         if (accessor.isSetter) {
-          LinkedNodeBuilder node = accessor.linkedNode;
-          if (node.functionDeclaration_returnType == null) {
-            node.functionDeclaration_returnType2 = LinkedNodeTypeBuilder(
-              kind: LinkedNodeTypeKind.void_,
-            );
-          }
+          LazyAst.setReturnType(accessor.linkedNode, _voidType);
         }
       }
     }
@@ -203,28 +190,22 @@
 
   void _setOmittedReturnTypesClass(ClassElement class_) {
     for (MethodElementImpl method in class_.methods) {
-      LinkedNodeBuilder methodNode = method.linkedNode;
-      if (methodNode.methodDeclaration_returnType == null) {
-        methodNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.dynamic_,
-        );
+      MethodDeclaration node = method.linkedNode;
+      if (node.returnType == null) {
+        LazyAst.setReturnType(node, _dynamicType);
       }
     }
 
     for (PropertyAccessorElementImpl accessor in class_.accessors) {
       if (accessor.isSynthetic) continue;
 
-      LinkedNodeBuilder accessorNode = accessor.linkedNode;
-      if (accessorNode.methodDeclaration_returnType != null) continue;
+      MethodDeclaration node = accessor.linkedNode;
+      if (node.returnType != null) continue;
 
       if (accessor.isSetter) {
-        accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.void_,
-        );
+        LazyAst.setReturnType(node, _voidType);
       } else {
-        accessorNode.methodDeclaration_returnType2 = LinkedNodeTypeBuilder(
-          kind: LinkedNodeTypeKind.dynamic_,
-        );
+        LazyAst.setReturnType(node, _dynamicType);
       }
     }
   }
diff --git a/pkg/analyzer/lib/src/summary2/type_builder.dart b/pkg/analyzer/lib/src/summary2/type_builder.dart
index 9423d65..3588181 100644
--- a/pkg/analyzer/lib/src/summary2/type_builder.dart
+++ b/pkg/analyzer/lib/src/summary2/type_builder.dart
@@ -2,220 +2,326 @@
 // for details. All 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/summary/format.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/src/dart/ast/ast.dart';
+import 'package:analyzer/src/dart/element/element.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:analyzer/src/generated/utilities_dart.dart';
 import 'package:analyzer/src/summary/idl.dart';
-import 'package:analyzer/src/summary2/linked_bundle_context.dart';
-import 'package:analyzer/src/summary2/linked_unit_context.dart';
-import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/reference_resolver.dart';
+import 'package:analyzer/src/summary2/lazy_ast.dart';
+import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 
-/// Build types in a [TypesToBuild].
+/// Type annotations and declarations to build types for.
+///
+/// Not all types can be build during reference resolution phase.
+/// For example `A` means `A<num>` if `class A<T extends num>`, but we don't
+/// know this until we resolved `A` declaration, and we might have not yet.
+///
+/// So, we remember type annotations that should be resolved later, and
+/// declarations to set types from explicit type annotations.
+class NodesToBuildType {
+  final List<NodeToBuildType> items = [];
+
+  void addDeclaration(AstNode declaration) {
+    items.add(NodeToBuildType._(null, declaration));
+  }
+
+  void addTypeAnnotation(TypeAnnotation typeAnnotation) {
+    items.add(NodeToBuildType._(typeAnnotation, null));
+  }
+}
+
+/// A type annotation to build type for, or a declaration to set its explicitly
+/// declared type.
+class NodeToBuildType {
+  final TypeAnnotation typeAnnotation;
+  final AstNode declaration;
+
+  NodeToBuildType._(this.typeAnnotation, this.declaration);
+}
+
+/// Build types in a [NodesToBuildType].
 class TypeBuilder {
-  final LinkedBundleContext bundleContext;
+  final LinkingBundleContext bundleContext;
 
   TypeBuilder(this.bundleContext);
 
-  LinkedNodeTypeBuilder get _dynamicType {
-    return LinkedNodeTypeBuilder(
-      kind: LinkedNodeTypeKind.dynamic_,
-    );
+  DynamicTypeImpl get _dynamicType {
+    return DynamicTypeImpl.instance;
   }
 
-  void build(TypesToBuild typesToBuild) {
-    for (var node in typesToBuild.typeAnnotations) {
-      var kind = node.kind;
-      if (kind == LinkedNodeKind.genericFunctionType) {
-        _buildGenericFunctionType(node);
-      } else if (kind == LinkedNodeKind.typeName) {
-        _buildTypeName(node);
-      } else {
-        throw StateError('$kind');
+  void build(NodesToBuildType nodesToBuildType) {
+    for (var item in nodesToBuildType.items) {
+      if (item.typeAnnotation != null) {
+        var node = item.typeAnnotation;
+        if (node is GenericFunctionType) {
+          _buildGenericFunctionType(node);
+        } else if (node is TypeName) {
+          _buildTypeName(node);
+        } else {
+          throw StateError('${node.runtimeType}');
+        }
+      } else if (item.declaration != null) {
+        _setTypesForDeclaration(item.declaration);
       }
     }
-    for (var node in typesToBuild.declarations) {
-      _setTypesForDeclaration(node);
-    }
   }
 
-  LinkedNodeTypeBuilder _buildFunctionType(
-    LinkedNode returnTypeNode,
-    LinkedNode parameterList,
+  DartType _buildFunctionType(
+    TypeAnnotation returnTypeNode,
+    FormalParameterList parameterList,
   ) {
-    var returnType = _getType(returnTypeNode);
+    var returnType = returnTypeNode?.type ?? _dynamicType;
 
-    var formalParameters = <LinkedNodeTypeFormalParameterBuilder>[];
-    for (var parameter in parameterList.formalParameterList_parameters) {
-      formalParameters.add(LinkedNodeTypeFormalParameterBuilder(
-        kind: parameter.formalParameter_kind,
-        type: _getFormalParameterType(parameter),
-      ));
-    }
+    // TODO(scheglov) type parameters
+    var typeParameters = const <TypeParameterElement>[];
 
-    return LinkedNodeTypeBuilder(
-      kind: LinkedNodeTypeKind.function,
-      functionFormalParameters: formalParameters,
-      functionReturnType: returnType,
+    var formalParameters = parameterList.parameters.map((p) {
+      // TODO(scheglov) other types and kinds
+      return ParameterElementImpl.synthetic(
+        (p as SimpleFormalParameter).identifier.name,
+        LazyAst.getType(p),
+        ParameterKind.REQUIRED,
+      );
+    }).toList();
+
+    return FunctionTypeImpl.synthetic(
+      returnType,
+      typeParameters,
+      formalParameters,
     );
   }
 
-  void _buildGenericFunctionType(LinkedNodeBuilder node) {
+  void _buildGenericFunctionType(GenericFunctionTypeImpl node) {
     // TODO(scheglov) Type parameters?
-    node.genericFunctionType_type = _buildFunctionType(
-      node.genericFunctionType_returnType,
-      node.genericFunctionType_formalParameters,
-    );
+    node.type = _buildFunctionType(node.returnType, node.parameters);
   }
 
-  void _buildTypeName(LinkedNodeBuilder node) {
-    var referenceIndex = _typeNameElementIndex(node.typeName_name);
-    var reference = bundleContext.referenceOfIndex(referenceIndex);
+  void _buildTypeName(TypeName node) {
+    var element = node.name.staticElement;
 
-    List<LinkedNodeTypeBuilder> typeArguments;
-    var typeArgumentList = node.typeName_typeArguments;
+    List<DartType> typeArguments;
+    var typeArgumentList = node.typeArguments;
     if (typeArgumentList != null) {
-      typeArguments = typeArgumentList.typeArgumentList_arguments
-          .map((node) => _getType(node))
-          .toList();
+      typeArguments = typeArgumentList.arguments.map((a) => a.type).toList();
     }
 
-    if (reference.isClass) {
+    if (element is ClassElement) {
+      if (element.isEnum) {
+        node.type = InterfaceTypeImpl.explicit(element, const []);
+      } else {
+        // TODO(scheglov) Use instantiate to bounds.
+        var typeParametersLength = element.typeParameters.length;
+        if (typeArguments == null ||
+            typeArguments.length != typeParametersLength) {
+          typeArguments = List<DartType>.filled(
+            typeParametersLength,
+            DynamicTypeImpl.instance,
+          );
+        }
+        node.type = InterfaceTypeImpl.explicit(element, typeArguments);
+      }
+    } else if (element is GenericTypeAliasElement) {
       // TODO(scheglov) Use instantiate to bounds.
-      var typeParametersLength = _typeParametersLength(reference);
+      var typeParametersLength = element.typeParameters.length;
       if (typeArguments == null ||
           typeArguments.length != typeParametersLength) {
-        typeArguments = List<LinkedNodeTypeBuilder>.filled(
+        typeArguments = List<DartType>.filled(
           typeParametersLength,
-          _dynamicType,
+          DynamicTypeImpl.instance,
         );
       }
-      node.typeName_type = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.interface,
-        interfaceClass: referenceIndex,
-        interfaceTypeArguments: typeArguments,
+
+      var substitution = Substitution.fromPairs(
+        element.typeParameters,
+        typeArguments,
       );
-    } else if (reference.isDynamic) {
-      node.typeName_type = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.dynamic_,
-      );
-    } else if (reference.isGenericTypeAlias) {
-      // TODO(scheglov) Use instantiate to bounds.
-      var typeParametersLength = _typeParametersLength(reference);
-      if (typeArguments == null ||
-          typeArguments.length != typeParametersLength) {
-        typeArguments = List<LinkedNodeTypeBuilder>.filled(
-          typeParametersLength,
-          _dynamicType,
-        );
-      }
-      node.typeName_type = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.genericTypeAlias,
-        genericTypeAliasReference: referenceIndex,
-        genericTypeAliasTypeArguments: typeArguments,
-      );
-    } else if (reference.isEnum) {
-      node.typeName_type = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.interface,
-        interfaceClass: referenceIndex,
-      );
-    } else if (reference.isTypeParameter) {
-      node.typeName_type = LinkedNodeTypeBuilder(
-        kind: LinkedNodeTypeKind.typeParameter,
-        typeParameterParameter: referenceIndex,
-      );
+
+      // TODO(scheglov) Not sure if I like this.
+      var type = substitution.substituteType(element.function.type);
+      node.type = type;
+    } else if (element is TypeParameterElement) {
+      node.type = TypeParameterTypeImpl(element);
     } else {
-      node.typeName_type = _dynamicType;
+//      throw UnimplementedError('${element.runtimeType}');
+      // TODO(scheglov) implement
+      node.type = DynamicTypeImpl.instance;
     }
+
+//    var referenceIndex = typeNameElementIndex(node.typeName_name);
+//    var reference = bundleContext.referenceOfIndex(referenceIndex);
+//
+//    List<LinkedNodeTypeBuilder> typeArguments;
+//    var typeArgumentList = node.typeName_typeArguments;
+//    if (typeArgumentList != null) {
+//      typeArguments = typeArgumentList.typeArgumentList_arguments
+//          .map((node) => _getType(node))
+//          .toList();
+//    }
+//
+//    if (reference.isClass) {
+//      // TODO(scheglov) Use instantiate to bounds.
+//      var typeParametersLength = _typeParametersLength(reference);
+//      if (typeArguments == null ||
+//          typeArguments.length != typeParametersLength) {
+//        typeArguments = List<LinkedNodeTypeBuilder>.filled(
+//          typeParametersLength,
+//          _dynamicType,
+//        );
+//      }
+//      node.typeName_type = LinkedNodeTypeBuilder(
+//        kind: LinkedNodeTypeKind.interface,
+//        interfaceClass: referenceIndex,
+//        interfaceTypeArguments: typeArguments,
+//      );
+//    } else if (reference.isDynamic) {
+//      node.typeName_type = LinkedNodeTypeBuilder(
+//        kind: LinkedNodeTypeKind.dynamic_,
+//      );
+//    } else if (reference.isTypeAlias) {
+//      // TODO(scheglov) Use instantiate to bounds.
+//      var typeParametersLength = _typeParametersLength(reference);
+//      if (typeArguments == null ||
+//          typeArguments.length != typeParametersLength) {
+//        typeArguments = List<LinkedNodeTypeBuilder>.filled(
+//          typeParametersLength,
+//          _dynamicType,
+//        );
+//      }
+//      node.typeName_type = LinkedNodeTypeBuilder(
+//        kind: LinkedNodeTypeKind.genericTypeAlias,
+//        genericTypeAliasReference: referenceIndex,
+//        genericTypeAliasTypeArguments: typeArguments,
+//      );
+//    } else if (reference.isEnum) {
+//      node.typeName_type = LinkedNodeTypeBuilder(
+//        kind: LinkedNodeTypeKind.interface,
+//        interfaceClass: referenceIndex,
+//      );
+//    } else if (reference.isTypeParameter) {
+//      node.typeName_type = LinkedNodeTypeBuilder(
+//        kind: LinkedNodeTypeKind.typeParameter,
+//        typeParameterParameter: referenceIndex,
+//      );
+//    } else {
+//      node.typeName_type = _dynamicType;
+//    }
   }
 
-  void _fieldFormalParameter(LinkedNodeBuilder node) {
-    var parameterList = node.fieldFormalParameter_formalParameters;
+  void _fieldFormalParameter(FieldFormalParameter node) {
+    var parameterList = node.parameters;
     if (parameterList != null) {
-      node.fieldFormalParameter_type2 = _buildFunctionType(
-        node.fieldFormalParameter_type,
-        parameterList,
-      );
+      var type = _buildFunctionType(node.type, parameterList);
+      LazyAst.setType(node, type);
     } else {
-      var type = _getType(node.fieldFormalParameter_type);
-      node.fieldFormalParameter_type2 = type;
+      LazyAst.setType(node, node.type?.type ?? _dynamicType);
     }
   }
 
-  void _functionTypedFormalParameter(LinkedNodeBuilder node) {
-    node.functionTypedFormalParameter_type2 = _buildFunctionType(
-      node.functionTypedFormalParameter_returnType,
-      node.functionTypedFormalParameter_formalParameters,
-    );
+  void _functionTypedFormalParameter(FunctionTypedFormalParameter node) {
+    var type = _buildFunctionType(node.returnType, node.parameters);
+    LazyAst.setType(node, type);
   }
 
-  LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.defaultFormalParameter) {
-      return _getFormalParameterType(node.defaultFormalParameter_parameter);
-    }
-    if (kind == LinkedNodeKind.functionTypedFormalParameter) {
-      return node.functionTypedFormalParameter_type2;
-    }
-    if (kind == LinkedNodeKind.simpleFormalParameter) {
-      return _getType(node.simpleFormalParameter_type);
-    }
-    throw UnimplementedError('$kind');
-  }
+//  LinkedNodeTypeBuilder _getFormalParameterType(LinkedNode node) {
+//    var kind = node.kind;
+//    if (kind == LinkedNodeKind.defaultFormalParameter) {
+//      return _getFormalParameterType(node.defaultFormalParameter_parameter);
+//    }
+//    if (kind == LinkedNodeKind.functionTypedFormalParameter) {
+//      return node.functionTypedFormalParameter_type2;
+//    }
+//    if (kind == LinkedNodeKind.simpleFormalParameter) {
+//      return _getType(node.simpleFormalParameter_type);
+//    }
+//    throw UnimplementedError('$kind');
+//  }
 
-  LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
-    if (node == null) return _dynamicType;
+//  LinkedNodeTypeBuilder _getType(LinkedNodeBuilder node) {
+//    if (node == null) return _dynamicType;
+//
+//    var kind = node.kind;
+//    if (kind == LinkedNodeKind.genericFunctionType) {
+//      return node.genericFunctionType_type;
+//    } else if (kind == LinkedNodeKind.typeName) {
+//      return node.typeName_type;
+//    } else {
+//      throw UnimplementedError('$kind');
+//    }
+//  }
 
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.genericFunctionType) {
-      return node.genericFunctionType_type;
-    } else if (kind == LinkedNodeKind.typeName) {
-      return node.typeName_type;
-    } else {
-      throw UnimplementedError('$kind');
-    }
-  }
-
-  void _setTypesForDeclaration(LinkedNodeBuilder node) {
-    var kind = node.kind;
-    if (kind == LinkedNodeKind.fieldFormalParameter) {
+  void _setTypesForDeclaration(AstNode node) {
+    if (node is FieldFormalParameter) {
       _fieldFormalParameter(node);
-    } else if (kind == LinkedNodeKind.functionDeclaration) {
-      node.functionDeclaration_returnType2 = _getType(
-        node.functionDeclaration_returnType,
-      );
-    } else if (kind == LinkedNodeKind.functionTypeAlias) {
-      node.functionTypeAlias_returnType2 = _getType(
-        node.functionTypeAlias_returnType,
-      );
-    } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
+    } else if (node is FunctionDeclaration) {
+      LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
+    } else if (node is FunctionTypeAlias) {
+      LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
+    } else if (node is FunctionTypedFormalParameter) {
       _functionTypedFormalParameter(node);
-    } else if (kind == LinkedNodeKind.genericFunctionType) {
-      node.genericFunctionType_returnType2 = _getType(
-        node.genericFunctionType_returnType,
-      );
-    } else if (kind == LinkedNodeKind.methodDeclaration) {
-      node.methodDeclaration_returnType2 = _getType(
-        node.methodDeclaration_returnType,
-      );
-    } else if (kind == LinkedNodeKind.simpleFormalParameter) {
-      node.simpleFormalParameter_type2 = _getType(
-        node.simpleFormalParameter_type,
-      );
-    } else if (kind == LinkedNodeKind.variableDeclarationList) {
-      var typeNode = node.variableDeclarationList_type;
-      for (var variable in node.variableDeclarationList_variables) {
-        variable.variableDeclaration_type2 = _getType(typeNode);
+    } else if (node is GenericFunctionType) {
+      LazyAst.setReturnType(node, node.returnType?.type ?? _dynamicType);
+    } else if (node is MethodDeclaration) {
+      if (node.returnType != null) {
+        LazyAst.setReturnType(node, node.returnType.type);
+      }
+    } else if (node is SimpleFormalParameter) {
+      // TODO(scheglov) use top-level inference
+      LazyAst.setType(node, node.type?.type ?? _dynamicType);
+    } else if (node is VariableDeclarationList) {
+      var type = node.type?.type;
+      if (type != null) {
+        for (var variable in node.variables) {
+          LazyAst.setType(variable, type);
+        }
       }
     } else {
-      throw UnimplementedError('$kind');
+      throw UnimplementedError('${node.runtimeType}');
     }
+//    var kind = node.kind;
+//    if (kind == LinkedNodeKind.fieldFormalParameter) {
+//      _fieldFormalParameter(node);
+//    } else if (kind == LinkedNodeKind.functionDeclaration) {
+//      node.functionDeclaration_returnType2 = _getType(
+//        node.functionDeclaration_returnType,
+//      );
+//    } else if (kind == LinkedNodeKind.functionTypeAlias) {
+//      node.functionTypeAlias_returnType2 = _getType(
+//        node.functionTypeAlias_returnType,
+//      );
+//    } else if (kind == LinkedNodeKind.functionTypedFormalParameter) {
+//      _functionTypedFormalParameter(node);
+//    } else if (kind == LinkedNodeKind.genericFunctionType) {
+//      node.genericFunctionType_returnType2 = _getType(
+//        node.genericFunctionType_returnType,
+//      );
+//    } else if (kind == LinkedNodeKind.methodDeclaration) {
+//      node.methodDeclaration_returnType2 = _getType(
+//        node.methodDeclaration_returnType,
+//      );
+//    } else if (kind == LinkedNodeKind.simpleFormalParameter) {
+//      node.simpleFormalParameter_type2 = _getType(
+//        node.simpleFormalParameter_type,
+//      );
+//    } else if (kind == LinkedNodeKind.variableDeclarationList) {
+//      var typeNode = node.variableDeclarationList_type;
+//      for (var variable in node.variableDeclarationList_variables) {
+//        variable.variableDeclaration_type2 = _getType(typeNode);
+//      }
+//    } else {
+//      throw UnimplementedError('$kind');
+//    }
   }
 
-  int _typeParametersLength(Reference reference) {
-    var node = bundleContext.elementFactory.nodeOfReference(reference);
-    return LinkedUnitContext.getTypeParameters(node)?.length ?? 0;
-  }
+//  int _typeParametersLength(Reference reference) {
+//    var node = bundleContext.elementFactory.nodeOfReference(reference);
+//    return LinkedUnitContext.getTypeParameters(node)?.length ?? 0;
+//  }
 
-  static int _typeNameElementIndex(LinkedNode name) {
+  static int typeNameElementIndex(LinkedNode name) {
     if (name.kind == LinkedNodeKind.simpleIdentifier) {
       return name.simpleIdentifier_element;
     } else {
diff --git a/pkg/analyzer/lib/src/task/options.dart b/pkg/analyzer/lib/src/task/options.dart
index 351daef..9bc342b 100644
--- a/pkg/analyzer/lib/src/task/options.dart
+++ b/pkg/analyzer/lib/src/task/options.dart
@@ -121,9 +121,13 @@
   static const String exclude = 'exclude';
   static const String include = 'include';
   static const String language = 'language';
+  static const String optionalChecks = 'optional-checks';
   static const String plugins = 'plugins';
   static const String strong_mode = 'strong-mode';
 
+  // Optional checks options.
+  static const String chromeOsManifestChecks = 'chrome-os-manifest-checks';
+
   // Strong mode options (see AnalysisOptionsImpl for documentation).
   static const String declarationCasts = 'declaration-casts';
   static const String implicitCasts = 'implicit-casts';
@@ -152,6 +156,7 @@
     errors,
     exclude,
     language,
+    optionalChecks,
     plugins,
     strong_mode,
   ];
@@ -168,6 +173,11 @@
     strictInference,
     strictRawTypes
   ];
+
+  // Supported 'analyzer' optional checks options.
+  static const List<String> optionalCecksOptions = const [
+    chromeOsManifestChecks,
+  ];
 }
 
 /// Validates `analyzer` options.
@@ -178,7 +188,8 @@
           new StrongModeOptionValueValidator(),
           new ErrorFilterOptionValidator(),
           new EnabledExperimentsValidator(),
-          new LanguageOptionValidator()
+          new LanguageOptionValidator(),
+          new OptionalChecksValueValidator()
         ]);
 }
 
@@ -484,6 +495,43 @@
   }
 }
 
+/// Validates `analyzer` optional-checks value configuration options.
+class OptionalChecksValueValidator extends OptionsValidator {
+  ErrorBuilder builder = new ErrorBuilder(AnalyzerOptions.optionalCecksOptions);
+  ErrorBuilder trueOrFalseBuilder = new TrueOrFalseValueErrorBuilder();
+
+  @override
+  void validate(ErrorReporter reporter, YamlMap options) {
+    var analyzer = getValue(options, AnalyzerOptions.analyzer);
+    if (analyzer is YamlMap) {
+      var v = getValue(analyzer, AnalyzerOptions.optionalChecks);
+      if (v is YamlScalar) {
+        var value = toLowerCase(v.value);
+        if (value != AnalyzerOptions.chromeOsManifestChecks) {
+          builder.reportError(
+              reporter, AnalyzerOptions.chromeOsManifestChecks, v);
+        }
+      } else if (v is YamlMap) {
+        v.nodes.forEach((k, v) {
+          String key, value;
+          if (k is YamlScalar) {
+            key = k.value?.toString();
+            if (key != AnalyzerOptions.chromeOsManifestChecks) {
+              builder.reportError(
+                  reporter, AnalyzerOptions.chromeOsManifestChecks, k);
+            } else {
+              value = toLowerCase(v.value);
+              if (!AnalyzerOptions.trueOrFalse.contains(value)) {
+                trueOrFalseBuilder.reportError(reporter, key, v);
+              }
+            }
+          }
+        });
+      }
+    }
+  }
+}
+
 /// Validates `analyzer` top-level options.
 class TopLevelAnalyzerOptionsValidator extends TopLevelOptionValidator {
   TopLevelAnalyzerOptionsValidator()
@@ -572,6 +620,10 @@
         options.enabledExperiments = enabledExperiments;
       }
 
+      // Process optional checks options.
+      var optionalChecks = getValue(analyzer, AnalyzerOptions.optionalChecks);
+      _applyOptionalChecks(options, optionalChecks);
+
       // Process language options.
       var language = getValue(analyzer, AnalyzerOptions.language);
       _applyLanguageOptions(options, language);
@@ -675,6 +727,31 @@
     }
   }
 
+  void _applyOptionalChecksOption(
+      AnalysisOptionsImpl options, String feature, Object value) {
+    bool boolValue = toBool(value);
+    if (boolValue != null) {
+      if (feature == AnalyzerOptions.chromeOsManifestChecks) {
+        options.chromeOsManifestChecks = boolValue;
+      }
+    }
+  }
+
+  void _applyOptionalChecks(AnalysisOptionsImpl options, YamlNode config) {
+    if (config is YamlMap) {
+      config.nodes.forEach((k, v) {
+        if (k is YamlScalar && v is YamlScalar) {
+          _applyOptionalChecksOption(options, k.value?.toString(), v.value);
+        }
+      });
+    }
+    if (config is YamlScalar) {
+      if (config.value?.toString() == AnalyzerOptions.chromeOsManifestChecks) {
+        options.chromeOsManifestChecks = true;
+      }
+    }
+  }
+
   String _toString(YamlNode node) {
     if (node is YamlScalar) {
       var value = node.value;
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index d4c070c..917fc1c 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -340,6 +340,7 @@
   external factory String.fromCharCodes(Iterable<int> charCodes,
       [int start = 0, int end]);
   List<int> get codeUnits;
+  int indexOf(Pattern pattern, [int start]);
   bool get isEmpty => false;
   bool get isNotEmpty => false;
   int get length => 0;
diff --git a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
index 9ad69d8..9fe449e 100644
--- a/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
+++ b/pkg/analyzer/lib/src/test_utilities/package_mixin.dart
@@ -22,6 +22,7 @@
 const Immutable immutable = const Immutable();
 const _Literal literal = const _Literal();
 const _MustCallSuper mustCallSuper = const _MustCallSuper();
+const _OptionalTypeArgs optionalTypeArgs = const _OptionalTypeArgs();
 const _Protected protected = const _Protected();
 const Required required = const Required();
 const _Sealed sealed = const _Sealed();
@@ -43,6 +44,9 @@
 class _MustCallSuper {
   const _MustCallSuper();
 }
+class _OptionalTypeArgs {
+  const _OptionalTypeArgs();
+}
 class _Protected {
   const _Protected();
 }
diff --git a/pkg/analyzer/lib/src/workspace/gn.dart b/pkg/analyzer/lib/src/workspace/gn.dart
index 6490363..1f2a608 100644
--- a/pkg/analyzer/lib/src/workspace/gn.dart
+++ b/pkg/analyzer/lib/src/workspace/gn.dart
@@ -267,15 +267,14 @@
    * that file cannot be found, looks for standard output directory locations.
    */
   static Folder _getOutDirectory(String root, ResourceProvider provider) {
+    const String fuchsiaDirConfigFile = '.fx-build-dir';
+
     path.Context pathContext = provider.pathContext;
-    File config = provider.getFile(pathContext.join(root, '.config'));
-    if (config.exists) {
-      String content = config.readAsStringSync();
-      Match match =
-          new RegExp(r'^FUCHSIA_BUILD_DIR=["\x27](.+)["\x27]$', multiLine: true)
-              .firstMatch(content);
-      if (match != null) {
-        String buildDirPath = match.group(1);
+    File configFile =
+        provider.getFile(pathContext.join(root, fuchsiaDirConfigFile));
+    if (configFile.exists) {
+      String buildDirPath = configFile.readAsStringSync().trim();
+      if (buildDirPath.isNotEmpty) {
         if (pathContext.isRelative(buildDirPath)) {
           buildDirPath = pathContext.join(root, buildDirPath);
         }
diff --git a/pkg/analyzer/pubspec.yaml b/pkg/analyzer/pubspec.yaml
index b49c0f3..cf9777b 100644
--- a/pkg/analyzer/pubspec.yaml
+++ b/pkg/analyzer/pubspec.yaml
@@ -1,5 +1,5 @@
 name: analyzer
-version: 0.36.0
+version: 0.36.1-dev
 author: Dart Team <misc@dartlang.org>
 description: Static analyzer for Dart.
 homepage: https://github.com/dart-lang/sdk/tree/master/pkg/analyzer
@@ -13,6 +13,7 @@
   crypto: '>=1.1.1 <3.0.0'
   front_end: 0.1.15
   glob: ^1.0.3
+  html: '>=0.13.4+1 <0.15.0'
   kernel: 0.3.15
   meta: ^1.0.2
   package_config: '>=0.1.5 <2.0.0'
diff --git a/pkg/analyzer/test/error/error_test.dart b/pkg/analyzer/test/error/error_test.dart
index 379efcd..b68dbac 100644
--- a/pkg/analyzer/test/error/error_test.dart
+++ b/pkg/analyzer/test/error/error_test.dart
@@ -6,14 +6,17 @@
 import 'dart:io';
 
 import 'package:analyzer/dart/ast/ast.dart';
-import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:path/path.dart' as path;
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../generated/parser_test.dart';
 
+List<String> _analyzerRootComponents;
+
 main() {
+  _analyzerRootComponents =
+      path.split(path.fromUri(Platform.script.resolve("../../")));
   defineReflectiveSuite(() {
     defineReflectiveTests(ErrorCodeValuesTest);
   });
@@ -21,17 +24,6 @@
 
 @reflectiveTest
 class ErrorCodeValuesTest extends ParserTestCase {
-  List<String> _rootComponents;
-
-  List<String> get rootComponents {
-    if (_rootComponents == null) {
-      List<String> components = path.split(package_root.packageRoot);
-      components.add('analyzer');
-      _rootComponents = components;
-    }
-    return _rootComponents;
-  }
-
   bool bad() {
     return false;
   }
@@ -77,7 +69,7 @@
   }
 
   CompilationUnit parseFile(List<String> relativeComponents) {
-    List<String> pathComponents = rootComponents.toList()
+    List<String> pathComponents = _analyzerRootComponents.toList()
       ..addAll(relativeComponents);
     String filePath = path.normalize(path.joinAll(pathComponents));
     return parseCompilationUnit(new File(filePath).readAsStringSync());
diff --git a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
index 3601b5c..6318820 100644
--- a/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/checked_mode_compile_time_error_code_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/generated/engine.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../src/dart/resolution/driver_resolution.dart';
@@ -16,9 +15,6 @@
 
 @reflectiveTest
 class CheckedModeCompileTimeErrorCodeTest extends DriverResolutionTest {
-  @override
-  AnalysisOptions get defaultAnalysisOptions => new AnalysisOptionsImpl();
-
   test_assertion_throws() async {
     await assertErrorsInCode(r'''
 class A {
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index b767777..2daae3d 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/dart/analysis/declared_variables.dart';
 import 'package:analyzer/error/error.dart';
+import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/parser.dart' show ParserErrorCode;
 import 'package:analyzer/src/generated/source_io.dart';
@@ -622,14 +623,18 @@
   }
 
   test_constEvalTypeBoolNumString_equal() async {
-    await assertErrorsInCode(r'''
+    await assertErrorsInCode(
+        r'''
 class A {
   const A();
 }
 
 const num a = 0;
 const _ = a == const A();
-''', [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
+''',
+        IsEnabledByDefault.constant_update_2018
+            ? []
+            : [CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING]);
   }
 
   test_constEvalTypeBoolNumString_notEqual() async {
diff --git a/pkg/analyzer/test/generated/hint_code_test.dart b/pkg/analyzer/test/generated/hint_code_test.dart
index 18bb4a8..d13e5f5 100644
--- a/pkg/analyzer/test/generated/hint_code_test.dart
+++ b/pkg/analyzer/test/generated/hint_code_test.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/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/parser.dart';
@@ -19,58 +18,11 @@
   });
 }
 
-/// The contents of the 'meta' package. Code that uses this variable should be
-/// converted to use PackageMixin.addMetaPackage.
-final _metaLibraryStub = r'''
-library meta;
-
-const _AlwaysThrows alwaysThrows = const _AlwaysThrows();
-const _Factory factory = const _Factory();
-const Immutable immutable = const Immutable();
-const _Literal literal = const _Literal();
-const _MustCallSuper mustCallSuper = const _MustCallSuper();
-const _Protected protected = const _Protected();
-const Required required = const Required();
-const _Sealed sealed = const _Sealed();
-const _VisibleForTesting visibleForTesting = const _VisibleForTesting();
-
-class Immutable {
-  final String reason;
-  const Immutable([this.reason]);
-}
-class _AlwaysThrows {
-  const _AlwaysThrows();
-}
-class _Factory {
-  const _Factory();
-}
-class _Literal {
-  const _Literal();
-}
-class _MustCallSuper {
-  const _MustCallSuper();
-}
-class _Protected {
-  const _Protected();
-}
-class Required {
-  final String reason;
-  const Required([this.reason]);
-}
-class _Sealed {
-  const _Sealed();
-}
-class _VisibleForTesting {
-  const _VisibleForTesting();
-}
-''';
-
 @reflectiveTest
 class HintCodeTest extends ResolverTestCase {
   @override
   void reset() {
     super.resetWith(packages: [
-      ['meta', _metaLibraryStub],
       [
         'js',
         r'''
@@ -80,18 +32,6 @@
 }
 '''
       ],
-      [
-        'angular_meta',
-        r'''
-library angular.meta;
-
-const _VisibleForTemplate visibleForTemplate = const _VisibleForTemplate();
-
-class _VisibleForTemplate {
-  const _VisibleForTemplate();
-}
-'''
-      ],
     ]);
   }
 
@@ -174,1004 +114,6 @@
     verify([source]);
   }
 
-  test_factory__expr_return_null_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  State createState() => null;
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_abstract_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-abstract class Stateful {
-  @factory
-  State createState();
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_bad_return() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  State _s = new State();
-
-  @factory
-  State createState() => _s;
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_IMPL]);
-    verify([source]);
-  }
-
-  test_factory_block_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  State createState() {
-    return new State();
-  }
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_block_return_null_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  State createState() {
-    return null;
-  }
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_expr_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  State createState() => new State();
-}
-
-class State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_misplaced_annotation() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-@factory
-class X {
-  @factory
-  int x;
-}
-
-@factory
-main() { }
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [
-      HintCode.INVALID_FACTORY_ANNOTATION,
-      HintCode.INVALID_FACTORY_ANNOTATION,
-      HintCode.INVALID_FACTORY_ANNOTATION
-    ]);
-    verify([source]);
-  }
-
-  test_factory_no_return_type_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  createState() {
-    return new Stateful();
-  }
-}
-''');
-    // Null return types will get flagged elsewhere, no need to pile-on here.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_subclass_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-abstract class Stateful {
-  @factory
-  State createState();
-}
-
-class MyThing extends Stateful {
-  @override
-  State createState() {
-    print('my state');
-    return new MyState();
-  }
-}
-
-class State { }
-class MyState extends State { }
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_factory_void_return() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class Stateful {
-  @factory
-  void createState() {}
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.INVALID_FACTORY_METHOD_DECL]);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_closure() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-
-class A {
-  @protected
-  int a() => 42;
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  var leak = new A().a;
-  print(leak);
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_field() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int a;
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-abstract class B {
-  int b() => new A().a;
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_field_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int a;
-}
-abstract class B implements A {
-  int b() => a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_fromSuperclassConstraint() async {
-    Source sourceA = addNamedSource('/a.dart', r'''
-import 'package:meta/meta.dart';
-
-abstract class A {
-  @protected
-  void foo() {}
-}
-''');
-    Source sourceM = addNamedSource('/m.dart', r'''
-import 'a.dart';
-
-mixin M on A {
-  @override
-  void foo() {
-    super.foo();
-  }
-}
-''');
-
-    await computeAnalysisResult(sourceA);
-    await computeAnalysisResult(sourceM);
-    assertNoErrors(sourceA);
-    assertNoErrors(sourceM);
-    verify([sourceA, sourceM]);
-  }
-
-  test_invalidUseOfProtectedMember_function() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-main() {
-  new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_function_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int a() => 0;
-}
-
-abstract class B implements A {
-  int b() => a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_function_OK2() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-main() {
-  new A().a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_getter() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int get a => 42;
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B {
-  A a;
-  int b() => a.a;
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_getter_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int get a => 42;
-}
-abstract class B implements A {
-  int b() => a;
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_in_docs_OK() async {
-    addNamedSource('/a.dart', r'''
-import 'package:meta/meta.dart';
-
-class A {
-  @protected
-  int c = 0;
-
-  @protected
-  int get b => 0;
-
-  @protected
-  int a() => 0;
-}
-''');
-    Source source = addSource(r'''
-import 'a.dart';
-
-/// OK: [A.a], [A.b], [A.c].
-f() {}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_message() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_method_1() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_method_OK() async {
-    // https://github.com/dart-lang/linter/issues/257
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-typedef void VoidCallback();
-
-class State<E> {
-  @protected
-  void setState(VoidCallback fn) {}
-}
-
-class Button extends State<Object> {
-  void handleSomething() {
-    setState(() {});
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_1() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-class B extends A {
-  void b() => a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_2() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-class B extends Object with A {
-  void b() => a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_3() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected m1() {}
-}
-class B extends A {
-  static m2(A a) => a.m1();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_4() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void a(){ }
-}
-class B extends A {
-  void a() => a();
-}
-main() {
-  new B().a();
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_field() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int a = 42;
-}
-class B extends A {
-  int b() => a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_getter() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  int get a => 42;
-}
-class B extends A {
-  int b() => a;
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_setter() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void set a(int i) { }
-}
-class B extends A {
-  void b(int i) {
-    a = i;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_OK_setter_2() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  int _a;
-  @protected
-  void set a(int a) { _a = a; }
-  A(int a) {
-    this.a = a;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_setter() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void set a(int i) { }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B{
-  A a;
-  b(int i) {
-    a.a = i;
-  }
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
-    assertNoErrors(source);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfProtectedMember_setter_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  void set a(int i) { }
-}
-abstract class B implements A {
-  b(int i) {
-    a = i;
-  }
-}''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfProtectedMember_topLevelVariable() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-@protected
-int x = 0;
-main() {
-  print(x);
-}''');
-    // TODO(brianwilkerson) This should produce a hint because the annotation is
-    // being applied to the wrong kind of declaration.
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_constructor() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-class A {
-  int _x;
-
-  @visibleForTemplate
-  A.forTemplate(this._x);
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  new A.forTemplate(0);
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(
-        source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_export_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-
-@visibleForTemplate
-int fn0() => 1;
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-export 'lib1.dart' show fn0;
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_method() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-class A {
-  @visibleForTemplate
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(
-        source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_method_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-class A {
-  @visibleForTemplate
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib1.template.dart', r'''
-import 'lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_propertyAccess() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-class A {
-  @visibleForTemplate
-  int get a => 7;
-
-  @visibleForTemplate
-  set b(_) => 7;
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  new A().a;
-  new A().b = 6;
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [
-      HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
-      HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER
-    ]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTemplateMember_topLevelFunction() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-
-@visibleForTemplate
-int fn0() => 1;
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  fn0();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(
-        source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_constructor() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  int _x;
-
-  @visibleForTesting
-  A.forTesting(this._x);
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  new A.forTesting(0);
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_export_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-
-@visibleForTesting
-int fn0() => 1;
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-export 'lib1.dart' show fn0;
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_method() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @visibleForTesting
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_method_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @visibleForTesting
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/test/test1.dart', r'''
-import '../lib1.dart';
-
-class B {
-  void b() => new A().a();
-}
-''');
-    Source source3 = addNamedSource('/testing/lib1.dart', r'''
-import '../lib1.dart';
-
-class C {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    await computeAnalysisResult(source3);
-    assertNoErrors(source2);
-    assertNoErrors(source3);
-    verify([source, source2, source3]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_propertyAccess() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @visibleForTesting
-  int get a => 7;
-
-  @visibleForTesting
-  set b(_) => 7;
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  new A().a;
-  new A().b = 6;
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [
-      HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER,
-      HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER
-    ]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseOfVisibleForTestingMember_topLevelFunction() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-
-@visibleForTesting
-int fn0() => 1;
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  fn0();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertErrors(source2, [HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
-    verify([source, source2]);
-  }
-
-  test_invalidUseProtectedAndForTemplate_asProtected_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  @visibleForTemplate
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B extends A {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseProtectedAndForTemplate_asTemplate_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:angular_meta/angular_meta.dart';
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  @visibleForTemplate
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib1.template.dart', r'''
-import 'lib1.dart';
-
-void main() {
-  new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseProtectedAndForTesting_asProtected_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  @visibleForTesting
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/lib2.dart', r'''
-import 'lib1.dart';
-
-class B extends A {
-  void b() => new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
-  test_invalidUseProtectedAndForTesting_asTesting_OK() async {
-    Source source = addNamedSource('/lib1.dart', r'''
-import 'package:meta/meta.dart';
-class A {
-  @protected
-  @visibleForTesting
-  void a(){ }
-}
-''');
-    Source source2 = addNamedSource('/test/test1.dart', r'''
-import '../lib1.dart';
-
-void main() {
-  new A().a();
-}
-''');
-    await computeAnalysisResult(source);
-    await computeAnalysisResult(source2);
-    assertNoErrors(source2);
-    verify([source, source2]);
-  }
-
   test_isDouble() async {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.dart2jsHint = true;
@@ -1293,173 +235,6 @@
     verify([source]);
   }
 
-  test_required_constructor_param() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@Required('must specify an `a`') int a}) {}
-}
-
-main() {
-  new C();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
-    verify([source]);
-  }
-
-  test_required_constructor_param_no_reason() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@required int a}) {}
-}
-
-main() {
-  new C();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
-    verify([source]);
-  }
-
-  test_required_constructor_param_null_reason() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@Required(null) int a}) {}
-}
-
-main() {
-  new C();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
-    verify([source]);
-  }
-
-  test_required_constructor_param_OK() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@required int a}) {}
-}
-
-main() {
-  new C(a: 2);
-}
-''');
-    await computeAnalysisResult(source);
-    assertNoErrors(source);
-    verify([source]);
-  }
-
-  test_required_constructor_param_redirecting_cons_call() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@required int x});
-  C.named() : this();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
-    verify([source]);
-  }
-
-  test_required_constructor_param_super_call() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-class C {
-  C({@Required('must specify an `a`') int a}) {}
-}
-
-class D extends C {
-  D() : super();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
-    verify([source]);
-  }
-
-  test_required_function_param() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-void f({@Required('must specify an `a`') int a}) {}
-
-main() {
-  f();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
-    verify([source]);
-  }
-
-  test_required_method_param() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-class A {
-  void m({@Required('must specify an `a`') int a}) {}
-}
-f() {
-  new A().m();
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
-    verify([source]);
-  }
-
-  test_required_method_param_in_other_lib() async {
-    addNamedSource('/a_lib.dart', r'''
-library a_lib;
-import 'package:meta/meta.dart';
-class A {
-  void m({@Required('must specify an `a`') int a}) {}
-}
-''');
-
-    Source source = addSource(r'''
-import "a_lib.dart";
-f() {
-  new A().m();
-}
-''');
-
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
-    verify([source]);
-  }
-
-  test_required_typedef_function_param() async {
-    Source source = addSource(r'''
-import 'package:meta/meta.dart';
-
-String test(C c) => c.m()();
-
-typedef String F({@required String x});
-
-class C {
-  F m() => ({@required String x}) => null;
-}
-''');
-    await computeAnalysisResult(source);
-    assertErrors(source, [HintCode.MISSING_REQUIRED_PARAM]);
-    verify([source]);
-  }
-
   test_strongMode_downCastCompositeHint() async {
     AnalysisOptionsImpl options = new AnalysisOptionsImpl();
     options.strongModeHints = true;
diff --git a/pkg/analyzer/test/generated/non_hint_code_test.dart b/pkg/analyzer/test/generated/non_hint_code_test.dart
index 03d2693..24c5811 100644
--- a/pkg/analyzer/test/generated/non_hint_code_test.dart
+++ b/pkg/analyzer/test/generated/non_hint_code_test.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/error/error.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:analyzer/src/generated/source_io.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
diff --git a/pkg/analyzer/test/generated/parser_fasta_test.dart b/pkg/analyzer/test/generated/parser_fasta_test.dart
index 1beed7e..738676c 100644
--- a/pkg/analyzer/test/generated/parser_fasta_test.dart
+++ b/pkg/analyzer/test/generated/parser_fasta_test.dart
@@ -878,6 +878,11 @@
     //super.test_expectedStringLiteral();
   }
 
+  void test_factory_issue_36400() {
+    parseCompilationUnit('class T { T factory T() { return null; } }',
+        errors: [expectedError(ParserErrorCode.TYPE_BEFORE_FACTORY, 10, 1)]);
+  }
+
   void test_getterNativeWithBody() {
     createParser('String get m native "str" => 0;');
     parser.parseClassMember('C') as MethodDeclaration;
diff --git a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
index 1c63c45..36e49bc 100644
--- a/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/evaluation_test.dart
@@ -90,7 +90,11 @@
       'c',
       errorCodes: [CompileTimeErrorCode.INVALID_CONSTANT],
     );
-    expect(result, isNull);
+    if (analysisOptions.experimentStatus.constant_update_2018) {
+      expect(result.toIntValue(), 1);
+    } else {
+      expect(result, isNull);
+    }
   }
 
   test_visitConditionalExpression_eager_true_invalid_int() async {
diff --git a/pkg/analyzer/test/src/dart/element/test_all.dart b/pkg/analyzer/test/src/dart/element/test_all.dart
index 134b672..d51bf52 100644
--- a/pkg/analyzer/test/src/dart/element/test_all.dart
+++ b/pkg/analyzer/test/src/dart/element/test_all.dart
@@ -7,6 +7,7 @@
 import 'element_test.dart' as element;
 import 'function_type_test.dart' as function_type;
 import 'inheritance_manager2_test.dart' as inheritance_manager2;
+import 'type_algebra_test.dart' as type_algebra;
 
 /// Utility for manually running all tests.
 main() {
@@ -14,5 +15,6 @@
     element.main();
     function_type.main();
     inheritance_manager2.main();
+    type_algebra.main();
   }, name: 'element');
 }
diff --git a/pkg/analyzer/test/src/dart/element/type_algebra_test.dart b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
new file mode 100644
index 0000000..5aa1321
--- /dev/null
+++ b/pkg/analyzer/test/src/dart/element/type_algebra_test.dart
@@ -0,0 +1,271 @@
+// 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/dart/element/element.dart';
+import 'package:analyzer/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type.dart';
+import 'package:analyzer/src/dart/element/type_algebra.dart';
+import 'package:test/test.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(SubstituteEmptyTest);
+    defineReflectiveTests(SubstituteFromInterfaceTypeTest);
+    defineReflectiveTests(SubstituteFromPairsTest);
+    defineReflectiveTests(SubstituteFromUpperAndLowerBoundsTest);
+    defineReflectiveTests(SubstituteTest);
+  });
+}
+
+@reflectiveTest
+class SubstituteEmptyTest extends DriverResolutionTest {
+  test_interface() async {
+    addTestFile(r'''
+class A<T> {}
+''');
+    await resolveTestFile();
+
+    var type = findElement.class_('A').type;
+    var result = Substitution.empty.substituteType(type);
+    expect(result, same(type));
+  }
+}
+
+@reflectiveTest
+class SubstituteFromInterfaceTypeTest extends _Base {
+  test_interface() async {
+    addTestFile(r'''
+class A<T> {}
+class B<U> extends A<U> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var b = findElement.class_('B');
+    var u = b.typeParameters.single;
+
+    var bType = _instantiate(b, [intType]);
+    var substitution = Substitution.fromInterfaceType(bType);
+
+    // `extends A<U>`
+    var type = _instantiate(a, [u.type]);
+    assertElementTypeString(type, 'A<U>');
+
+    var result = substitution.substituteType(type);
+    assertElementTypeString(result, 'A<int>');
+  }
+}
+
+@reflectiveTest
+class SubstituteFromPairsTest extends DriverResolutionTest {
+  test_interface() async {
+    addTestFile(r'''
+class A<T, U> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var result = Substitution.fromPairs(
+      a.typeParameters,
+      [intType, doubleType],
+    ).substituteType(a.type);
+    assertElementTypeString(result, 'A<int, double>');
+  }
+}
+
+@reflectiveTest
+class SubstituteFromUpperAndLowerBoundsTest extends DriverResolutionTest {
+  test_function() async {
+    addTestFile(r'''
+typedef F<T> = T Function(T);
+''');
+    await resolveTestFile();
+
+    var type = findElement.genericTypeAlias('F').function.type;
+    var t = findElement.typeParameter('T');
+
+    var result = Substitution.fromUpperAndLowerBounds(
+      {t: intType},
+      {t: BottomTypeImpl.instance},
+    ).substituteType(type);
+    assertElementTypeString(result, '(<bottom>) → int');
+  }
+}
+
+@reflectiveTest
+class SubstituteTest extends _Base {
+  test_bottom() async {
+    addTestFile(r'''
+class A<T> {}
+''');
+    await resolveTestFile();
+
+    var t = findElement.typeParameter('T');
+    _assertIdenticalType(typeProvider.bottomType, {t: intType});
+  }
+
+  test_dynamic() async {
+    addTestFile(r'''
+class A<T> {}
+''');
+    await resolveTestFile();
+
+    var t = findElement.typeParameter('T');
+    _assertIdenticalType(typeProvider.dynamicType, {t: intType});
+  }
+
+  test_function_noTypeParameters() async {
+    addTestFile(r'''
+typedef F = bool Function(int);
+class B<T> {}
+''');
+    await resolveTestFile();
+
+    var type = findElement.genericTypeAlias('F').function.type;
+    var t = findElement.typeParameter('T');
+    _assertIdenticalType(type, {t: intType});
+  }
+
+  test_function_typeFormals() async {
+    addTestFile(r'''
+typedef F<T> = T Function<U extends T>(U);
+''');
+    await resolveTestFile();
+
+    var type = findElement.genericTypeAlias('F').function.type;
+    var t = findElement.typeParameter('T');
+    assertElementTypeString(type, '<U extends T>(U) → T');
+    _assertSubstitution(
+      type,
+      {t: intType},
+      '<U extends int>(U) → int',
+    );
+  }
+
+  test_function_typeParameters() async {
+    addTestFile(r'''
+typedef F<T, U> = T Function(U u, bool);
+''');
+    await resolveTestFile();
+
+    var type = findElement.genericTypeAlias('F').function.type;
+    var t = findElement.typeParameter('T');
+    var u = findElement.typeParameter('U');
+    assertElementTypeString(type, '(U, bool) → T');
+    _assertSubstitution(
+      type,
+      {t: intType},
+      '(U, bool) → int',
+    );
+    _assertSubstitution(
+      type,
+      {t: intType, u: doubleType},
+      '(double, bool) → int',
+    );
+  }
+
+  test_interface_arguments() async {
+    addTestFile(r'''
+class A<T> {}
+class B<U> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var u = findElement.typeParameter('U');
+    var uType = new TypeParameterTypeImpl(u);
+
+    var type = _instantiate(a, [uType]);
+    assertElementTypeString(type, 'A<U>');
+    _assertSubstitution(type, {u: intType}, 'A<int>');
+  }
+
+  test_interface_arguments_deep() async {
+    addTestFile(r'''
+class A<T> {}
+class B<U> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var u = findElement.typeParameter('U');
+    var uType = new TypeParameterTypeImpl(u);
+
+    var type = _instantiate(a, [
+      _instantiate(listElement, [uType])
+    ]);
+    assertElementTypeString(type, 'A<List<U>>');
+    _assertSubstitution(type, {u: intType}, 'A<List<int>>');
+  }
+
+  test_interface_noArguments() async {
+    addTestFile(r'''
+class A {}
+class B<T> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var t = findElement.typeParameter('T');
+    _assertIdenticalType(a.type, {t: intType});
+  }
+
+  test_interface_noArguments_inArguments() async {
+    addTestFile(r'''
+class A<T> {}
+class B<U> {}
+''');
+    await resolveTestFile();
+
+    var a = findElement.class_('A');
+    var u = findElement.typeParameter('U');
+    _assertIdenticalType(
+      _instantiate(a, [intType]),
+      {u: doubleType},
+    );
+  }
+
+  test_void() async {
+    addTestFile(r'''
+class A<T> {}
+''');
+    await resolveTestFile();
+
+    var t = findElement.typeParameter('T');
+    _assertIdenticalType(voidType, {t: intType});
+  }
+
+  test_void_emptyMap() async {
+    addTestFile('');
+    await resolveTestFile();
+    _assertIdenticalType(voidType, {});
+  }
+
+  void _assertIdenticalType(
+      DartType type, Map<TypeParameterElement, DartType> substitution) {
+    var result = substitute(type, substitution);
+    expect(result, same(type));
+  }
+
+  void _assertSubstitution(
+    DartType type,
+    Map<TypeParameterElement, DartType> substitution,
+    String expected,
+  ) {
+    var result = substitute(type, substitution);
+    assertElementTypeString(result, expected);
+  }
+}
+
+class _Base extends DriverResolutionTest {
+  /// Intentionally low-level implementation for creating [InterfaceType]
+  /// for [ClassElement] and type arguments. We just create it explicitly,
+  /// without using `InterfaceType.instantiate()`.
+  InterfaceType _instantiate(ClassElement element, List<DartType> arguments) {
+    return new InterfaceTypeImpl(element)..typeArguments = arguments;
+  }
+}
diff --git a/pkg/analyzer/test/src/dart/resolution/resolution.dart b/pkg/analyzer/test/src/dart/resolution/resolution.dart
index 08971b0..262e9cf 100644
--- a/pkg/analyzer/test/src/dart/resolution/resolution.dart
+++ b/pkg/analyzer/test/src/dart/resolution/resolution.dart
@@ -42,6 +42,10 @@
 
   Element get dynamicElement => typeProvider.dynamicType.element;
 
+  bool get enableUnusedElement => false;
+
+  bool get enableUnusedLocalVariable => false;
+
   ClassElement get intElement => typeProvider.intType.element;
 
   InterfaceType get intType => typeProvider.intType;
@@ -62,6 +66,8 @@
   /// Whether `DartType.toString()` with nullability should be asked.
   bool get typeToStringWithNullability => false;
 
+  VoidType get voidType => VoidTypeImpl.instance;
+
   void addTestFile(String content) {
     newFile('/test/lib/test.dart', content: content);
   }
@@ -144,10 +150,6 @@
     expect(element.enclosingElement, expectedEnclosing);
   }
 
-  bool get enableUnusedLocalVariable => false;
-
-  bool get enableUnusedElement => false;
-
   /**
    * Assert that the number of error codes in reported [errors] matches the
    * number of [expected] error codes. The order of errors is ignored.
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 8c52012..47b2dd1 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
@@ -13,6 +13,7 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(ConstEvalThrowsExceptionTest);
+    defineReflectiveTests(ConstEvalThrowsExceptionWithConstantUpdateTest);
     defineReflectiveTests(ConstEvalThrowsExceptionWithUIAsCodeTest);
   });
 }
@@ -131,6 +132,26 @@
 }
 
 @reflectiveTest
+class ConstEvalThrowsExceptionWithConstantUpdateTest
+    extends ConstEvalThrowsExceptionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.constant_update_2018,
+    ];
+
+  test_eqEq_nonPrimitiveRightOperand() async {
+    await assertNoErrorsInCode('''
+const c = const T.eq(1, const Object());
+class T {
+  final Object value;
+  const T.eq(Object o1, Object o2) : value = o1 == o2;
+}
+''');
+  }
+}
+
+@reflectiveTest
 class ConstEvalThrowsExceptionWithUIAsCodeTest
     extends ConstEvalThrowsExceptionTest {
   @override
diff --git a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
index 48ccc75..f2f92f9 100644
--- a/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/dead_code_test.dart
@@ -19,6 +19,52 @@
 
 @reflectiveTest
 class DeadCodeTest extends DriverResolutionTest with PackageMixin {
+  test_afterForEachWithBreakLabel() async {
+    await assertNoErrorsInCode(r'''
+f() {
+  named: {
+    for (var x in [1]) {
+      if (x == null)
+        break named;
+    }
+    return;
+  }
+  print('not dead');
+}
+''');
+  }
+
+  test_afterForWithBreakLabel() async {
+    await assertNoErrorsInCode(r'''
+f() {
+  named: {
+    for (int i = 0; i < 7; i++) {
+      if (i == null)
+        break named;
+    }
+    return;
+  }
+  print('not dead');
+}
+''');
+  }
+
+  test_afterTryCatch() async {
+    await assertNoErrorsInCode(r'''
+main() {
+  try {
+    return f();
+  } catch (e) {
+    print(e);
+  }
+  print('not dead');
+}
+f() {
+  throw 'foo';
+}
+''');
+  }
+
   test_deadBlock_conditionalElse() async {
     await assertErrorsInCode(r'''
 f() {
@@ -26,6 +72,14 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
+  test_deadBlock_conditionalElse_debugConst() async {
+    await assertNoErrorsInCode(r'''
+const bool DEBUG = true;
+f() {
+  DEBUG ? 1 : 2;
+}''');
+  }
+
   test_deadBlock_conditionalElse_nested() async {
     // Test that a dead else-statement can't generate additional violations.
     await assertErrorsInCode(r'''
@@ -41,22 +95,6 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
-  test_deadBlock_conditionalIf_nested() async {
-    // Test that a dead then-statement can't generate additional violations.
-    await assertErrorsInCode(r'''
-f() {
-  false ? false && false : true;
-}''', [HintCode.DEAD_CODE]);
-  }
-
-  test_deadBlock_conditionalElse_debugConst() async {
-    await assertNoErrorsInCode(r'''
-const bool DEBUG = true;
-f() {
-  DEBUG ? 1 : 2;
-}''');
-  }
-
   test_deadBlock_conditionalIf_debugConst() async {
     await assertNoErrorsInCode(r'''
 const bool DEBUG = false;
@@ -65,6 +103,14 @@
 }''');
   }
 
+  test_deadBlock_conditionalIf_nested() async {
+    // Test that a dead then-statement can't generate additional violations.
+    await assertErrorsInCode(r'''
+f() {
+  false ? false && false : true;
+}''', [HintCode.DEAD_CODE]);
+  }
+
   test_deadBlock_else() async {
     await assertErrorsInCode(r'''
 f() {
@@ -80,6 +126,21 @@
 }''');
   }
 
+  test_deadBlock_else_nested() async {
+    // Test that a dead else-statement can't generate additional violations.
+    await assertErrorsInCode(r'''
+f() {
+  if(true) {} else {if (false) {}}
+}''', [HintCode.DEAD_CODE]);
+  }
+
+  test_deadBlock_if() async {
+    await assertErrorsInCode(r'''
+f() {
+  if(false) {}
+}''', [HintCode.DEAD_CODE]);
+  }
+
   test_deadBlock_if_debugConst_prefixedIdentifier() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -126,21 +187,6 @@
 }''');
   }
 
-  test_deadBlock_else_nested() async {
-    // Test that a dead else-statement can't generate additional violations.
-    await assertErrorsInCode(r'''
-f() {
-  if(true) {} else {if (false) {}}
-}''', [HintCode.DEAD_CODE]);
-  }
-
-  test_deadBlock_if() async {
-    await assertErrorsInCode(r'''
-f() {
-  if(false) {}
-}''', [HintCode.DEAD_CODE]);
-  }
-
   test_deadBlock_if_nested() async {
     // Test that a dead then-statement can't generate additional violations.
     await assertErrorsInCode(r'''
@@ -156,14 +202,6 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
-  test_deadBlock_while_nested() async {
-    // Test that a dead while body can't generate additional violations.
-    await assertErrorsInCode(r'''
-f() {
-  while(false) {if(false) {}}
-}''', [HintCode.DEAD_CODE]);
-  }
-
   test_deadBlock_while_debugConst() async {
     await assertNoErrorsInCode(r'''
 const bool DEBUG = false;
@@ -172,6 +210,14 @@
 }''');
   }
 
+  test_deadBlock_while_nested() async {
+    // Test that a dead while body can't generate additional violations.
+    await assertErrorsInCode(r'''
+f() {
+  while(false) {if(false) {}}
+}''', [HintCode.DEAD_CODE]);
+  }
+
   test_deadCatch_catchFollowingCatch() async {
     await assertErrorsInCode(r'''
 class A {}
@@ -232,20 +278,21 @@
 }''');
   }
 
-  test_afterTryCatch() async {
+  test_deadFinalBreakInCase() async {
     await assertNoErrorsInCode(r'''
-main() {
-  try {
-    return f();
-  } catch (e) {
-    print(e);
-  }
-  print('not dead');
-}
 f() {
-  throw 'foo';
-}
-''');
+  switch (true) {
+  case true:
+    try {
+      int a = 1;
+    } finally {
+      return;
+    }
+    break;
+  default:
+    break;
+  }
+}''');
   }
 
   test_deadFinalReturnInCase() async {
@@ -282,23 +329,6 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
-  test_deadFinalBreakInCase() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  switch (true) {
-  case true:
-    try {
-      int a = 1;
-    } finally {
-      return;
-    }
-    break;
-  default:
-    break;
-  }
-}''');
-  }
-
   test_deadOperandLHS_and() async {
     await assertErrorsInCode(r'''
 f() {
@@ -306,6 +336,14 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
+  test_deadOperandLHS_and_debugConst() async {
+    await assertNoErrorsInCode(r'''
+const bool DEBUG = false;
+f() {
+  bool b = DEBUG && false;
+}''');
+  }
+
   test_deadOperandLHS_and_nested() async {
     await assertErrorsInCode(r'''
 f() {
@@ -320,21 +358,6 @@
 }''', [HintCode.DEAD_CODE]);
   }
 
-  test_deadOperandLHS_or_nested() async {
-    await assertErrorsInCode(r'''
-f() {
-  bool b = true || (false && false);
-}''', [HintCode.DEAD_CODE]);
-  }
-
-  test_deadOperandLHS_and_debugConst() async {
-    await assertNoErrorsInCode(r'''
-const bool DEBUG = false;
-f() {
-  bool b = DEBUG && false;
-}''');
-  }
-
   test_deadOperandLHS_or_debugConst() async {
     await assertNoErrorsInCode(r'''
 const bool DEBUG = true;
@@ -343,6 +366,13 @@
 }''');
   }
 
+  test_deadOperandLHS_or_nested() async {
+    await assertErrorsInCode(r'''
+f() {
+  bool b = true || (false && false);
+}''', [HintCode.DEAD_CODE]);
+  }
+
   test_statementAfterAlwaysThrowsFunction() async {
     addMetaPackage();
     await assertErrorsInCode(r'''
@@ -576,36 +606,6 @@
   var two = 2;
 }''', [HintCode.DEAD_CODE]);
   }
-
-  test_afterForEachWithBreakLabel() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  named: {
-    for (var x in [1]) {
-      if (x == null)
-        break named;
-    }
-    return;
-  }
-  print('not dead');
-}
-''');
-  }
-
-  test_afterForWithBreakLabel() async {
-    await assertNoErrorsInCode(r'''
-f() {
-  named: {
-    for (int i = 0; i < 7; i++) {
-      if (i == null)
-        break named;
-    }
-    return;
-  }
-  print('not dead');
-}
-''');
-  }
 }
 
 @reflectiveTest
diff --git a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
index 237cf68..428e9b2 100644
--- a/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/duplicate_import_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -32,22 +31,6 @@
     assertTestErrors([HintCode.DUPLICATE_IMPORT]);
   }
 
-  test_twoDuplicateImports() async {
-    newFile('/lib2.dart', content: r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart';
-import 'lib1.dart';
-A a;''');
-    newFile('/lib1.dart', content: r'''
-library lib1;
-class A {}''');
-
-    await _resolveTestFile('/lib1.dart');
-    await _resolveTestFile('/lib2.dart');
-    assertTestErrors([HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
-  }
-
   test_importsHaveIdenticalShowHide() async {
     newFile('/lib2.dart', content: r'''
 library L;
@@ -65,23 +48,6 @@
     assertTestErrors([HintCode.DUPLICATE_IMPORT]);
   }
 
-  test_oneImportUsesAs() async {
-    newFile('/lib2.dart', content: r'''
-library L;
-import 'lib1.dart';
-import 'lib1.dart' as one;
-A a;
-one.A a2;''');
-
-    newFile('/lib1.dart', content: r'''
-library lib1;
-class A {}''');
-
-    await _resolveTestFile('/lib1.dart');
-    await _resolveTestFile('/lib2.dart');
-    assertNoTestErrors();
-  }
-
   test_oneImportHasHide() async {
     newFile('/lib2.dart', content: r'''
 library L;
@@ -118,6 +84,39 @@
     assertNoTestErrors();
   }
 
+  test_oneImportUsesAs() async {
+    newFile('/lib2.dart', content: r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart' as one;
+A a;
+one.A a2;''');
+
+    newFile('/lib1.dart', content: r'''
+library lib1;
+class A {}''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_twoDuplicateImports() async {
+    newFile('/lib2.dart', content: r'''
+library L;
+import 'lib1.dart';
+import 'lib1.dart';
+import 'lib1.dart';
+A a;''');
+    newFile('/lib1.dart', content: r'''
+library lib1;
+class A {}''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.DUPLICATE_IMPORT, HintCode.DUPLICATE_IMPORT]);
+  }
+
   /// Resolve the test file at [path].
   ///
   /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
diff --git a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
index 0500bcc..93e6065 100644
--- a/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/import_deferred_library_with_load_function_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -32,6 +31,21 @@
     assertTestErrors([HintCode.IMPORT_DEFERRED_LIBRARY_WITH_LOAD_FUNCTION]);
   }
 
+  test_deferredImport_withoutLoadLibraryFunction() async {
+    newFile('/pkg1/lib/lib1.dart', content: r'''
+library lib1;
+f() {}''');
+
+    newFile('/pkg1/lib/lib2.dart', content: r'''
+library root;
+import 'lib1.dart' deferred as lib1;
+main() { lib1.f(); }''');
+
+    await _resolveTestFile('/pkg1/lib/lib1.dart');
+    await _resolveTestFile('/pkg1/lib/lib2.dart');
+    assertNoTestErrors();
+  }
+
   test_nonDeferredImport_withLoadLibraryFunction() async {
     newFile('/pkg1/lib/lib1.dart', content: r'''
 library lib1;
@@ -48,21 +62,6 @@
     assertNoTestErrors();
   }
 
-  test_deferredImport_withoutLoadLibraryFunction() async {
-    newFile('/pkg1/lib/lib1.dart', content: r'''
-library lib1;
-f() {}''');
-
-    newFile('/pkg1/lib/lib2.dart', content: r'''
-library root;
-import 'lib1.dart' deferred as lib1;
-main() { lib1.f(); }''');
-
-    await _resolveTestFile('/pkg1/lib/lib1.dart');
-    await _resolveTestFile('/pkg1/lib/lib2.dart');
-    assertNoTestErrors();
-  }
-
   /// Resolve the test file at [path].
   ///
   /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
new file mode 100644
index 0000000..fc57260
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_annotation_test.dart
@@ -0,0 +1,49 @@
+// 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:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidFactoryAnnotationTest);
+  });
+}
+
+@reflectiveTest
+class InvalidFactoryAnnotationTest extends DriverResolutionTest
+    with PackageMixin {
+  test_class() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@factory
+class X {
+}
+''', [HintCode.INVALID_FACTORY_ANNOTATION]);
+  }
+
+  test_field() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class X {
+  @factory
+  int x;
+}
+''', [HintCode.INVALID_FACTORY_ANNOTATION]);
+  }
+
+  test_topLevelFunction() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@factory
+main() { }
+''', [HintCode.INVALID_FACTORY_ANNOTATION]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_test.dart
new file mode 100644
index 0000000..8ba3959
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_factory_method_impl_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.
+
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidFactoryMethodImplTest);
+  });
+}
+
+@reflectiveTest
+class InvalidFactoryMethodImplTest extends DriverResolutionTest
+    with PackageMixin {
+  test_abstract() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+abstract class Stateful {
+  @factory
+  State createState();
+}
+class State { }
+''');
+  }
+
+  test_badReturn() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  State _s = new State();
+
+  @factory
+  State createState() => _s;
+}
+class State { }
+''', [HintCode.INVALID_FACTORY_METHOD_IMPL]);
+  }
+
+  test_block() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  @factory
+  State createState() {
+    return new State();
+  }
+}
+class State { }
+''');
+  }
+
+  test_block_returnNull() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  @factory
+  State createState() {
+    return null;
+  }
+}
+class State { }
+''');
+  }
+
+  test_expr() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  @factory
+  State createState() => new State();
+}
+class State { }
+''');
+  }
+
+  test_expr_returnNull() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  @factory
+  State createState() => null;
+}
+class State { }
+''');
+  }
+
+  test_noReturnType() async {
+    addMetaPackage();
+    // Null return types will get flagged elsewhere, no need to pile on here.
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class Stateful {
+  @factory
+  createState() {
+    return new Stateful();
+  }
+}
+''');
+  }
+
+  test_subclass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+abstract class Stateful {
+  @factory
+  State createState();
+}
+class MyThing extends Stateful {
+  @override
+  State createState() {
+    print('my state');
+    return new MyState();
+  }
+}
+class State { }
+class MyState extends State { }
+''');
+  }
+
+  test_voidReturn() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class Stateful {
+  @factory
+  void createState() {}
+}
+''', [HintCode.INVALID_FACTORY_METHOD_DECL]);
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
index 8b6e57f..85ee340e 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_immutable_annotation_test.dart
@@ -17,17 +17,6 @@
 @reflectiveTest
 class InvalidImmutableAnnotationTest extends DriverResolutionTest
     with PackageMixin {
-  test_method() async {
-    addMetaPackage();
-    await assertErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @immutable
-  void m() {}
-}
-''', [HintCode.INVALID_IMMUTABLE_ANNOTATION]);
-  }
-
   test_class() async {
     addMetaPackage();
     await assertNoErrorsInCode(r'''
@@ -38,4 +27,15 @@
 }
 ''');
   }
+
+  test_method() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @immutable
+  void m() {}
+}
+''', [HintCode.INVALID_IMMUTABLE_ANNOTATION]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
index 9751a2b..c9a88ca 100644
--- a/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/invalid_literal_annotation_test.dart
@@ -17,6 +17,17 @@
 @reflectiveTest
 class InvalidLiteralAnnotationTest extends DriverResolutionTest
     with PackageMixin {
+  test_constConstructor() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+''');
+  }
+
   test_nonConstConstructor() async {
     addMetaPackage();
     await assertErrorsInCode(r'''
@@ -38,15 +49,4 @@
 }
 ''', [HintCode.INVALID_LITERAL_ANNOTATION]);
   }
-
-  test_constConstructor() async {
-    addMetaPackage();
-    await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-''');
-  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
new file mode 100644
index 0000000..81c2a4c
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_protected_member_test.dart
@@ -0,0 +1,427 @@
+// 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:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidUseOfProtectedMemberTest);
+  });
+}
+
+@reflectiveTest
+class InvalidUseOfProtectedMemberTest extends DriverResolutionTest
+    with PackageMixin {
+  test_closure() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+
+class A {
+  @protected
+  int a() => 42;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+void main() {
+  var leak = new A().a;
+  print(leak);
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_extendingSubclass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+class B extends A {
+  void b() => a();
+}''');
+  }
+
+  test_field() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int a = 42;
+}
+class B extends A {
+  int b() => a;
+}
+''');
+  }
+
+  test_field_outsideClassAndLibrary() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int a;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+abstract class B {
+  int b() => new A().a;
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_field_subclassAndSameLibrary() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int a;
+}
+abstract class B implements A {
+  int b() => a;
+}''');
+  }
+
+  test_fromSuperclassConstraint() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+abstract class A {
+  @protected
+  void foo() {}
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+mixin M on A {
+  @override
+  void foo() {
+    super.foo();
+  }
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_function_outsideClassAndLibrary() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+main() {
+  new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_function_sameLibrary() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+main() {
+  new A().a();
+}''');
+  }
+
+  test_function_subclass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int a() => 0;
+}
+
+abstract class B implements A {
+  int b() => a();
+}''');
+  }
+
+  test_getter() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int get a => 42;
+}
+class B extends A {
+  int b() => a;
+}
+''');
+  }
+
+  test_getter_outsideClassAndLibrary() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int get a => 42;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+class B {
+  A a;
+  int b() => a.a;
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_getter_subclass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  int get a => 42;
+}
+abstract class B implements A {
+  int b() => a;
+}''');
+  }
+
+  test_inDocs() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+
+class A {
+  @protected
+  int c = 0;
+
+  @protected
+  int get b => 0;
+
+  @protected
+  int a() => 0;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+/// OK: [A.a], [A.b], [A.c].
+f() {}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_method_outsideClassAndLibrary() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a() {}
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_method_subclass() async {
+    // https://github.com/dart-lang/linter/issues/257
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+typedef void VoidCallback();
+
+class State<E> {
+  @protected
+  void setState(VoidCallback fn) {}
+}
+
+class Button extends State<Object> {
+  void handleSomething() {
+    setState(() {});
+  }
+}
+''');
+  }
+
+  test_mixingIn() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+class B extends Object with A {
+  void b() => a();
+}''');
+  }
+
+  test_mixingIn_asParameter() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected m1() {}
+}
+class B extends A {
+  static m2(A a) => a.m1();
+}''');
+  }
+
+  test_sameLibrary() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void a(){ }
+}
+class B extends A {
+  void a() => a();
+}
+main() {
+  new B().a();
+}''');
+  }
+
+  test_setter_outsideClassAndFile() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void set a(int i) { }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+class B {
+  A a;
+  b(int i) {
+    a.a = i;
+  }
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_PROTECTED_MEMBER]);
+  }
+
+  test_setter_sameClass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  int _a;
+  @protected
+  void set a(int a) { _a = a; }
+  A(int a) {
+    this.a = a;
+  }
+}
+''');
+  }
+
+  test_setter_subclass() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void set a(int i) { }
+}
+class B extends A {
+  void b(int i) {
+    a = i;
+  }
+}
+''');
+  }
+
+  test_setter_subclassImplementing() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  void set a(int i) { }
+}
+abstract class B implements A {
+  b(int i) {
+    a = i;
+  }
+}''');
+  }
+
+  test_topLevelVariable() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@protected
+int x = 0;
+main() {
+  print(x);
+}''');
+    // TODO(brianwilkerson) This should produce a hint because the
+    // annotation is being applied to the wrong kind of declaration.
+  }
+
+  /// Resolve the test file at [path].
+  ///
+  /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
+  Future<void> _resolveTestFile(String path) async {
+    result = await resolveFile(convertPath(path));
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
new file mode 100644
index 0000000..71dde80
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_template_member_test.dart
@@ -0,0 +1,226 @@
+// 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/file_system/file_system.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidUseOfVisibleForTemplateMemberTest);
+  });
+}
+
+@reflectiveTest
+class InvalidUseOfVisibleForTemplateMemberTest extends DriverResolutionTest
+    with PackageMixin {
+  void addAngularMetaPackage() {
+    Folder lib = addPubPackage('angular_meta');
+    newFile(join(lib.path, 'angular_meta.dart'), content: r'''
+library angular.meta;
+
+const _VisibleForTemplate visibleForTemplate = const _VisibleForTemplate();
+
+class _VisibleForTemplate {
+  const _VisibleForTemplate();
+}
+''');
+  }
+
+  test_constructor() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+class A {
+  int _x;
+
+  @visibleForTemplate
+  A.forTemplate(this._x);
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+void main() {
+  new A.forTemplate(0);
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+  }
+
+  test_export() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+
+@visibleForTemplate
+int fn0() => 1;
+''');
+    newFile('/lib2.dart', content: r'''
+export 'lib1.dart' show fn0;
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_method() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+class A {
+  @visibleForTemplate
+  void a(){ }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+  }
+
+  test_method_fromTemplate() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+class A {
+  @visibleForTemplate
+  void a(){ }
+}
+''');
+    addAngularMetaPackage();
+    newFile('/lib1.template.dart', content: r'''
+import 'lib1.dart';
+
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib1.template.dart');
+    assertNoTestErrors();
+  }
+
+  test_propertyAccess() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+class A {
+  @visibleForTemplate
+  int get a => 7;
+
+  @visibleForTemplate
+  set b(_) => 7;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+void main() {
+  new A().a;
+  new A().b = 6;
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([
+      HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER,
+      HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER
+    ]);
+  }
+
+  test_protectedAndForTemplate_usedAsProtected() async {
+    addAngularMetaPackage();
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  @visibleForTemplate
+  void a(){ }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+class B extends A {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_protectedAndForTemplate_usedAsTemplate() async {
+    addAngularMetaPackage();
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  @visibleForTemplate
+  void a(){ }
+}
+''');
+    addAngularMetaPackage();
+    addMetaPackage();
+    newFile('/lib1.template.dart', content: r'''
+import 'lib1.dart';
+void main() {
+  new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib1.template.dart');
+    assertNoTestErrors();
+  }
+
+  test_topLevelFunction() async {
+    addAngularMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:angular_meta/angular_meta.dart';
+
+@visibleForTemplate
+int fn0() => 1;
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+
+void main() {
+  fn0();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TEMPLATE_MEMBER]);
+  }
+
+  /// Resolve the test file at [path].
+  ///
+  /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
+  Future<void> _resolveTestFile(String path) async {
+    result = await resolveFile(convertPath(path));
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
new file mode 100644
index 0000000..5090d0d
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/invalid_use_of_visible_for_testing_member_test.dart
@@ -0,0 +1,234 @@
+// 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:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(InvalidUseOfVisibleForTestingMemberTest);
+  });
+}
+
+@reflectiveTest
+class InvalidUseOfVisibleForTestingMemberTest extends DriverResolutionTest
+    with PackageMixin {
+  test_constructor() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  int _x;
+
+  @visibleForTesting
+  A.forTesting(this._x);
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+void main() {
+  new A.forTesting(0);
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+  }
+
+  test_export() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+@visibleForTesting
+int fn0() => 1;
+''');
+    newFile('/lib2.dart', content: r'''
+export 'lib1.dart' show fn0;
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_fromTestDirectory() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('/test/test.dart', content: r'''
+import '../lib1.dart';
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/test/test.dart');
+    assertNoTestErrors();
+  }
+
+  test_fromTestingDirectory() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('/testing/lib1.dart', content: r'''
+import '../lib1.dart';
+class C {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/testing/lib1.dart');
+    assertNoTestErrors();
+  }
+
+  test_getter() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  int get a => 7;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+void main() {
+  new A().a;
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+  }
+
+  test_method() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+class B {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+  }
+
+  test_protectedAndForTesting_usedAsProtected() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+class B extends A {
+  void b() => new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertNoTestErrors();
+  }
+
+  test_protectedAndForTesting_usedAsTesting() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @protected
+  @visibleForTesting
+  void a(){ }
+}
+''');
+    addMetaPackage();
+    newFile('/test/test1.dart', content: r'''
+import '../lib1.dart';
+void main() {
+  new A().a();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/test/test1.dart');
+    assertNoTestErrors();
+  }
+
+  test_setter() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+class A {
+  @visibleForTesting
+  set b(_) => 7;
+}
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+void main() {
+  new A().b = 6;
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+  }
+
+  test_topLevelFunction() async {
+    addMetaPackage();
+    newFile('/lib1.dart', content: r'''
+import 'package:meta/meta.dart';
+@visibleForTesting
+int fn0() => 1;
+''');
+    newFile('/lib2.dart', content: r'''
+import 'lib1.dart';
+void main() {
+  fn0();
+}
+''');
+
+    await _resolveTestFile('/lib1.dart');
+    await _resolveTestFile('/lib2.dart');
+    assertTestErrors([HintCode.INVALID_USE_OF_VISIBLE_FOR_TESTING_MEMBER]);
+  }
+
+  /// Resolve the test file at [path].
+  ///
+  /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
+  Future<void> _resolveTestFile(String path) async {
+    result = await resolveFile(convertPath(path));
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
new file mode 100644
index 0000000..d73c1e7
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/missing_required_param_test.dart
@@ -0,0 +1,171 @@
+// 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:analyzer/src/test_utilities/package_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(MissingRequiredParamTest);
+  });
+}
+
+@reflectiveTest
+class MissingRequiredParamTest extends DriverResolutionTest with PackageMixin {
+  test_constructorParam_argumentGiven() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@required int a}) {}
+}
+
+main() {
+  new C(a: 2);
+}
+''');
+  }
+
+  test_constructorParam_missingArgument() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  C({@Required('must specify an `a`') int a}) {}
+}
+main() {
+  new C();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+  }
+
+  test_constructorParam_noReason() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@required int a}) {}
+}
+
+main() {
+  new C();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM]);
+  }
+
+  test_constructorParam_nullReason() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@Required(null) int a}) {}
+}
+
+main() {
+  new C();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM]);
+  }
+
+  test_constructorParam_redirectingConstructorCall() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class C {
+  C({@required int x});
+  C.named() : this();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM]);
+  }
+
+  test_functionParam() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+void f({@Required('must specify an `a`') int a}) {}
+
+main() {
+  f();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+  }
+
+  test_methodParam() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  void m({@Required('must specify an `a`') int a}) {}
+}
+f() {
+  new A().m();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+  }
+
+  test_methodParam_inOtherLib() async {
+    addMetaPackage();
+    newFile('/a_lib.dart', content: r'''
+library a_lib;
+import 'package:meta/meta.dart';
+class A {
+  void m({@Required('must specify an `a`') int a}) {}
+}
+''');
+    newFile('/test.dart', content: r'''
+import "a_lib.dart";
+f() {
+  new A().m();
+}
+''');
+
+    await _resolveTestFile('/a_lib.dart');
+    await _resolveTestFile('/test.dart');
+    assertTestErrors([HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+  }
+
+  test_requiredConstructor_paramSuperCall() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+class C {
+  C({@Required('must specify an `a`') int a}) {}
+}
+
+class D extends C {
+  D() : super();
+}
+''', [HintCode.MISSING_REQUIRED_PARAM_WITH_DETAILS]);
+  }
+
+  test_typedef_functionParam() async {
+    addMetaPackage();
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+String test(C c) => c.m()();
+
+typedef String F({@required String x});
+
+class C {
+  F m() => ({@required String x}) => null;
+}
+''', [HintCode.MISSING_REQUIRED_PARAM]);
+  }
+
+  /// Resolve the test file at [path].
+  ///
+  /// Similar to ResolutionTest.resolveTestFile, but a custom path is supported.
+  Future<void> _resolveTestFile(String path) async {
+    result = await resolveFile(convertPath(path));
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
index 5b03a7c..a83bb3a 100644
--- a/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/missing_return_test.dart
@@ -16,6 +16,21 @@
 
 @reflectiveTest
 class MissingReturnTest extends DriverResolutionTest with PackageMixin {
+  test_alwaysThrows() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+
+@alwaysThrows
+void a() {
+  throw 'msg';
+}
+
+int f() {
+  a();
+}''');
+  }
+
   test_async() async {
     await assertErrorsInCode(r'''
 import 'dart:async';
@@ -23,6 +38,33 @@
 ''', [HintCode.MISSING_RETURN]);
   }
 
+  test_async_futureOrVoid() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:async';
+FutureOr<void> f(Future f) async {}
+''');
+  }
+
+  test_async_futureVoid() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:async';
+Future<void> f() async {}
+''');
+  }
+
+  test_emptyFunctionBody() async {
+    await assertNoErrorsInCode(r'''
+abstract class A {
+  int m();
+}''');
+  }
+
+  test_expressionFunctionBody() async {
+    await assertNoErrorsInCode(r'''
+int f() => 0;
+''');
+  }
+
   test_factory() async {
     await assertErrorsInCode(r'''
 class A {
@@ -55,33 +97,6 @@
 ''', [HintCode.MISSING_RETURN]);
   }
 
-  test_emptyFunctionBody() async {
-    await assertNoErrorsInCode(r'''
-abstract class A {
-  int m();
-}''');
-  }
-
-  test_expressionFunctionBody() async {
-    await assertNoErrorsInCode(r'''
-int f() => 0;
-''');
-  }
-
-  test_async_futureVoid() async {
-    await assertNoErrorsInCode(r'''
-import 'dart:async';
-Future<void> f() async {}
-''');
-  }
-
-  test_async_futureOrVoid() async {
-    await assertNoErrorsInCode(r'''
-import 'dart:async';
-FutureOr<void> f(Future f) async {}
-''');
-  }
-
   test_noReturnType() async {
     await assertNoErrorsInCode(r'''
 f() {}
@@ -93,19 +108,4 @@
 void f() {}
 ''');
   }
-
-  test_alwaysThrows() async {
-    addMetaPackage();
-    await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-
-@alwaysThrows
-void a() {
-  throw 'msg';
-}
-
-int f() {
-  a();
-}''');
-  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
index c444236..2e425d4 100644
--- a/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/must_be_immutable_test.dart
@@ -52,6 +52,17 @@
 ''', [HintCode.MUST_BE_IMMUTABLE]);
   }
 
+  test_finalField() async {
+    addMetaPackage();
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+@immutable
+class A {
+  final x = 7;
+}
+''');
+  }
+
   test_fromMixinWithAnnotation() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -64,16 +75,6 @@
 ''', [HintCode.MUST_BE_IMMUTABLE]);
   }
 
-  test_staticField() async {
-    await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-@immutable
-class A {
-  static int x;
-}
-''');
-  }
-
   test_mixinApplication() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -98,13 +99,12 @@
 ''', [HintCode.MUST_BE_IMMUTABLE]);
   }
 
-  test_finalField() async {
-    addMetaPackage();
+  test_staticField() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
 @immutable
 class A {
-  final x = 7;
+  static int x;
 }
 ''');
   }
diff --git a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
index d2e6efb..5ef8e97 100644
--- a/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/must_call_super_test.dart
@@ -21,6 +21,22 @@
     addMetaPackage();
   }
 
+  test_containsSuperCall() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @mustCallSuper
+  void a() {}
+}
+class C extends A {
+  @override
+  void a() {
+    super.a(); // OK
+  }
+}
+''');
+  }
+
   test_fromExtendingClass() async {
     await assertErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -70,22 +86,6 @@
 ''', [HintCode.MUST_CALL_SUPER]);
   }
 
-  test_containsSuperCall() async {
-    await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @mustCallSuper
-  void a() {}
-}
-class C extends A {
-  @override
-  void a() {
-    super.a(); // OK
-  }
-}
-''');
-  }
-
   test_overriddenWithFuture() async {
     // https://github.com/flutter/flutter/issues/11646
     await assertNoErrorsInCode(r'''
diff --git a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
index a0f1591..e4b8eab 100644
--- a/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
+++ b/pkg/analyzer/test/src/diagnostics/non_const_call_to_literal_constructor.dart
@@ -23,45 +23,6 @@
     addMetaPackage();
   }
 
-  test_nonConstContext() async {
-    await assertErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-void main() {
-  var a = A();
-}
-''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]);
-  }
-
-  test_usingNew() async {
-    await assertErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-void main() {
-  var a = new A();
-}
-''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW]);
-  }
-
-  test_namedConstructor() async {
-    await assertErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A.named();
-}
-void main() {
-  var a = A.named();
-}
-''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]);
-  }
-
   test_constConstructor() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -72,20 +33,6 @@
 ''');
   }
 
-  test_constCreation() async {
-    await assertNoErrorsInCode(r'''
-import 'package:meta/meta.dart';
-class A {
-  @literal
-  const A();
-}
-
-void main() {
-  const a = const A();
-}
-''');
-  }
-
   test_constContextCreation() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -100,6 +47,46 @@
 ''');
   }
 
+  test_constCreation() async {
+    await assertNoErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+
+void main() {
+  const a = const A();
+}
+''');
+  }
+
+  test_namedConstructor() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A.named();
+}
+void main() {
+  var a = A.named();
+}
+''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]);
+  }
+
+  test_nonConstContext() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+void main() {
+  var a = A();
+}
+''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR]);
+  }
+
   test_unconstableCreation() async {
     await assertNoErrorsInCode(r'''
 import 'package:meta/meta.dart';
@@ -113,4 +100,17 @@
 }
 ''');
   }
+
+  test_usingNew() async {
+    await assertErrorsInCode(r'''
+import 'package:meta/meta.dart';
+class A {
+  @literal
+  const A();
+}
+void main() {
+  var a = new A();
+}
+''', [HintCode.NON_CONST_CALL_TO_LITERAL_CONSTRUCTOR_USING_NEW]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_test.dart
new file mode 100644
index 0000000..4a04ab2
--- /dev/null
+++ b/pkg/analyzer/test/src/diagnostics/not_null_aware_null_spread_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.
+
+import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/error/codes.dart';
+import 'package:analyzer/src/generated/engine.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../dart/resolution/driver_resolution.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(NotNullAwareNullSpreadTest);
+  });
+}
+
+@reflectiveTest
+class NotNullAwareNullSpreadTest extends DriverResolutionTest {
+  @override
+  AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
+    ..enabledExperiments = [
+      EnableString.control_flow_collections,
+      EnableString.spread_collections,
+    ];
+
+  test_listLiteral_notNullAware_nullLiteral() async {
+    await assertErrorsInCode('''
+var v = [...null];
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_listLiteral_notNullAware_nullTyped() async {
+    await assertErrorsInCode('''
+Null a = null;
+var v = [...a];
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_listLiteral_nullAware_nullLiteral() async {
+    await assertNoErrorsInCode('''
+var v = [...?null];
+''');
+  }
+
+  test_listLiteral_nullAware_nullTyped() async {
+    await assertNoErrorsInCode('''
+Null a = null;
+var v = [...?a];
+''');
+  }
+
+  test_mapLiteral_notNullAware_nullLiteral() async {
+    await assertErrorsInCode('''
+var v = <int, int>{...null};
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_mapLiteral_notNullAware_nullType() async {
+    await assertErrorsInCode('''
+Null a = null;
+var v = <int, int>{...a};
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_mapLiteral_nullAware_nullLiteral() async {
+    await assertNoErrorsInCode('''
+var v = <int, int>{...?null};
+''');
+  }
+
+  test_mapLiteral_nullAware_nullType() async {
+    await assertNoErrorsInCode('''
+Null a = null;
+var v = <int, int>{...?a};
+''');
+  }
+
+  test_setLiteral_notNullAware_nullLiteral() async {
+    await assertErrorsInCode('''
+var v = <int>{...null};
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_setLiteral_notNullAware_nullTyped() async {
+    await assertErrorsInCode('''
+Null a = null;
+var v = <int>{...a};
+''', [CompileTimeErrorCode.NOT_NULL_AWARE_NULL_SPREAD]);
+  }
+
+  test_setLiteral_nullAware_nullLiteral() async {
+    await assertNoErrorsInCode('''
+var v = <int>{...?null};
+''');
+  }
+
+  test_setLiteral_nullAware_nullTyped() async {
+    await assertNoErrorsInCode('''
+Null a = null;
+var v = <int>{...?a};
+''');
+  }
+}
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
index a5b4154..5505086 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_before_operator_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,14 +15,6 @@
 
 @reflectiveTest
 class NullAwareBeforeOperatorTest extends DriverResolutionTest {
-  test_minus() async {
-    await assertErrorsInCode(r'''
-m(x) {
-  x?.a - '';
-}
-''', [HintCode.NULL_AWARE_BEFORE_OPERATOR]);
-  }
-
   test_assignment() async {
     await assertNoErrorsInCode(r'''
 m(x) {
@@ -56,6 +47,14 @@
 ''');
   }
 
+  test_minus() async {
+    await assertErrorsInCode(r'''
+m(x) {
+  x?.a - '';
+}
+''', [HintCode.NULL_AWARE_BEFORE_OPERATOR]);
+  }
+
   test_not_equal() async {
     await assertNoErrorsInCode(r'''
 m(x) {
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
index db754f2..18bed78 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_condition_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
diff --git a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
index e3b48d2..05f7a5e 100644
--- a/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/null_aware_in_logical_operator_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -64,14 +63,6 @@
 ''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]);
   }
 
-  test_not() async {
-    await assertErrorsInCode(r'''
-m(x) {
-  !x?.a;
-}
-''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]);
-  }
-
   test_for_noCondition() async {
     await assertNoErrorsInCode(r'''
 m(x) {
@@ -87,4 +78,12 @@
 }
 ''');
   }
+
+  test_not() async {
+    await assertErrorsInCode(r'''
+m(x) {
+  !x?.a;
+}
+''', [HintCode.NULL_AWARE_IN_LOGICAL_OPERATOR]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
index 4a8a42c..898bbe1 100644
--- a/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_equals_but_not_hashcode_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,14 +15,6 @@
 
 @reflectiveTest
 class OverrideEqualsButNotHashCodeTest extends DriverResolutionTest {
-  @failingTest
-  test_overrideEquals_andNotHashCode() async {
-    await assertErrorsInCode(r'''
-class A {
-  bool operator ==(x) {}
-}''', [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
-  }
-
   test_overrideBoth() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -31,4 +22,12 @@
   get hashCode => 0;
 }''');
   }
+
+  @failingTest
+  test_overrideEquals_andNotHashCode() async {
+    await assertErrorsInCode(r'''
+class A {
+  bool operator ==(x) {}
+}''', [HintCode.OVERRIDE_EQUALS_BUT_NOT_HASH_CODE]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
index 3bd7122..8bb0368 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_field_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,16 +15,6 @@
 
 @reflectiveTest
 class OverrideOnNonOverridingFieldTest extends DriverResolutionTest {
-  test_invalid() async {
-    await assertErrorsInCode(r'''
-class A {
-}
-class B extends A {
-  @override
-  final int m = 1;
-}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD]);
-  }
-
   test_inInterface() async {
     await assertErrorsInCode(r'''
 class A {
@@ -59,4 +48,14 @@
   int c;
 }''', [CompileTimeErrorCode.INVALID_OVERRIDE]);
   }
+
+  test_invalid() async {
+    await assertErrorsInCode(r'''
+class A {
+}
+class B extends A {
+  @override
+  final int m = 1;
+}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_FIELD]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
index 7ccce0e..c9b41a6 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_getter_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,16 +15,6 @@
 
 @reflectiveTest
 class OverrideOnNonOverridingGetterTest extends DriverResolutionTest {
-  test_invalid() async {
-    await assertErrorsInCode(r'''
-class A {
-}
-class B extends A {
-  @override
-  int get m => 1;
-}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
-  }
-
   test_inInterface() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -47,4 +36,14 @@
   int get m => 1;
 }''');
   }
+
+  test_invalid() async {
+    await assertErrorsInCode(r'''
+class A {
+}
+class B extends A {
+  @override
+  int get m => 1;
+}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_GETTER]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
index bc7f3f1..fb6038e 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_method_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,16 +15,6 @@
 
 @reflectiveTest
 class OverrideOnNonOverridingMethodTest extends DriverResolutionTest {
-  test_invalid() async {
-    await assertErrorsInCode(r'''
-class A {
-}
-class B extends A {
-  @override
-  int m() => 1;
-}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
-  }
-
   test_inInterface() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -74,4 +63,14 @@
   int m() => 1;
 }''');
   }
+
+  test_invalid() async {
+    await assertErrorsInCode(r'''
+class A {
+}
+class B extends A {
+  @override
+  int m() => 1;
+}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_METHOD]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
index 2cf04df..a9b4b62 100644
--- a/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/override_on_non_overriding_setter_test.dart
@@ -3,7 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/error/codes.dart';
-import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import '../dart/resolution/driver_resolution.dart';
@@ -16,16 +15,6 @@
 
 @reflectiveTest
 class OverrideOnNonOverridingSetterTest extends DriverResolutionTest {
-  test_invalid() async {
-    await assertErrorsInCode(r'''
-class A {
-}
-class B extends A {
-  @override
-  set m(int x) {}
-}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
-  }
-
   test_inInterface() async {
     await assertNoErrorsInCode(r'''
 class A {
@@ -47,4 +36,14 @@
   set m(int x) {}
 }''');
   }
+
+  test_invalid() async {
+    await assertErrorsInCode(r'''
+class A {
+}
+class B extends A {
+  @override
+  set m(int x) {}
+}''', [HintCode.OVERRIDE_ON_NON_OVERRIDING_SETTER]);
+  }
 }
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
index c0efd81..6801637 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_sealed_class_test.dart
@@ -66,17 +66,18 @@
     assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
   }
 
-  test_mixinImplementsSealedClass() async {
+  test_mixinApplicationOfSealedMixin() async {
     addMetaPackage();
     _addPackage('foo', r'''
 import 'package:meta/meta.dart';
-@sealed class Foo {}
+@sealed mixin Foo {}
 ''');
 
     _newPubPackageRoot('/pkg1');
     newFile('/pkg1/lib/lib1.dart', content: r'''
 import 'package:foo/foo.dart';
-mixin Bar implements Foo {}
+class Bar1 {}
+class Bar2 = Bar1 with Foo;
 ''');
     await _resolveTestFile('/pkg1/lib/lib1.dart');
     assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
@@ -98,18 +99,17 @@
     assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
   }
 
-  test_mixinApplicationOfSealedMixin() async {
+  test_mixinImplementsSealedClass() async {
     addMetaPackage();
     _addPackage('foo', r'''
 import 'package:meta/meta.dart';
-@sealed mixin Foo {}
+@sealed class Foo {}
 ''');
 
     _newPubPackageRoot('/pkg1');
     newFile('/pkg1/lib/lib1.dart', content: r'''
 import 'package:foo/foo.dart';
-class Bar1 {}
-class Bar2 = Bar1 with Foo;
+mixin Bar implements Foo {}
 ''');
     await _resolveTestFile('/pkg1/lib/lib1.dart');
     assertTestErrors([HintCode.SUBTYPE_OF_SEALED_CLASS]);
diff --git a/pkg/analyzer/test/src/diagnostics/test_all.dart b/pkg/analyzer/test/src/diagnostics/test_all.dart
index 8de2941..7bf4d02 100644
--- a/pkg/analyzer/test/src/diagnostics/test_all.dart
+++ b/pkg/analyzer/test/src/diagnostics/test_all.dart
@@ -32,6 +32,8 @@
     as import_deferred_library_with_load_function;
 import 'invalid_assignment_test.dart' as invalid_assignment;
 import 'invalid_cast_new_expr_test.dart' as invalid_cast_new_expr;
+import 'invalid_factory_annotation_test.dart' as invalid_factory_annotation;
+import 'invalid_factory_method_impl_test.dart' as invalid_factory_method_impl;
 import 'invalid_immutable_annotation_test.dart' as invalid_immutable_annotation;
 import 'invalid_literal_annotation_test.dart' as invalid_literal_annotation;
 import 'invalid_override_different_default_values_named_test.dart'
@@ -40,6 +42,12 @@
     as invalid_override_different_default_values_positional;
 import 'invalid_required_param_test.dart' as invalid_required_param;
 import 'invalid_sealed_annotation_test.dart' as invalid_sealed_annotation;
+import 'invalid_use_of_protected_member_test.dart'
+    as invalid_use_of_protected_member;
+import 'invalid_use_of_visible_for_template_member_test.dart'
+    as invalid_use_of_visible_for_template_member;
+import 'invalid_use_of_visible_for_testing_member_test.dart'
+    as invalid_use_of_visible_for_testing_member;
 import 'invalid_visibility_annotation_test.dart'
     as invalid_visibility_annotation;
 import 'list_element_type_not_assignable_test.dart'
@@ -48,6 +56,7 @@
 import 'map_key_type_not_assignable_test.dart' as map_key_type_not_assignable;
 import 'map_value_type_not_assignable_test.dart'
     as map_value_type_not_assignable;
+import 'missing_required_param_test.dart' as missing_required_param;
 import 'missing_return_test.dart' as missing_return;
 import 'mixin_on_sealed_class_test.dart' as mixin_on_sealed_class;
 import 'must_be_immutable_test.dart' as must_be_immutable;
@@ -72,6 +81,7 @@
     as non_constant_spread_expression_from_deferred_library;
 import 'not_iterable_spread_test.dart' as not_iterable_spread;
 import 'not_map_spread_test.dart' as not_map_spread;
+import 'not_null_aware_null_spread_test.dart' as not_null_aware_null_spread;
 import 'null_aware_before_operator_test.dart' as null_aware_before_operator;
 import 'null_aware_in_condition_test.dart' as null_aware_in_condition;
 import 'null_aware_in_logical_operator_test.dart'
@@ -153,17 +163,23 @@
     import_deferred_library_with_load_function.main();
     invalid_assignment.main();
     invalid_cast_new_expr.main();
+    invalid_factory_annotation.main();
+    invalid_factory_method_impl.main();
     invalid_immutable_annotation.main();
     invalid_literal_annotation.main();
     invalid_override_different_default_values_named.main();
     invalid_override_different_default_values_positional.main();
     invalid_required_param.main();
     invalid_sealed_annotation.main();
+    invalid_use_of_protected_member.main();
+    invalid_use_of_visible_for_template_member.main();
+    invalid_use_of_visible_for_testing_member.main();
     invalid_visibility_annotation.main();
     list_element_type_not_assignable.main();
     map_entry_not_in_map.main();
     map_key_type_not_assignable.main();
     map_value_type_not_assignable.main();
+    missing_required_param.main();
     missing_return.main();
     mixin_on_sealed_class.main();
     must_be_immutable.main();
@@ -182,6 +198,7 @@
     non_constant_spread_expression_from_deferred_library.main();
     not_iterable_spread.main();
     not_map_spread.main();
+    not_null_aware_null_spread.main();
     null_aware_before_operator.main();
     null_aware_in_condition.main();
     null_aware_in_logical_operator.main();
diff --git a/pkg/analyzer/test/src/manifest/manifest_validator_test.dart b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
new file mode 100644
index 0000000..8cd846cc6
--- /dev/null
+++ b/pkg/analyzer/test/src/manifest/manifest_validator_test.dart
@@ -0,0 +1,75 @@
+// 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/error/error.dart';
+import 'package:analyzer/file_system/file_system.dart';
+import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/manifest/manifest_validator.dart';
+import 'package:analyzer/src/manifest/manifest_warning_code.dart';
+import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import '../../generated/test_support.dart';
+
+main() {
+  defineReflectiveSuite(() {
+    defineReflectiveTests(ManifestValidatorTest);
+  });
+}
+
+@reflectiveTest
+class ManifestValidatorTest with ResourceProviderMixin {
+  ManifestValidator validator;
+
+  /**
+   * Assert that when the validator is used on the given [content] the
+   * [expectedErrorCodes] are produced.
+   */
+  void assertErrors(String content, List<ErrorCode> expectedErrorCodes) {
+    List<AnalysisError> errors = validator.validate(content, true);
+    GatheringErrorListener listener = new GatheringErrorListener();
+    listener.addAll(errors);
+    listener.assertErrorsWithCodes(expectedErrorCodes);
+  }
+
+  /**
+   * Assert that when the validator is used on the given [content] no errors are
+   * produced.
+   */
+  void assertNoErrors(String content) {
+    assertErrors(content, []);
+  }
+
+  void setUp() {
+    File ManifestFile = getFile('/sample/Manifest.xml');
+    Source source = ManifestFile.createSource();
+    validator = new ManifestValidator(source);
+  }
+
+  test_hardwareNotSupported_error() {
+    assertErrors('''
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-feature android:name="android.software.home_screen" />
+</manifest>
+''', [ManifestWarningCode.UNSUPPORTED_CHROME_OS_HARDWARE]);
+  }
+
+  test_cameraPermissions_error() {
+    assertErrors('''
+<manifest
+     xmlns:android="http://schemas.android.com/apk/res/android">
+    <uses-permission android:name="android.permission.CAMERA" />
+</manifest>
+''', [ManifestWarningCode.CAMERA_PERMISSIONS_INCOMPATIBLE]);
+  }
+
+  test_no_errors() {
+    assertErrors('''
+<manifest
+     xmlns:android="http://schemas.android.com/apk/res/android">
+</manifest>
+''', []);
+  }
+}
diff --git a/pkg/analyzer/test/src/manifest/test_all.dart b/pkg/analyzer/test/src/manifest/test_all.dart
new file mode 100644
index 0000000..09e62ac
--- /dev/null
+++ b/pkg/analyzer/test/src/manifest/test_all.dart
@@ -0,0 +1,13 @@
+// Copyright (c) 2019, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:test_reflective_loader/test_reflective_loader.dart';
+
+import 'manifest_validator_test.dart' as manifest_test;
+
+main() {
+  defineReflectiveSuite(() {
+    manifest_test.main();
+  }, name: 'task');
+}
diff --git a/pkg/analyzer/test/src/services/available_declarations_test.dart b/pkg/analyzer/test/src/services/available_declarations_test.dart
index 8045e44..206a034 100644
--- a/pkg/analyzer/test/src/services/available_declarations_test.dart
+++ b/pkg/analyzer/test/src/services/available_declarations_test.dart
@@ -203,11 +203,18 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
-      _ExpectedDeclaration.enum_('E'),
-      _ExpectedDeclaration.enumConstant('v', 'E'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.enum_('E', [
+        _ExpectedDeclaration.enumConstant('v'),
+      ]),
     ]);
   }
 
@@ -240,15 +247,23 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:test/c.dart');
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     newFile(c, content: r'''
@@ -258,19 +273,33 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -285,7 +314,9 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
 
@@ -296,10 +327,14 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     var librariesObject = declarationsContext.getLibraries(
@@ -327,11 +362,15 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     newFile(b, content: r'''
@@ -342,12 +381,18 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:test/b.dart');
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -382,7 +427,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('package:test/test.dart'),
+      _getDeclaration(
+        _getLibrary('package:test/test.dart').declarations,
+        'A',
+      ),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['package:test/test.dart::A'],
@@ -394,7 +442,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('package:test/test.dart'),
+      _getDeclaration(
+        _getLibrary('package:test/test.dart').declarations,
+        'B',
+      ),
       'B',
       DeclarationKind.CLASS,
       relevanceTags: ['package:test/test.dart::B'],
@@ -426,7 +477,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('package:aaa/a.dart'),
+      _getDeclaration(
+        _getLibrary('package:aaa/a.dart').declarations,
+        'A',
+      ),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['package:aaa/a.dart::A'],
@@ -438,7 +492,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('package:aaa/a.dart'),
+      _getDeclaration(
+        _getLibrary('package:aaa/a.dart').declarations,
+        'B',
+      ),
       'B',
       DeclarationKind.CLASS,
       relevanceTags: ['package:aaa/a.dart::B'],
@@ -457,7 +514,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('dart:math'),
+      _getDeclaration(
+        _getLibrary('dart:math').declarations,
+        'A',
+      ),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['dart:math::A'],
@@ -469,7 +529,10 @@
     await _doAllTrackerWork();
 
     _assertDeclaration(
-      _getLibrary('dart:math'),
+      _getDeclaration(
+        _getLibrary('dart:math').declarations,
+        'B',
+      ),
       'B',
       DeclarationKind.CLASS,
       relevanceTags: ['dart:math::B'],
@@ -500,19 +563,33 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     deleteFile(c);
@@ -520,15 +597,23 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:test/c.dart');
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -596,11 +681,17 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     deleteFile(b);
@@ -608,10 +699,14 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -652,19 +747,33 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     newFile(c, content: r'''
@@ -674,19 +783,33 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C2'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C2'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C2'),
+      _ExpectedDeclaration.class_('C2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/d.dart', declarations: [
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -704,10 +827,14 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     newFile(a, content: r'''
@@ -717,10 +844,14 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A2'),
+      _ExpectedDeclaration.class_('A2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -744,11 +875,17 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     newFile(b, content: r'''
@@ -759,11 +896,17 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B2'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -845,27 +988,27 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['package:test/test.dart::A'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'B'),
       'B',
       DeclarationKind.CLASS,
       isAbstract: true,
       relevanceTags: ['package:test/test.dart::B'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'C'),
       'C',
       DeclarationKind.CLASS,
       isDeprecated: true,
       relevanceTags: ['package:test/test.dart::C'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'D'),
       'D',
       DeclarationKind.CLASS,
       docSummary: 'aaa',
@@ -894,20 +1037,20 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.CLASS_TYPE_ALIAS,
       relevanceTags: ['package:test/test.dart::A'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'B'),
       'B',
       DeclarationKind.CLASS_TYPE_ALIAS,
       isDeprecated: true,
       relevanceTags: ['package:test/test.dart::B'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'C'),
       'C',
       DeclarationKind.CLASS_TYPE_ALIAS,
       docSummary: 'aaa',
@@ -944,49 +1087,69 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, '', DeclarationKind.CONSTRUCTOR,
-        name2: 'C',
-        parameterNames: [],
-        parameters: '()',
-        parameterTypes: [],
-        requiredParameterCount: 0);
-    _assertDeclaration(library, 'a', DeclarationKind.CONSTRUCTOR,
-        name2: 'C',
-        parameterNames: [],
-        parameters: '()',
-        parameterTypes: [],
-        requiredParameterCount: 0);
-    _assertDeclaration(library, 'b', DeclarationKind.CONSTRUCTOR,
-        isDeprecated: true,
-        name2: 'C',
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0);
-    _assertDeclaration(library, 'c', DeclarationKind.CONSTRUCTOR,
-        docSummary: 'aaa',
-        docComplete: 'aaa\n\nbbb bbb',
-        name2: 'C',
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0);
-    _assertDeclaration(library, 'd', DeclarationKind.CONSTRUCTOR,
-        defaultArgumentListString: 'p1, p2',
-        defaultArgumentListTextRanges: [0, 2, 4, 2],
-        name2: 'C',
-        parameters: '(Map<String, int> p1, int p2, {double p3})',
-        parameterNames: ['p1', 'p2', 'p3'],
-        parameterTypes: ['Map<String, int>', 'int', 'double'],
-        requiredParameterCount: 2);
-    _assertDeclaration(library, 'e', DeclarationKind.CONSTRUCTOR,
-        defaultArgumentListString: 'f1, f2',
-        defaultArgumentListTextRanges: [0, 2, 4, 2],
-        name2: 'C',
-        parameters: '(this.f1, this.f2)',
-        parameterNames: ['f1', 'f2'],
-        parameterTypes: ['', ''],
-        requiredParameterCount: 2);
+    var classDeclaration = _getDeclaration(library.declarations, 'C');
+
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, ''),
+      '',
+      DeclarationKind.CONSTRUCTOR,
+      parameterNames: [],
+      parameters: '()',
+      parameterTypes: [],
+      requiredParameterCount: 0,
+    );
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, 'a'),
+      'a',
+      DeclarationKind.CONSTRUCTOR,
+      parameterNames: [],
+      parameters: '()',
+      parameterTypes: [],
+      requiredParameterCount: 0,
+    );
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, 'b'),
+      'b',
+      DeclarationKind.CONSTRUCTOR,
+      isDeprecated: true,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+    );
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, 'c'),
+      'c',
+      DeclarationKind.CONSTRUCTOR,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+    );
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, 'd'),
+      'd',
+      DeclarationKind.CONSTRUCTOR,
+      defaultArgumentListString: 'p1, p2',
+      defaultArgumentListTextRanges: [0, 2, 4, 2],
+      parameters: '(Map<String, int> p1, int p2, {double p3})',
+      parameterNames: ['p1', 'p2', 'p3'],
+      parameterTypes: ['Map<String, int>', 'int', 'double'],
+      requiredParameterCount: 2,
+    );
+    _assertDeclaration(
+      _getDeclaration(classDeclaration.children, 'e'),
+      'e',
+      DeclarationKind.CONSTRUCTOR,
+      defaultArgumentListString: 'f1, f2',
+      defaultArgumentListTextRanges: [0, 2, 4, 2],
+      parameters: '(this.f1, this.f2)',
+      parameterNames: ['f1', 'f2'],
+      parameterTypes: ['', ''],
+      requiredParameterCount: 2,
+    );
   }
 
   test_ENUM() async {
@@ -1007,20 +1170,20 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.ENUM,
       relevanceTags: ['package:test/test.dart::A'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'B'),
       'B',
       DeclarationKind.ENUM,
       isDeprecated: true,
       relevanceTags: ['package:test/test.dart::B'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'C'),
       'C',
       DeclarationKind.ENUM,
       docSummary: 'aaa',
@@ -1048,28 +1211,27 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
+    var enumDeclaration = _getDeclaration(library.declarations, 'MyEnum');
+
     _assertDeclaration(
-      library,
+      _getDeclaration(enumDeclaration.children, 'a'),
       'a',
       DeclarationKind.ENUM_CONSTANT,
-      name2: 'MyEnum',
       relevanceTags: ['package:test/test.dart::MyEnum'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(enumDeclaration.children, 'b'),
       'b',
       DeclarationKind.ENUM_CONSTANT,
       isDeprecated: true,
-      name2: 'MyEnum',
       relevanceTags: ['package:test/test.dart::MyEnum'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(enumDeclaration.children, 'c'),
       'c',
       DeclarationKind.ENUM_CONSTANT,
       docSummary: 'aaa',
       docComplete: 'aaa\n\nbbb bbb',
-      name2: 'MyEnum',
       relevanceTags: ['package:test/test.dart::MyEnum'],
     );
   }
@@ -1095,42 +1257,62 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, 'a', DeclarationKind.FUNCTION,
-        parameterNames: [],
-        parameters: '()',
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'b', DeclarationKind.FUNCTION,
-        isDeprecated: true,
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'c', DeclarationKind.FUNCTION,
-        docSummary: 'aaa',
-        docComplete: 'aaa\n\nbbb bbb',
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'd', DeclarationKind.FUNCTION,
-        defaultArgumentListString: 'p1, p2',
-        defaultArgumentListTextRanges: [0, 2, 4, 2],
-        parameters: '(Map<String, int> p1, int p2, {double p3})',
-        parameterNames: ['p1', 'p2', 'p3'],
-        parameterTypes: ['Map<String, int>', 'int', 'double'],
-        requiredParameterCount: 2,
-        returnType: 'List<String>');
-    _assertDeclaration(library, 'e', DeclarationKind.FUNCTION,
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        returnType: 'void',
-        typeParameters: '<T extends num, U>');
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'a'),
+      'a',
+      DeclarationKind.FUNCTION,
+      parameterNames: [],
+      parameters: '()',
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'b'),
+      'b',
+      DeclarationKind.FUNCTION,
+      isDeprecated: true,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'c'),
+      'c',
+      DeclarationKind.FUNCTION,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'd'),
+      'd',
+      DeclarationKind.FUNCTION,
+      defaultArgumentListString: 'p1, p2',
+      defaultArgumentListTextRanges: [0, 2, 4, 2],
+      parameters: '(Map<String, int> p1, int p2, {double p3})',
+      parameterNames: ['p1', 'p2', 'p3'],
+      parameterTypes: ['Map<String, int>', 'int', 'double'],
+      requiredParameterCount: 2,
+      returnType: 'List<String>',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'e'),
+      'e',
+      DeclarationKind.FUNCTION,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      returnType: 'void',
+      typeParameters: '<T extends num, U>',
+    );
   }
 
   test_FUNCTION_defaultArgumentList() async {
@@ -1148,36 +1330,52 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, 'a', DeclarationKind.FUNCTION,
-        parameterNames: [],
-        parameters: '()',
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'b', DeclarationKind.FUNCTION,
-        defaultArgumentListString: 'a, bb, ccc',
-        defaultArgumentListTextRanges: [0, 1, 3, 2, 7, 3],
-        parameters: '(int a, double bb, String ccc)',
-        parameterNames: ['a', 'bb', 'ccc'],
-        parameterTypes: ['int', 'double', 'String'],
-        requiredParameterCount: 3,
-        returnType: 'void');
-    _assertDeclaration(library, 'c', DeclarationKind.FUNCTION,
-        defaultArgumentListString: 'a',
-        defaultArgumentListTextRanges: [0, 1],
-        parameters: '(int a, [double b, String c])',
-        parameterNames: ['a', 'b', 'c'],
-        parameterTypes: ['int', 'double', 'String'],
-        requiredParameterCount: 1,
-        returnType: 'void');
-    _assertDeclaration(library, 'd', DeclarationKind.FUNCTION,
-        defaultArgumentListString: 'a, c: null, d: null',
-        defaultArgumentListTextRanges: [0, 1, 6, 4, 15, 4],
-        parameters: '(int a, {int b, @required int c, @required int d, int e})',
-        parameterNames: ['a', 'b', 'c', 'd', 'e'],
-        parameterTypes: ['int', 'int', 'int', 'int', 'int'],
-        requiredParameterCount: 1,
-        returnType: 'void');
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'a'),
+      'a',
+      DeclarationKind.FUNCTION,
+      parameterNames: [],
+      parameters: '()',
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'b'),
+      'b',
+      DeclarationKind.FUNCTION,
+      defaultArgumentListString: 'a, bb, ccc',
+      defaultArgumentListTextRanges: [0, 1, 3, 2, 7, 3],
+      parameters: '(int a, double bb, String ccc)',
+      parameterNames: ['a', 'bb', 'ccc'],
+      parameterTypes: ['int', 'double', 'String'],
+      requiredParameterCount: 3,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'c'),
+      'c',
+      DeclarationKind.FUNCTION,
+      defaultArgumentListString: 'a',
+      defaultArgumentListTextRanges: [0, 1],
+      parameters: '(int a, [double b, String c])',
+      parameterNames: ['a', 'b', 'c'],
+      parameterTypes: ['int', 'double', 'String'],
+      requiredParameterCount: 1,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'd'),
+      'd',
+      DeclarationKind.FUNCTION,
+      defaultArgumentListString: 'a, c: null, d: null',
+      defaultArgumentListTextRanges: [0, 1, 6, 4, 15, 4],
+      parameters: '(int a, {int b, @required int c, @required int d, int e})',
+      parameterNames: ['a', 'b', 'c', 'd', 'e'],
+      parameterTypes: ['int', 'int', 'int', 'int', 'int'],
+      requiredParameterCount: 1,
+      returnType: 'void',
+    );
   }
 
   test_FUNCTION_TYPE_ALIAS() async {
@@ -1203,52 +1401,88 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, 'A', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        relevanceTags: ['package:test/test.dart::A'],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'B', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        isDeprecated: true,
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        relevanceTags: ['package:test/test.dart::B'],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'C', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        docSummary: 'aaa',
-        docComplete: 'aaa\n\nbbb bbb',
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        relevanceTags: ['package:test/test.dart::C'],
-        requiredParameterCount: 0,
-        returnType: 'void');
-    _assertDeclaration(library, 'D', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        parameters: '(int p1, [double p2, String p3])',
-        parameterNames: ['p1', 'p2', 'p3'],
-        parameterTypes: ['int', 'double', 'String'],
-        relevanceTags: ['package:test/test.dart::D'],
-        requiredParameterCount: 1,
-        returnType: 'int');
-    _assertDeclaration(library, 'E', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        parameters: '(int, double, {String p3})',
-        parameterNames: ['', '', 'p3'],
-        parameterTypes: ['int', 'double', 'String'],
-        relevanceTags: ['package:test/test.dart::E'],
-        requiredParameterCount: 2,
-        returnType: 'void');
-    _assertDeclaration(library, 'F', DeclarationKind.FUNCTION_TYPE_ALIAS,
-        parameters: '()',
-        parameterNames: [],
-        parameterTypes: [],
-        requiredParameterCount: 0,
-        relevanceTags: ['package:test/test.dart::F'],
-        returnType: 'void',
-        typeParameters: '<T extends num, U>');
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'A'),
+      'A',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      relevanceTags: ['package:test/test.dart::A'],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'B'),
+      'B',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      isDeprecated: true,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      relevanceTags: ['package:test/test.dart::B'],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'C'),
+      'C',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      relevanceTags: ['package:test/test.dart::C'],
+      requiredParameterCount: 0,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'D'),
+      'D',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      parameters: '(int p1, [double p2, String p3])',
+      parameterNames: ['p1', 'p2', 'p3'],
+      parameterTypes: ['int', 'double', 'String'],
+      relevanceTags: ['package:test/test.dart::D'],
+      requiredParameterCount: 1,
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'E'),
+      'E',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      parameters: '(int, double, {String p3})',
+      parameterNames: ['', '', 'p3'],
+      parameterTypes: ['int', 'double', 'String'],
+      relevanceTags: ['package:test/test.dart::E'],
+      requiredParameterCount: 2,
+      returnType: 'void',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'F'),
+      'F',
+      DeclarationKind.FUNCTION_TYPE_ALIAS,
+      parameters: '()',
+      parameterNames: [],
+      parameterTypes: [],
+      requiredParameterCount: 0,
+      relevanceTags: ['package:test/test.dart::F'],
+      returnType: 'void',
+      typeParameters: '<T extends num, U>',
+    );
+  }
+
+  test_FUNCTION_TYPE_ALIAS_noFunction() async {
+    newFile('/home/test/lib/test.dart', content: r'''
+typedef A = ;
+''');
+
+    tracker.addContext(testAnalysisContext);
+    await _doAllTrackerWork();
+
+    var library = _getLibrary('package:test/test.dart');
+    _assertNoDeclaration(library, 'A');
   }
 
   test_GETTER() async {
@@ -1268,16 +1502,21 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, 'a', DeclarationKind.GETTER, returnType: 'int');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'a'),
+      'a',
+      DeclarationKind.GETTER,
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'b'),
       'b',
       DeclarationKind.GETTER,
       isDeprecated: true,
       returnType: 'int',
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'c'),
       'c',
       DeclarationKind.GETTER,
       docSummary: 'aaa',
@@ -1317,7 +1556,7 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['package:test/test.dart::A'],
@@ -1336,7 +1575,7 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.CLASS,
       relevanceTags: ['package:test/test.dart::A'],
@@ -1361,9 +1600,15 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1382,8 +1627,12 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1402,10 +1651,12 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.enum_('A'),
-      _ExpectedDeclaration.enumConstant('a', 'A'),
-      _ExpectedDeclaration.enum_('B'),
-      _ExpectedDeclaration.enumConstant('b', 'B'),
+      _ExpectedDeclaration.enum_('A', [
+        _ExpectedDeclaration.enumConstant('a'),
+      ]),
+      _ExpectedDeclaration.enum_('B', [
+        _ExpectedDeclaration.enumConstant('b'),
+      ]),
     ]);
   }
 
@@ -1422,7 +1673,7 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.CLASS,
       locationOffset: code.indexOf('A {}'),
@@ -1432,7 +1683,7 @@
       relevanceTags: ['package:test/test.dart::A'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'B'),
       'B',
       DeclarationKind.CLASS,
       locationOffset: code.indexOf('B {}'),
@@ -1462,20 +1713,20 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'A'),
       'A',
       DeclarationKind.MIXIN,
       relevanceTags: ['package:test/test.dart::A'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'B'),
       'B',
       DeclarationKind.MIXIN,
       isDeprecated: true,
       relevanceTags: ['package:test/test.dart::B'],
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'C'),
       'C',
       DeclarationKind.MIXIN,
       docSummary: 'aaa',
@@ -1502,7 +1753,7 @@
 
     var library = _getLibrary('package:test/test.dart');
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'a'),
       'a',
       DeclarationKind.SETTER,
       parameters: '(int value)',
@@ -1511,7 +1762,7 @@
       requiredParameterCount: 1,
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'b'),
       'b',
       DeclarationKind.SETTER,
       isDeprecated: true,
@@ -1521,7 +1772,7 @@
       requiredParameterCount: 1,
     );
     _assertDeclaration(
-      library,
+      _getDeclaration(library.declarations, 'c'),
       'c',
       DeclarationKind.SETTER,
       docSummary: 'aaa',
@@ -1554,18 +1805,43 @@
     await _doAllTrackerWork();
 
     var library = _getLibrary('package:test/test.dart');
-    _assertDeclaration(library, 'a', DeclarationKind.VARIABLE,
-        returnType: 'int');
-    _assertDeclaration(library, 'b', DeclarationKind.VARIABLE,
-        isDeprecated: true, returnType: 'int');
-    _assertDeclaration(library, 'c', DeclarationKind.VARIABLE,
-        docSummary: 'aaa', docComplete: 'aaa\n\nbbb bbb', returnType: 'int');
-    _assertDeclaration(library, 'd', DeclarationKind.VARIABLE,
-        isConst: true, relevanceTags: ['dart:core::int'], returnType: '');
-    _assertDeclaration(library, 'e', DeclarationKind.VARIABLE,
-        isFinal: true,
-        relevanceTags: ['dart:core::double'],
-        returnType: 'double');
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'a'),
+      'a',
+      DeclarationKind.VARIABLE,
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'b'),
+      'b',
+      DeclarationKind.VARIABLE,
+      isDeprecated: true,
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'c'),
+      'c',
+      DeclarationKind.VARIABLE,
+      docSummary: 'aaa',
+      docComplete: 'aaa\n\nbbb bbb',
+      returnType: 'int',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'd'),
+      'd',
+      DeclarationKind.VARIABLE,
+      isConst: true,
+      relevanceTags: ['dart:core::int'],
+      returnType: '',
+    );
+    _assertDeclaration(
+      _getDeclaration(library.declarations, 'e'),
+      'e',
+      DeclarationKind.VARIABLE,
+      isFinal: true,
+      relevanceTags: ['dart:core::double'],
+      returnType: 'double',
+    );
   }
 }
 
@@ -1585,9 +1861,15 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('C'),
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1605,8 +1887,12 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('D'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('D', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1622,8 +1908,9 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.enum_('E1'),
-      _ExpectedDeclaration.enumConstant('a', 'E1'),
+      _ExpectedDeclaration.enum_('E1', [
+        _ExpectedDeclaration.enumConstant('a'),
+      ]),
     ]);
   }
 
@@ -1645,19 +1932,33 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1670,12 +1971,14 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.enum_('E1'),
-      _ExpectedDeclaration.enumConstant('a', 'E1'),
-      _ExpectedDeclaration.enumConstant('b', 'E1'),
-      _ExpectedDeclaration.enum_('E2'),
-      _ExpectedDeclaration.enumConstant('a', 'E2'),
-      _ExpectedDeclaration.enumConstant('b', 'E2'),
+      _ExpectedDeclaration.enum_('E1', [
+        _ExpectedDeclaration.enumConstant('a'),
+        _ExpectedDeclaration.enumConstant('b'),
+      ]),
+      _ExpectedDeclaration.enum_('E2', [
+        _ExpectedDeclaration.enumConstant('a'),
+        _ExpectedDeclaration.enumConstant('b'),
+      ]),
     ]);
   }
 
@@ -1688,7 +1991,9 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1709,18 +2014,30 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:test/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     _assertHasLibrary('package:test/b.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 
@@ -1738,7 +2055,9 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
       _ExpectedDeclaration.mixin('B'),
     ]);
   }
@@ -1756,9 +2075,15 @@
 
     await _doAllTrackerWork();
     _assertHasLibrary('package:test/test.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
-      _ExpectedDeclaration.class_('B'),
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
   }
 }
@@ -1816,28 +2141,38 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:aaa/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:aaa/src/a2.dart');
 
     _assertHasLibrary('package:bbb/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:bbb/src/b2.dart');
 
     _assertHasLibrary('package:material_button/button.dart', declarations: [
-      _ExpectedDeclaration.class_('MaterialButton'),
+      _ExpectedDeclaration.class_('MaterialButton', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary(
       toUriStr('/home/material_button/test/button_test.dart'),
       declarations: [
-        _ExpectedDeclaration.class_('MaterialButtonTest'),
+        _ExpectedDeclaration.class_('MaterialButtonTest', [
+          _ExpectedDeclaration.constructor(''),
+        ]),
       ],
     );
     _assertHasLibrary(
       'package:material_button_testing/material_button_po.dart',
       declarations: [
-        _ExpectedDeclaration.class_('MaterialButtonPO'),
+        _ExpectedDeclaration.class_('MaterialButtonPO', [
+          _ExpectedDeclaration.constructor(''),
+        ]),
       ],
     );
 
@@ -2005,29 +2340,41 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:aaa/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:aaa/src/a2.dart');
 
     _assertHasLibrary('package:bbb/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:bbb/src/b2.dart');
 
     _assertHasLibrary('package:ccc/c.dart', declarations: [
-      _ExpectedDeclaration.class_('C'),
+      _ExpectedDeclaration.class_('C', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:ccc/src/c2.dart');
 
     _assertHasLibrary('package:test/t.dart', declarations: [
-      _ExpectedDeclaration.class_('T'),
+      _ExpectedDeclaration.class_('T', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/src/t2.dart', declarations: [
-      _ExpectedDeclaration.class_('T2'),
+      _ExpectedDeclaration.class_('T2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     _assertHasLibrary('package:basic/s.dart', declarations: [
-      _ExpectedDeclaration.class_('S'),
+      _ExpectedDeclaration.class_('S', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     {
@@ -2180,23 +2527,35 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary('package:aaa/a.dart', declarations: [
-      _ExpectedDeclaration.class_('A1'),
-      _ExpectedDeclaration.class_('A2'),
+      _ExpectedDeclaration.class_('A1', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
+      _ExpectedDeclaration.class_('A2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary('package:aaa/src/a2.dart');
     _assertHasLibrary('package:bbb/b.dart', declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/t.dart', declarations: [
-      _ExpectedDeclaration.class_('T'),
+      _ExpectedDeclaration.class_('T', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary('package:test/src/t2.dart', declarations: [
-      _ExpectedDeclaration.class_('T2'),
+      _ExpectedDeclaration.class_('T2', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary(
       toUriStr('/home/test/test/t3.dart'),
       declarations: [
-        _ExpectedDeclaration.class_('T3'),
+        _ExpectedDeclaration.class_('T3', [
+          _ExpectedDeclaration.constructor(''),
+        ]),
       ],
     );
 
@@ -2272,7 +2631,9 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary(aUri, declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasNoLibrary(bUri);
 
@@ -2293,10 +2654,14 @@
     await _doAllTrackerWork();
 
     _assertHasLibrary(aUri, declarations: [
-      _ExpectedDeclaration.class_('A'),
+      _ExpectedDeclaration.class_('A', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
     _assertHasLibrary(bUri, declarations: [
-      _ExpectedDeclaration.class_('B'),
+      _ExpectedDeclaration.class_('B', [
+        _ExpectedDeclaration.constructor(''),
+      ]),
     ]);
 
     // The package can see package:bbb, but not package:aaa
@@ -2344,7 +2709,7 @@
   }
 
   void _assertDeclaration(
-    Library library,
+    Declaration declaration,
     String name,
     DeclarationKind kind, {
     String defaultArgumentListString,
@@ -2359,7 +2724,6 @@
     String locationPath,
     int locationStartColumn,
     int locationStartLine,
-    String name2,
     String parameters,
     List<String> parameterNames,
     List<String> parameterTypes,
@@ -2368,7 +2732,6 @@
     String returnType,
     String typeParameters,
   }) {
-    var declaration = _getDeclaration(library, name, name2);
     expect(declaration.defaultArgumentListString, defaultArgumentListString);
     expect(
       declaration.defaultArgumentListTextRanges,
@@ -2377,7 +2740,6 @@
     expect(declaration.docComplete, docComplete);
     expect(declaration.docSummary, docSummary);
     expect(declaration.name, name);
-    expect(declaration.name2, name2);
     expect(declaration.kind, kind);
     expect(declaration.isAbstract, isAbstract);
     expect(declaration.isConst, isConst);
@@ -2398,16 +2760,20 @@
     }
   }
 
-  void _assertHasDeclaration(Library library, _ExpectedDeclaration expected) {
-    expect(
-      library.declarations,
-      contains(predicate((Declaration d) {
-        return d.name == expected.name &&
-            d.name2 == expected.name2 &&
-            d.kind == expected.kind;
-      })),
-      reason: '$expected',
-    );
+  void _assertHasDeclaration(
+      List<Declaration> declarations, _ExpectedDeclaration expected) {
+    var matching = declarations.where((d) {
+      return d.name == expected.name && d.kind == expected.kind;
+    }).toList();
+    if (matching.length != 1) {
+      fail('Expected $expected in\n${declarations.join('\n')}');
+    }
+
+    var actual = matching.single;
+    expect(actual.children, hasLength(expected.children.length));
+    for (var expectedChild in expected.children) {
+      _assertHasDeclaration(actual.children, expectedChild);
+    }
   }
 
   /// Assert that the current state has the library with the given [uri].
@@ -2421,7 +2787,7 @@
     if (declarations != null) {
       expect(library.declarations, hasLength(declarations.length));
       for (var expected in declarations) {
-        _assertHasDeclaration(library, expected);
+        _assertHasDeclaration(library.declarations, expected);
       }
     }
   }
@@ -2430,6 +2796,13 @@
     expect(uriToLibrary, isNot(contains(uri)));
   }
 
+  void _assertNoDeclaration(Library library, String name) {
+    expect(
+      library.declarations.where((declaration) => declaration.name == name),
+      isEmpty,
+    );
+  }
+
   void _createTracker() {
     uriToLibrary.clear();
 
@@ -2456,9 +2829,8 @@
     await pumpEventQueue();
   }
 
-  Declaration _getDeclaration(Library library, String name, String name2) {
-    return library.declarations.singleWhere((declaration) =>
-        declaration.name == name && declaration.name2 == name2);
+  Declaration _getDeclaration(List<Declaration> declarations, String name) {
+    return declarations.singleWhere((declaration) => declaration.name == name);
   }
 
   Library _getLibrary(String uriStr) {
@@ -2471,40 +2843,38 @@
 class _ExpectedDeclaration {
   final DeclarationKind kind;
   final String name;
-  final String name2;
+  final List<_ExpectedDeclaration> children;
 
-  _ExpectedDeclaration(this.kind, this.name, this.name2);
+  _ExpectedDeclaration(this.kind, this.name, {this.children: const []});
 
-  _ExpectedDeclaration.class_(String name)
-      : this(DeclarationKind.CLASS, name, null);
+  _ExpectedDeclaration.class_(String name, List<_ExpectedDeclaration> children)
+      : this(DeclarationKind.CLASS, name, children: children);
 
   _ExpectedDeclaration.classTypeAlias(String name)
-      : this(DeclarationKind.CLASS_TYPE_ALIAS, name, null);
+      : this(DeclarationKind.CLASS_TYPE_ALIAS, name);
 
-  _ExpectedDeclaration.enum_(String name)
-      : this(DeclarationKind.ENUM, name, null);
+  _ExpectedDeclaration.constructor(String name)
+      : this(DeclarationKind.CONSTRUCTOR, name);
 
-  _ExpectedDeclaration.enumConstant(String name, String name2)
-      : this(DeclarationKind.ENUM_CONSTANT, name, name2);
+  _ExpectedDeclaration.enum_(String name, List<_ExpectedDeclaration> children)
+      : this(DeclarationKind.ENUM, name, children: children);
+
+  _ExpectedDeclaration.enumConstant(String name)
+      : this(DeclarationKind.ENUM_CONSTANT, name);
 
   _ExpectedDeclaration.function(String name)
-      : this(DeclarationKind.FUNCTION, name, null);
+      : this(DeclarationKind.FUNCTION, name);
 
   _ExpectedDeclaration.functionTypeAlias(String name)
-      : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name, null);
+      : this(DeclarationKind.FUNCTION_TYPE_ALIAS, name);
 
-  _ExpectedDeclaration.mixin(String name)
-      : this(DeclarationKind.MIXIN, name, null);
+  _ExpectedDeclaration.mixin(String name) : this(DeclarationKind.MIXIN, name);
 
   _ExpectedDeclaration.variable(String name)
-      : this(DeclarationKind.VARIABLE, name, null);
+      : this(DeclarationKind.VARIABLE, name);
 
   @override
   String toString() {
-    if (name2 != null) {
-      return '($kind, $name, $name2)';
-    } else {
-      return '($kind, $name)';
-    }
+    return '($kind, $name)';
   }
 }
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index ca7d14f..61c752d 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -551,6 +551,9 @@
         buffer.write(e.keyword.lexeme);
         buffer.write(' ');
       }
+      if (withTypes && e.constructorName.type.typeArguments == null) {
+        writeInterfaceTypeArgsComment(e);
+      }
       writeNode(e.constructorName);
       writeList('(', ')', e.argumentList.arguments, ', ', writeNode,
           includeEmpty: true);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 2cf841b..16c94d1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -10,6 +10,7 @@
 import 'package:analyzer/src/generated/type_system.dart';
 import 'package:analyzer/src/summary/summary_sdk.dart';
 import 'package:analyzer/src/summary2/link.dart';
+import 'package:analyzer/src/summary2/linked_bundle_context.dart';
 import 'package:analyzer/src/summary2/linked_element_factory.dart';
 import 'package:analyzer/src/summary2/reference.dart';
 import 'package:test/test.dart';
@@ -175,8 +176,12 @@
       null,
       rootReference,
     );
-    elementFactory.addBundle(dartCoreResult.bundle);
-    elementFactory.addBundle(linkResult.bundle);
+    elementFactory.addBundle(
+      LinkedBundleContext(elementFactory, dartCoreResult.bundle),
+    );
+    elementFactory.addBundle(
+      LinkedBundleContext(elementFactory, linkResult.bundle),
+    );
 
     var dartCore = elementFactory.libraryOfUri('dart:core');
     var dartAsync = elementFactory.libraryOfUri('dart:async');
@@ -191,6 +196,74 @@
 
   @override
   @failingTest
+  test_class_alias_notSimplyBounded_self() async {
+    await super.test_class_alias_notSimplyBounded_self();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_circularity_via_typedef() async {
+    await super.test_class_notSimplyBounded_circularity_via_typedef();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_complex_by_cycle() async {
+    await super.test_class_notSimplyBounded_complex_by_cycle();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
+    await super.test_class_notSimplyBounded_complex_by_reference_to_cycle();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_complex_by_use_of_parameter() async {
+    await super.test_class_notSimplyBounded_complex_by_use_of_parameter();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_dependency_with_type_params() async {
+    await super.test_class_notSimplyBounded_dependency_with_type_params();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async {
+    await super
+        .test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async {
+    await super
+        .test_class_notSimplyBounded_function_typed_bound_complex_via_return_type();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_refers_to_circular_typedef() async {
+    await super.test_class_notSimplyBounded_refers_to_circular_typedef();
+  }
+
+  @override
+  @failingTest
+  test_class_notSimplyBounded_self() async {
+    await super.test_class_notSimplyBounded_self();
+  }
+
+  @override
+  @failingTest
+  test_class_type_parameters_bound() async {
+    await super.test_class_type_parameters_bound();
+  }
+
+  @override
+  @failingTest
   test_class_type_parameters_f_bound_complex() async {
     await super.test_class_type_parameters_f_bound_complex();
   }
@@ -209,6 +282,12 @@
 
   @override
   @failingTest
+  test_closure_in_variable_declaration_in_part() async {
+    await super.test_closure_in_variable_declaration_in_part();
+  }
+
+  @override
+  @failingTest
   test_const_constructor_inferred_args() async {
     await super.test_const_constructor_inferred_args();
   }
@@ -259,48 +338,193 @@
 
   @override
   @failingTest
+  test_constructor_initializers_assertInvocation() async {
+    await super.test_constructor_initializers_assertInvocation();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_assertInvocation_message() async {
+    await super.test_constructor_initializers_assertInvocation_message();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_field() async {
+    await super.test_constructor_initializers_field();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_field_notConst() async {
+    await super.test_constructor_initializers_field_notConst();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_field_withParameter() async {
+    await super.test_constructor_initializers_field_withParameter();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_superInvocation_named() async {
+    await super.test_constructor_initializers_superInvocation_named();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_superInvocation_named_underscore() async {
+    await super
+        .test_constructor_initializers_superInvocation_named_underscore();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_superInvocation_namedExpression() async {
+    await super.test_constructor_initializers_superInvocation_namedExpression();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_superInvocation_unnamed() async {
+    await super.test_constructor_initializers_superInvocation_unnamed();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_thisInvocation_named() async {
+    await super.test_constructor_initializers_thisInvocation_named();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_thisInvocation_namedExpression() async {
+    await super.test_constructor_initializers_thisInvocation_namedExpression();
+  }
+
+  @override
+  @failingTest
+  test_constructor_initializers_thisInvocation_unnamed() async {
+    await super.test_constructor_initializers_thisInvocation_unnamed();
+  }
+
+  @override
+  @failingTest
+  test_constructor_redirected_factory_named() async {
+    await super.test_constructor_redirected_factory_named();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_named_generic() async {
     await super.test_constructor_redirected_factory_named_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_factory_named_imported() async {
+    await super.test_constructor_redirected_factory_named_imported();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_named_imported_generic() async {
     await super.test_constructor_redirected_factory_named_imported_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_factory_named_prefixed() async {
+    await super.test_constructor_redirected_factory_named_prefixed();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_named_prefixed_generic() async {
     await super.test_constructor_redirected_factory_named_prefixed_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_factory_unnamed() async {
+    await super.test_constructor_redirected_factory_unnamed();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_unnamed_generic() async {
     await super.test_constructor_redirected_factory_unnamed_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_factory_unnamed_imported() async {
+    await super.test_constructor_redirected_factory_unnamed_imported();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_unnamed_imported_generic() async {
     await super.test_constructor_redirected_factory_unnamed_imported_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_factory_unnamed_prefixed() async {
+    await super.test_constructor_redirected_factory_unnamed_prefixed();
+  }
+
+  @override
+  @failingTest
   test_constructor_redirected_factory_unnamed_prefixed_generic() async {
     await super.test_constructor_redirected_factory_unnamed_prefixed_generic();
   }
 
   @override
   @failingTest
+  test_constructor_redirected_thisInvocation_named() async {
+    await super.test_constructor_redirected_thisInvocation_named();
+  }
+
+  @override
+  @failingTest
+  test_constructor_redirected_thisInvocation_named_generic() async {
+    await super.test_constructor_redirected_thisInvocation_named_generic();
+  }
+
+  @override
+  @failingTest
+  test_constructor_redirected_thisInvocation_unnamed() async {
+    await super.test_constructor_redirected_thisInvocation_unnamed();
+  }
+
+  @override
+  @failingTest
+  test_constructor_redirected_thisInvocation_unnamed_generic() async {
+    await super.test_constructor_redirected_thisInvocation_unnamed_generic();
+  }
+
+  @override
+  @failingTest
+  test_constructor_withCycles_const() async {
+    await super.test_constructor_withCycles_const();
+  }
+
+  @override
+  @failingTest
   test_defaultValue_genericFunction() async {
     await super.test_defaultValue_genericFunction();
   }
 
   @override
   @failingTest
+  test_defaultValue_refersToGenericClass() async {
+    await super.test_defaultValue_refersToGenericClass();
+  }
+
+  @override
+  @failingTest
   test_defaultValue_refersToGenericClass_constructor() async {
     await super.test_defaultValue_refersToGenericClass_constructor();
   }
@@ -337,6 +561,12 @@
 
   @override
   @failingTest
+  test_export_class_type_alias() async {
+    await super.test_export_class_type_alias();
+  }
+
+  @override
+  @failingTest
   test_export_configurations_useFirst() async {
     await super.test_export_configurations_useFirst();
   }
@@ -379,12 +609,24 @@
 
   @override
   @failingTest
+  test_futureOr_inferred() async {
+    await super.test_futureOr_inferred();
+  }
+
+  @override
+  @failingTest
   test_getter_inferred_type_nonStatic_implicit_return() async {
     await super.test_getter_inferred_type_nonStatic_implicit_return();
   }
 
   @override
   @failingTest
+  test_implicitConstructor_named_const() async {
+    await super.test_implicitConstructor_named_const();
+  }
+
+  @override
+  @failingTest
   test_import_configurations_useFirst() async {
     await super.test_import_configurations_useFirst();
   }
@@ -405,6 +647,12 @@
 
   @override
   @failingTest
+  test_infer_generic_typedef_complex() async {
+    await super.test_infer_generic_typedef_complex();
+  }
+
+  @override
+  @failingTest
   test_infer_generic_typedef_simple() async {
     await super.test_infer_generic_typedef_simple();
   }
@@ -435,6 +683,12 @@
 
   @override
   @failingTest
+  test_inferred_type_refers_to_function_typed_param_of_typedef() async {
+    await super.test_inferred_type_refers_to_function_typed_param_of_typedef();
+  }
+
+  @override
+  @failingTest
   test_inferred_type_refers_to_function_typed_parameter_type_generic_class() async {
     await super
         .test_inferred_type_refers_to_function_typed_parameter_type_generic_class();
@@ -456,6 +710,19 @@
 
   @override
   @failingTest
+  test_inferred_type_refers_to_nested_function_typed_param() async {
+    await super.test_inferred_type_refers_to_nested_function_typed_param();
+  }
+
+  @override
+  @failingTest
+  test_inferred_type_refers_to_nested_function_typed_param_named() async {
+    await super
+        .test_inferred_type_refers_to_nested_function_typed_param_named();
+  }
+
+  @override
+  @failingTest
   test_inferred_type_refers_to_setter_function_typed_parameter_type() async {
     await super
         .test_inferred_type_refers_to_setter_function_typed_parameter_type();
@@ -475,6 +742,47 @@
 
   @override
   @failingTest
+  test_initializer_executable_with_return_type_from_closure() async {
+    await super.test_initializer_executable_with_return_type_from_closure();
+  }
+
+  @override
+  @failingTest
+  test_initializer_executable_with_return_type_from_closure_await_dynamic() async {
+    await super
+        .test_initializer_executable_with_return_type_from_closure_await_dynamic();
+  }
+
+  @override
+  @failingTest
+  test_initializer_executable_with_return_type_from_closure_await_future3_int() async {
+    await super
+        .test_initializer_executable_with_return_type_from_closure_await_future3_int();
+  }
+
+  @override
+  @failingTest
+  test_initializer_executable_with_return_type_from_closure_await_future_int() async {
+    await super
+        .test_initializer_executable_with_return_type_from_closure_await_future_int();
+  }
+
+  @override
+  @failingTest
+  test_initializer_executable_with_return_type_from_closure_await_future_noArg() async {
+    await super
+        .test_initializer_executable_with_return_type_from_closure_await_future_noArg();
+  }
+
+  @override
+  @failingTest
+  test_initializer_executable_with_return_type_from_closure_field() async {
+    await super
+        .test_initializer_executable_with_return_type_from_closure_field();
+  }
+
+  @override
+  @failingTest
   test_instantiateToBounds_boundRefersToEarlierTypeArgument() async {
     await super.test_instantiateToBounds_boundRefersToEarlierTypeArgument();
   }
@@ -511,14 +819,14 @@
 
   @override
   @failingTest
-  test_invalid_setterParameter_fieldFormalParameter() async {
-    await super.test_invalid_setterParameter_fieldFormalParameter();
+  test_invalid_nameConflict_imported_exported() async {
+    await super.test_invalid_nameConflict_imported_exported();
   }
 
   @override
   @failingTest
-  test_invalid_setterParameter_fieldFormalParameter_self() async {
-    await super.test_invalid_setterParameter_fieldFormalParameter_self();
+  test_invalid_nameConflict_local() async {
+    await super.test_invalid_nameConflict_local();
   }
 
   @override
@@ -547,18 +855,6 @@
 
   @override
   @failingTest
-  test_metadata_importDirective() async {
-    await super.test_metadata_importDirective();
-  }
-
-  @override
-  @failingTest
-  test_metadata_partDirective() async {
-    await super.test_metadata_partDirective();
-  }
-
-  @override
-  @failingTest
   test_method_inferred_type_nonStatic_implicit_param() async {
     await super.test_method_inferred_type_nonStatic_implicit_param();
   }
@@ -579,6 +875,24 @@
 
   @override
   @failingTest
+  test_new_typedef_notSimplyBounded_self() async {
+    await super.test_new_typedef_notSimplyBounded_self();
+  }
+
+  @override
+  @failingTest
+  test_old_typedef_notSimplyBounded_self() async {
+    await super.test_old_typedef_notSimplyBounded_self();
+  }
+
+  @override
+  @failingTest
+  test_parameter_covariant() async {
+    await super.test_parameter_covariant();
+  }
+
+  @override
+  @failingTest
   test_parameter_covariant_inherited() async {
     await super.test_parameter_covariant_inherited();
   }
@@ -591,6 +905,12 @@
 
   @override
   @failingTest
+  test_setter_covariant() async {
+    await super.test_setter_covariant();
+  }
+
+  @override
+  @failingTest
   test_setter_inferred_type_nonStatic_implicit_param() async {
     await super.test_setter_inferred_type_nonStatic_implicit_param();
   }
@@ -603,6 +923,24 @@
 
   @override
   @failingTest
+  test_syntheticFunctionType_inGenericClass() async {
+    await super.test_syntheticFunctionType_inGenericClass();
+  }
+
+  @override
+  @failingTest
+  test_syntheticFunctionType_noArguments() async {
+    await super.test_syntheticFunctionType_noArguments();
+  }
+
+  @override
+  @failingTest
+  test_syntheticFunctionType_withArguments() async {
+    await super.test_syntheticFunctionType_withArguments();
+  }
+
+  @override
+  @failingTest
   test_type_inference_based_on_loadLibrary() async {
     await super.test_type_inference_based_on_loadLibrary();
   }
@@ -627,6 +965,18 @@
 
   @override
   @failingTest
+  test_type_inference_nested_function() async {
+    await super.test_type_inference_nested_function();
+  }
+
+  @override
+  @failingTest
+  test_type_inference_nested_function_with_parameter_types() async {
+    await super.test_type_inference_nested_function_with_parameter_types();
+  }
+
+  @override
+  @failingTest
   test_type_inference_of_closure_with_default_value() async {
     await super.test_type_inference_of_closure_with_default_value();
   }
@@ -645,6 +995,47 @@
 
   @override
   @failingTest
+  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
+    await super
+        .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included();
+  }
+
+  @override
+  @failingTest
+  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
+    await super
+        .test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted();
+  }
+
+  @override
+  @failingTest
+  test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
+    await super
+        .test_typedef_notSimplyBounded_dependency_via_param_type_old_style();
+  }
+
+  @override
+  @failingTest
+  test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
+    await super
+        .test_typedef_notSimplyBounded_dependency_via_return_type_new_style();
+  }
+
+  @override
+  @failingTest
+  test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
+    await super
+        .test_typedef_notSimplyBounded_dependency_via_return_type_old_style();
+  }
+
+  @override
+  @failingTest
+  test_typedef_type_parameters_bound() async {
+    await super.test_typedef_type_parameters_bound();
+  }
+
+  @override
+  @failingTest
   test_typedef_type_parameters_bound_recursive() async {
     await super.test_typedef_type_parameters_bound_recursive();
   }
@@ -675,6 +1066,12 @@
 
   @override
   @failingTest
+  test_unresolved_annotation_instanceCreation_argument_super() async {
+    await super.test_unresolved_annotation_instanceCreation_argument_super();
+  }
+
+  @override
+  @failingTest
   test_unresolved_export() async {
     await super.test_unresolved_export();
   }
@@ -687,6 +1084,12 @@
 
   @override
   @failingTest
+  test_unused_type_parameter() async {
+    await super.test_unused_type_parameter();
+  }
+
+  @override
+  @failingTest
   test_variable_propagatedType_final_dep_inLib() async {
     await super.test_variable_propagatedType_final_dep_inLib();
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
index de84750..40b6c41 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast_test.dart
@@ -40,6 +40,12 @@
 
   @override
   @failingTest
+  test_defaultValue_refersToGenericClass() async {
+    await super.test_defaultValue_refersToGenericClass();
+  }
+
+  @override
+  @failingTest
   test_syntheticFunctionType_inGenericClass() async {
     await super.test_syntheticFunctionType_inGenericClass();
   }
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index b8f7ab6..77b78c1 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -345,6 +345,61 @@
 ''');
   }
 
+  test_class_alias_notSimplyBounded_self() async {
+    var library = await checkLibrary('''
+class C<T extends C> = D with E;
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class alias C<T extends C<dynamic>> extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_notSimplyBounded_simple_no_type_parameter_bound() async {
+    // If no bounds are specified, then the class is simply bounded by syntax
+    // alone, so there is no reason to assign it a slot.
+    var library = await checkLibrary('''
+class C<T> = D with E;
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+class alias C<T> extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
+  test_class_alias_notSimplyBounded_simple_non_generic() async {
+    // If no type parameters are specified, then the class is simply bounded, so
+    // there is no reason to assign it a slot.
+    var library = await checkLibrary('''
+class C = D with E;
+class D {}
+class E {}
+''');
+    checkElementText(library, r'''
+class alias C extends D with E {
+  synthetic C() = D;
+}
+class D {
+}
+class E {
+}
+''');
+  }
+
   test_class_alias_with_forwarding_constructors() async {
     addLibrarySource('/a.dart', '''
 class Base {
@@ -1185,6 +1240,180 @@
 ''');
   }
 
+  test_class_notSimplyBounded_circularity_via_typedef() async {
+    // C's type parameter T is not simply bounded because its bound, F, expands
+    // to `dynamic F(C)`, which refers to C.
+    var library = await checkLibrary('''
+class C<T extends F> {}
+typedef F(C value);
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function(C<dynamic> value);
+notSimplyBounded class C<T extends (C<dynamic>) → dynamic> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_circularity_with_type_params() async {
+    // C's type parameter T is simply bounded because even though it refers to
+    // C, it specifies a bound.
+    var library = await checkLibrary('''
+class C<T extends C<dynamic>> {}
+''');
+    checkElementText(library, r'''
+class C<T extends C<dynamic>> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_complex_by_cycle() async {
+    var library = await checkLibrary('''
+class C<T extends D> {}
+class D<T extends C> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends D<dynamic>> {
+}
+notSimplyBounded class D<T extends C<D<dynamic>>> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_complex_by_reference_to_cycle() async {
+    var library = await checkLibrary('''
+class C<T extends D> {}
+class D<T extends D> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends D<dynamic>> {
+}
+notSimplyBounded class D<T extends D<dynamic>> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_complex_by_use_of_parameter() async {
+    var library = await checkLibrary('''
+class C<T extends D<T>> {}
+class D<T> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends D<T>> {
+}
+class D<T> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_dependency_with_type_params() async {
+    // C's type parameter T is simply bounded because even though it refers to
+    // non-simply-bounded type D, it specifies a bound.
+    var library = await checkLibrary('''
+class C<T extends D<dynamic>> {}
+class D<T extends D<T>> {}
+''');
+    checkElementText(library, r'''
+class C<T extends D<dynamic>> {
+}
+notSimplyBounded class D<T extends D<T>> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_function_typed_bound_complex_via_parameter_type() async {
+    var library = await checkLibrary('''
+class C<T extends void Function(T)> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends (T) → void> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_function_typed_bound_complex_via_return_type() async {
+    var library = await checkLibrary('''
+class C<T extends T Function()> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends () → T> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_function_typed_bound_simple() async {
+    var library = await checkLibrary('''
+class C<T extends void Function()> {}
+''');
+    checkElementText(library, r'''
+class C<T extends () → void> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_refers_to_circular_typedef() async {
+    // C's type parameter T has a bound of F, which is a circular typedef.  This
+    // is illegal in Dart, but we need to make sure it doesn't lead to a crash
+    // or infinite loop.
+    var library = await checkLibrary('''
+class C<T extends F> {}
+typedef F(G value);
+typedef G(F value);
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = dynamic Function(((...) → dynamic) → dynamic value);
+notSimplyBounded typedef G = dynamic Function(((...) → dynamic) → dynamic value);
+notSimplyBounded class C<T extends ((...) → dynamic) → dynamic> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_self() async {
+    var library = await checkLibrary('''
+class C<T extends C> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded class C<T extends C<dynamic>> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_simple_because_non_generic() async {
+    // If no type parameters are specified, then the class is simply bounded, so
+    // there is no reason to assign it a slot.
+    var library = await checkLibrary('''
+class C {}
+''');
+    checkElementText(library, r'''
+class C {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_simple_by_lack_of_cycles() async {
+    var library = await checkLibrary('''
+class C<T extends D> {}
+class D<T> {}
+''');
+    checkElementText(library, r'''
+class C<T extends D<dynamic>> {
+}
+class D<T> {
+}
+''');
+  }
+
+  test_class_notSimplyBounded_simple_by_syntax() async {
+    // If no bounds are specified, then the class is simply bounded by syntax
+    // alone, so there is no reason to assign it a slot.
+    var library = await checkLibrary('''
+class C<T> {}
+''');
+    checkElementText(library, r'''
+class C<T> {
+}
+''');
+  }
+
   test_class_setter_abstract() async {
     var library =
         await checkLibrary('abstract class C { void set x(int value); }');
@@ -4527,6 +4756,29 @@
 ''');
   }
 
+  test_defaultValue_refersToGenericClass() async {
+    var library = await checkLibrary('''
+class B<T1, T2> {
+  const B();
+}
+class C {
+  void foo([B<int, double> b = const B()]) {}
+}
+''');
+    checkElementText(
+        library,
+        r'''
+class B<T1, T2> {
+  const B();
+}
+class C {
+  void foo([B<int, double> b = const /*typeArgs=int,double*/
+        B/*location: test.dart;B*/()]) {}
+}
+''',
+        withTypes: true);
+  }
+
   test_defaultValue_refersToGenericClass_constructor() async {
     var library = await checkLibrary('''
 class B<T> {
@@ -4536,7 +4788,21 @@
   const C([B<T> b = const B()]);
 }
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+class B<T> {
+  const B();
+}
+class C<T> {
+  const C([B<T> b = const /*typeArgs=Null*/
+        B/*location: test.dart;B*/()]);
+}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 class B<T> {
   const B();
 }
@@ -4545,6 +4811,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''');
+    }
   }
 
   test_defaultValue_refersToGenericClass_constructor2() async {
@@ -4557,7 +4824,23 @@
   const C([A<T> a = const B()]);
 }
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+abstract class A<T> {
+}
+class B<T> implements A<T> {
+  const B();
+}
+class C<T> implements A<Iterable<T>> {
+  const C([A<T> a = const /*typeArgs=Null*/
+        B/*location: test.dart;B*/()]);
+}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 abstract class A<T> {
 }
 class B<T> implements A<T> {
@@ -4568,6 +4851,7 @@
         B/*location: test.dart;B*/()]);
 }
 ''');
+    }
   }
 
   test_defaultValue_refersToGenericClass_functionG() async {
@@ -4577,13 +4861,26 @@
 }
 void foo<T>([B<T> b = const B()]) {}
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+class B<T> {
+  const B();
+}
+void foo<T>([B<T> b = const /*typeArgs=Null*/
+        B/*location: test.dart;B*/()]) {}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 class B<T> {
   const B();
 }
 void foo<T>([B<T> b = const
         B/*location: test.dart;B*/()]) {}
 ''');
+    }
   }
 
   test_defaultValue_refersToGenericClass_methodG() async {
@@ -4595,7 +4892,21 @@
   void foo<T>([B<T> b = const B()]) {}
 }
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+class B<T> {
+  const B();
+}
+class C {
+  void foo<T>([B<T> b = const /*typeArgs=Null*/
+        B/*location: test.dart;B*/()]) {}
+}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 class B<T> {
   const B();
 }
@@ -4604,6 +4915,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''');
+    }
   }
 
   test_defaultValue_refersToGenericClass_methodG_classG() async {
@@ -4615,7 +4927,21 @@
   void foo<E2>([B<E1, E2> b = const B()]) {}
 }
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+class B<T1, T2> {
+  const B();
+}
+class C<E1> {
+  void foo<E2>([B<E1, E2> b = const /*typeArgs=Null,Null*/
+        B/*location: test.dart;B*/()]) {}
+}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 class B<T1, T2> {
   const B();
 }
@@ -4624,6 +4950,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''');
+    }
   }
 
   test_defaultValue_refersToGenericClass_methodNG() async {
@@ -4635,7 +4962,21 @@
   void foo([B<T> b = const B()]) {}
 }
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(
+          library,
+          r'''
+class B<T> {
+  const B();
+}
+class C<T> {
+  void foo([B<T> b = const /*typeArgs=Null*/
+        B/*location: test.dart;B*/()]) {}
+}
+''',
+          withTypes: true);
+    } else {
+      checkElementText(library, r'''
 class B<T> {
   const B();
 }
@@ -4644,6 +4985,7 @@
         B/*location: test.dart;B*/()]) {}
 }
 ''');
+    }
   }
 
   test_enum_documented() async {
@@ -6616,11 +6958,19 @@
 import 'c.dart';
 foo([p = V]) {}
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(library, r'''
+import 'c.dart';
+dynamic foo([dynamic p =
+        V/*location: a.dart;V*/]) {}
+''');
+    } else {
+      checkElementText(library, r'''
 import 'c.dart';
 dynamic foo([dynamic p =
         V/*location: null*/]) {}
 ''');
+    }
   }
 
   test_invalid_nameConflict_local() async {
@@ -6629,12 +6979,21 @@
 V() {}
 var V;
 ''');
-    checkElementText(library, r'''
+    if (isAstBasedSummary) {
+      checkElementText(library, r'''
+dynamic V;
+dynamic foo([dynamic p =
+        V/*location: test.dart;V?*/]) {}
+dynamic V() {}
+''');
+    } else {
+      checkElementText(library, r'''
 dynamic V;
 dynamic foo([dynamic p =
         V/*location: null*/]) {}
 dynamic V() {}
 ''');
+    }
   }
 
   test_invalid_setterParameter_fieldFormalParameter() async {
@@ -7824,6 +8183,58 @@
 ''');
   }
 
+  test_new_typedef_notSimplyBounded_self() async {
+    var library = await checkLibrary('''
+typedef F<T extends F> = void Function();
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F<T extends () → void> = void Function();
+''');
+  }
+
+  test_new_typedef_notSimplyBounded_simple_no_bounds() async {
+    var library = await checkLibrary('''
+typedef F<T> = void Function();
+''');
+    checkElementText(library, r'''
+typedef F<T> = void Function();
+''');
+  }
+
+  test_new_typedef_notSimplyBounded_simple_non_generic() async {
+    var library = await checkLibrary('''
+typedef F = void Function();
+''');
+    checkElementText(library, r'''
+typedef F = void Function();
+''');
+  }
+
+  test_old_typedef_notSimplyBounded_self() async {
+    var library = await checkLibrary('''
+typedef void F<T extends F>();
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F<T extends () → void> = void Function();
+''');
+  }
+
+  test_old_typedef_notSimplyBounded_simple_because_non_generic() async {
+    var library = await checkLibrary('''
+typedef void F();
+''');
+    checkElementText(library, r'''
+typedef F = void Function();
+''');
+  }
+
+  test_old_typedef_notSimplyBounded_simple_no_bounds() async {
+    var library = await checkLibrary('typedef void F<T>();');
+    checkElementText(library, r'''
+typedef F<T> = void Function();
+''');
+  }
+
   test_operator() async {
     var library =
         await checkLibrary('class C { C operator+(C other) => null; }');
@@ -8814,6 +9225,76 @@
 ''');
   }
 
+  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_included() async {
+    // F is considered "not simply bounded" because it expands to a type that
+    // refers to C, which is not simply bounded.
+    var library = await checkLibrary('''
+typedef F = void Function(C c);
+class C<T extends C<T>> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+  }
+
+  test_typedef_notSimplyBounded_dependency_via_param_type_new_style_name_omitted() async {
+    // F is considered "not simply bounded" because it expands to a type that
+    // refers to C, which is not simply bounded.
+    var library = await checkLibrary('''
+typedef F = void Function(C);
+class C<T extends C<T>> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<C<dynamic>> );
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+  }
+
+  test_typedef_notSimplyBounded_dependency_via_param_type_old_style() async {
+    // F is considered "not simply bounded" because it expands to a type that
+    // refers to C, which is not simply bounded.
+    var library = await checkLibrary('''
+typedef void F(C c);
+class C<T extends C<T>> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = void Function(C<C<dynamic>> c);
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+  }
+
+  test_typedef_notSimplyBounded_dependency_via_return_type_new_style() async {
+    // F is considered "not simply bounded" because it expands to a type that
+    // refers to C, which is not simply bounded.
+    var library = await checkLibrary('''
+typedef F = C Function();
+class C<T extends C<T>> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = C<C<dynamic>> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+  }
+
+  test_typedef_notSimplyBounded_dependency_via_return_type_old_style() async {
+    // F is considered "not simply bounded" because it expands to a type that
+    // refers to C, which is not simply bounded.
+    var library = await checkLibrary('''
+typedef C F();
+class C<T extends C<T>> {}
+''');
+    checkElementText(library, r'''
+notSimplyBounded typedef F = C<C<dynamic>> Function();
+notSimplyBounded class C<T extends C<T>> {
+}
+''');
+  }
+
   test_typedef_parameter_parameters() async {
     var library = await checkLibrary('typedef F(g(x, y));');
     checkElementText(library, r'''
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 b4d8961..77990a8 100644
--- a/pkg/analyzer/test/src/summary/top_level_inference_test.dart
+++ b/pkg/analyzer/test/src/summary/top_level_inference_test.dart
@@ -33,9 +33,6 @@
 
 @reflectiveTest
 class TopLevelInferenceErrorsTest extends AbstractStrongTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-
   test_initializer_additive() async {
     await _assertErrorOnlyLeft(['+', '-']);
   }
diff --git a/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart b/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart
index efe0133..e79a3a7 100644
--- a/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_binary_writer_integration_test.dart
@@ -6,6 +6,7 @@
 
 import 'package:analyzer/file_system/physical_file_system.dart';
 import 'package:analyzer/source/line_info.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary/idl.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/ast_binary_writer.dart';
@@ -15,7 +16,6 @@
 import 'package:analyzer/src/summary2/linked_unit_context.dart';
 import 'package:analyzer/src/summary2/linking_bundle_context.dart';
 import 'package:analyzer/src/summary2/reference.dart';
-import 'package:analyzer/src/summary2/tokens_context.dart';
 import 'package:analyzer/src/summary2/tokens_writer.dart';
 import 'package:front_end/src/testing/package_root.dart' as package_root;
 import 'package:test/test.dart';
@@ -41,9 +41,7 @@
   code = code.replaceAll('\r', '\n');
 
   LineInfo lineInfo;
-  LinkedNodeReferences nodeReferences;
-  UnlinkedTokens unlinkedTokens;
-  LinkedNode unitLinkedNode;
+  LinkedNodeUnit linkedNodeUnit;
   {
     var path = base.newFile('/home/test/lib/test.dart', content: code).path;
 
@@ -73,22 +71,31 @@
 
     var linkingBundleContext = LinkingBundleContext(dynamicRef);
     var writer = new AstBinaryWriter(linkingBundleContext, tokensContext);
-    unitLinkedNode = writer.writeNode(originalUnit);
+    var unitLinkedNode = writer.writeNode(originalUnit);
 
-    unlinkedTokens = tokensResult.tokens;
-    nodeReferences = linkingBundleContext.referencesBuilder;
+    linkedNodeUnit = LinkedNodeUnitBuilder(
+      node: unitLinkedNode,
+      tokens: tokensResult.tokens,
+    );
   }
 
   var rootReference = Reference.root();
   var bundleContext = LinkedBundleContext(
     LinkedElementFactory(null, null, rootReference),
-    nodeReferences,
+    LinkedNodeBundleBuilder(
+      references: LinkedNodeReferencesBuilder(name: ['']),
+    ),
   );
-  var tokensContext = TokensContext(unlinkedTokens);
-  var unitContext = LinkedUnitContext(bundleContext, tokensContext);
+  var unitContext = LinkedUnitContext(
+    bundleContext,
+    null,
+    0,
+    null,
+    linkedNodeUnit,
+  );
 
   var reader = AstBinaryReader(unitContext);
-  var deserializedUnit = reader.readNode(unitLinkedNode);
+  var deserializedUnit = reader.readNode(linkedNodeUnit.node);
 
   var buffer = StringBuffer();
   deserializedUnit.accept(
diff --git a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart b/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
index 53f650d..e23f4c1 100644
--- a/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
+++ b/pkg/analyzer/test/src/summary2/ast_binary_writer_test.dart
@@ -4,6 +4,7 @@
 
 import 'package:analyzer/src/dart/analysis/experiments.dart';
 import 'package:analyzer/src/generated/engine.dart';
+import 'package:analyzer/src/summary/format.dart';
 import 'package:analyzer/src/summary2/ast_binary_reader.dart';
 import 'package:analyzer/src/summary2/ast_binary_writer.dart';
 import 'package:analyzer/src/summary2/linked_bundle_context.dart';
@@ -142,9 +143,20 @@
 
     var bundleContext = LinkedBundleContext(
       LinkedElementFactory(null, null, rootReference),
-      linkingBundleContext.referencesBuilder,
+      LinkedNodeBundleBuilder(
+        references: LinkedNodeReferencesBuilder(name: ['']),
+      ),
     );
-    var unitContext = LinkedUnitContext(bundleContext, tokensContext);
+    var unitContext = LinkedUnitContext(
+      bundleContext,
+      null,
+      0,
+      null,
+      LinkedNodeUnitBuilder(
+        node: builder,
+        tokens: tokensResult.tokens,
+      ),
+    );
 
     var reader = AstBinaryReader(unitContext);
     var deserializedUnit = reader.readNode(builder);
diff --git a/pkg/analyzer/test/src/task/options_test.dart b/pkg/analyzer/test/src/task/options_test.dart
index 93af17b..5aef022 100644
--- a/pkg/analyzer/test/src/task/options_test.dart
+++ b/pkg/analyzer/test/src/task/options_test.dart
@@ -125,6 +125,24 @@
     List<String> names = analysisOptions.enabledPluginNames;
     expect(names, ['angular2']);
   }
+
+  test_configure_chromeos_checks() {
+    configureContext('''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks
+''');
+    expect(true, analysisOptions.chromeOsManifestChecks);
+  }
+
+  test_configure_chromeos_checks_map() {
+    configureContext('''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks : true
+''');
+    expect(true, analysisOptions.chromeOsManifestChecks);
+  }
 }
 
 @reflectiveTest
@@ -463,6 +481,22 @@
     ''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
   }
 
+  test_chromeos_manifest_checks() {
+    validate('''
+analyzer:
+  optional-checks:
+    chrome-os-manifest-checks
+''', []);
+  }
+
+  test_chromeos_manifest_checks_invalid() {
+    validate('''
+analyzer:
+  optional-checks:
+    chromeos-manifest
+''', [AnalysisOptionsWarningCode.UNSUPPORTED_OPTION_WITH_LEGAL_VALUE]);
+  }
+
   void validate(String source, List<ErrorCode> expected) {
     var options = optionsProvider.getOptionsFromString(source);
     var errors = validator.validate(options);
diff --git a/pkg/analyzer/test/src/task/strong/checker_test.dart b/pkg/analyzer/test/src/task/strong/checker_test.dart
index 972e5ad..49432eb 100644
--- a/pkg/analyzer/test/src/task/strong/checker_test.dart
+++ b/pkg/analyzer/test/src/task/strong/checker_test.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:analyzer/src/dart/analysis/experiments.dart';
+import 'package:analyzer/src/test_utilities/package_mixin.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
 
 import 'strong_test_helper.dart';
@@ -15,10 +16,7 @@
 }
 
 @reflectiveTest
-class CheckerTest extends AbstractStrongTest {
-  @override
-  bool get enableNewAnalysisDriver => true;
-
+class CheckerTest extends AbstractStrongTest with PackageMixin {
   test_awaitForInCastsStreamElementToVariable() async {
     await checkFile('''
 import 'dart:async';
@@ -375,7 +373,6 @@
     ''');
   }
 
-  @failingTest // See dartbug.com/32918
   test_constantGenericTypeArg_infer() async {
     // Regression test for https://github.com/dart-lang/sdk/issues/26141
     await checkFile('''
@@ -3774,11 +3771,7 @@
   }
 
   test_strictRawTypes_classes_optionalTypeArgs() async {
-    addFile(r'''
-class _OptionalTypeArgs { const _OptionalTypeArgs(); }
-const optionalTypeArgs = _OptionalTypeArgs();
-    ''', name: 'package:meta/meta.dart');
-
+    addMetaPackage();
     addFile(r'''
 import 'package:meta/meta.dart';
 @optionalTypeArgs
@@ -3864,11 +3857,7 @@
   }
 
   test_strictRawTypes_typedefs_optionalTypeArgs() async {
-    addFile(r'''
-class _OptionalTypeArgs { const _OptionalTypeArgs(); }
-const optionalTypeArgs = _OptionalTypeArgs();
-    ''', name: 'package:meta/meta.dart');
-
+    addMetaPackage();
     addFile(r'''
 import 'package:meta/meta.dart';
 
@@ -4520,9 +4509,6 @@
   List<String> get enabledExperiments =>
       [EnableString.spread_collections, EnableString.control_flow_collections];
 
-  @override
-  bool get enableNewAnalysisDriver => true;
-
   test_list_ifElement_dynamicCondition_disableImplicitCasts() async {
     addFile(r'''
 dynamic c;
@@ -4997,7 +4983,7 @@
 
   @failingTest
   test_spread_dynamicInList_disableImplicitCasts() async {
-    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569
+    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267
     addFile(r'''
 dynamic dyn;
 void main() {
@@ -5019,7 +5005,7 @@
 
   @failingTest
   test_spread_dynamicInMap_disableImplicitCasts() async {
-    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569
+    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267
     addFile(r'''
 dynamic dyn;
 void main() {
@@ -5041,7 +5027,7 @@
 
   @failingTest
   test_spread_dynamicInSet_disableImplicitCasts() async {
-    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/35569
+    // TODO(mfairhurst) fix this, see https://github.com/dart-lang/sdk/issues/36267
     addFile(r'''
 dynamic dyn;
 void main() {
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 a6da936..4a036db 100644
--- a/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
+++ b/pkg/analyzer/test/src/task/strong/inferred_type_test.dart
@@ -4393,9 +4393,6 @@
 @reflectiveTest
 class InferredTypeTest extends AbstractStrongTest with InferredTypeMixin {
   @override
-  bool get enableNewAnalysisDriver => true;
-
-  @override
   bool get hasExtraTaskModelPass => false;
 
   @override
@@ -4426,9 +4423,6 @@
 class InferredTypeTest_SetLiterals extends AbstractStrongTest
     with InferredTypeMixin {
   @override
-  bool get enableNewAnalysisDriver => true;
-
-  @override
   bool get hasExtraTaskModelPass => false;
 
   @override
diff --git a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
index 9589973..7ea6be3 100644
--- a/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
+++ b/pkg/analyzer/test/src/task/strong/strong_test_helper.dart
@@ -12,7 +12,6 @@
 import 'package:analyzer/dart/ast/token.dart';
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/error/error.dart';
-import 'package:analyzer/error/listener.dart';
 import 'package:analyzer/file_system/file_system.dart';
 import 'package:analyzer/file_system/memory_file_system.dart';
 import 'package:analyzer/source/error_processor.dart';
@@ -25,6 +24,7 @@
 import 'package:analyzer/src/file_system/file_system.dart';
 import 'package:analyzer/src/generated/engine.dart';
 import 'package:analyzer/src/generated/source.dart';
+import 'package:analyzer/src/source/package_map_resolver.dart';
 import 'package:analyzer/src/test_utilities/mock_sdk.dart';
 import 'package:analyzer/src/test_utilities/resource_provider_mixin.dart';
 import 'package:source_span/source_span.dart';
@@ -78,7 +78,7 @@
 }
 
 void _expectErrors(AnalysisOptions analysisOptions, CompilationUnit unit,
-    List<AnalysisError> actualErrors) {
+    Iterable<AnalysisError> actualErrors) {
   var expectedErrors = _findExpectedErrors(unit.beginToken);
 
   var actualMap = new SplayTreeMap<int, List<AnalysisError>>();
@@ -245,7 +245,7 @@
 
   List<String> get enabledExperiments => [];
 
-  bool get enableNewAnalysisDriver => false;
+  Map<String, List<Folder>> packageMap;
 
   /// Adds a file to check. The file should contain:
   ///
@@ -297,43 +297,48 @@
     var mockSdk = new MockSdk(resourceProvider: resourceProvider);
     mockSdk.context.analysisOptions = analysisOptions;
 
-    SourceFactory sourceFactory;
-    {
-      var uriResolver = new _TestUriResolver(resourceProvider);
-      sourceFactory =
-          new SourceFactory([new DartUriResolver(mockSdk), uriResolver]);
-    }
+    SourceFactory sourceFactory = new SourceFactory([
+      new DartUriResolver(mockSdk),
+      new PackageMapUriResolver(resourceProvider, packageMap),
+      new ResourceUriResolver(resourceProvider),
+    ]);
 
     CompilationUnit mainUnit;
-    if (enableNewAnalysisDriver) {
-      StringBuffer logBuffer = new StringBuffer();
-      FileContentOverlay fileContentOverlay = new FileContentOverlay();
-      PerformanceLog log = new PerformanceLog(logBuffer);
-      AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log);
-      _driver = new AnalysisDriver(
-          scheduler,
-          log,
-          resourceProvider,
-          new MemoryByteStore(),
-          fileContentOverlay,
-          null,
-          sourceFactory,
-          analysisOptions);
-      scheduler.start();
+    StringBuffer logBuffer = new StringBuffer();
+    FileContentOverlay fileContentOverlay = new FileContentOverlay();
+    PerformanceLog log = new PerformanceLog(logBuffer);
+    AnalysisDriverScheduler scheduler = new AnalysisDriverScheduler(log);
+    _driver = new AnalysisDriver(
+        scheduler,
+        log,
+        resourceProvider,
+        new MemoryByteStore(),
+        fileContentOverlay,
+        null,
+        sourceFactory,
+        analysisOptions);
+    scheduler.start();
 
-      mainUnit = (await _driver.getResult(mainFile.path)).unit;
-    } else {
-      _context = AnalysisEngine.instance.createAnalysisContext();
-      _context.analysisOptions = analysisOptions;
-      _context.sourceFactory = sourceFactory;
+    mainUnit = (await _driver.getResult(mainFile.path)).unit;
 
-      // Run the checker on /main.dart.
-      Source mainSource = sourceFactory.forUri2(mainFile.toUri());
-      mainUnit = _context.resolveCompilationUnit2(mainSource, mainSource);
+    bool isRelevantError(AnalysisError error) {
+      var code = error.errorCode;
+      // We don't care about these.
+      if (code == HintCode.UNUSED_ELEMENT ||
+          code == HintCode.UNUSED_FIELD ||
+          code == HintCode.UNUSED_IMPORT ||
+          code == HintCode.UNUSED_LOCAL_VARIABLE ||
+          code == TodoCode.TODO) {
+        return false;
+      }
+      if (strictRawTypes) {
+        // When testing strict-raw-types, ignore anything else.
+        return code.errorSeverity.ordinal > ErrorSeverity.INFO.ordinal ||
+            code == HintCode.STRICT_RAW_TYPE;
+      }
+      return true;
     }
 
-    var collector = new _ErrorCollector(analysisOptions);
-
     // Extract expectations from the comments in the test files, and
     // check that all errors we emit are included in the expected map.
     LibraryElement mainLibrary =
@@ -341,9 +346,6 @@
     Set<LibraryElement> allLibraries = _reachableLibraries(mainLibrary);
     for (LibraryElement library in allLibraries) {
       for (CompilationUnitElement unit in library.units) {
-        var errors = <AnalysisError>[];
-        collector.errors = errors;
-
         var source = unit.source;
         if (source.uri.scheme == 'dart') {
           continue;
@@ -351,18 +353,8 @@
 
         var analysisResult = await _resolve(source);
 
-        errors.addAll(analysisResult.errors.where((e) =>
-            // We don't care about any of these:
-            e.errorCode != HintCode.UNUSED_ELEMENT &&
-            e.errorCode != HintCode.UNUSED_FIELD &&
-            e.errorCode != HintCode.UNUSED_IMPORT &&
-            e.errorCode != HintCode.UNUSED_LOCAL_VARIABLE &&
-            e.errorCode != TodoCode.TODO &&
-            // If testing strict-raw-types, ignore other (unrelated) hints.
-            (!strictRawTypes ||
-                e.errorCode.errorSeverity.ordinal >
-                    ErrorSeverity.INFO.ordinal ||
-                e.errorCode == HintCode.STRICT_RAW_TYPE)));
+        Iterable<AnalysisError> errors =
+            analysisResult.errors.where(isRelevantError);
         _expectErrors(analysisOptions, analysisResult.unit, errors);
       }
     }
@@ -382,7 +374,11 @@
     );
   }
 
-  void setUp() {}
+  void setUp() {
+    packageMap = {
+      'meta': [getFolder('/.pub-cache/meta/lib')],
+    };
+  }
 
   void tearDown() {
     // This is a sanity check, in case only addFile is called.
@@ -393,31 +389,8 @@
   }
 
   Future<_TestAnalysisResult> _resolve(Source source) async {
-    if (enableNewAnalysisDriver) {
-      var result = await _driver.getResult(source.fullName);
-      return new _TestAnalysisResult(source, result.unit, result.errors);
-    } else {
-      List<Source> libraries = _context.getLibrariesContaining(source);
-      var unit = _context.resolveCompilationUnit2(source, libraries.single);
-      var errors = _context.computeErrors(source);
-      return new _TestAnalysisResult(source, unit, errors);
-    }
-  }
-}
-
-class _ErrorCollector implements AnalysisErrorListener {
-  final AnalysisOptions analysisOptions;
-  List<AnalysisError> errors;
-  final bool hints;
-
-  _ErrorCollector(this.analysisOptions, {this.hints: true});
-
-  void onError(AnalysisError error) {
-    // Unless DDC hints are requested, filter them out.
-    var HINT = ErrorSeverity.INFO.ordinal;
-    if (hints || _errorSeverity(analysisOptions, error).ordinal > HINT) {
-      errors.add(error);
-    }
+    var result = await _driver.getResult(source.fullName);
+    return new _TestAnalysisResult(source, result.unit, result.errors);
   }
 }
 
@@ -471,20 +444,3 @@
   final List<AnalysisError> errors;
   _TestAnalysisResult(this.source, this.unit, this.errors);
 }
-
-class _TestUriResolver extends ResourceUriResolver {
-  final MemoryResourceProvider provider;
-  _TestUriResolver(provider)
-      : provider = provider,
-        super(provider);
-
-  @override
-  Source resolveAbsolute(Uri uri, [Uri actualUri]) {
-    if (uri.scheme == 'package') {
-      return (provider.getResource(
-              provider.convertPath('/packages/' + uri.path)) as File)
-          .createSource(uri);
-    }
-    return super.resolveAbsolute(uri, actualUri);
-  }
-}
diff --git a/pkg/analyzer/test/src/test_all.dart b/pkg/analyzer/test/src/test_all.dart
index 90a00db..80fbf6b 100644
--- a/pkg/analyzer/test/src/test_all.dart
+++ b/pkg/analyzer/test/src/test_all.dart
@@ -12,6 +12,7 @@
 import 'fasta/test_all.dart' as fasta;
 import 'hint/test_all.dart' as hint;
 import 'lint/test_all.dart' as lint;
+import 'manifest/test_all.dart' as manifest;
 import 'options/test_all.dart' as options;
 import 'pubspec/test_all.dart' as pubspec;
 import 'services/test_all.dart' as services;
@@ -32,6 +33,7 @@
     fasta.main();
     hint.main();
     lint.main();
+    manifest.main();
     options.main();
     pubspec.main();
     services.main();
diff --git a/pkg/analyzer/test/src/workspace/gn_test.dart b/pkg/analyzer/test/src/workspace/gn_test.dart
index 8cd0a5b..5d15441 100644
--- a/pkg/analyzer/test/src/workspace/gn_test.dart
+++ b/pkg/analyzer/test/src/workspace/gn_test.dart
@@ -42,8 +42,7 @@
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
     String buildDir = convertPath('out/debug-x87_128');
-    newFile('/workspace/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '$buildDir\n');
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages');
     GnWorkspace workspace =
         GnWorkspace.find(resourceProvider, convertPath('/workspace/some/code'));
@@ -56,8 +55,7 @@
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
     String buildDir = convertPath('out/debug-x87_128');
-    newFile('/workspace/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '$buildDir\n');
     String packageLocation = convertPath('/workspace/this/is/the/package');
     Uri packageUri = resourceProvider.pathContext.toUri(packageLocation);
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages',
@@ -75,8 +73,7 @@
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
     String buildDir = convertPath('/workspace/out/debug-x87_128');
-    newFile('/workspace/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '$buildDir\n');
     String packageLocation = convertPath('/workspace/this/is/the/package');
     Uri packageUri = resourceProvider.pathContext.toUri(packageLocation);
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages',
@@ -109,7 +106,7 @@
     newFolder('/workspace/.jiri_root');
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
-    newFile('/workspace/.config', content: 'FOO=foo\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '');
     String packageLocation = convertPath('/workspace/this/is/the/package');
     Uri packageUri = resourceProvider.pathContext.toUri(packageLocation);
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages',
@@ -127,8 +124,7 @@
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
     String buildDir = convertPath('out/release-y22_256');
-    newFile('/workspace/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '$buildDir\n');
     String packageLocation = convertPath('/workspace/this/is/the/package');
     Uri packageUri = resourceProvider.pathContext.toUri(packageLocation);
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages',
@@ -152,8 +148,7 @@
     newFolder('/workspace/some/code');
     newFile('/workspace/some/code/pubspec.yaml');
     String buildDir = convertPath('out/debug-x87_128');
-    newFile('/workspace/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR=$buildDir\n' + 'BAR=bar\n');
+    newFile('/workspace/.fx-build-dir', content: '$buildDir\n');
     String packageOneLocation = convertPath('/workspace/this/is/the/package');
     Uri packageOneUri = resourceProvider.pathContext.toUri(packageOneLocation);
     newFile('/workspace/out/debug-x87_128/dartlang/gen/some/code/foo.packages',
@@ -179,8 +174,7 @@
   GnWorkspace _buildStandardGnWorkspace() {
     newFolder('/ws/.jiri_root');
     String buildDir = convertPath('out/debug-x87_128');
-    newFile('/ws/.config',
-        content: 'FOO=foo\n' + 'FUCHSIA_BUILD_DIR="$buildDir"\n' + 'BAR=bar\n');
+    newFile('/ws/.fx-build-dir', content: '$buildDir\n');
     newFile('/ws/out/debug-x87_128/dartlang/gen/some/code/foo.packages');
     newFolder('/ws/some/code');
     return GnWorkspace.find(resourceProvider, convertPath('/ws/some/code'));
diff --git a/pkg/analyzer/tool/summary/generate.dart b/pkg/analyzer/tool/summary/generate.dart
index f8a77f4..798e369 100644
--- a/pkg/analyzer/tool/summary/generate.dart
+++ b/pkg/analyzer/tool/summary/generate.dart
@@ -2,21 +2,19 @@
 // for 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 file contains code to generate serialization/deserialization logic for
- * summaries based on an "IDL" description of the summary format (written in
- * stylized Dart).
- *
- * For each class in the "IDL" input, two corresponding classes are generated:
- * - A class with the same name which represents deserialized summary data in
- *   memory.  This class has read-only semantics.
- * - A "builder" class which can be used to generate serialized summary data.
- *   This class has write-only semantics.
- *
- * Each of the "builder" classes has a single `finish` method which writes
- * the entity being built into the given FlatBuffer and returns the `Offset`
- * reference to it.
- */
+/// This file contains code to generate serialization/deserialization logic for
+/// summaries based on an "IDL" description of the summary format (written in
+/// stylized Dart).
+///
+/// For each class in the "IDL" input, two corresponding classes are generated:
+/// - A class with the same name which represents deserialized summary data in
+///   memory.  This class has read-only semantics.
+/// - A "builder" class which can be used to generate serialized summary data.
+///   This class has write-only semantics.
+///
+/// Each of the "builder" classes has a single `finish` method which writes
+/// the entity being built into the given FlatBuffer and returns the `Offset`
+/// reference to it.
 import 'dart:convert';
 import 'dart:io';
 
@@ -60,19 +58,13 @@
   static const String _throwDeprecated =
       "throw new UnimplementedError('attempt to access deprecated field')";
 
-  /**
-   * Buffer in which generated code is accumulated.
-   */
+  /// Buffer in which generated code is accumulated.
   final StringBuffer _outBuffer = new StringBuffer();
 
-  /**
-   * Current indentation level.
-   */
+  /// Current indentation level.
   String _indentation = '';
 
-  /**
-   * Semantic model of the "IDL" input file.
-   */
+  /// Semantic model of the "IDL" input file.
   idlModel.Idl _idl;
 
   _CodeGenerator(String idlPath) {
@@ -90,10 +82,8 @@
     checkIdl();
   }
 
-  /**
-   * Perform basic sanity checking of the IDL (over and above that done by
-   * [extractIdl]).
-   */
+  /// Perform basic sanity checking of the IDL (over and above that done by
+  /// [extractIdl]).
   void checkIdl() {
     _idl.classes.forEach((String name, idlModel.ClassDeclaration cls) {
       if (cls.fileIdentifier != null) {
@@ -143,10 +133,8 @@
     });
   }
 
-  /**
-   * Generate a string representing the Dart type which should be used to
-   * represent [type] when deserialized.
-   */
+  /// Generate a string representing the Dart type which should be used to
+  /// represent [type] when deserialized.
   String dartType(idlModel.FieldType type) {
     String baseType = idlPrefix(type.typeName);
     if (type.isList) {
@@ -156,13 +144,11 @@
     }
   }
 
-  /**
-   * Generate a Dart expression representing the default value for a field
-   * having the given [type], or `null` if there is no default value.
-   *
-   * If [builder] is `true`, the returned type should be appropriate for use in
-   * a builder class.
-   */
+  /// Generate a Dart expression representing the default value for a field
+  /// having the given [type], or `null` if there is no default value.
+  ///
+  /// If [builder] is `true`, the returned type should be appropriate for use in
+  /// a builder class.
   String defaultValue(idlModel.FieldType type, bool builder) {
     if (type.isList) {
       if (builder) {
@@ -188,10 +174,8 @@
     }
   }
 
-  /**
-   * Generate a string representing the Dart type which should be used to
-   * represent [type] while building a serialized data structure.
-   */
+  /// Generate a string representing the Dart type which should be used to
+  /// represent [type] while building a serialized data structure.
   String encodedType(idlModel.FieldType type) {
     String typeStr;
     if (_idl.classes.containsKey(type.typeName)) {
@@ -206,10 +190,8 @@
     }
   }
 
-  /**
-   * Process the AST in [idlParsed] and store the resulting semantic model in
-   * [_idl].  Also perform some error checking.
-   */
+  /// Process the AST in [idlParsed] and store the resulting semantic model in
+  /// [_idl].  Also perform some error checking.
   void extractIdl(CompilationUnit idlParsed) {
     _idl = new idlModel.Idl();
     for (CompilationUnitMember decl in idlParsed.declarations) {
@@ -301,10 +283,8 @@
     }
   }
 
-  /**
-   * Generate a string representing the FlatBuffer schema type which should be
-   * used to represent [type].
-   */
+  /// Generate a string representing the FlatBuffer schema type which should be
+  /// used to represent [type].
   String fbsType(idlModel.FieldType type) {
     String typeStr;
     switch (type.typeName) {
@@ -337,9 +317,7 @@
     }
   }
 
-  /**
-   * Entry point to the code generator when generating the "format.fbs" file.
-   */
+  /// Entry point to the code generator when generating the "format.fbs" file.
   void generateFlatBufferSchema() {
     outputHeader();
     for (idlModel.EnumDeclaration enm in _idl.enums.values) {
@@ -392,9 +370,7 @@
     }
   }
 
-  /**
-   * Entry point to the code generator when generating the "format.dart" file.
-   */
+  /// Entry point to the code generator when generating the "format.dart" file.
   void generateFormatCode() {
     outputHeader();
     out('library analyzer.src.summary.format;');
@@ -430,10 +406,8 @@
     }
   }
 
-  /**
-   * Add the prefix `idl.` to a type name, unless that type name is the name of
-   * a built-in type.
-   */
+  /// Add the prefix `idl.` to a type name, unless that type name is the name of
+  /// a built-in type.
   String idlPrefix(String s) {
     switch (s) {
       case 'bool':
@@ -446,9 +420,7 @@
     }
   }
 
-  /**
-   * Execute [callback] with two spaces added to [_indentation].
-   */
+  /// Execute [callback] with two spaces added to [_indentation].
   void indent(void callback()) {
     String oldIndentation = _indentation;
     try {
@@ -459,10 +431,8 @@
     }
   }
 
-  /**
-   * Add the string [s] to the output as a single line, indenting as
-   * appropriate.
-   */
+  /// Add the string [s] to the output as a single line, indenting as
+  /// appropriate.
   void out([String s = '']) {
     if (s == '') {
       _outBuffer.writeln('');
@@ -489,9 +459,7 @@
     out();
   }
 
-  /**
-   * Enclose [s] in quotes, escaping as necessary.
-   */
+  /// Enclose [s] in quotes, escaping as necessary.
   String quoted(String s) {
     return json.encode(s);
   }
@@ -713,7 +681,7 @@
           if (field.variantMap != null) {
             for (var logicalName in field.variantMap.keys) {
               var variants = field.variantMap[logicalName];
-              out('void set $logicalName($typeStr value) {');
+              out('set $logicalName($typeStr value) {');
               indent(() {
                 out(_variantAssertStatement(cls, variants));
                 _generateNonNegativeInt(fieldType);
@@ -723,7 +691,7 @@
               out();
             }
           } else {
-            out('void set $fieldName($typeStr value) {');
+            out('set $fieldName($typeStr value) {');
             indent(() {
               _generateNonNegativeInt(fieldType);
               out('this._$fieldName = value;');
@@ -782,9 +750,7 @@
       // Generate flushInformative().
       {
         out();
-        out('/**');
-        out(' * Flush [informative] data recursively.');
-        out(' */');
+        out('/// Flush [informative] data recursively.');
         out('void flushInformative() {');
         indent(() {
           for (idlModel.FieldDeclaration field in cls.fields) {
@@ -806,9 +772,7 @@
       // Generate collectApiSignature().
       {
         out();
-        out('/**');
-        out(' * Accumulate non-[informative] data into [signature].');
-        out(' */');
+        out('/// Accumulate non-[informative] data into [signature].');
         out('void collectApiSignature(api_sig.ApiSignature signature) {');
         indent(() {
           List<idlModel.FieldDeclaration> sortedFields = cls.fields.toList()
@@ -1241,12 +1205,10 @@
     out('}');
   }
 
-  /**
-   * Generate a call to the appropriate method of [ApiSignature] for the type
-   * [typeName], using the data named by [ref].  If [couldBeNull] is `true`,
-   * generate code to handle the possibility that [ref] is `null` (substituting
-   * in the appropriate default value).
-   */
+  /// Generate a call to the appropriate method of [ApiSignature] for the type
+  /// [typeName], using the data named by [ref].  If [couldBeNull] is `true`,
+  /// generate code to handle the possibility that [ref] is `null` (substituting
+  /// in the appropriate default value).
   void _generateSignatureCall(String typeName, String ref, bool couldBeNull) {
     if (_idl.enums.containsKey(typeName)) {
       if (couldBeNull) {
@@ -1291,10 +1253,8 @@
     }
   }
 
-  /**
-   * Return the documentation text of the given [node], or `null` if the [node]
-   * does not have a comment.  Each line is `\n` separated.
-   */
+  /// Return the documentation text of the given [node], or `null` if the [node]
+  /// does not have a comment.  Each line is `\n` separated.
   String _getNodeDoc(AnnotatedNode node) {
     Comment comment = node.documentationComment;
     if (comment != null && comment.isDocumentation) {
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
index f35495b..5051946 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_core.dart
@@ -21,17 +21,17 @@
   String eol = null;
 
   /**
-   * The change that is being built.
-   */
-  final SourceChange _change = new SourceChange('');
-
-  /**
    * A table mapping group ids to the associated linked edit groups.
    */
   final Map<String, LinkedEditGroup> _linkedEditGroups =
       <String, LinkedEditGroup>{};
 
   /**
+   * The source change selection or `null` if none.
+   */
+  Position _selection;
+
+  /**
    * The range of the selection for the change being built, or `null` if there
    * is no selection.
    */
@@ -44,6 +44,11 @@
   final Set<Position> _lockedPositions = new HashSet<Position>.identity();
 
   /**
+   * A map of absolute normalized path to file edit builder.
+   */
+  final _fileEditBuilders = <String, FileEditBuilderImpl>{};
+
+  /**
    * Initialize a newly created change builder.
    */
   ChangeBuilderImpl();
@@ -53,27 +58,34 @@
 
   @override
   SourceChange get sourceChange {
+    final SourceChange change = new SourceChange('');
+    for (var builder in _fileEditBuilders.values) {
+      if (builder.hasEdits) {
+        change.addFileEdit(builder.fileEdit);
+        builder.finalize();
+      }
+    }
     _linkedEditGroups.forEach((String name, LinkedEditGroup group) {
-      _change.addLinkedEditGroup(group);
+      change.addLinkedEditGroup(group);
     });
-    _linkedEditGroups.clear();
-    return _change;
+    if (_selection != null) {
+      change.selection = _selection;
+    }
+    return change;
   }
 
   @override
   Future<void> addFileEdit(
       String path, void buildFileEdit(FileEditBuilder builder)) async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
-    FileEditBuilderImpl builder = await createFileEditBuilder(path);
+    FileEditBuilderImpl builder = _fileEditBuilders[path];
     if (builder == null) {
-      return;
+      builder = await createFileEditBuilder(path);
+      if (builder != null) {
+        _fileEditBuilders[path] = builder;
+      }
     }
-
-    buildFileEdit(builder);
-    if (builder.hasEdits) {
-      _change.addFileEdit(builder.fileEdit);
-      await builder.finalize();
+    if (builder != null) {
+      buildFileEdit(builder);
     }
   }
 
@@ -102,7 +114,7 @@
 
   @override
   void setSelection(Position position) {
-    _change.selection = position;
+    _selection = position;
   }
 
   void _setSelectionRange(SourceRange range) {
@@ -126,9 +138,8 @@
         _updatePosition(position);
       }
     }
-    Position selection = _change.selection;
-    if (selection != null) {
-      _updatePosition(selection);
+    if (_selection != null) {
+      _updatePosition(_selection);
     }
   }
 }
@@ -349,9 +360,7 @@
   /**
    * Finalize the source file edit that is being built.
    */
-  Future<void> finalize() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+  void finalize() {
     // Nothing to do.
   }
 
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
index 785a0f3..86a386f 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/change_builder_dart.dart
@@ -72,7 +72,24 @@
       throw new AnalysisException('Cannot analyze "$path"');
     }
     int timeStamp = state == ResultState.VALID ? 0 : -1;
-    return DartFileEditBuilderImpl(this, path, timeStamp, session, result.unit);
+
+    CompilationUnit unit = result.unit;
+    CompilationUnitElement declaredUnit = unit.declaredElement;
+    CompilationUnitElement libraryUnit =
+        declaredUnit.library.definingCompilationUnit;
+
+    DartFileEditBuilderImpl libraryEditBuilder;
+    if (libraryUnit != declaredUnit) {
+      // If the receiver is a part file builder, then proactively cache the
+      // library file builder so that imports can be finalized synchronously.
+      await addFileEdit(libraryUnit.source.fullName,
+          (DartFileEditBuilder builder) {
+        libraryEditBuilder = builder as DartFileEditBuilderImpl;
+      });
+    }
+
+    return DartFileEditBuilderImpl(
+        this, path, timeStamp, session, unit, libraryEditBuilder);
   }
 }
 
@@ -1123,6 +1140,12 @@
   final LibraryElement libraryElement;
 
   /**
+   * The change builder for the library
+   * or `null` if the receiver is the builder for the library.
+   */
+  final DartFileEditBuilderImpl libraryChangeBuilder;
+
+  /**
    * The optional generator of prefixes for new imports.
    */
   ImportPrefixGenerator importPrefixGenerator;
@@ -1134,17 +1157,27 @@
   Map<Uri, _LibraryToImport> librariesToImport = {};
 
   /**
+   * A mapping from libraries that need to be imported relatively in order to
+   * make visible the names used in generated code, to information about these
+   * imports.
+   */
+  Map<String, _LibraryToImport> librariesToRelativelyImport = {};
+
+  /**
    * Initialize a newly created builder to build a source file edit within the
    * change being built by the given [changeBuilder]. The file being edited has
    * the given [path] and [timeStamp], and the given fully resolved [unit].
    */
   DartFileEditBuilderImpl(DartChangeBuilderImpl changeBuilder, String path,
-      int timeStamp, this.session, this.unit)
+      int timeStamp, this.session, this.unit, this.libraryChangeBuilder)
       : libraryElement = unit.declaredElement.library,
         super(changeBuilder, path, timeStamp);
 
   @override
-  bool get hasEdits => super.hasEdits || librariesToImport.isNotEmpty;
+  bool get hasEdits =>
+      super.hasEdits ||
+      librariesToImport.isNotEmpty ||
+      librariesToRelativelyImport.isNotEmpty;
 
   @override
   void addInsertion(int offset, void buildEdit(DartEditBuilder builder)) =>
@@ -1181,21 +1214,12 @@
   }
 
   @override
-  Future<void> finalize() async {
-    // TODO(brianwilkerson) Determine whether this await is necessary.
-    await null;
+  void finalize() {
     if (librariesToImport.isNotEmpty) {
-      CompilationUnitElement definingUnitElement =
-          libraryElement.definingCompilationUnit;
-      if (definingUnitElement == unit.declaredElement) {
-        _addLibraryImports(librariesToImport.values);
-      } else {
-        await (changeBuilder as DartChangeBuilder).addFileEdit(
-            definingUnitElement.source.fullName, (DartFileEditBuilder builder) {
-          (builder as DartFileEditBuilderImpl)
-              ._addLibraryImports(librariesToImport.values);
-        });
-      }
+      _addLibraryImports(librariesToImport.values);
+    }
+    if (librariesToRelativelyImport.isNotEmpty) {
+      _addLibraryImports(librariesToRelativelyImport.values);
     }
   }
 
@@ -1204,6 +1228,10 @@
     return _importLibrary(uri).uriText;
   }
 
+  String importLibraryWithRelativeUri(String uriText, [String prefix = null]) {
+    return _importLibraryWithRelativeUri(uriText, prefix).uriText;
+  }
+
   @override
   ImportLibraryElementResult importLibraryElement({
     @required ResolvedLibraryResult targetLibrary,
@@ -1212,7 +1240,8 @@
     @required LibraryElement requestedLibrary,
     @required Element requestedElement,
   }) {
-    if (librariesToImport.isNotEmpty) {
+    if (librariesToImport.isNotEmpty ||
+        librariesToRelativelyImport.isNotEmpty) {
       throw StateError('Only one library can be safely imported.');
     }
 
@@ -1227,7 +1256,8 @@
     var prefix = request.prefix;
     if (request.uri != null) {
       var uriText = _getLibraryUriText(request.uri);
-      librariesToImport[request.uri] = _LibraryToImport(uriText, prefix);
+      (libraryChangeBuilder ?? this).librariesToImport[request.uri] =
+          _LibraryToImport(uriText, prefix);
     }
 
     return ImportLibraryElementResultImpl(prefix);
@@ -1462,31 +1492,45 @@
   }
 
   /**
-   * Computes the best URI to import [what] into the target library.
+   * Computes the best URI to import [uri] into the target library.
    */
-  String _getLibraryUriText(Uri what) {
-    if (what.scheme == 'file') {
+  String _getLibraryUriText(Uri uri) {
+    if (uri.scheme == 'file') {
       var pathContext = session.resourceProvider.pathContext;
-      String whatPath = pathContext.fromUri(what);
+      String whatPath = pathContext.fromUri(uri);
       String libraryPath = libraryElement.source.fullName;
       String libraryFolder = pathContext.dirname(libraryPath);
       String relativeFile = pathContext.relative(whatPath, from: libraryFolder);
       return pathContext.split(relativeFile).join('/');
     }
-    return what.toString();
+    return uri.toString();
   }
 
   /**
    * Arrange to have an import added for the library with the given [uri].
    */
   _LibraryToImport _importLibrary(Uri uri) {
-    var import = librariesToImport[uri];
+    var import = (libraryChangeBuilder ?? this).librariesToImport[uri];
     if (import == null) {
       String uriText = _getLibraryUriText(uri);
       String prefix =
           importPrefixGenerator != null ? importPrefixGenerator(uri) : null;
       import = new _LibraryToImport(uriText, prefix);
-      librariesToImport[uri] = import;
+      (libraryChangeBuilder ?? this).librariesToImport[uri] = import;
+    }
+    return import;
+  }
+
+  /**
+   * Arrange to have an import added for the library with the given relative
+   * [uriText].
+   */
+  _LibraryToImport _importLibraryWithRelativeUri(String uriText,
+      [String prefix = null]) {
+    var import = librariesToRelativelyImport[uriText];
+    if (import == null) {
+      import = new _LibraryToImport(uriText, prefix);
+      librariesToRelativelyImport[uriText] = import;
     }
     return import;
   }
diff --git a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
index 1739677..2f545d1 100644
--- a/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
+++ b/pkg/analyzer_plugin/lib/src/utilities/change_builder/dart/syntactic_scope.dart
@@ -225,6 +225,20 @@
     _visitClassOrMixinMembers(node);
   }
 
+  @override
+  void visitTopLevelVariableDeclaration(TopLevelVariableDeclaration node) {
+    // `TypeName^` is recovered as `<noType> TypeName;`, remove the name.
+    var variableList = node.variables;
+    if (variableList.keyword == null && variableList.type == null) {
+      for (var variable in variableList.variables) {
+        names.remove(variable.name.name);
+      }
+      return;
+    }
+
+    super.visitTopLevelVariableDeclaration(node);
+  }
+
   void _addForLoopParts(ForLoopParts forLoopParts, AstNode body) {
     if (forLoopParts is ForEachPartsWithDeclaration) {
       if (_isCoveredBy(body)) {
@@ -260,9 +274,10 @@
   }
 
   void _addName(SimpleIdentifier node) {
-    if (node != null) {
-      names.add(node.name);
-    }
+    if (node == null) return;
+    if (node.end == offset) return;
+
+    names.add(node.name);
   }
 
   void _addTypeParameters(TypeParameterList typeParameterList) {
diff --git a/pkg/analyzer_plugin/pubspec.yaml b/pkg/analyzer_plugin/pubspec.yaml
index 277eda1..5ac22f2 100644
--- a/pkg/analyzer_plugin/pubspec.yaml
+++ b/pkg/analyzer_plugin/pubspec.yaml
@@ -10,7 +10,7 @@
 dependencies:
   analyzer: '^0.35.3'
   charcode: '^1.1.0'
-  html: '^0.13.1'
+  html: '>=0.13.1 <0.15.0'
   meta: ^1.0.2
   path: '^1.4.1'
   pub_semver: '^1.3.2'
diff --git a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
index 51cc21e..8873d2e 100644
--- a/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
+++ b/pkg/analyzer_plugin/test/src/utilities/change_builder/dart/import_library_element_test.dart
@@ -16,6 +16,7 @@
   defineReflectiveSuite(() {
     defineReflectiveTests(ImportLibraryElementTest);
     defineReflectiveTests(ImportLibraryElement_existingImport_Test);
+    defineReflectiveTests(ImportLibraryElement_incompleteCode_Test);
     defineReflectiveTests(ImportLibraryElement_newImport_withoutPrefix_Test);
     defineReflectiveTests(ImportLibraryElement_newImport_withPrefix_Test);
   });
@@ -159,6 +160,47 @@
 }
 
 @reflectiveTest
+class ImportLibraryElement_incompleteCode_Test extends _Base {
+  test_formalParameter() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+f(A^) {}
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+f(A) {}
+''',
+    );
+  }
+
+  test_topLevelVariable() async {
+    newFile('/home/test/lib/a.dart', content: 'class A {}');
+    newFile('/home/test/lib/b.dart', content: r'''
+export 'a.dart';
+''');
+    await _assertImportLibraryElement(
+      initialCode: r'''
+A^
+''',
+      uriStr: 'package:test/a.dart',
+      name: 'A',
+      expectedCode: r'''
+import 'package:test/a.dart';
+
+A
+''',
+    );
+  }
+}
+
+@reflectiveTest
 class ImportLibraryElement_newImport_withoutPrefix_Test extends _Base {
   test_exported() async {
     newFile('/home/test/lib/a.dart', content: 'class A {}');
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index 8598e78..03f5b05 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -78,7 +78,7 @@
 
   api.CompilerOutput get outputProvider => _outputProvider;
 
-  Uri _mainLibraryUri;
+  List<CodeLocation> _userCodeLocations = <CodeLocation>[];
 
   JClosedWorld backendClosedWorldForTesting;
 
@@ -231,20 +231,7 @@
       });
 
   Future runInternal(Uri uri) async {
-    // TODO(ahe): This prevents memory leaks when invoking the compiler
-    // multiple times. Implement a better mechanism where we can store
-    // such caches in the compiler and get access to them through a
-    // suitably maintained static reference to the current compiler.
-    clearStringTokenCanonicalizer();
-    Selector.canonicalizedValues.clear();
-
-    // The selector objects held in static fields must remain canonical.
-    for (Selector selector in Selectors.ALL) {
-      Selector.canonicalizedValues
-          .putIfAbsent(selector.hashCode, () => <Selector>[])
-          .add(selector);
-    }
-
+    clearState();
     assert(uri != null);
     // As far as I can tell, this branch is only used by test code.
     reporter.log('Compiling $uri (${options.buildId})');
@@ -265,7 +252,6 @@
         return;
       }
       if (options.cfeOnly) return;
-      _mainLibraryUri = result.rootLibraryUri;
 
       frontendStrategy.registerLoadedLibraries(result);
       for (Uri uri in result.libraries) {
@@ -287,6 +273,23 @@
     }
   }
 
+  /// Clear the internal compiler state to prevent memory leaks when invoking
+  /// the compiler multiple times (e.g. in batch mode).
+  // TODO(ahe): implement a better mechanism where we can store
+  // such caches in the compiler and get access to them through a
+  // suitably maintained static reference to the current compiler.
+  void clearState() {
+    clearStringTokenCanonicalizer();
+    Selector.canonicalizedValues.clear();
+
+    // The selector objects held in static fields must remain canonical.
+    for (Selector selector in Selectors.ALL) {
+      Selector.canonicalizedValues
+          .putIfAbsent(selector.hashCode, () => <Selector>[])
+          .add(selector);
+    }
+  }
+
   /// Starts the resolution phase, creating the [ResolutionEnqueuer] if not
   /// already created.
   ///
@@ -396,6 +399,7 @@
   }
 
   void compileFromKernel(Uri rootLibraryUri, Iterable<Uri> libraries) {
+    _userCodeLocations.add(new CodeLocation(rootLibraryUri));
     selfTask.measureSubtask("compileFromKernel", () {
       JClosedWorld closedWorld = selfTask.measureSubtask("computeClosedWorld",
           () => computeClosedWorld(rootLibraryUri, libraries));
@@ -567,25 +571,11 @@
     if (element == null) return assumeInUserCode;
     Uri libraryUri = _uriFromElement(element);
     if (libraryUri == null) return false;
-    Iterable<CodeLocation> userCodeLocations =
-        computeUserCodeLocations(assumeInUserCode: assumeInUserCode);
-    return userCodeLocations.any(
+    if (_userCodeLocations.isEmpty && assumeInUserCode) return true;
+    return _userCodeLocations.any(
         (CodeLocation codeLocation) => codeLocation.inSameLocation(libraryUri));
   }
 
-  Iterable<CodeLocation> computeUserCodeLocations(
-      {bool assumeInUserCode: false}) {
-    List<CodeLocation> userCodeLocations = <CodeLocation>[];
-    if (_mainLibraryUri != null) {
-      userCodeLocations.add(new CodeLocation(_mainLibraryUri));
-    }
-    if (userCodeLocations.isEmpty && assumeInUserCode) {
-      // Assume in user code since [mainApp] has not been set yet.
-      userCodeLocations.add(const AnyLocation());
-    }
-    return userCodeLocations;
-  }
-
   /// Return a canonical URI for the source of [element].
   ///
   /// For a package library with canonical URI 'package:foo/bar/baz.dart' the
diff --git a/pkg/compiler/lib/src/constants/constant_system.dart b/pkg/compiler/lib/src/constants/constant_system.dart
index 40ef21c..2d154b7 100644
--- a/pkg/compiler/lib/src/constants/constant_system.dart
+++ b/pkg/compiler/lib/src/constants/constant_system.dart
@@ -845,7 +845,7 @@
       // In order to preserve runtime semantics which says that NaN !== NaN
       // don't constant fold NaN === NaN. Otherwise the output depends on
       // inlined variables and other optimizations.
-      if (left.isNaN && right.isNaN) return null;
+      if (left.isNaN && right.isNaN) return new FalseConstantValue();
       return createBool(left == right);
     }
 
diff --git a/pkg/compiler/lib/src/inferrer/builder_kernel.dart b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
index b3098c9..585c560 100644
--- a/pkg/compiler/lib/src/inferrer/builder_kernel.dart
+++ b/pkg/compiler/lib/src/inferrer/builder_kernel.dart
@@ -14,6 +14,7 @@
 import '../elements/types.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../inferrer/types.dart';
+import '../ir/constants.dart';
 import '../ir/static_type_provider.dart';
 import '../ir/util.dart';
 import '../js_backend/backend.dart';
@@ -1127,9 +1128,13 @@
   int _findLength(ir.Arguments arguments) {
     ir.Expression firstArgument = arguments.positional.first;
     if (firstArgument is ir.ConstantExpression &&
-        firstArgument.constant is ir.IntConstant) {
-      ir.IntConstant constant = firstArgument.constant;
-      return constant.value;
+        firstArgument.constant is ir.DoubleConstant) {
+      ir.DoubleConstant constant = firstArgument.constant;
+      double doubleValue = constant.value;
+      int truncatedValue = doubleValue.truncate();
+      if (doubleValue == truncatedValue) {
+        return truncatedValue;
+      }
     } else if (firstArgument is ir.IntLiteral) {
       return firstArgument.value;
     } else if (firstArgument is ir.StaticGet) {
@@ -2165,51 +2170,3 @@
     return sb.toString();
   }
 }
-
-/// Class to represent a reference to a constant in allocation nodes.
-///
-/// This class is needed in order to support serialization of references to
-/// constant nodes. Since the constant nodes are not [ir.TreeNode]s we can only
-/// serialize the constants as values which would bypass by the canonicalization
-/// performed by the CFE. This class extends only as a trick to easily pass
-/// it through serialization.
-///
-/// By adding a reference to the constant expression in which the constant
-/// occurred, we can serialize references to constants in two steps: a reference
-/// to the constant expression followed by an index of the referred constant
-/// in the traversal order of the constant held by the constant expression.
-///
-/// This is used for list, map, and set literals.
-class ConstantReference extends ir.TreeNode {
-  final ir.ConstantExpression expression;
-  final ir.Constant constant;
-
-  ConstantReference(this.expression, this.constant);
-
-  @override
-  void visitChildren(ir.Visitor v) {
-    throw new UnsupportedError("ConstantReference.visitChildren");
-  }
-
-  @override
-  accept(ir.TreeVisitor v) {
-    throw new UnsupportedError("ConstantReference.accept");
-  }
-
-  @override
-  transformChildren(ir.Transformer v) {
-    throw new UnsupportedError("ConstantReference.transformChildren");
-  }
-
-  @override
-  int get hashCode => 13 * constant.hashCode;
-
-  @override
-  bool operator ==(Object other) {
-    if (identical(this, other)) return true;
-    return other is ConstantReference && constant == other.constant;
-  }
-
-  @override
-  String toString() => 'ConstantReference(constant=$constant)';
-}
diff --git a/pkg/compiler/lib/src/ir/constants.dart b/pkg/compiler/lib/src/ir/constants.dart
index bf36eee..06a6eb3 100644
--- a/pkg/compiler/lib/src/ir/constants.dart
+++ b/pkg/compiler/lib/src/ir/constants.dart
@@ -139,3 +139,51 @@
     return false;
   }
 }
+
+/// Class to represent a reference to a constant in allocation nodes.
+///
+/// This class is needed in order to support serialization of references to
+/// constant nodes. Since the constant nodes are not [ir.TreeNode]s we can only
+/// serialize the constants as values which would bypass by the canonicalization
+/// performed by the CFE. This class extends only as a trick to easily pass
+/// it through serialization.
+///
+/// By adding a reference to the constant expression in which the constant
+/// occurred, we can serialize references to constants in two steps: a reference
+/// to the constant expression followed by an index of the referred constant
+/// in the traversal order of the constant held by the constant expression.
+///
+/// This is used for list, map, and set literals.
+class ConstantReference extends ir.TreeNode {
+  final ir.ConstantExpression expression;
+  final ir.Constant constant;
+
+  ConstantReference(this.expression, this.constant);
+
+  @override
+  void visitChildren(ir.Visitor v) {
+    throw new UnsupportedError("ConstantReference.visitChildren");
+  }
+
+  @override
+  accept(ir.TreeVisitor v) {
+    throw new UnsupportedError("ConstantReference.accept");
+  }
+
+  @override
+  transformChildren(ir.Transformer v) {
+    throw new UnsupportedError("ConstantReference.transformChildren");
+  }
+
+  @override
+  int get hashCode => 13 * constant.hashCode;
+
+  @override
+  bool operator ==(Object other) {
+    if (identical(this, other)) return true;
+    return other is ConstantReference && constant == other.constant;
+  }
+
+  @override
+  String toString() => 'ConstantReference(constant=$constant)';
+}
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 66a527e..d635b78 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -10,6 +10,7 @@
 import 'package:kernel/type_environment.dart' as ir;
 
 import '../common.dart';
+import 'constants.dart';
 import 'impact_data.dart';
 import 'runtime_type_analysis.dart';
 import 'scope.dart';
@@ -90,6 +91,9 @@
 
   void registerFieldInitialization(ir.Field node);
 
+  void registerFieldConstantInitialization(
+      ir.Field node, ConstantReference constant);
+
   void registerLoadLibrary();
 
   void registerRedirectingInitializer(
@@ -655,7 +659,7 @@
   @override
   void handleConstantExpression(ir.ConstantExpression node) {
     ir.LibraryDependency import = getDeferredImport(node);
-    node.constant.accept(new ConstantImpactVisitor(this, import));
+    node.constant.accept(new ConstantImpactVisitor(this, import, node));
   }
 }
 
@@ -698,8 +702,9 @@
 class ConstantImpactVisitor implements ir.ConstantVisitor<void> {
   final ImpactRegistry registry;
   final ir.LibraryDependency import;
+  final ir.ConstantExpression expression;
 
-  ConstantImpactVisitor(this.registry, this.import);
+  ConstantImpactVisitor(this.registry, this.import, this.expression);
 
   @override
   void defaultConstant(ir.Constant node) {
@@ -736,7 +741,8 @@
         node.classNode, node.typeArguments, import);
     node.fieldValues.forEach((ir.Reference reference, ir.Constant value) {
       ir.Field field = reference.asField;
-      registry.registerFieldInitialization(field);
+      registry.registerFieldConstantInitialization(
+          field, new ConstantReference(expression, value));
       value.accept(this);
     });
   }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 1d0abe6..543d3ed 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -8,6 +8,7 @@
 
 import '../serialization/serialization.dart';
 import '../util/enumset.dart';
+import 'constants.dart';
 import 'impact.dart';
 import 'runtime_type_analysis.dart';
 import 'static_type.dart';
@@ -230,6 +231,13 @@
   }
 
   @override
+  void registerFieldConstantInitialization(
+      ir.Field node, ConstantReference constant) {
+    _data._fieldConstantInitializers ??= {};
+    _data._fieldConstantInitializers.putIfAbsent(node, () => []).add(constant);
+  }
+
+  @override
   void registerTypeLiteral(ir.DartType type, ir.LibraryDependency import) {
     _data._typeLiterals ??= [];
     _data._typeLiterals.add(new _TypeLiteral(type, import));
@@ -482,6 +490,7 @@
   List<_TypeUse> _typeUses;
   List<_RedirectingInitializer> _redirectingInitializers;
   List<ir.Field> _fieldInitializers;
+  Map<ir.Field, List<ConstantReference>> _fieldConstantInitializers;
   List<_TypeLiteral> _typeLiterals;
   List<ir.TreeNode> _localFunctions;
   List<_GenericInstantiation> _genericInstantiations;
@@ -555,6 +564,8 @@
         () => new _RedirectingInitializer.fromDataSource(source),
         emptyAsNull: true);
     _fieldInitializers = source.readMemberNodes(emptyAsNull: true);
+    _fieldConstantInitializers =
+        source.readMemberMap(() => source.readTreeNodes(), emptyAsNull: true);
     _typeLiterals = source.readList(
         () => new _TypeLiteral.fromDataSource(source),
         emptyAsNull: true);
@@ -649,6 +660,8 @@
         (_RedirectingInitializer o) => o.toDataSink(sink),
         allowNull: true);
     sink.writeMemberNodes(_fieldInitializers, allowNull: true);
+    sink.writeMemberNodeMap(_fieldConstantInitializers, sink.writeTreeNodes,
+        allowNull: true);
     sink.writeList(_typeLiterals, (_TypeLiteral o) => o.toDataSink(sink),
         allowNull: true);
     sink.writeTreeNodes(_localFunctions, allowNull: true);
@@ -896,6 +909,14 @@
         registry.registerFieldInitialization(data);
       }
     }
+    if (_fieldConstantInitializers != null) {
+      _fieldConstantInitializers
+          .forEach((ir.Field field, List<ConstantReference> constants) {
+        for (ConstantReference constant in constants) {
+          registry.registerFieldConstantInitialization(field, constant);
+        }
+      });
+    }
     if (_typeLiterals != null) {
       for (_TypeLiteral data in _typeLiterals) {
         registry.registerTypeLiteral(data.type, data.import);
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 6907520..7aee79e 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -164,6 +164,9 @@
     while (type is ir.TypeParameterType) {
       type = (type as ir.TypeParameterType).parameter.bound;
     }
+    if (type == typeEnvironment.nullType) {
+      return superclass.bottomType;
+    }
     if (type is ir.InterfaceType) {
       ir.InterfaceType upcastType =
           typeEnvironment.getTypeAsInstanceOf(type, superclass);
@@ -171,6 +174,7 @@
     } else if (type is ir.BottomType) {
       return superclass.bottomType;
     }
+    // TODO(johnniwinther): Should we assert that this doesn't happen?
     return superclass.rawType;
   }
 
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 9682f5b..751295e 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -127,6 +127,7 @@
     const CheckedModeHelper('doubleTypeCheck'),
     const CheckedModeHelper('numTypeCast'),
     const CheckedModeHelper('numTypeCheck'),
+    const CheckedModeHelper('boolConversionCheck'),
     const CheckedModeHelper('boolTypeCast'),
     const CheckedModeHelper('boolTypeCheck'),
     const CheckedModeHelper('intTypeCast'),
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 915dd48..7349b4d 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -163,6 +163,11 @@
   final Map<KConstructor, Initializer> initializers = {};
 
   AllocatorData(this.initialValue);
+
+  @override
+  String toString() =>
+      'AllocatorData(initialValue=${initialValue?.toStructuredText()},'
+      'initializers=$initializers)';
 }
 
 enum InitializerKind {
@@ -284,6 +289,8 @@
               }
             }
 
+            memberUsage.initialConstants.forEach(includeInitialValue);
+
             bool inAllConstructors = true;
             for (KConstructor constructor in classData.constructors) {
               if (isTooComplex) {
@@ -292,7 +299,10 @@
 
               MemberUsage constructorUsage =
                   closedWorld.liveMemberUsage[constructor];
-              if (constructorUsage == null) return;
+              if (constructorUsage == null) {
+                // This constructor isn't called.
+                continue;
+              }
               ParameterStructure invokedParameters =
                   closedWorld.annotationsData.hasNoElision(constructor)
                       ? constructor.parameterStructure
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types.dart b/pkg/compiler/lib/src/js_backend/runtime_types.dart
index e5132c6..5094315 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types.dart
@@ -2073,6 +2073,7 @@
       classUse.instance = true;
     });
 
+    Set<ClassEntity> visitedSuperClasses = {};
     codegenWorldBuilder.instantiatedTypes.forEach((InterfaceType type) {
       liveTypeVisitor.visitType(type, TypeVisitorState.direct);
       ClassUse classUse =
@@ -2082,6 +2083,28 @@
       if (callType != null) {
         liveTypeVisitor.visitType(callType, TypeVisitorState.direct);
       }
+
+      // Superclass might make classes live as type arguments. For instance
+      //
+      //    class A {}
+      //    class B<T> {}
+      //    class C implements B<A> {}
+      //    main() => new C();
+      //
+      // Here `A` is live as a type argument through the liveness of `C`.
+      for (InterfaceType supertype
+          in _closedWorld.dartTypes.getSupertypes(type.element)) {
+        if (supertype.typeArguments.isEmpty &&
+            visitedSuperClasses.contains(supertype.element)) {
+          // If [superclass] is not generic then a second visit cannot add more
+          // information that the first. In the example above, visiting `C`
+          // twice can only result in a second registration of `A` as live
+          // type argument.
+          break;
+        }
+        visitedSuperClasses.add(supertype.element);
+        liveTypeVisitor.visitType(supertype, TypeVisitorState.direct);
+      }
     });
 
     for (FunctionEntity element
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 bbf43e4..f5b5b0c 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
@@ -765,7 +765,13 @@
           assert(!field.needsUncheckedSetter);
           FieldEntity element = field.element;
           js.Expression code = _generatedCode[element];
-          assert(code != null);
+          if (code == null) {
+            // TODO(johnniwinther): Static types are not honoured in the dynamic
+            // uses created in codegen, leading to dead code, as known by the
+            // closed world computation, being triggered by the codegen
+            // enqueuer. We cautiously generate an empty function for this case.
+            code = js.js("function() {}");
+          }
           js.Name name = _namer.deriveSetterName(field.accessorName);
           checkedSetters.add(_buildStubMethod(name, code, element: element));
         }
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 a1ba755..1cac12f 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
@@ -1084,12 +1084,10 @@
     if (field.isElided) {
       ConstantValue constantValue = field.constantValue;
       if (constantValue == null) {
-        assert(_closedWorld.abstractValueDomain is TrivialAbstractValueDomain);
-        // Since static types are not used in invocation/access of instance
-        // members in codegen, we see dynamic uses in codegen that are not
-        // present in resolution when using the trivial abstract value domain.
-        // This means that resolution can determine that a field is never read
-        // but codegen thinks it is read.
+        // TODO(johnniwinther): Static types are not honoured in the dynamic
+        // uses created in codegen, leading to dead code, as known by the closed
+        // world computation, being triggered by the codegen enqueuer. We
+        // cautiously generate a null constant for this case.
         constantValue = new NullConstantValue();
       }
       code = js.js(
diff --git a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
index 6497bf4..3233491 100644
--- a/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
+++ b/pkg/compiler/lib/src/js_emitter/startup_emitter/model_emitter.dart
@@ -37,7 +37,6 @@
 import '../../common_elements.dart' show CommonElements;
 import '../../elements/entities.dart';
 import '../../hash/sha1.dart' show Hasher;
-import '../../inferrer/trivial.dart';
 import '../../io/code_output.dart';
 import '../../io/location_provider.dart' show LocationCollector;
 import '../../io/source_map_builder.dart' show SourceMapBuilder;
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 0353f59..7a2b12a 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -77,6 +77,7 @@
   ir.TypeEnvironment _typeEnvironment;
   ir.ClassHierarchy _classHierarchy;
   Dart2jsConstantEvaluator _constantEvaluator;
+  ConstantValuefier _constantValuefier;
 
   /// Library environment. Used for fast lookup.
   KProgramEnv env = new KProgramEnv();
@@ -125,6 +126,7 @@
     _constantEnvironment = new KernelConstantEnvironment(this, _environment);
     _typeConverter = new DartTypeConverter(this);
     _types = new KernelDartTypes(this);
+    _constantValuefier = new ConstantValuefier(this);
   }
 
   @override
@@ -1031,7 +1033,7 @@
         }
         return null;
       } else {
-        return constant.accept(new ConstantValuefier(this));
+        return constant.accept(_constantValuefier);
       }
     }
 
@@ -1370,12 +1372,18 @@
       }
       ImpactData impactData = impactBuilderData.impactData;
       memberData.staticTypes = impactBuilderData.cachedStaticTypes;
-      KernelImpactConverter converter =
-          new KernelImpactConverter(this, member, reporter, options);
+      KernelImpactConverter converter = new KernelImpactConverter(
+          this, member, reporter, options, _constantValuefier);
       return converter.convert(impactData);
     } else {
       KernelImpactBuilder builder = new KernelImpactBuilder(
-          this, member, reporter, options, variableScopeModel, annotations);
+          this,
+          member,
+          reporter,
+          options,
+          variableScopeModel,
+          annotations,
+          _constantValuefier);
       if (retainDataForTesting) {
         typeMapsForTesting ??= {};
         typeMapsForTesting[member] = builder.typeMapsForTesting = {};
diff --git a/pkg/compiler/lib/src/kernel/kernel_impact.dart b/pkg/compiler/lib/src/kernel/kernel_impact.dart
index 4de44d7..e32ea87 100644
--- a/pkg/compiler/lib/src/kernel/kernel_impact.dart
+++ b/pkg/compiler/lib/src/kernel/kernel_impact.dart
@@ -13,12 +13,14 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
+import '../ir/constants.dart';
+import '../ir/impact.dart';
+import '../ir/impact_data.dart';
 import '../ir/runtime_type_analysis.dart';
 import '../ir/scope.dart';
 import '../ir/static_type.dart';
-import '../ir/impact.dart';
-import '../ir/impact_data.dart';
 import '../ir/util.dart';
+import '../ir/visitors.dart';
 import '../js_backend/annotations.dart';
 import '../js_backend/native_data.dart';
 import '../native/behavior.dart';
@@ -45,9 +47,17 @@
   @override
   final MemberEntity currentMember;
   final Set<PragmaAnnotation> _annotations;
+  @override
+  final ConstantValuefier _constantValuefier;
 
-  KernelImpactBuilder(this.elementMap, this.currentMember, this.reporter,
-      this._options, VariableScopeModel variableScopeModel, this._annotations)
+  KernelImpactBuilder(
+      this.elementMap,
+      this.currentMember,
+      this.reporter,
+      this._options,
+      VariableScopeModel variableScopeModel,
+      this._annotations,
+      this._constantValuefier)
       : this.impactBuilder =
             new ResolutionWorldImpactBuilder('${currentMember}'),
         super(elementMap.typeEnvironment, elementMap.classHierarchy,
@@ -80,9 +90,11 @@
   final CompilerOptions _options;
   @override
   final MemberEntity currentMember;
+  @override
+  final ConstantValuefier _constantValuefier;
 
-  KernelImpactConverter(
-      this.elementMap, this.currentMember, this.reporter, this._options)
+  KernelImpactConverter(this.elementMap, this.currentMember, this.reporter,
+      this._options, this._constantValuefier)
       : this.impactBuilder =
             new ResolutionWorldImpactBuilder('${currentMember}');
 
@@ -114,6 +126,7 @@
   ir.TypeEnvironment get typeEnvironment;
   CommonElements get commonElements;
   NativeBasicData get _nativeBasicData;
+  ConstantValuefier get _constantValuefier;
 
   Object _computeReceiverConstraint(
       ir.DartType receiverType, ClassRelation relation) {
@@ -781,6 +794,14 @@
   }
 
   @override
+  void registerFieldConstantInitialization(
+      ir.Field node, ConstantReference constant) {
+    impactBuilder.registerStaticUse(new StaticUse.fieldConstantInit(
+        elementMap.getField(node),
+        constant.constant.accept(_constantValuefier)));
+  }
+
+  @override
   void registerRedirectingInitializer(
       ir.Constructor constructor,
       int positionalArguments,
diff --git a/pkg/compiler/lib/src/kernel/loader.dart b/pkg/compiler/lib/src/kernel/loader.dart
index bfdf6ee..d1cd03c 100644
--- a/pkg/compiler/lib/src/kernel/loader.dart
+++ b/pkg/compiler/lib/src/kernel/loader.dart
@@ -105,7 +105,8 @@
             _options.librariesSpecificationUri,
             dependencies,
             _options.packageConfig,
-            experimentalFlags: _options.languageExperiments);
+            experimentalFlags: _options.languageExperiments,
+            enableAsserts: _options.enableUserAssertions);
         component = await fe.compile(
             initializedCompilerState,
             false,
diff --git a/pkg/compiler/lib/src/options.dart b/pkg/compiler/lib/src/options.dart
index 83db5ad2..7cb0278 100644
--- a/pkg/compiler/lib/src/options.dart
+++ b/pkg/compiler/lib/src/options.dart
@@ -267,6 +267,13 @@
   /// This is an internal configuration option derived from other flags.
   CheckPolicy implicitDowncastCheckPolicy;
 
+  /// What the compiler should do with a boolean value in a condition context
+  /// when the language specification says it is a runtime error for it to be
+  /// null.
+  ///
+  /// This is an internal configuration option derived from other flags.
+  CheckPolicy conditionCheckPolicy;
+
   /// Whether to generate code compliant with content security policy (CSP).
   bool useContentSecurityPolicy = false;
 
@@ -462,9 +469,11 @@
     if (omitImplicitChecks) {
       parameterCheckPolicy = CheckPolicy.trusted;
       implicitDowncastCheckPolicy = CheckPolicy.trusted;
+      conditionCheckPolicy = CheckPolicy.trusted;
     } else {
       parameterCheckPolicy = CheckPolicy.checked;
       implicitDowncastCheckPolicy = CheckPolicy.checked;
+      conditionCheckPolicy = CheckPolicy.checked;
     }
 
     if (_disableMinification) {
diff --git a/pkg/compiler/lib/src/serialization/mixins.dart b/pkg/compiler/lib/src/serialization/mixins.dart
index 385c282..695d112 100644
--- a/pkg/compiler/lib/src/serialization/mixins.dart
+++ b/pkg/compiler/lib/src/serialization/mixins.dart
@@ -156,6 +156,20 @@
   }
 
   @override
+  Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f(),
+      {bool emptyAsNull: false}) {
+    int count = readInt();
+    if (count == 0 && emptyAsNull) return null;
+    Map<K, V> map = {};
+    for (int i = 0; i < count; i++) {
+      ir.Member node = readMemberNode();
+      V value = f();
+      map[node] = value;
+    }
+    return map;
+  }
+
+  @override
   Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f(),
       {bool emptyAsNull: false}) {
     int count = readInt();
@@ -542,6 +556,21 @@
   }
 
   @override
+  void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value),
+      {bool allowNull: false}) {
+    if (map == null) {
+      assert(allowNull);
+      writeInt(0);
+    } else {
+      writeInt(map.length);
+      map.forEach((ir.Member key, V value) {
+        writeMemberNode(key);
+        f(value);
+      });
+    }
+  }
+
+  @override
   void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value),
       {bool allowNull: false}) {
     if (map == null) {
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 65276b3..8623f87 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -15,7 +15,7 @@
 import '../elements/entities.dart';
 import '../elements/indexed.dart';
 import '../elements/types.dart';
-import '../inferrer/builder_kernel.dart';
+import '../ir/constants.dart';
 import '../ir/static_type_base.dart';
 import '../js_model/closure.dart';
 import '../js_model/locals.dart';
@@ -139,6 +139,15 @@
   /// [DataSource.readMemberNodes].
   void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull: false});
 
+  /// Writes the [map] from references to kernel member nodes to [V] values to
+  /// this data sink, calling [f] to write each value to the data sink. If
+  /// [allowNull] is `true`, [map] is allowed to be `null`.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSource.readMemberNodeMap].
+  void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value),
+      {bool allowNull: false});
+
   /// Writes a kernel name node to this data sink.
   void writeName(ir.Name value);
 
@@ -480,6 +489,15 @@
   List<ir.Member> readMemberNodes<E extends ir.Member>(
       {bool emptyAsNull: false});
 
+  /// Reads a map from kernel member nodes to [V] values from this data source,
+  /// calling [f] to read each value from the data source. If [emptyAsNull] is
+  /// `true`, `null` is returned instead of an empty map.
+  ///
+  /// This is a convenience method to be used together with
+  /// [DataSink.writeMemberNodeMap].
+  Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f(),
+      {bool emptyAsNull: false});
+
   /// Reads a kernel name node from this data source.
   ir.Name readName();
 
diff --git a/pkg/compiler/lib/src/ssa/builder_kernel.dart b/pkg/compiler/lib/src/ssa/builder_kernel.dart
index 844bdb4..d8f8ff5 100644
--- a/pkg/compiler/lib/src/ssa/builder_kernel.dart
+++ b/pkg/compiler/lib/src/ssa/builder_kernel.dart
@@ -410,9 +410,7 @@
   HInstruction popBoolified() {
     HInstruction value = pop();
     if (typeBuilder.checkOrTrustTypes) {
-      InterfaceType type = commonElements.boolType;
-      return typeBuilder.potentiallyCheckOrTrustTypeOfAssignment(value, type,
-          kind: HTypeConversion.BOOLEAN_CONVERSION_CHECK);
+      return typeBuilder.potentiallyCheckOrTrustTypeOfCondition(value);
     }
     HInstruction result = new HBoolify(value, abstractValueDomain.boolType);
     add(result);
diff --git a/pkg/compiler/lib/src/ssa/type_builder.dart b/pkg/compiler/lib/src/ssa/type_builder.dart
index 9ba2e51..bb7e4ed 100644
--- a/pkg/compiler/lib/src/ssa/type_builder.dart
+++ b/pkg/compiler/lib/src/ssa/type_builder.dart
@@ -122,6 +122,20 @@
     return checkedOrTrusted;
   }
 
+  HInstruction potentiallyCheckOrTrustTypeOfCondition(HInstruction original) {
+    DartType boolType = builder.commonElements.boolType;
+    HInstruction checkedOrTrusted = original;
+    if (builder.options.conditionCheckPolicy.isTrusted) {
+      checkedOrTrusted = _trustType(original, boolType);
+    } else if (builder.options.conditionCheckPolicy.isEmitted) {
+      checkedOrTrusted = _checkType(
+          original, boolType, HTypeConversion.BOOLEAN_CONVERSION_CHECK);
+    }
+    if (checkedOrTrusted == original) return original;
+    builder.add(checkedOrTrusted);
+    return checkedOrTrusted;
+  }
+
   ClassTypeVariableAccess computeTypeVariableAccess(MemberEntity member);
 
   /// Helper to create an instruction that gets the value of a type variable.
diff --git a/pkg/compiler/lib/src/universe/codegen_world_builder.dart b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
index 8ab3ae4..eb54121 100644
--- a/pkg/compiler/lib/src/universe/codegen_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/codegen_world_builder.dart
@@ -400,7 +400,8 @@
       case StaticUseKind.INVOKE:
       case StaticUseKind.GET:
       case StaticUseKind.SET:
-      case StaticUseKind.INIT:
+      case StaticUseKind.FIELD_INIT:
+      case StaticUseKind.FIELD_CONSTANT_INIT:
         break;
     }
   }
@@ -441,7 +442,8 @@
       case StaticUseKind.SUPER_TEAR_OFF:
       case StaticUseKind.GET:
       case StaticUseKind.SET:
-      case StaticUseKind.INIT:
+      case StaticUseKind.FIELD_INIT:
+      case StaticUseKind.FIELD_CONSTANT_INIT:
         useSet.addAll(usage.normalUse());
         break;
       case StaticUseKind.CONSTRUCTOR_INVOKE:
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 1eb99bb..e368cbb 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -5,6 +5,7 @@
 import 'dart:math' as Math;
 
 import '../common.dart';
+import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../js_model/elements.dart' show JSignatureMethod;
 import '../util/enumset.dart';
@@ -75,6 +76,8 @@
   /// `true` if [entity] has been initialized.
   bool get hasInit => true;
 
+  Iterable<ConstantValue> get initialConstants => null;
+
   /// `true` if [entity] has been read as a value. For a field this is a normal
   /// read access, for a function this is a closurization.
   bool get hasRead => false;
@@ -120,6 +123,13 @@
   /// no-op.
   EnumSet<MemberUse> init() => MemberUses.NONE;
 
+  /// Registers the [entity] has been initialized with [constant] and returns
+  /// the new [MemberUse]s that it caused.
+  ///
+  /// For a field this is the initial write access, for a function this is a
+  /// no-op.
+  EnumSet<MemberUse> constantInit(ConstantValue constant) => MemberUses.NONE;
+
   /// Registers a read of the value of [entity] and returns the new [MemberUse]s
   /// that it caused.
   ///
@@ -183,6 +193,8 @@
   @override
   bool hasWrite;
 
+  List<ConstantValue> _initialConstants;
+
   FieldUsage.cloned(FieldEntity field, EnumSet<MemberUse> pendingUse,
       {this.hasInit, this.hasRead, this.hasWrite})
       : super.cloned(field, pendingUse);
@@ -199,6 +211,9 @@
   }
 
   @override
+  Iterable<ConstantValue> get initialConstants => _initialConstants ?? const [];
+
+  @override
   bool get hasPendingNormalUse => !fullyUsed;
 
   @override
@@ -218,6 +233,13 @@
   }
 
   @override
+  EnumSet<MemberUse> constantInit(ConstantValue constant) {
+    _initialConstants ??= [];
+    _initialConstants.add(constant);
+    return init();
+  }
+
+  @override
   EnumSet<MemberUse> read() {
     if (hasRead) {
       return MemberUses.NONE;
@@ -263,7 +285,8 @@
 
   @override
   String toString() => 'FieldUsage($entity,hasInit=$hasInit,hasRead=$hasRead,'
-      'hasWrite=$hasWrite,pendingUse=${_pendingUse.iterable(MemberUse.values)}';
+      'hasWrite=$hasWrite,pendingUse=${_pendingUse.iterable(MemberUse.values)},'
+      'initialConstants=${initialConstants.map((c) => c.toStructuredText())})';
 }
 
 class FinalFieldUsage extends MemberUsage {
@@ -272,6 +295,8 @@
   @override
   bool hasRead;
 
+  List<ConstantValue> _initialConstants;
+
   FinalFieldUsage.cloned(FieldEntity field, EnumSet<MemberUse> pendingUse,
       {this.hasInit, this.hasRead})
       : super.cloned(field, pendingUse);
@@ -286,6 +311,9 @@
   }
 
   @override
+  Iterable<ConstantValue> get initialConstants => _initialConstants ?? const [];
+
+  @override
   bool get hasPendingNormalUse => !fullyUsed;
 
   @override
@@ -305,6 +333,13 @@
   }
 
   @override
+  EnumSet<MemberUse> constantInit(ConstantValue constant) {
+    _initialConstants ??= [];
+    _initialConstants.add(constant);
+    return init();
+  }
+
+  @override
   EnumSet<MemberUse> read() {
     if (hasRead) {
       return MemberUses.NONE;
@@ -337,7 +372,8 @@
 
   @override
   String toString() => 'FinalFieldUsage($entity,hasInit=$hasInit,'
-      'hasRead=$hasRead,pendingUse=${_pendingUse.iterable(MemberUse.values)}';
+      'hasRead=$hasRead,pendingUse=${_pendingUse.iterable(MemberUse.values)},'
+      'initialConstants=${initialConstants.map((c) => c.toStructuredText())})';
 }
 
 class FunctionUsage extends MemberUsage {
@@ -817,6 +853,9 @@
   EnumSet<MemberUse> init() => normalUse();
 
   @override
+  EnumSet<MemberUse> constantInit(ConstantValue constant) => normalUse();
+
+  @override
   EnumSet<MemberUse> read() => tearOff();
 
   @override
@@ -829,6 +868,9 @@
   EnumSet<MemberUse> fullyUse() => normalUse();
 
   @override
+  Iterable<ConstantValue> get initialConstants => null;
+
+  @override
   bool get hasPendingNormalUse => _pendingUse.contains(MemberUse.NORMAL);
 
   @override
diff --git a/pkg/compiler/lib/src/universe/resolution_world_builder.dart b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
index 008a742..7415ea2 100644
--- a/pkg/compiler/lib/src/universe/resolution_world_builder.dart
+++ b/pkg/compiler/lib/src/universe/resolution_world_builder.dart
@@ -776,9 +776,12 @@
       case StaticUseKind.SET:
         useSet.addAll(usage.write());
         break;
-      case StaticUseKind.INIT:
+      case StaticUseKind.FIELD_INIT:
         useSet.addAll(usage.init());
         break;
+      case StaticUseKind.FIELD_CONSTANT_INIT:
+        useSet.addAll(usage.constantInit(staticUse.constant));
+        break;
       case StaticUseKind.INVOKE:
         registerStaticInvocation(staticUse);
         useSet.addAll(usage.invoke(staticUse.callStructure));
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index c8984b2..01b0d07 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -160,7 +160,8 @@
   INVOKE,
   GET,
   SET,
-  INIT,
+  FIELD_INIT,
+  FIELD_CONSTANT_INIT,
 }
 
 /// Statically known use of an [Entity].
@@ -174,12 +175,14 @@
   final InterfaceType type;
   final CallStructure callStructure;
   final ImportEntity deferredImport;
+  final ConstantValue constant;
 
   StaticUse.internal(Entity element, this.kind,
       {this.type,
       this.callStructure,
       this.deferredImport,
-      typeArgumentsHash: 0})
+      typeArgumentsHash: 0,
+      this.constant})
       : this.element = element,
         this.hashCode = Hashing.listHash([
           element,
@@ -187,7 +190,8 @@
           type,
           typeArgumentsHash,
           callStructure,
-          deferredImport
+          deferredImport,
+          constant
         ]);
 
   /// Short textual representation use for testing.
@@ -199,7 +203,7 @@
       case StaticUseKind.SET:
         sb.write('set:');
         break;
-      case StaticUseKind.INIT:
+      case StaticUseKind.FIELD_INIT:
         sb.write('init:');
         break;
       case StaticUseKind.CLOSURE:
@@ -238,6 +242,10 @@
       sb.write(deferredImport.name);
       sb.write('}');
     }
+    if (constant != null) {
+      sb.write('=');
+      sb.write(constant.toStructuredText());
+    }
     return sb.toString();
   }
 
@@ -321,7 +329,7 @@
             "or static method."));
     assert(element.isField,
         failedAt(element, "Static init element $element must be a field."));
-    return new StaticUse.internal(element, StaticUseKind.INIT);
+    return new StaticUse.internal(element, StaticUseKind.FIELD_INIT);
   }
 
   /// Invocation of a super method [element] with the given [callStructure].
@@ -541,7 +549,18 @@
         element.isInstanceMember,
         failedAt(
             element, "Field init element $element must be an instance field."));
-    return new StaticUse.internal(element, StaticUseKind.INIT);
+    return new StaticUse.internal(element, StaticUseKind.FIELD_INIT);
+  }
+
+  /// Constant initialization of an instance field [element].
+  factory StaticUse.fieldConstantInit(
+      FieldEntity element, ConstantValue constant) {
+    assert(
+        element.isInstanceMember,
+        failedAt(
+            element, "Field init element $element must be an instance field."));
+    return new StaticUse.internal(element, StaticUseKind.FIELD_CONSTANT_INIT,
+        constant: constant);
   }
 
   /// Read access of an instance field or boxed field [element].
@@ -603,12 +622,14 @@
   @override
   bool operator ==(other) {
     if (identical(this, other)) return true;
-    if (other is! StaticUse) return false;
-    return element == other.element &&
+    return other is StaticUse &&
+        element == other.element &&
         kind == other.kind &&
         type == other.type &&
         callStructure == other.callStructure &&
-        equalElements(typeArguments, other.typeArguments);
+        equalElements(typeArguments, other.typeArguments) &&
+        deferredImport == other.deferredImport &&
+        constant == other.constant;
   }
 
   @override
diff --git a/pkg/dartfix/lib/src/driver.dart b/pkg/dartfix/lib/src/driver.dart
index ba7cea7..42bec0e 100644
--- a/pkg/dartfix/lib/src/driver.dart
+++ b/pkg/dartfix/lib/src/driver.dart
@@ -179,10 +179,8 @@
     if (shouldApplyChanges(result)) {
       for (SourceFileEdit fileEdit in result.edits) {
         final file = new File(fileEdit.file);
-        String code = await file.readAsString();
-        for (SourceEdit edit in fileEdit.edits) {
-          code = edit.apply(code);
-        }
+        String code = file.existsSync() ? file.readAsStringSync() : '';
+        code = SourceEdit.applySequence(code, fileEdit.edits);
         await file.writeAsString(code);
       }
       logger.stdout(ansi.emphasized('Changes applied.'));
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 676be05..7a76be5 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -2754,17 +2754,18 @@
             body, parameters.parameters.last.declaredElement));
 
     JS.Block code = isSync
-        ? _emitFunctionBody(element, parameters, body)
-        : JS.Block([
-            _emitGeneratorFunction(element, parameters, body).toReturn()
-              ..sourceInformation = _nodeStart(body)
-          ]);
+        ? _emitSyncFunctionBody(element, parameters, body)
+        : _emitGeneratorFunctionBody(element, parameters, body);
 
     code = super.exitFunction(element.name, formals, code);
     return JS.Fun(formals, code);
   }
 
-  JS.Block _emitFunctionBody(ExecutableElement element,
+  /// Emits a `sync` function body (the default in Dart)
+  ///
+  /// To emit an `async`, `sync*`, or `async*` function body, use
+  /// [_emitGeneratorFunctionBody] instead.
+  JS.Block _emitSyncFunctionBody(ExecutableElement element,
       FormalParameterList parameters, FunctionBody body) {
     var savedFunction = _currentFunction;
     _currentFunction = body;
@@ -2785,6 +2786,40 @@
     return block;
   }
 
+  /// Emits an `async`, `sync*`, or `async*` function body.
+  ///
+  /// The body will perform these steps:
+  ///
+  /// - Run the argument initializers. These must be run synchronously
+  ///   (e.g. covariance checks), and this helps performance.
+  /// - Return the generator function, wrapped with the appropriate type
+  ///   (`Future`, `Itearble`, and `Stream` respectively).
+  ///
+  /// To emit a `sync` function body (the default in Dart), use
+  /// [_emitSyncFunctionBody] instead.
+  JS.Block _emitGeneratorFunctionBody(ExecutableElement element,
+      FormalParameterList parameters, FunctionBody body) {
+    var savedFunction = _currentFunction;
+    _currentFunction = body;
+
+    var initArgs = _emitArgumentInitializers(element, parameters);
+    var block = JS.Block([
+      _emitGeneratorFunction(element, parameters, body).toReturn()
+        ..sourceInformation = _nodeStart(body)
+    ]);
+    if (initArgs != null) block = JS.Block([initArgs, block]);
+
+    _currentFunction = savedFunction;
+
+    if (block.isScope) {
+      // TODO(jmesserly: JS AST printer does not understand the need to emit a
+      // nested scoped block in a JS function. So we need to add a non-scoped
+      // wrapper to ensure it gets printed.
+      block = JS.Block([block]);
+    }
+    return block;
+  }
+
   JS.Block _emitFunctionScopedBody(
       FunctionBody body, ExecutableElement element) {
     var block = body.accept(this) as JS.Block;
@@ -2830,9 +2865,13 @@
 
       // Visit the body with our async* controller set.
       //
-      // TODO(jmesserly): this will emit argument initializers (for default
-      // values) inside the generator function body. Is that the best place?
-      var jsBody = _emitFunctionBody(element, parameters, body);
+      // Note: we intentionally don't emit argument initializers here, because
+      // they were already emitted outside of the generator expression.
+      var savedFunction = _currentFunction;
+      _currentFunction = body;
+      var jsBody = _emitFunctionScopedBody(body, element);
+      _currentFunction = savedFunction;
+
       var genFn = JS.Fun(jsParams, jsBody, isGenerator: true);
 
       // Name the function if possible, to get better stack traces.
diff --git a/pkg/dev_compiler/lib/src/compiler/js_utils.dart b/pkg/dev_compiler/lib/src/compiler/js_utils.dart
index a0275c6..74820eb 100644
--- a/pkg/dev_compiler/lib/src/compiler/js_utils.dart
+++ b/pkg/dev_compiler/lib/src/compiler/js_utils.dart
@@ -25,18 +25,20 @@
   return fn;
 }
 
-Set<Identifier> findMutatedVariables(Node scope) {
+Set<String> findMutatedVariables(Node scope) {
   var v = MutationVisitor();
   scope.accept(v);
   return v.mutated;
 }
 
 class MutationVisitor extends BaseVisitor {
-  final mutated = Set<Identifier>();
+  /// Using Identifier names instead of a more precise key may result in
+  /// mutations being imprecisely reported when variables shadow each other.
+  final mutated = Set<String>();
   @override
   visitAssignment(node) {
     var id = node.leftHandSide;
-    if (id is Identifier) mutated.add(id);
+    if (id is Identifier) mutated.add(id.name);
     super.visitAssignment(node);
   }
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/builder.dart b/pkg/dev_compiler/lib/src/js_ast/builder.dart
index d81f7e3..fc44cb9 100644
--- a/pkg/dev_compiler/lib/src/js_ast/builder.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/builder.dart
@@ -293,59 +293,99 @@
     return Template.withStatementResult(ast);
   }
 
-  /// Creates a literal js string from [value].
+  /// Creates a literal js string from [value], escaped for use in a UTF-8
+  /// output.
   LiteralString escapedString(String value, [String quote = '"']) {
-    // Start by escaping the backslashes.
-    String escaped = value.replaceAll('\\', '\\\\');
+    int otherEscapes = 0;
+    int unpairedSurrogates = 0;
 
-    // Replace $ in template strings:
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-template-literal-lexical-components
-    var quoteReplace = quote == '`' ? r'`$' : quote;
+    int quoteRune = quote.codeUnitAt(0);
 
-    // http://www.ecma-international.org/ecma-262/6.0/#sec-literals-string-literals
-    // > All code points may appear literally in a string literal except for the
-    // > closing quote code points, U+005C (REVERSE SOLIDUS),
-    // > U+000D (CARRIAGE RETURN), U+2028 (LINE SEPARATOR),
-    // > U+2029 (PARAGRAPH SEPARATOR), and U+000A (LINE FEED).
-    var re = RegExp('[\n\r$quoteReplace\b\f\t\v\u2028\u2029]');
-    escaped = escaped.replaceAllMapped(re, (m) {
-      switch (m.group(0)) {
-        case "\n":
-          return r"\n";
-        case "\r":
-          return r"\r";
-        case "\u2028":
-          return r"\u2028";
-        case "\u2029":
-          return r"\u2029";
-        // Quotes and $ are only replaced if they conflict with the containing
-        // quote, see regex above.
-        case '"':
-          return r'\"';
-        case "'":
-          return r"\'";
-        case "`":
-          return r"\`";
-        case r"$":
-          return r"\$";
-        // TODO(jmesserly): these don't need to be escaped for correctness,
-        // but they are conventionally escaped.
-        case "\b":
-          return r"\b";
-        case "\t":
-          return r"\t";
-        case "\f":
-          return r"\f";
-        case "\v":
-          return r"\v";
+    for (int rune in value.runes) {
+      if (rune == charCodes.$BACKSLASH) {
+        ++otherEscapes;
+      } else if (rune == charCodes.$LF ||
+          rune == charCodes.$CR ||
+          rune == charCodes.$LS ||
+          rune == charCodes.$PS) {
+        // Line terminators.
+        ++otherEscapes;
+      } else if (rune == charCodes.$BS ||
+          rune == charCodes.$TAB ||
+          rune == charCodes.$VTAB ||
+          rune == charCodes.$FF) {
+        ++otherEscapes;
+      } else if (rune == quoteRune ||
+          rune == charCodes.$$ && quoteRune == charCodes.$BACKPING) {
+        ++otherEscapes;
+      } else if (_isUnpairedSurrogate(rune)) {
+        ++unpairedSurrogates;
       }
-      throw 'unreachable';
-    });
-    LiteralString result = LiteralString('$quote$escaped$quote');
-    // We don't escape quotes of a different style under the assumption that the
-    // string is wrapped into quotes. Verify that assumption.
-    assert(result.value.codeUnitAt(0) == quote.codeUnitAt(0));
-    return result;
+    }
+
+    if (otherEscapes == 0 && unpairedSurrogates == 0) {
+      return string(value, quote);
+    }
+
+    var sb = new StringBuffer();
+
+    for (int rune in value.runes) {
+      String escape = _irregularEscape(rune, quote);
+      if (escape != null) {
+        sb.write(escape);
+        continue;
+      }
+      if (rune == charCodes.$LS ||
+          rune == charCodes.$PS ||
+          _isUnpairedSurrogate(rune)) {
+        if (rune < 0x100) {
+          sb.write(r'\x');
+          sb.write(rune.toRadixString(16).padLeft(2, '0'));
+        } else if (rune < 0x10000) {
+          sb.write(r'\u');
+          sb.write(rune.toRadixString(16).padLeft(4, '0'));
+        } else {
+          sb.write(r'\u{');
+          sb.write(rune.toRadixString(16));
+          sb.write('}');
+        }
+      } else {
+        sb.writeCharCode(rune);
+      }
+    }
+
+    return string(sb.toString(), quote);
+  }
+
+  static bool _isUnpairedSurrogate(int code) => (code & 0xFFFFF800) == 0xD800;
+
+  static String _irregularEscape(int code, String quote) {
+    switch (code) {
+      case charCodes.$SQ:
+        return quote == "'" ? r"\'" : "'";
+      case charCodes.$DQ:
+        return quote == '"' ? r'\"' : '"';
+      case charCodes.$BACKPING:
+        return quote == '`' ? r'\`' : '`';
+      case charCodes.$$:
+        // Escape $ inside of template strings.
+        return quote == '`' ? r'\$' : r'$';
+      case charCodes.$BACKSLASH:
+        return r'\\';
+      case charCodes.$BS:
+        return r'\b';
+      case charCodes.$TAB:
+        return r'\t';
+      case charCodes.$LF:
+        return r'\n';
+      case charCodes.$VTAB:
+        return r'\v';
+      case charCodes.$FF:
+        return r'\f';
+      case charCodes.$CR:
+        return r'\r';
+    }
+    return null;
   }
 
   /// Creates a literal js string from [value].
diff --git a/pkg/dev_compiler/lib/src/js_ast/nodes.dart b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
index 68d15cd..9cd3b7b 100644
--- a/pkg/dev_compiler/lib/src/js_ast/nodes.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/nodes.dart
@@ -889,6 +889,8 @@
   @override
   int get precedenceLevel => PRIMARY;
   @override
+  String get parameterName => name.name;
+  @override
   Node _clone() => DestructuredVariable(
       name: name,
       property: property,
@@ -1146,7 +1148,9 @@
   int get precedenceLevel => UNARY;
 }
 
-abstract class Parameter implements Expression, VariableBinding {}
+abstract class Parameter implements Expression, VariableBinding {
+  String get parameterName;
+}
 
 class Identifier extends Expression implements Parameter {
   final String name;
@@ -1164,6 +1168,7 @@
   Identifier _clone() => Identifier(name, allowRename: allowRename);
   T accept<T>(NodeVisitor<T> visitor) => visitor.visitIdentifier(this);
   int get precedenceLevel => PRIMARY;
+  String get parameterName => name;
   void visitChildren(NodeVisitor visitor) {}
 }
 
@@ -1182,6 +1187,7 @@
   }
 
   int get precedenceLevel => PRIMARY;
+  String get parameterName => parameter.parameterName;
 }
 
 class This extends Expression {
@@ -1641,6 +1647,10 @@
     throw "InterpolatedParameter.name must not be invoked";
   }
 
+  String get parameterName {
+    throw "InterpolatedParameter.parameterName must not be invoked";
+  }
+
   bool shadows(Set<String> names) => false;
 
   bool get allowRename => false;
@@ -1718,6 +1728,8 @@
 
   int get precedenceLevel => PRIMARY;
   String get name => throw '$runtimeType does not support this member.';
+  String get parameterName =>
+      throw '$runtimeType does not support this member.';
   bool get allowRename => false;
 }
 
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 6076be4..55f5c10 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -1811,8 +1811,20 @@
     if (isUnsupportedFactoryConstructor(node)) return null;
 
     var function = node.function;
+
+    /// Note: factory constructors can't use `sync*`/`async*`/`async` bodies
+    /// because it would return the wrong type, so we can assume `sync` here.
+    ///
+    /// We can also skip the logic in [_emitFunction] related to operator
+    /// methods like ==, as well as generic method parameters.
+    ///
+    /// If a future Dart version allows factory constructors to take their
+    /// own type parameters, this will need to be changed to call
+    /// [_emitFunction] instead.
+    var jsBody = _emitSyncFunctionBody(function);
+
     return JS.Method(_constructorName(node.name.name),
-        JS.Fun(_emitParameters(function), _emitFunctionBody(function)),
+        JS.Fun(_emitParameters(function), jsBody),
         isStatic: true)
       ..sourceInformation = _nodeEnd(node.fileEndOffset);
   }
@@ -2653,16 +2665,11 @@
     // potentially mutated in Kernel. For now we assume all parameters are.
     super.enterFunction(name, formals, () => true);
 
-    JS.Block code = isSync
-        ? _emitFunctionBody(f)
-        : JS.Block([
-            _emitGeneratorFunction(f, name).toReturn()
-              ..sourceInformation = _nodeStart(f)
-          ]);
+    JS.Block block =
+        isSync ? _emitSyncFunctionBody(f) : _emitGeneratorFunctionBody(f, name);
 
-    code = super.exitFunction(name, formals, code);
-
-    return JS.Fun(formals, code);
+    block = super.exitFunction(name, formals, block);
+    return JS.Fun(formals, block);
   }
 
   List<JS.Parameter> _emitParameters(FunctionNode f) {
@@ -2692,10 +2699,13 @@
         .toList();
   }
 
-  JS.Expression _emitGeneratorFunction(FunctionNode function, String name) {
-    // Transforms `sync*` `async` and `async*` function bodies
-    // using ES6 generators.
-
+  /// Transforms `sync*` `async` and `async*` function bodies
+  /// using ES6 generators.
+  ///
+  /// This is an internal part of [_emitGeneratorFunctionBody] and should not be
+  /// called directly.
+  JS.Expression _emitGeneratorFunctionExpression(
+      FunctionNode function, String name) {
     emitGeneratorFn(List<JS.Parameter> getParameters(JS.Block jsBody)) {
       var savedController = _asyncStarController;
       _asyncStarController = function.asyncMarker == AsyncMarker.AsyncStar
@@ -2706,9 +2716,10 @@
       _superDisallowed(() {
         // Visit the body with our async* controller set.
         //
-        // TODO(jmesserly): this will emit argument initializers (for default
-        // values) inside the generator function body. Is that the best place?
-        var jsBody = _emitFunctionBody(function);
+        // Note: we intentionally don't emit argument initializers here, because
+        // they were already emitted outside of the generator expression.
+        var jsBody = JS.Block(_withCurrentFunction(
+            function, () => [_emitFunctionScopedBody(function)]));
         var genFn = JS.Fun(getParameters(jsBody), jsBody, isGenerator: true);
 
         // Name the function if possible, to get better stack traces.
@@ -2746,9 +2757,16 @@
       // In the future, we might be able to simplify this, see:
       // https://github.com/dart-lang/sdk/issues/28320
       var jsParams = _emitParameters(function);
-      var gen = emitGeneratorFn((fnBody) => jsParams =
-          jsParams.where(JS.findMutatedVariables(fnBody).contains).toList());
-      if (jsParams.isNotEmpty) gen = js.call('() => #(#)', [gen, jsParams]);
+      var mutatedParams = jsParams;
+      var gen = emitGeneratorFn((fnBody) {
+        var mutatedVars = JS.findMutatedVariables(fnBody);
+        mutatedParams = jsParams
+            .where((id) => mutatedVars.contains(id.parameterName))
+            .toList();
+        return mutatedParams;
+      });
+      if (mutatedParams.isNotEmpty)
+        gen = js.call('() => #(#)', [gen, mutatedParams]);
 
       var returnType =
           _getExpectedReturnType(function, coreTypes.iterableClass);
@@ -2801,8 +2819,16 @@
     return const DynamicType();
   }
 
-  JS.Block _emitFunctionBody(FunctionNode f) {
+  /// Emits a `sync` function body (the default in Dart)
+  ///
+  /// To emit an `async`, `sync*`, or `async*` function body, use
+  /// [_emitGeneratorFunctionBody] instead.
+  JS.Block _emitSyncFunctionBody(FunctionNode f) {
+    assert(f.asyncMarker == AsyncMarker.Sync);
+
     var block = _withCurrentFunction(f, () {
+      /// For (normal) `sync` bodies, execute the function body immediately
+      /// after the argument initializers.
       var block = _emitArgumentInitializers(f);
       block.add(_emitFunctionScopedBody(f));
       return block;
@@ -2811,6 +2837,27 @@
     return JS.Block(block);
   }
 
+  /// Emits an `async`, `sync*`, or `async*` function body.
+  ///
+  /// The body will perform these steps:
+  ///
+  /// - Run the argument initializers. These must be run synchronously
+  ///   (e.g. covariance checks), and this helps performance.
+  /// - Return the generator function, wrapped with the appropriate type
+  ///   (`Future`, `Itearble`, and `Stream` respectively).
+  ///
+  /// To emit a `sync` function body (the default in Dart), use
+  /// [_emitSyncFunctionBody] instead.
+  JS.Block _emitGeneratorFunctionBody(FunctionNode f, String name) {
+    assert(f.asyncMarker != AsyncMarker.Sync);
+
+    var statements =
+        _withCurrentFunction(f, () => _emitArgumentInitializers(f));
+    statements.add(_emitGeneratorFunctionExpression(f, name).toReturn()
+      ..sourceInformation = _nodeStart(f));
+    return JS.Block(statements);
+  }
+
   List<JS.Statement> _withCurrentFunction(
       FunctionNode fn, List<JS.Statement> action()) {
     var savedFunction = _currentFunction;
@@ -3093,7 +3140,7 @@
     //
     // NOTE: we do sometimes need to handle this because Dart and JS rules are
     // slightly different (in Dart, there is a nested scope), but that's handled
-    // by _emitFunctionBody.
+    // by _emitSyncFunctionBody.
     var isScope = !identical(node.parent, _currentFunction);
     return JS.Block(node.statements.map(_visitStatement).toList(),
         isScope: isScope);
@@ -4745,6 +4792,12 @@
   }
 
   @override
+  visitInstanceCreation(InstanceCreation node) {
+    // Only occurs inside unevaluated constants.
+    throw new UnsupportedError("Instance creation");
+  }
+
+  @override
   visitIsExpression(IsExpression node) {
     return _emitIsExpression(node.operand, node.type);
   }
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index 76b6570..1ecdfc0 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -230,7 +230,9 @@
   @override
   visitConstantExpression(ConstantExpression node) {
     var c = node.constant;
-    return c is PrimitiveConstant && c.value == null;
+    if (c is UnevaluatedConstant) return c.expression.accept(this);
+    if (c is PrimitiveConstant) return c.value == null;
+    return false;
   }
 
   @override
diff --git a/pkg/dev_compiler/tool/ddb b/pkg/dev_compiler/tool/ddb
index ea3a7a5..b5cb2fa 100755
--- a/pkg/dev_compiler/tool/ddb
+++ b/pkg/dev_compiler/tool/ddb
@@ -40,6 +40,8 @@
         abbr: 'p',
         help: 'Run with the corresponding chrome/V8 debugging port open.',
         defaultsTo: '9222')
+    ..addOption('enable-experiment',
+        help: 'Run with specified experiments enabled.', defaultsTo: '')
     ..addOption('binary', abbr: 'b', help: 'Runtime binary path.');
 
   var options = parser.parse(args);
@@ -53,6 +55,7 @@
   var debug = options['debug'] as bool;
   var kernel = options['kernel'] as bool;
   var binary = options['binary'] as String;
+  var experiment = options['enable-experiment'] as String;
   var port = int.parse(options['port'] as String);
 
   var dartBinary = Platform.resolvedExecutable;
@@ -121,6 +124,7 @@
       '--kernel',
       '--modules=$mod',
       '--dart-sdk-summary=$ddcSdk',
+      '--enable-experiment=$experiment',
       '-o',
       '$libRoot/$basename.js',
       entry
@@ -130,6 +134,7 @@
       '--modules=$mod',
       '--dart-sdk-summary=$ddcSdk',
       '--library-root=$libRoot',
+      '--enable-experiment=$experiment',
       '-o',
       '$libRoot/$basename.js',
       entry
diff --git a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
index 4f0b8a3..6f37ab2 100644
--- a/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
+++ b/pkg/front_end/lib/src/api_unstable/bazel_worker.dart
@@ -89,7 +89,8 @@
       ..librariesSpecificationUri = librariesSpecificationUri
       ..target = target
       ..fileSystem = fileSystem
-      ..omitPlatform = true;
+      ..omitPlatform = true
+      ..environmentDefines = const {};
 
     processedOpts = new ProcessedOptions(options: options);
     cachedSdkInput = WorkerInputComponent(
@@ -190,7 +191,8 @@
     ..inputSummaries = summaryInputs
     ..linkedDependencies = linkedInputs
     ..target = target
-    ..fileSystem = fileSystem;
+    ..fileSystem = fileSystem
+    ..environmentDefines = const {};
 
   ProcessedOptions processedOpts = new ProcessedOptions(options: options);
 
diff --git a/pkg/front_end/lib/src/api_unstable/dart2js.dart b/pkg/front_end/lib/src/api_unstable/dart2js.dart
index 7b95a51..8ec174d 100644
--- a/pkg/front_end/lib/src/api_unstable/dart2js.dart
+++ b/pkg/front_end/lib/src/api_unstable/dart2js.dart
@@ -114,7 +114,8 @@
     Uri packagesFileUri,
     {List<Uri> dependencies,
     Map<ExperimentalFlag, bool> experimentalFlags,
-    bool verify: false}) {
+    bool verify: false,
+    bool enableAsserts: false}) {
   bool mapEqual(Map<ExperimentalFlag, bool> a, Map<ExperimentalFlag, bool> b) {
     if (a == null || b == null) return a == b;
     if (a.length != b.length) return false;
@@ -149,7 +150,8 @@
     ..librariesSpecificationUri = librariesSpecificationUri
     ..packagesFileUri = packagesFileUri
     ..experimentalFlags = experimentalFlags
-    ..verify = verify;
+    ..verify = verify
+    ..enableAsserts = enableAsserts;
 
   ProcessedOptions processedOpts = new ProcessedOptions(options: options);
 
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index 828f7a4..de4fb58 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -1102,6 +1102,36 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
+        Constant
+            _constant)> templateConstEvalElementImplementsEqual = const Template<
+        Message Function(Constant _constant)>(
+    messageTemplate:
+        r"""The element '#constant' does not have a primitive operator '=='.""",
+    withArguments: _withArgumentsConstEvalElementImplementsEqual);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant _constant)>
+    codeConstEvalElementImplementsEqual =
+    const Code<Message Function(Constant _constant)>(
+        "ConstEvalElementImplementsEqual",
+        templateConstEvalElementImplementsEqual,
+        analyzerCodes: <String>["CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS"]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalElementImplementsEqual(Constant _constant) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> constantParts = labeler.labelConstant(_constant);
+  String constant = constantParts.join();
+  return new Message(codeConstEvalElementImplementsEqual,
+      message:
+          """The element '${constant}' does not have a primitive operator '=='.""" +
+              labeler.originMessages,
+      arguments: {'constant': _constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeConstEvalFailedAssertion = messageConstEvalFailedAssertion;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -1212,6 +1242,40 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
+        Constant _constant,
+        DartType
+            _type)> templateConstEvalInvalidEqualsOperandType = const Template<
+        Message Function(Constant _constant, DartType _type)>(
+    messageTemplate:
+        r"""Binary operator '==' requires receiver constant '#constant' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '#type'.""",
+    withArguments: _withArgumentsConstEvalInvalidEqualsOperandType);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant _constant, DartType _type)>
+    codeConstEvalInvalidEqualsOperandType =
+    const Code<Message Function(Constant _constant, DartType _type)>(
+  "ConstEvalInvalidEqualsOperandType",
+  templateConstEvalInvalidEqualsOperandType,
+);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalInvalidEqualsOperandType(
+    Constant _constant, DartType _type) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> constantParts = labeler.labelConstant(_constant);
+  List<Object> typeParts = labeler.labelType(_type);
+  String constant = constantParts.join();
+  String type = typeParts.join();
+  return new Message(codeConstEvalInvalidEqualsOperandType,
+      message:
+          """Binary operator '==' requires receiver constant '${constant}' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '${type}'.""" +
+              labeler.originMessages,
+      arguments: {'constant': _constant, 'type': _type});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+    Message Function(
         String string,
         Constant
             _constant)> templateConstEvalInvalidMethodInvocation = const Template<
@@ -1429,6 +1493,35 @@
     message: r"""Iteration can't be used in a constant set.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<Message Function(Constant _constant)>
+    templateConstEvalKeyImplementsEqual =
+    const Template<Message Function(Constant _constant)>(
+        messageTemplate:
+            r"""The key '#constant' does not have a primitive operator '=='.""",
+        withArguments: _withArgumentsConstEvalKeyImplementsEqual);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Message Function(Constant _constant)>
+    codeConstEvalKeyImplementsEqual =
+    const Code<Message Function(Constant _constant)>(
+        "ConstEvalKeyImplementsEqual", templateConstEvalKeyImplementsEqual,
+        analyzerCodes: <String>[
+      "CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS"
+    ]);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsConstEvalKeyImplementsEqual(Constant _constant) {
+  TypeLabeler labeler = new TypeLabeler();
+  List<Object> constantParts = labeler.labelConstant(_constant);
+  String constant = constantParts.join();
+  return new Message(codeConstEvalKeyImplementsEqual,
+      message:
+          """The key '${constant}' does not have a primitive operator '=='.""" +
+              labeler.originMessages,
+      arguments: {'constant': _constant});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         String string,
@@ -2539,7 +2632,7 @@
 const Template<Message Function(Token token)> templateDuplicatedModifier =
     const Template<Message Function(Token token)>(
         messageTemplate: r"""The modifier '#lexeme' was already specified.""",
-        tipTemplate: r"""Try removing all but one occurance of the modifier.""",
+        tipTemplate: r"""Try removing all but one occurence of the modifier.""",
         withArguments: _withArgumentsDuplicatedModifier);
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -2553,7 +2646,7 @@
   String lexeme = token.lexeme;
   return new Message(codeDuplicatedModifier,
       message: """The modifier '${lexeme}' was already specified.""",
-      tip: """Try removing all but one occurance of the modifier.""",
+      tip: """Try removing all but one occurence of the modifier.""",
       arguments: {'token': token});
 }
 
@@ -3159,7 +3252,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageExportAfterPart = const MessageCode("ExportAfterPart",
     index: 75,
-    message: r"""Export directives must preceed part directives.""",
+    message: r"""Export directives must precede part directives.""",
     tip: r"""Try moving the export directives before the part directives.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -4415,7 +4508,7 @@
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageImportAfterPart = const MessageCode("ImportAfterPart",
     index: 10,
-    message: r"""Import directives must preceed part directives.""",
+    message: r"""Import directives must precede part directives.""",
     tip: r"""Try moving the import directives before the part directives.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -6693,7 +6786,7 @@
     "MissingOperatorKeyword",
     index: 31,
     message:
-        r"""Operator declarations must be preceeded by the keyword 'operator'.""",
+        r"""Operator declarations must be preceded by the keyword 'operator'.""",
     tip: r"""Try adding the keyword 'operator'.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -9211,6 +9304,16 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeTypeBeforeFactory = messageTypeBeforeFactory;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageTypeBeforeFactory = const MessageCode(
+    "TypeBeforeFactory",
+    index: 97,
+    message: r"""Factory constructors cannot have a return type.""",
+    tip: r"""Try removing the type appearing before 'factory'.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(String name)> templateTypeNotFound =
     const Template<Message Function(String name)>(
         messageTemplate: r"""Type '#name' not found.""",
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 203386b..e360c2e 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -68,14 +68,10 @@
 
 import 'collections.dart'
     show
-        ForElement,
-        ForInElement,
-        ForInMapEntry,
-        ForMapEntry,
-        IfElement,
-        IfMapEntry,
         SpreadElement,
-        SpreadMapEntry;
+        SpreadMapEntry,
+        convertToMapEntry,
+        isConvertibleToMapEntry;
 
 import 'constness.dart' show Constness;
 
@@ -914,10 +910,22 @@
 
   void resolveRedirectingFactoryTargets() {
     for (StaticInvocation invocation in redirectingFactoryInvocations) {
-      // If the invocation was invalid, it has already been desugared into
-      // an exception throwing expression. There is nothing to resolve anymore.
-      if (invocation.parent == null) {
-        continue;
+      // If the invocation was invalid, it or its parent has already been
+      // desugared into an exception throwing expression.  There is nothing to
+      // resolve anymore.  Note that in the case where the invocation's parent
+      // was invalid, type inference won't reach the invocation node and won't
+      // set its inferredType field.  If type inference is disabled, reach to
+      // the outtermost parent to check if the node is a dead code.
+      if (invocation.parent == null) continue;
+      if (_typeInferrer != null) {
+        if (invocation is FactoryConstructorInvocationJudgment &&
+            invocation.inferredType == null) {
+          continue;
+        }
+      } else {
+        TreeNode parent = invocation.parent;
+        while (parent is! Component && parent != null) parent = parent.parent;
+        if (parent == null) continue;
       }
 
       Procedure initialTarget = invocation.target;
@@ -2308,10 +2316,6 @@
       push(invalidCollectionElement);
       return;
     }
-    if (entry == invalidCollectionElement) {
-      push(invalidCollectionElement);
-      return;
-    }
     transformCollections = true;
     List<VariableDeclaration> variables =
         buildVariableDeclarations(variableOrExpression);
@@ -2545,7 +2549,7 @@
         if (setOrMapEntries[i] is MapEntry) {
           mapEntries[i] = setOrMapEntries[i];
         } else {
-          mapEntries[i] = convertToMapEntry(setOrMapEntries[i]);
+          mapEntries[i] = convertToMapEntry(setOrMapEntries[i], this);
         }
       }
       buildLiteralMap(typeArguments, constKeyword, leftBrace, mapEntries);
@@ -2572,56 +2576,6 @@
     push(forest.literalNull(token));
   }
 
-  bool isConvertibleToMapEntry(Expression element) {
-    if (element is SpreadElement) return true;
-    if (element is IfElement) {
-      return isConvertibleToMapEntry(element.then) &&
-          (element.otherwise == null ||
-              isConvertibleToMapEntry(element.otherwise));
-    }
-    if (element is ForElement) {
-      return isConvertibleToMapEntry(element.body);
-    }
-    if (element is ForInElement) {
-      return isConvertibleToMapEntry(element.body);
-    }
-    return false;
-  }
-
-  MapEntry convertToMapEntry(Expression element) {
-    if (element is SpreadElement) {
-      return new SpreadMapEntry(element.expression, element.isNullAware)
-        ..fileOffset = element.expression.fileOffset;
-    }
-    if (element is IfElement) {
-      return new IfMapEntry(
-          element.condition,
-          convertToMapEntry(element.then),
-          element.otherwise == null
-              ? null
-              : convertToMapEntry(element.otherwise))
-        ..fileOffset = element.fileOffset;
-    }
-    if (element is ForElement) {
-      return new ForMapEntry(element.variables, element.condition,
-          element.updates, convertToMapEntry(element.body))
-        ..fileOffset = element.fileOffset;
-    }
-    if (element is ForInElement) {
-      return new ForInMapEntry(element.variable, element.iterable,
-          element.prologue, convertToMapEntry(element.body), element.problem)
-        ..fileOffset = element.fileOffset;
-    }
-    return new MapEntry(
-        desugarSyntheticExpression(buildProblem(
-          fasta.templateExpectedAfterButGot.withArguments(':'),
-          element.fileOffset,
-          // TODO(danrubel): what is the length of the expression?
-          1,
-        )),
-        new NullLiteral());
-  }
-
   void buildLiteralMap(List<UnresolvedType<KernelTypeBuilder>> typeArguments,
       Token constKeyword, Token leftBrace, List<MapEntry> entries) {
     DartType keyType;
@@ -3726,13 +3680,25 @@
         token.next, token.offset, Constness.explicitConst);
   }
 
+  @override
   void beginIfControlFlow(Token ifToken) {
     // TODO(danrubel): consider removing this when control flow support is added
     // if the ifToken is not needed for error reporting
     push(ifToken);
   }
 
-  void handleElseControlFlow(Token elseToken) {}
+  @override
+  void beginThenControlFlow(Token token) {
+    Expression condition = popForValue();
+    enterThenForTypePromotion(condition);
+    push(condition);
+    super.beginThenControlFlow(token);
+  }
+
+  @override
+  void handleElseControlFlow(Token elseToken) {
+    typePromoter?.enterElse();
+  }
 
   @override
   void endIfControlFlow(Token token) {
@@ -3740,6 +3706,8 @@
     var entry = pop();
     var condition = pop(); // parenthesized expression
     Token ifToken = pop();
+    typePromoter?.enterElse();
+    typePromoter?.exitConditional();
     if (!library.loader.target.enableControlFlowCollections) {
       // TODO(danrubel): Report a more user friendly error message
       // when an experiment is not enabled
@@ -3750,10 +3718,6 @@
       push(invalidCollectionElement);
       return;
     }
-    if (entry == invalidCollectionElement) {
-      push(invalidCollectionElement);
-      return;
-    }
     transformCollections = true;
     if (entry is MapEntry) {
       push(forest.ifMapEntry(toValue(condition), entry, null, ifToken));
@@ -3769,6 +3733,7 @@
     var thenEntry = pop(); // then entry
     var condition = pop(); // parenthesized expression
     Token ifToken = pop();
+    typePromoter?.exitConditional();
     if (!library.loader.target.enableControlFlowCollections) {
       // TODO(danrubel): Report a more user friendly error message
       // when an experiment is not enabled
@@ -3779,11 +3744,6 @@
       push(invalidCollectionElement);
       return;
     }
-    if (thenEntry == invalidCollectionElement ||
-        elseEntry == invalidCollectionElement) {
-      push(invalidCollectionElement);
-      return;
-    }
     transformCollections = true;
     if (thenEntry is MapEntry) {
       if (elseEntry is MapEntry) {
@@ -3796,7 +3756,16 @@
             new SpreadMapEntry(elseEntry.expression, elseEntry.isNullAware),
             ifToken));
       } else {
-        push(invalidCollectionElement);
+        int offset = elseEntry is Expression
+            ? elseEntry.fileOffset
+            : offsetForToken(ifToken);
+        push(new MapEntry(
+            desugarSyntheticExpression(buildProblem(
+                fasta.templateExpectedAfterButGot.withArguments(':'),
+                offset,
+                1)),
+            new NullLiteral())
+          ..fileOffset = offsetForToken(ifToken));
       }
     } else if (elseEntry is MapEntry) {
       if (thenEntry is SpreadElement) {
@@ -3806,7 +3775,16 @@
             elseEntry,
             ifToken));
       } else {
-        push(invalidCollectionElement);
+        int offset = thenEntry is Expression
+            ? thenEntry.fileOffset
+            : offsetForToken(ifToken);
+        push(new MapEntry(
+            desugarSyntheticExpression(buildProblem(
+                fasta.templateExpectedAfterButGot.withArguments(':'),
+                offset,
+                1)),
+            new NullLiteral())
+          ..fileOffset = offsetForToken(ifToken));
       }
     } else {
       push(forest.ifElement(
@@ -4137,10 +4115,6 @@
       push(invalidCollectionElement);
       return;
     }
-    if (entry == invalidCollectionElement) {
-      push(invalidCollectionElement);
-      return;
-    }
     transformCollections = true;
     VariableDeclaration variable = buildForInVariable(lvalue);
     Expression problem = checkForInVariable(lvalue, variable, forToken);
diff --git a/pkg/front_end/lib/src/fasta/kernel/collections.dart b/pkg/front_end/lib/src/fasta/kernel/collections.dart
index c3a79d1..a943ece 100644
--- a/pkg/front_end/lib/src/fasta/kernel/collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/collections.dart
@@ -10,11 +10,12 @@
         DartType,
         Expression,
         MapEntry,
-        setParents,
+        NullLiteral,
         Statement,
-        transformList,
         TreeNode,
         VariableDeclaration,
+        setParents,
+        transformList,
         visitList;
 
 import 'package:kernel/type_environment.dart' show TypeEnvironment;
@@ -27,8 +28,13 @@
         TreeVisitor,
         Visitor;
 
+import '../messages.dart'
+    show templateExpectedAfterButGot, templateExpectedButGot;
+
 import '../problems.dart' show getFileUri, unsupported;
 
+import '../type_inference/inference_helper.dart' show InferenceHelper;
+
 /// Mixin for spread and control-flow elements.
 ///
 /// Spread and control-flow elements are not truly expressions and they cannot
@@ -55,6 +61,11 @@
 class SpreadElement extends Expression with ControlFlowElement {
   Expression expression;
   bool isNullAware;
+
+  /// The type of the elements of the collection that [expression] evaluates to.
+  ///
+  /// It is set during type inference and is used to add appropriate type casts
+  /// during the desugaring.
   DartType elementType;
 
   SpreadElement(this.expression, this.isNullAware) {
@@ -228,6 +239,11 @@
 class SpreadMapEntry extends TreeNode with ControlFlowMapEntry {
   Expression expression;
   bool isNullAware;
+
+  /// The type of the map entries of the map that [expression] evaluates to.
+  ///
+  /// It is set during type inference and is used to add appropriate type casts
+  /// during the desugaring.
   DartType entryType;
 
   SpreadMapEntry(this.expression, this.isNullAware) {
@@ -371,3 +387,90 @@
     }
   }
 }
+
+Expression convertToElement(MapEntry entry, InferenceHelper helper) {
+  if (entry is SpreadMapEntry) {
+    return new SpreadElement(entry.expression, entry.isNullAware)
+      ..fileOffset = entry.expression.fileOffset;
+  }
+  if (entry is IfMapEntry) {
+    return new IfElement(
+        entry.condition,
+        convertToElement(entry.then, helper),
+        entry.otherwise == null
+            ? null
+            : convertToElement(entry.otherwise, helper))
+      ..fileOffset = entry.fileOffset;
+  }
+  if (entry is ForMapEntry) {
+    return new ForElement(entry.variables, entry.condition, entry.updates,
+        convertToElement(entry.body, helper))
+      ..fileOffset = entry.fileOffset;
+  }
+  if (entry is ForInMapEntry) {
+    return new ForInElement(entry.variable, entry.iterable, entry.prologue,
+        convertToElement(entry.body, helper), entry.problem,
+        isAsync: entry.isAsync)
+      ..fileOffset = entry.fileOffset;
+  }
+  return helper.desugarSyntheticExpression(helper.buildProblem(
+    templateExpectedButGot.withArguments(','),
+    entry.fileOffset,
+    1,
+  ));
+}
+
+bool isConvertibleToMapEntry(Expression element) {
+  if (element is SpreadElement) return true;
+  if (element is IfElement) {
+    return isConvertibleToMapEntry(element.then) &&
+        (element.otherwise == null ||
+            isConvertibleToMapEntry(element.otherwise));
+  }
+  if (element is ForElement) {
+    return isConvertibleToMapEntry(element.body);
+  }
+  if (element is ForInElement) {
+    return isConvertibleToMapEntry(element.body);
+  }
+  return false;
+}
+
+MapEntry convertToMapEntry(Expression element, InferenceHelper helper) {
+  if (element is SpreadElement) {
+    return new SpreadMapEntry(element.expression, element.isNullAware)
+      ..fileOffset = element.expression.fileOffset;
+  }
+  if (element is IfElement) {
+    return new IfMapEntry(
+        element.condition,
+        convertToMapEntry(element.then, helper),
+        element.otherwise == null
+            ? null
+            : convertToMapEntry(element.otherwise, helper))
+      ..fileOffset = element.fileOffset;
+  }
+  if (element is ForElement) {
+    return new ForMapEntry(element.variables, element.condition,
+        element.updates, convertToMapEntry(element.body, helper))
+      ..fileOffset = element.fileOffset;
+  }
+  if (element is ForInElement) {
+    return new ForInMapEntry(
+        element.variable,
+        element.iterable,
+        element.prologue,
+        convertToMapEntry(element.body, helper),
+        element.problem,
+        isAsync: element.isAsync)
+      ..fileOffset = element.fileOffset;
+  }
+  return new MapEntry(
+      helper.desugarSyntheticExpression(helper.buildProblem(
+        templateExpectedAfterButGot.withArguments(':'),
+        element.fileOffset,
+        // TODO(danrubel): what is the length of the expression?
+        1,
+      )),
+      new NullLiteral());
+}
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 85c5de0..d35150d 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -49,15 +49,18 @@
         templateConstEvalDeferredLibrary,
         templateConstEvalDuplicateElement,
         templateConstEvalDuplicateKey,
+        templateConstEvalElementImplementsEqual,
         templateConstEvalFailedAssertionWithMessage,
         templateConstEvalFreeTypeParameter,
         templateConstEvalInvalidType,
         templateConstEvalInvalidBinaryOperandType,
+        templateConstEvalInvalidEqualsOperandType,
         templateConstEvalInvalidMethodInvocation,
         templateConstEvalInvalidPropertyGet,
         templateConstEvalInvalidStaticInvocation,
         templateConstEvalInvalidStringInterpolationOperand,
         templateConstEvalInvalidSymbolName,
+        templateConstEvalKeyImplementsEqual,
         templateConstEvalNegativeShift,
         templateConstEvalNonConstantLiteral,
         templateConstEvalNonConstantVariableGet,
@@ -122,6 +125,22 @@
   }
 }
 
+class JavaScriptIntConstant extends DoubleConstant {
+  final BigInt bigIntValue;
+  JavaScriptIntConstant(int value) : this.fromBigInt(BigInt.from(value));
+  JavaScriptIntConstant.fromDouble(double value)
+      : bigIntValue = BigInt.from(value),
+        super(value);
+  JavaScriptIntConstant.fromBigInt(this.bigIntValue)
+      : super(bigIntValue.toDouble());
+  JavaScriptIntConstant.fromUInt64(int value)
+      : this.fromBigInt(BigInt.from(value).toUnsigned(64));
+
+  DartType getType(TypeEnvironment types) => types.intType;
+
+  String toString() => '$bigIntValue';
+}
+
 class ConstantsTransformer extends Transformer {
   final ConstantEvaluator constantEvaluator;
   final TypeEnvironment typeEnvironment;
@@ -245,7 +264,7 @@
   void transformExpressions(List<Expression> nodes, TreeNode parent) {
     constantEvaluator.withNewEnvironment(() {
       for (int i = 0; i < nodes.length; ++i) {
-        nodes[i] = tryEvaluateAndTransformWithContext(parent, nodes[i])
+        nodes[i] = evaluateAndTransformWithContext(parent, nodes[i])
           ..parent = parent;
       }
     });
@@ -260,7 +279,7 @@
       transformAnnotations(variable.annotations, variable);
       if (variable.initializer != null) {
         variable.initializer =
-            tryEvaluateAndTransformWithContext(variable, variable.initializer)
+            evaluateAndTransformWithContext(variable, variable.initializer)
               ..parent = variable;
       }
     }
@@ -268,7 +287,7 @@
       transformAnnotations(variable.annotations, variable);
       if (variable.initializer != null) {
         variable.initializer =
-            tryEvaluateAndTransformWithContext(variable, variable.initializer)
+            evaluateAndTransformWithContext(variable, variable.initializer)
               ..parent = variable;
       }
     }
@@ -283,26 +302,20 @@
 
     if (node.initializer != null) {
       if (node.isConst) {
-        final Constant constant =
-            tryEvaluateWithContext(node, node.initializer);
+        final Constant constant = evaluateWithContext(node, node.initializer);
+        constantEvaluator.env.addVariableValue(node, constant);
 
-        // If there was a constant evaluation error we will not continue and
-        // simply keep the old [node].
-        if (constant != null) {
-          constantEvaluator.env.addVariableValue(node, constant);
-
-          if (keepVariables) {
-            // So the value of the variable is still available for debugging
-            // purposes we convert the constant variable to be a final variable
-            // initialized to the evaluated constant expression.
-            node.initializer = makeConstantExpression(constant)..parent = node;
-            node.isFinal = true;
-            node.isConst = false;
-          } else {
-            // Since we convert all use-sites of constants, the constant
-            // [VariableDeclaration] is unused and we'll therefore remove it.
-            return null;
-          }
+        if (keepVariables) {
+          // So the value of the variable is still available for debugging
+          // purposes we convert the constant variable to be a final variable
+          // initialized to the evaluated constant expression.
+          node.initializer = makeConstantExpression(constant)..parent = node;
+          node.isFinal = true;
+          node.isConst = false;
+        } else {
+          // Since we convert all use-sites of constants, the constant
+          // [VariableDeclaration] is unused and we'll therefore remove it.
+          return null;
         }
       } else {
         node.initializer = node.initializer.accept(this)..parent = node;
@@ -325,7 +338,7 @@
         transformAnnotations(node.annotations, node);
         if (node.initializer != null) {
           node.initializer =
-              tryEvaluateAndTransformWithContext(node, node.initializer)
+              evaluateAndTransformWithContext(node, node.initializer)
                 ..parent = node;
         }
       } else {
@@ -347,11 +360,9 @@
   visitStaticGet(StaticGet node) {
     final Member target = node.target;
     if (target is Field && target.isConst) {
-      final Constant constant =
-          tryEvaluateWithContext(node, target.initializer);
-      return constant != null ? makeConstantExpression(constant) : node;
+      return evaluateAndTransformWithContext(node, target.initializer);
     } else if (target is Procedure && target.kind == ProcedureKind.Method) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitStaticGet(node);
   }
@@ -363,42 +374,42 @@
 
   visitVariableGet(VariableGet node) {
     if (node.variable.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitVariableGet(node);
   }
 
   visitListLiteral(ListLiteral node) {
     if (node.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitListLiteral(node);
   }
 
   visitSetLiteral(SetLiteral node) {
     if (node.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitSetLiteral(node);
   }
 
   visitMapLiteral(MapLiteral node) {
     if (node.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitMapLiteral(node);
   }
 
   visitConstructorInvocation(ConstructorInvocation node) {
     if (node.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitConstructorInvocation(node);
   }
 
   visitStaticInvocation(StaticInvocation node) {
     if (node.isConst) {
-      return tryEvaluateAndTransformWithContext(node, node);
+      return evaluateAndTransformWithContext(node, node);
     }
     return super.visitStaticInvocation(node);
   }
@@ -407,19 +418,18 @@
     Constant constant = node.constant;
     if (constant is UnevaluatedConstant) {
       Expression expression = constant.expression;
-      return tryEvaluateAndTransformWithContext(expression, expression);
+      return evaluateAndTransformWithContext(expression, expression);
     } else {
       node.constant = constantEvaluator.canonicalize(constant);
       return node;
     }
   }
 
-  tryEvaluateAndTransformWithContext(TreeNode treeContext, Expression node) {
-    final Constant constant = tryEvaluateWithContext(treeContext, node);
-    return constant != null ? makeConstantExpression(constant) : node;
+  evaluateAndTransformWithContext(TreeNode treeContext, Expression node) {
+    return makeConstantExpression(evaluateWithContext(treeContext, node));
   }
 
-  tryEvaluateWithContext(TreeNode treeContext, Expression node) {
+  evaluateWithContext(TreeNode treeContext, Expression node) {
     if (treeContext == node) {
       return constantEvaluator.evaluate(node);
     }
@@ -456,6 +466,8 @@
   final Map<Node, Object> nodeCache;
   final CloneVisitor cloner = new CloneVisitor();
 
+  Map<Class, bool> primitiveEqualCache;
+
   final NullConstant nullConstant = new NullConstant();
   final BoolConstant trueConstant = new BoolConstant(true);
   final BoolConstant falseConstant = new BoolConstant(false);
@@ -485,7 +497,22 @@
         unmodifiableSetMap = desugarSets
             ? typeEnvironment.coreTypes.index
                 .getMember('dart:collection', '_UnmodifiableSet', '_map')
-            : null;
+            : null {
+    primitiveEqualCache = <Class, bool>{
+      coreTypes.boolClass: true,
+      coreTypes.doubleClass: false,
+      coreTypes.intClass: true,
+      coreTypes.internalSymbolClass: true,
+      coreTypes.listClass: true,
+      coreTypes.mapClass: true,
+      coreTypes.nullClass: true,
+      coreTypes.objectClass: true,
+      coreTypes.setClass: true,
+      coreTypes.stringClass: true,
+      coreTypes.symbolClass: true,
+      coreTypes.typeClass: true,
+    };
+  }
 
   Uri getFileUri(TreeNode node) {
     while (node != null && node is! FileUriNode) {
@@ -671,13 +698,15 @@
   visitNullLiteral(NullLiteral node) => nullConstant;
 
   visitBoolLiteral(BoolLiteral node) {
-    return node.value ? trueConstant : falseConstant;
+    return makeBoolConstant(node.value);
   }
 
   visitIntLiteral(IntLiteral node) {
-    // The frontend will ensure the integer literals are in signed 64-bit
-    // range.
-    return canonicalize(new IntConstant(node.value));
+    // The frontend ensures that integer literals are valid according to the
+    // target representation.
+    return targetingJavaScript
+        ? canonicalize(new JavaScriptIntConstant.fromUInt64(node.value))
+        : canonicalize(new IntConstant(node.value));
   }
 
   visitDoubleLiteral(DoubleLiteral node) {
@@ -700,6 +729,14 @@
       result = runInsideContext(constant.expression, () {
         return _evaluateSubexpression(constant.expression);
       });
+    } else if (targetingJavaScript) {
+      if (constant is DoubleConstant) {
+        double value = constant.value;
+        // TODO(askesc, fishythefish): Handle infinite integers.
+        if (value.isFinite && value.truncateToDouble() == value) {
+          result = new JavaScriptIntConstant.fromDouble(value);
+        }
+      }
     }
     // If there were already constants in the AST then we make sure we
     // re-canonicalize them.  After running the transformer we will therefore
@@ -828,12 +865,19 @@
         } else {
           parts.add(listOrSet = <Constant>[]);
         }
-        if (isSet && !seen.add(constant)) {
-          report(element,
-              templateConstEvalDuplicateElement.withArguments(constant));
-        } else {
-          listOrSet.add(ensureIsSubtype(constant, elementType, element));
+        if (isSet) {
+          if (!hasPrimitiveEqual(constant)) {
+            report(
+                element,
+                templateConstEvalElementImplementsEqual
+                    .withArguments(constant));
+          }
+          if (!seen.add(constant)) {
+            report(element,
+                templateConstEvalDuplicateElement.withArguments(constant));
+          }
         }
+        listOrSet.add(ensureIsSubtype(constant, elementType, element));
       }
     }
   }
@@ -1051,13 +1095,16 @@
         } else {
           parts.add(entries = <ConstantMapEntry>[]);
         }
+        if (!hasPrimitiveEqual(key)) {
+          report(
+              element, templateConstEvalKeyImplementsEqual.withArguments(key));
+        }
         if (!seenKeys.add(key)) {
           report(element.key, templateConstEvalDuplicateKey.withArguments(key));
-        } else {
-          entries.add(new ConstantMapEntry(
-              ensureIsSubtype(key, keyType, element.key),
-              ensureIsSubtype(value, valueType, element.value)));
         }
+        entries.add(new ConstantMapEntry(
+            ensureIsSubtype(key, keyType, element.key),
+            ensureIsSubtype(value, valueType, element.value)));
       }
     }
   }
@@ -1115,6 +1162,7 @@
   visitConstructorInvocation(ConstructorInvocation node) {
     final Constructor constructor = node.target;
     final Class klass = constructor.enclosingClass;
+    bool isSymbol = klass == coreTypes.internalSymbolClass;
     if (!constructor.isConst) {
       return reportInvalid(node, 'Non-const constructor invocation.');
     }
@@ -1138,7 +1186,7 @@
         constructor.initializers.isEmpty &&
         constructor.enclosingClass.supertype != null;
 
-    if (isUnavailable || shouldBeUnevaluated) {
+    if (isUnavailable || (isSymbol && shouldBeUnevaluated)) {
       return unevaluated(
           node,
           new ConstructorInvocation(constructor,
@@ -1146,6 +1194,18 @@
               isConst: true));
     }
 
+    // Special case the dart:core's Symbol class here and convert it to a
+    // [SymbolConstant].  For invalid values we report a compile-time error.
+    if (isSymbol) {
+      final Constant nameValue = positionals.single;
+
+      if (nameValue is StringConstant && isValidSymbolName(nameValue.value)) {
+        return canonicalize(new SymbolConstant(nameValue.value, null));
+      }
+      return report(node.arguments.positional.first,
+          templateConstEvalInvalidSymbolName.withArguments(nameValue));
+    }
+
     final typeArguments = evaluateTypeArguments(node, node.arguments);
 
     // Fill in any missing type arguments with "dynamic".
@@ -1158,33 +1218,39 @@
       return runInsideContextIfNoContext(node, () {
         // "Run" the constructor (and any super constructor calls), which will
         // initialize the fields of the new instance.
+        if (shouldBeUnevaluated) {
+          enterLazy();
+          handleConstructorInvocation(
+              constructor, typeArguments, positionals, named);
+          leaveLazy();
+          return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
+        }
         handleConstructorInvocation(
             constructor, typeArguments, positionals, named);
-        final InstanceConstant result = instanceBuilder.buildInstance();
-
-        // Special case the dart:core's Symbol class here and convert it to a
-        // [SymbolConstant].  For invalid values we report a compile-time error.
-        if (result.classNode == coreTypes.internalSymbolClass) {
-          // The dart:_internal's Symbol class has only the name field.
-          assert(coreTypes.internalSymbolClass.fields
-                  .where((f) => !f.isStatic)
-                  .length ==
-              1);
-          final nameValue = result.fieldValues.values.single;
-
-          if (nameValue is StringConstant &&
-              isValidSymbolName(nameValue.value)) {
-            return canonicalize(new SymbolConstant(nameValue.value, null));
-          }
-          return report(node.arguments.positional.first,
-              templateConstEvalInvalidSymbolName.withArguments(nameValue));
+        if (shouldBeUnevaluated) {
+          return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
         }
-
-        return canonicalize(result);
+        return canonicalize(instanceBuilder.buildInstance());
       });
     });
   }
 
+  visitInstanceCreation(InstanceCreation node) {
+    return withNewInstanceBuilder(node.classNode, node.typeArguments, () {
+      for (AssertStatement statement in node.asserts) {
+        checkAssert(statement);
+      }
+      node.fieldValues.forEach((Reference fieldRef, Expression value) {
+        instanceBuilder.setFieldValue(
+            fieldRef.asField, _evaluateSubexpression(value));
+      });
+      if (shouldBeUnevaluated) {
+        return unevaluated(node, instanceBuilder.buildUnevaluatedInstance());
+      }
+      return canonicalize(instanceBuilder.buildInstance());
+    });
+  }
+
   bool isValidSymbolName(String name) {
     // See https://api.dartlang.org/stable/2.0.0/dart-core/Symbol/Symbol.html:
     //
@@ -1370,40 +1436,7 @@
                 evaluatePositionalArguments(init.arguments),
                 evaluateNamedArguments(init.arguments));
           } else if (init is AssertInitializer) {
-            if (enableAsserts) {
-              final Constant condition =
-                  _evaluateSubexpression(init.statement.condition);
-
-              if (condition is BoolConstant) {
-                if (!condition.value) {
-                  if (init.statement.message == null) {
-                    return report(init.statement.condition,
-                        messageConstEvalFailedAssertion);
-                  }
-                  final Constant message =
-                      _evaluateSubexpression(init.statement.message);
-                  if (message is StringConstant) {
-                    return report(
-                        init.statement.condition,
-                        templateConstEvalFailedAssertionWithMessage
-                            .withArguments(message.value));
-                  }
-                  return report(
-                      init.statement.message,
-                      templateConstEvalInvalidType.withArguments(
-                          message,
-                          typeEnvironment.stringType,
-                          message.getType(typeEnvironment)));
-                }
-              } else {
-                return report(
-                    init.statement.condition,
-                    templateConstEvalInvalidType.withArguments(
-                        condition,
-                        typeEnvironment.boolType,
-                        condition.getType(typeEnvironment)));
-              }
-            }
+            checkAssert(init.statement);
           } else {
             return reportInvalid(
                 constructor,
@@ -1415,6 +1448,55 @@
     });
   }
 
+  void checkAssert(AssertStatement statement) {
+    if (enableAsserts) {
+      final Constant condition = _evaluateSubexpression(statement.condition);
+
+      if (shouldBeUnevaluated) {
+        Expression message = null;
+        if (statement.message != null) {
+          enterLazy();
+          message = extract(_evaluateSubexpression(statement.message));
+          leaveLazy();
+        }
+        instanceBuilder.asserts.add(new AssertStatement(extract(condition),
+            message: message,
+            conditionStartOffset: statement.conditionStartOffset,
+            conditionEndOffset: statement.conditionEndOffset));
+      } else if (condition is BoolConstant) {
+        if (!condition.value) {
+          if (statement.message == null) {
+            report(statement.condition, messageConstEvalFailedAssertion);
+          }
+          final Constant message = _evaluateSubexpression(statement.message);
+          if (shouldBeUnevaluated) {
+            instanceBuilder.asserts.add(new AssertStatement(extract(condition),
+                message: extract(message),
+                conditionStartOffset: statement.conditionStartOffset,
+                conditionEndOffset: statement.conditionEndOffset));
+          } else if (message is StringConstant) {
+            report(
+                statement.condition,
+                templateConstEvalFailedAssertionWithMessage
+                    .withArguments(message.value));
+          } else {
+            report(
+                statement.message,
+                templateConstEvalInvalidType.withArguments(
+                    message,
+                    typeEnvironment.stringType,
+                    message.getType(typeEnvironment)));
+          }
+        }
+      } else {
+        report(
+            statement.condition,
+            templateConstEvalInvalidType.withArguments(condition,
+                typeEnvironment.boolType, condition.getType(typeEnvironment)));
+      }
+    }
+  }
+
   visitInvalidExpression(InvalidExpression node) {
     return reportInvalid(node, node.message);
   }
@@ -1434,17 +1516,36 @@
               unevaluatedArguments(arguments, {}, node.arguments.types)));
     }
 
-    // TODO(http://dartbug.com/31799): Ensure we only invoke ==/!= on
-    // null/bool/int/double/String objects.
-
-    // Handle == and != first (it's common between all types).
+    // Handle == and != first (it's common between all types). Since `a != b` is
+    // parsed as `!(a == b)` it is handled implicitly through ==.
     if (arguments.length == 1 && node.name.name == '==') {
       final right = arguments[0];
-      return receiver == right ? trueConstant : falseConstant;
-    }
-    if (arguments.length == 1 && node.name.name == '!=') {
-      final right = arguments[0];
-      return receiver != right ? trueConstant : falseConstant;
+
+      // [DoubleConstant] uses [identical] to determine equality, so we need two
+      // special cases:
+      // Two NaNs are always unequal even if [identical] returns `true`.
+      if (isNaN(receiver) || isNaN(right)) {
+        return falseConstant;
+      }
+
+      // Two zero values are always equal regardless of sign.
+      if (isZero(receiver)) {
+        return makeBoolConstant(isZero(right));
+      }
+
+      if (receiver is NullConstant ||
+          receiver is BoolConstant ||
+          receiver is IntConstant ||
+          receiver is DoubleConstant ||
+          receiver is StringConstant ||
+          right is NullConstant) {
+        return makeBoolConstant(receiver == right);
+      } else {
+        return report(
+            node,
+            templateConstEvalInvalidEqualsOperandType.withArguments(
+                receiver, receiver.getType(typeEnvironment)));
+      }
     }
 
     // This is a white-listed set of methods we need to support on constants.
@@ -1466,64 +1567,118 @@
                     other.getType(typeEnvironment)));
         }
       }
-    } else if (receiver is IntConstant) {
+    } else if (receiver is IntConstant || receiver is JavaScriptIntConstant) {
       if (arguments.length == 0) {
         switch (node.name.name) {
           case 'unary-':
-            return canonicalize(new IntConstant(-receiver.value));
+            if (targetingJavaScript) {
+              BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
+              if (value == BigInt.zero) {
+                return canonicalize(new DoubleConstant(-0.0));
+              }
+              return canonicalize(new JavaScriptIntConstant.fromBigInt(-value));
+            }
+            int value = (receiver as IntConstant).value;
+            return canonicalize(new IntConstant(-value));
           case '~':
-            return canonicalize(new IntConstant(~receiver.value));
+            if (targetingJavaScript) {
+              BigInt value = (receiver as JavaScriptIntConstant).bigIntValue;
+              return canonicalize(new JavaScriptIntConstant.fromBigInt(
+                  (~value).toUnsigned(32)));
+            }
+            int value = (receiver as IntConstant).value;
+            return canonicalize(new IntConstant(~value));
         }
       } else if (arguments.length == 1) {
         final Constant other = arguments[0];
         final op = node.name.name;
-        if (other is IntConstant) {
-          if ((op == '<<' || op == '>>' || op == '>>>') && other.value < 0) {
-            return report(
-                node.arguments.positional.first,
-                // TODO(askesc): Change argument types in template to constants.
-                templateConstEvalNegativeShift.withArguments(
-                    op, '${receiver.value}', '${other.value}'));
+        if (other is IntConstant || other is JavaScriptIntConstant) {
+          if ((op == '<<' || op == '>>' || op == '>>>')) {
+            var receiverValue = receiver is IntConstant
+                ? receiver.value
+                : (receiver as JavaScriptIntConstant).bigIntValue;
+            int otherValue = other is IntConstant
+                ? other.value
+                : (other as JavaScriptIntConstant).bigIntValue.toInt();
+            if (otherValue < 0) {
+              return report(
+                  node.arguments.positional.first,
+                  // TODO(askesc): Change argument types in template to constants.
+                  templateConstEvalNegativeShift.withArguments(
+                      op, '${receiverValue}', '${otherValue}'));
+            }
           }
+
+          if ((op == '%' || op == '~/')) {
+            var receiverValue = receiver is IntConstant
+                ? receiver.value
+                : (receiver as JavaScriptIntConstant).bigIntValue;
+            int otherValue = other is IntConstant
+                ? other.value
+                : (other as JavaScriptIntConstant).bigIntValue.toInt();
+            if (otherValue == 0) {
+              return report(
+                  node.arguments.positional.first,
+                  // TODO(askesc): Change argument type in template to constant.
+                  templateConstEvalZeroDivisor.withArguments(
+                      op, '${receiverValue}'));
+            }
+          }
+
           switch (op) {
             case '|':
-              return canonicalize(
-                  new IntConstant(receiver.value | other.value));
             case '&':
-              return canonicalize(
-                  new IntConstant(receiver.value & other.value));
             case '^':
-              return canonicalize(
-                  new IntConstant(receiver.value ^ other.value));
+              int receiverValue = receiver is IntConstant
+                  ? receiver.value
+                  : (receiver as JavaScriptIntConstant)
+                      .bigIntValue
+                      .toUnsigned(32)
+                      .toInt();
+              int otherValue = other is IntConstant
+                  ? other.value
+                  : (other as JavaScriptIntConstant)
+                      .bigIntValue
+                      .toUnsigned(32)
+                      .toInt();
+              return evaluateBinaryBitOperation(
+                  node.name.name, receiverValue, otherValue, node);
             case '<<':
-              return canonicalize(
-                  new IntConstant(receiver.value << other.value));
             case '>>':
-              return canonicalize(
-                  new IntConstant(receiver.value >> other.value));
             case '>>>':
-              int result = other.value >= 64
-                  ? 0
-                  : (receiver.value >> other.value) &
-                      ((1 << (64 - other.value)) - 1);
-              return canonicalize(new IntConstant(result));
-          }
-        }
+              bool negative = false;
+              int receiverValue;
+              if (receiver is IntConstant) {
+                receiverValue = receiver.value;
+              } else {
+                BigInt bigIntValue =
+                    (receiver as JavaScriptIntConstant).bigIntValue;
+                receiverValue = bigIntValue.toUnsigned(32).toInt();
+                negative = bigIntValue.isNegative;
+              }
+              int otherValue = other is IntConstant
+                  ? other.value
+                  : (other as JavaScriptIntConstant).bigIntValue.toInt();
 
-        if (other is IntConstant) {
-          if (other.value == 0 && (op == '%' || op == '~/')) {
-            return report(
-                node.arguments.positional.first,
-                // TODO(askesc): Change argument type in template to constant.
-                templateConstEvalZeroDivisor.withArguments(
-                    op, '${receiver.value}'));
+              return evaluateBinaryShiftOperation(
+                  node.name.name, receiverValue, otherValue, node,
+                  negativeReceiver: negative);
+            default:
+              num receiverValue = receiver is IntConstant
+                  ? receiver.value
+                  : (receiver as DoubleConstant).value;
+              num otherValue = other is IntConstant
+                  ? other.value
+                  : (other as DoubleConstant).value;
+              return evaluateBinaryNumericOperation(
+                  node.name.name, receiverValue, otherValue, node);
           }
-
-          return evaluateBinaryNumericOperation(
-              node.name.name, receiver.value, other.value, node);
         } else if (other is DoubleConstant) {
+          num receiverValue = receiver is IntConstant
+              ? receiver.value
+              : (receiver as DoubleConstant).value;
           return evaluateBinaryNumericOperation(
-              node.name.name, receiver.value, other.value, node);
+              node.name.name, receiverValue, other.value, node);
         }
         return report(
             node,
@@ -1688,6 +1843,9 @@
 
     final Constant receiver = _evaluateSubexpression(node.receiver);
     if (receiver is StringConstant && node.name.name == 'length') {
+      if (targetingJavaScript) {
+        return canonicalize(new JavaScriptIntConstant(receiver.value.length));
+      }
       return canonicalize(new IntConstant(receiver.value.length));
     } else if (shouldBeUnevaluated) {
       return unevaluated(node,
@@ -1765,7 +1923,7 @@
     for (int i = 0; i < node.expressions.length; i++) {
       Constant constant = _evaluateSubexpression(node.expressions[i]);
       if (constant is PrimitiveConstant<Object>) {
-        String value = constant.value.toString();
+        String value = constant.toString();
         Object last = concatenated.last;
         if (last is StringBuffer) {
           last.write(value);
@@ -1827,16 +1985,22 @@
                   : value == "false"
                       ? falseConstant
                       : defaultValue is BoolConstant
-                          ? defaultValue.value ? trueConstant : falseConstant
+                          ? makeBoolConstant(defaultValue.value)
                           : defaultValue is NullConstant
                               ? nullConstant
                               : falseConstant;
               return boolConstant;
             } else if (target.enclosingClass == coreTypes.intClass) {
               int intValue = value != null ? int.tryParse(value) : null;
-              intValue ??=
-                  defaultValue is IntConstant ? defaultValue.value : null;
+              intValue ??= defaultValue is IntConstant
+                  ? defaultValue.value
+                  : defaultValue is JavaScriptIntConstant
+                      ? defaultValue.bigIntValue.toInt()
+                      : null;
               if (intValue == null) return nullConstant;
+              if (targetingJavaScript) {
+                return canonicalize(new JavaScriptIntConstant(intValue));
+              }
               return canonicalize(new IntConstant(intValue));
             } else if (target.enclosingClass == coreTypes.stringClass) {
               value ??=
@@ -1862,9 +2026,23 @@
       if (parent is Library && parent == coreTypes.coreLibrary) {
         final Constant left = positionals[0];
         final Constant right = positionals[1];
+
+        if (targetingJavaScript) {
+          // In JavaScript, we lower [identical] to `===`, so any comparison
+          // against NaN yields `false`.
+          if (isNaN(left) || isNaN(right)) {
+            return falseConstant;
+          }
+
+          // In JavaScript, `-0.0 === 0.0`.
+          if (isZero(left)) {
+            return makeBoolConstant(isZero(right));
+          }
+        }
+
         // Since we canonicalize constants during the evaluation, we can use
         // identical here.
-        return identical(left, right) ? trueConstant : falseConstant;
+        return makeBoolConstant(identical(left, right));
       }
     }
 
@@ -1900,21 +2078,18 @@
       return unevaluated(node, new IsExpression(extract(constant), node.type));
     }
     if (constant is NullConstant) {
-      return node.type == typeEnvironment.nullType ||
-              node.type == typeEnvironment.objectType ||
-              node.type is DynamicType
-          ? trueConstant
-          : falseConstant;
+      return makeBoolConstant(node.type == typeEnvironment.nullType ||
+          node.type == typeEnvironment.objectType ||
+          node.type is DynamicType);
     }
-    return isSubtype(constant, evaluateDartType(node, node.type))
-        ? trueConstant
-        : falseConstant;
+    return makeBoolConstant(
+        isSubtype(constant, evaluateDartType(node, node.type)));
   }
 
   visitNot(Not node) {
     final Constant constant = _evaluateSubexpression(node.operand);
     if (constant is BoolConstant) {
-      return constant == trueConstant ? falseConstant : trueConstant;
+      return makeBoolConstant(constant != trueConstant);
     }
     if (shouldBeUnevaluated) {
       return unevaluated(node, new Not(extract(constant)));
@@ -1963,13 +2138,46 @@
 
   // Helper methods:
 
-  Constant makeDoubleConstant(double value) {
+  bool isZero(Constant value) =>
+      (value is IntConstant && value.value == 0) ||
+      (value is JavaScriptIntConstant && value.bigIntValue == BigInt.zero) ||
+      (value is DoubleConstant && value.value == 0);
+
+  bool isNaN(Constant value) => value is DoubleConstant && value.value.isNaN;
+
+  bool hasPrimitiveEqual(Constant constant) {
+    // TODO(askesc, fishythefish): Make sure the correct class is inferred
+    // when we clean up JavaScript int constant handling.
+    DartType type = constant.getType(typeEnvironment);
+    return !(type is InterfaceType && !classHasPrimitiveEqual(type.classNode));
+  }
+
+  bool classHasPrimitiveEqual(Class klass) {
+    bool cached = primitiveEqualCache[klass];
+    if (cached != null) return cached;
+    for (Procedure procedure in klass.procedures) {
+      if (procedure.kind == ProcedureKind.Operator &&
+          procedure.name.name == '==' &&
+          !procedure.isAbstract &&
+          !procedure.isForwardingStub) {
+        return primitiveEqualCache[klass] = false;
+      }
+    }
+    if (klass.supertype == null) return true; // To be on the safe side
+    return primitiveEqualCache[klass] =
+        classHasPrimitiveEqual(klass.supertype.classNode);
+  }
+
+  BoolConstant makeBoolConstant(bool value) =>
+      value ? trueConstant : falseConstant;
+
+  DoubleConstant makeDoubleConstant(double value) {
     if (targetingJavaScript) {
       // Convert to an integer when possible (matching the runtime behavior
       // of `is int`).
-      if (value.isFinite) {
+      if (value.isFinite && !identical(value, -0.0)) {
         var i = value.toInt();
-        if (value == i.toDouble()) return new IntConstant(i);
+        if (value == i.toDouble()) return new JavaScriptIntConstant(i);
       }
     }
     return new DoubleConstant(value);
@@ -2060,7 +2268,7 @@
   withNewInstanceBuilder(Class klass, List<DartType> typeArguments, fn()) {
     InstanceBuilder old = instanceBuilder;
     try {
-      instanceBuilder = new InstanceBuilder(klass, typeArguments);
+      instanceBuilder = new InstanceBuilder(this, klass, typeArguments);
       return fn();
     } finally {
       instanceBuilder = old;
@@ -2077,12 +2285,58 @@
     }
   }
 
+  Constant evaluateBinaryBitOperation(String op, int a, int b, TreeNode node) {
+    int result;
+    switch (op) {
+      case '|':
+        result = a | b;
+        break;
+      case '&':
+        result = a & b;
+        break;
+      case '^':
+        result = a ^ b;
+        break;
+    }
+
+    if (targetingJavaScript) {
+      return canonicalize(new JavaScriptIntConstant(result));
+    }
+    return canonicalize(new IntConstant(result));
+  }
+
+  Constant evaluateBinaryShiftOperation(String op, int a, int b, TreeNode node,
+      {negativeReceiver: false}) {
+    int result;
+    switch (op) {
+      case '<<':
+        result = a << b;
+        break;
+      case '>>':
+        if (targetingJavaScript) {
+          if (negativeReceiver) {
+            const signBit = 0x80000000;
+            a -= (a & signBit) << 1;
+          }
+          result = a >> b;
+        } else {
+          result = a >> b;
+        }
+        break;
+      case '>>>':
+        // TODO(fishythefish): Implement JS semantics for `>>>`.
+        result = b >= 64 ? 0 : (a >> b) & ((1 << (64 - b)) - 1);
+        break;
+    }
+
+    if (targetingJavaScript) {
+      return canonicalize(new JavaScriptIntConstant(result.toUnsigned(32)));
+    }
+    return canonicalize(new IntConstant(result));
+  }
+
   Constant evaluateBinaryNumericOperation(
       String op, num a, num b, TreeNode node) {
-    if (targetingJavaScript) {
-      a = a.toDouble();
-      b = b.toDouble();
-    }
     num result;
     switch (op) {
       case '+':
@@ -2106,6 +2360,9 @@
     }
 
     if (result is int) {
+      if (targetingJavaScript) {
+        return canonicalize(new JavaScriptIntConstant(result));
+      }
       return canonicalize(new IntConstant(result.toSigned(64)));
     }
     if (result is double) {
@@ -2114,13 +2371,13 @@
 
     switch (op) {
       case '<':
-        return a < b ? trueConstant : falseConstant;
+        return makeBoolConstant(a < b);
       case '<=':
-        return a <= b ? trueConstant : falseConstant;
+        return makeBoolConstant(a <= b);
       case '>=':
-        return a >= b ? trueConstant : falseConstant;
+        return makeBoolConstant(a >= b);
       case '>':
-        return a > b ? trueConstant : falseConstant;
+        return makeBoolConstant(a > b);
     }
 
     return reportInvalid(node, "Unexpected binary numeric operation '$op'.");
@@ -2142,6 +2399,8 @@
 ///   * the [fields] the instance will obtain (all fields from the
 ///     instantiated [klass] up to the [Object] klass).
 class InstanceBuilder {
+  ConstantEvaluator evaluator;
+
   /// The class of the new instance.
   final Class klass;
 
@@ -2151,19 +2410,32 @@
   /// The field values of the new instance.
   final Map<Field, Constant> fields = <Field, Constant>{};
 
-  InstanceBuilder(this.klass, this.typeArguments);
+  final List<AssertStatement> asserts = <AssertStatement>[];
+
+  InstanceBuilder(this.evaluator, this.klass, this.typeArguments);
 
   void setFieldValue(Field field, Constant constant) {
     fields[field] = constant;
   }
 
   InstanceConstant buildInstance() {
+    assert(asserts.isEmpty);
     final Map<Reference, Constant> fieldValues = <Reference, Constant>{};
     fields.forEach((Field field, Constant value) {
+      assert(value is! UnevaluatedConstant);
       fieldValues[field.reference] = value;
     });
     return new InstanceConstant(klass.reference, typeArguments, fieldValues);
   }
+
+  InstanceCreation buildUnevaluatedInstance() {
+    final Map<Reference, Expression> fieldValues = <Reference, Expression>{};
+    fields.forEach((Field field, Constant value) {
+      fieldValues[field.reference] = evaluator.extract(value);
+    });
+    return new InstanceCreation(
+        klass.reference, typeArguments, fieldValues, asserts);
+  }
 }
 
 /// Holds an environment of type parameters, parameters and variables.
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index 89a79f1..830e13a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -7,6 +7,20 @@
 class InferenceVisitor extends BodyVisitor1<void, DartType> {
   final ShadowTypeInferrer inferrer;
 
+  Class mapEntryClass;
+
+  // Stores the offset of the map entry found by inferMapEntry.
+  int mapEntryOffset = null;
+
+  // Stores the offset of the map spread found by inferMapEntry.
+  int mapSpreadOffset = null;
+
+  // Stores the offset of the iterable spread found by inferMapEntry.
+  int iterableSpreadOffset = null;
+
+  // Stores the type of the iterable spread found by inferMapEntry.
+  DartType iterableSpreadType = null;
+
   InferenceVisitor(this.inferrer);
 
   @override
@@ -729,9 +743,12 @@
           getSpreadElementType(spreadType, element.isNullAware) ??
               const DynamicType();
     } else if (element is IfElement) {
-      inferrer.inferExpression(element.condition,
-          inferrer.coreTypes.boolClass.rawType, typeChecksNeeded,
+      DartType boolType = inferrer.coreTypes.boolClass.rawType;
+      DartType conditionType = inferrer.inferExpression(
+          element.condition, boolType, typeChecksNeeded,
           isVoidAllowed: false);
+      inferrer.ensureAssignable(boolType, conditionType, element.condition,
+          element.condition.fileOffset);
       DartType thenType = inferElement(
           element.then,
           element,
@@ -755,10 +772,14 @@
               .getStandardUpperBound(thenType, otherwiseType);
     } else if (element is ForElement) {
       for (VariableDeclaration declaration in element.variables) {
-        if (declaration.initializer != null) {
-          inferrer.inferExpression(declaration.initializer, declaration.type,
-              inferenceNeeded || typeChecksNeeded,
-              isVoidAllowed: true);
+        if (declaration.name == null) {
+          if (declaration.initializer != null) {
+            declaration.type = inferrer.inferExpression(declaration.initializer,
+                declaration.type, inferenceNeeded || typeChecksNeeded,
+                isVoidAllowed: true);
+          }
+        } else {
+          inferrer.inferStatement(declaration);
         }
       }
       if (element.condition != null) {
@@ -793,14 +814,20 @@
       return inferElement(element.body, element, inferredTypeArgument,
           inferredSpreadTypes, inferenceNeeded, typeChecksNeeded);
     } else {
-      return inferrer.inferExpression(
+      DartType inferredType = inferrer.inferExpression(
           element, inferredTypeArgument, inferenceNeeded || typeChecksNeeded,
           isVoidAllowed: true);
+      if (inferredTypeArgument is! UnknownType) {
+        inferrer.ensureAssignable(
+            inferredTypeArgument, inferredType, element, element.fileOffset,
+            isVoidAllowed: inferredTypeArgument is VoidType);
+      }
+      return inferredType;
     }
   }
 
   void checkElement(Expression item, Expression parent, DartType typeArgument,
-      DartType actualType, Map<TreeNode, DartType> inferredSpreadTypes) {
+      Map<TreeNode, DartType> inferredSpreadTypes) {
     if (item is SpreadElement) {
       DartType spreadType = inferredSpreadTypes[item.expression];
       if (spreadType is DynamicType) {
@@ -808,24 +835,9 @@
             spreadType, item.expression, item.expression.fileOffset);
       }
     } else if (item is IfElement) {
-      if (!inferrer.isAssignable(typeArgument, actualType)) {
-        int offset =
-            item.otherwise == null ? item.then.fileOffset : item.fileOffset;
-        parent.replaceChild(
-            item,
-            inferrer.helper.desugarSyntheticExpression(inferrer.helper
-                .buildProblem(
-                    templateInvalidAssignment.withArguments(
-                        actualType, typeArgument),
-                    offset,
-                    1)));
-      } else {
-        checkElement(
-            item.then, item, typeArgument, actualType, inferredSpreadTypes);
-        if (item.otherwise != null) {
-          checkElement(item.otherwise, item, typeArgument, actualType,
-              inferredSpreadTypes);
-        }
+      checkElement(item.then, item, typeArgument, inferredSpreadTypes);
+      if (item.otherwise != null) {
+        checkElement(item.otherwise, item, typeArgument, inferredSpreadTypes);
       }
     } else if (item is ForElement) {
       if (item.condition != null) {
@@ -833,36 +845,11 @@
         inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType,
             conditionType, item.condition, item.condition.fileOffset);
       }
-      if (!inferrer.isAssignable(typeArgument, actualType)) {
-        parent.replaceChild(
-            item,
-            inferrer.helper.desugarSyntheticExpression(inferrer.helper
-                .buildProblem(
-                    templateInvalidAssignment.withArguments(
-                        actualType, typeArgument),
-                    item.body.fileOffset,
-                    1)));
-      } else {
-        checkElement(
-            item.body, item, typeArgument, actualType, inferredSpreadTypes);
-      }
+      checkElement(item.body, item, typeArgument, inferredSpreadTypes);
     } else if (item is ForInElement) {
-      if (!inferrer.isAssignable(typeArgument, actualType)) {
-        parent.replaceChild(
-            item,
-            inferrer.helper.desugarSyntheticExpression(inferrer.helper
-                .buildProblem(
-                    templateInvalidAssignment.withArguments(
-                        actualType, typeArgument),
-                    item.body.fileOffset,
-                    1)));
-      } else {
-        checkElement(
-            item.body, item, typeArgument, actualType, inferredSpreadTypes);
-      }
+      checkElement(item.body, item, typeArgument, inferredSpreadTypes);
     } else {
-      inferrer.ensureAssignable(typeArgument, actualType, item, item.fileOffset,
-          isVoidAllowed: typeArgument is VoidType);
+      // Do nothing.  Assignability checks are done during type inference.
     }
   }
 
@@ -924,8 +911,8 @@
     }
     if (typeChecksNeeded) {
       for (int i = 0; i < node.expressions.length; i++) {
-        checkElement(node.expressions[i], node, node.typeArgument,
-            actualTypes[i], inferredSpreadTypes);
+        checkElement(
+            node.expressions[i], node, node.typeArgument, inferredSpreadTypes);
       }
     }
     node.inferredType = new InterfaceType(listClass, [inferredTypeArgument]);
@@ -977,11 +964,10 @@
   }
 
   // Note that inferMapEntry adds exactly two elements to actualTypes -- the
-  // actual types of the key and the value.
-  int mapEntryOffset = null;
-  int mapSpreadOffset = null;
-  int iterableSpreadOffset = null;
-  DartType iterableSpreadType = null;
+  // actual types of the key and the value.  The same technique is used for
+  // actualTypesForSet, only inferMapEntry adds exactly one element to that
+  // list: the actual type of the iterable spread elements in case the map
+  // literal will be disambiguated as a set literal later.
   void inferMapEntry(
       MapEntry entry,
       TreeNode parent,
@@ -1077,7 +1063,7 @@
       // recovery.
       actualTypesForSet.add(actualElementType ?? const DynamicType());
 
-      Class mapEntryClass =
+      mapEntryClass ??=
           inferrer.coreTypes.index.getClass('dart:core', 'MapEntry');
       // TODO(dmitryas):  Handle the case of an ambiguous Set.
       entry.entryType = new InterfaceType(
@@ -1096,9 +1082,12 @@
 
       return;
     } else if (entry is IfMapEntry) {
-      inferrer.inferExpression(entry.condition,
-          inferrer.coreTypes.boolClass.rawType, typeChecksNeeded,
+      DartType boolType = inferrer.coreTypes.boolClass.rawType;
+      DartType conditionType = inferrer.inferExpression(
+          entry.condition, boolType, typeChecksNeeded,
           isVoidAllowed: false);
+      inferrer.ensureAssignable(
+          boolType, conditionType, entry.condition, entry.condition.fileOffset);
       // Note that this recursive invocation of inferMapEntry will add two types
       // to actualTypes; they are the actual types of the current invocation if
       // the 'else' branch is empty.
@@ -1143,10 +1132,14 @@
       return;
     } else if (entry is ForMapEntry) {
       for (VariableDeclaration declaration in entry.variables) {
-        if (declaration.initializer != null) {
-          inferrer.inferExpression(declaration.initializer, declaration.type,
-              inferenceNeeded || typeChecksNeeded,
-              isVoidAllowed: true);
+        if (declaration.name == null) {
+          if (declaration.initializer != null) {
+            declaration.type = inferrer.inferExpression(declaration.initializer,
+                declaration.type, inferenceNeeded || typeChecksNeeded,
+                isVoidAllowed: true);
+          }
+        } else {
+          inferrer.inferStatement(declaration);
         }
       }
       if (entry.condition != null) {
@@ -1229,8 +1222,6 @@
       Expression cachedValue,
       DartType keyType,
       DartType valueType,
-      DartType actualKeyType,
-      DartType actualValueType,
       Map<TreeNode, DartType> inferredSpreadTypes) {
     // It's disambiguated as a map literal.
     if (iterableSpreadOffset != null) {
@@ -1252,37 +1243,11 @@
             spreadType, entry.expression, entry.expression.fileOffset);
       }
     } else if (entry is IfMapEntry) {
-      Expression keyError;
-      Expression valueError;
-      int offset =
-          entry.otherwise == null ? entry.then.fileOffset : entry.fileOffset;
-      if (!inferrer.isAssignable(keyType, actualKeyType)) {
-        keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(actualKeyType, keyType),
-                offset,
-                1));
-      }
-      if (!inferrer.isAssignable(valueType, actualValueType)) {
-        valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(
-                    actualValueType, valueType),
-                offset,
-                1));
-      }
-      if (keyError != null || valueError != null) {
-        keyError ??= new NullLiteral();
-        valueError ??= new NullLiteral();
-        parent.replaceChild(entry,
-            new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset);
-      } else {
-        checkMapEntry(entry.then, entry, cachedKey, cachedValue, keyType,
-            valueType, actualKeyType, actualValueType, inferredSpreadTypes);
-        if (entry.otherwise != null) {
-          checkMapEntry(entry.otherwise, entry, cachedKey, cachedValue, keyType,
-              valueType, actualKeyType, actualValueType, inferredSpreadTypes);
-        }
+      checkMapEntry(entry.then, entry, cachedKey, cachedValue, keyType,
+          valueType, inferredSpreadTypes);
+      if (entry.otherwise != null) {
+        checkMapEntry(entry.otherwise, entry, cachedKey, cachedValue, keyType,
+            valueType, inferredSpreadTypes);
       }
     } else if (entry is ForMapEntry) {
       if (entry.condition != null) {
@@ -1290,92 +1255,16 @@
         inferrer.ensureAssignable(inferrer.coreTypes.boolClass.rawType,
             conditionType, entry.condition, entry.condition.fileOffset);
       }
-      Expression keyError;
-      Expression valueError;
-      if (!inferrer.isAssignable(keyType, actualKeyType)) {
-        keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(actualKeyType, keyType),
-                entry.fileOffset,
-                1));
-      }
-      if (!inferrer.isAssignable(valueType, actualValueType)) {
-        valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(
-                    actualValueType, valueType),
-                entry.fileOffset,
-                1));
-      }
-      if (keyError != null || valueError != null) {
-        keyError ??= new NullLiteral();
-        valueError ??= new NullLiteral();
-        parent.replaceChild(entry,
-            new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset);
-      } else {
-        checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
-            valueType, actualKeyType, actualValueType, inferredSpreadTypes);
-      }
+      checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
+          valueType, inferredSpreadTypes);
     } else if (entry is ForInMapEntry) {
-      Expression keyError;
-      Expression valueError;
-      if (!inferrer.isAssignable(keyType, actualKeyType)) {
-        keyError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(actualKeyType, keyType),
-                entry.fileOffset,
-                1));
-      }
-      if (!inferrer.isAssignable(valueType, actualValueType)) {
-        valueError = inferrer.helper.desugarSyntheticExpression(inferrer.helper
-            .buildProblem(
-                templateInvalidAssignment.withArguments(
-                    actualValueType, valueType),
-                entry.fileOffset,
-                1));
-      }
-      if (keyError != null || valueError != null) {
-        keyError ??= new NullLiteral();
-        valueError ??= new NullLiteral();
-        parent.replaceChild(entry,
-            new MapEntry(keyError, valueError)..fileOffset = entry.fileOffset);
-      } else {
-        checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
-            valueType, actualKeyType, actualValueType, inferredSpreadTypes);
-      }
+      checkMapEntry(entry.body, entry, cachedKey, cachedValue, keyType,
+          valueType, inferredSpreadTypes);
     } else {
       // Do nothing.  Assignability checks are done during type inference.
     }
   }
 
-  Expression convertToElement(MapEntry entry) {
-    if (entry is SpreadMapEntry) {
-      return new SpreadElement(entry.expression, entry.isNullAware)
-        ..fileOffset = entry.expression.fileOffset;
-    }
-    if (entry is IfMapEntry) {
-      return new IfElement(entry.condition, convertToElement(entry.then),
-          entry.otherwise == null ? null : convertToElement(entry.otherwise))
-        ..fileOffset = entry.fileOffset;
-    }
-    if (entry is ForMapEntry) {
-      return new ForElement(entry.variables, entry.condition, entry.updates,
-          convertToElement(entry.body))
-        ..fileOffset = entry.fileOffset;
-    }
-    if (entry is ForInMapEntry) {
-      return new ForInElement(entry.variable, entry.iterable, entry.prologue,
-          convertToElement(entry.body), entry.problem)
-        ..fileOffset = entry.fileOffset;
-    }
-    return inferrer.helper
-        .desugarSyntheticExpression(inferrer.helper.buildProblem(
-      templateExpectedButGot.withArguments(','),
-      entry.fileOffset,
-      1,
-    ));
-  }
-
   void visitMapLiteralJudgment(MapLiteralJudgment node, DartType typeContext) {
     var mapClass = inferrer.coreTypes.mapClass;
     var mapType = mapClass.thisType;
@@ -1493,7 +1382,7 @@
         List<DartType> formalTypesForSet = <DartType>[];
         InterfaceType setType = inferrer.coreTypes.setClass.thisType;
         for (int i = 0; i < node.entries.length; ++i) {
-          setElements.add(convertToElement(node.entries[i]));
+          setElements.add(convertToElement(node.entries[i], inferrer.helper));
           formalTypesForSet.add(setType.typeArguments[0]);
         }
 
@@ -1526,12 +1415,8 @@
         node.parent.replaceChild(node, setLiteral);
         if (typeChecksNeeded) {
           for (int i = 0; i < setLiteral.expressions.length; i++) {
-            checkElement(
-                setLiteral.expressions[i],
-                setLiteral,
-                setLiteral.typeArgument,
-                actualTypesForSet[i],
-                inferredSpreadTypes);
+            checkElement(setLiteral.expressions[i], setLiteral,
+                setLiteral.typeArgument, inferredSpreadTypes);
           }
         }
 
@@ -1579,16 +1464,8 @@
     }
     if (typeChecksNeeded) {
       for (int i = 0; i < node.entries.length; ++i) {
-        checkMapEntry(
-            node.entries[i],
-            node,
-            cachedKeys[i],
-            cachedValues[i],
-            node.keyType,
-            node.valueType,
-            actualTypes[2 * i],
-            actualTypes[2 * i + 1],
-            inferredSpreadTypes);
+        checkMapEntry(node.entries[i], node, cachedKeys[i], cachedValues[i],
+            node.keyType, node.valueType, inferredSpreadTypes);
       }
     }
     node.inferredType =
@@ -1875,8 +1752,8 @@
     }
     if (typeChecksNeeded) {
       for (int i = 0; i < node.expressions.length; i++) {
-        checkElement(node.expressions[i], node, node.typeArgument,
-            actualTypes[i], inferredSpreadTypes);
+        checkElement(
+            node.expressions[i], node, node.typeArgument, inferredSpreadTypes);
       }
     }
     node.inferredType = new InterfaceType(setClass, [inferredTypeArgument]);
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
index 8e04138..bca9db5 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_ast_api.dart
@@ -18,6 +18,7 @@
         Catch,
         CheckLibraryIsLoaded,
         Class,
+        Component,
         Constructor,
         ConstructorInvocation,
         ContinueSwitchStatement,
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
index f89f7ea..e91b0a4 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_shadow_ast.dart
@@ -42,11 +42,9 @@
         messageVoidExpression,
         noLength,
         templateCantInferTypeDueToCircularity,
-        templateExpectedButGot,
         templateForInLoopElementTypeNotAssignable,
         templateForInLoopTypeNotIterable,
         templateIntegerLiteralIsOutOfRange,
-        templateInvalidAssignment,
         templateSpreadElementTypeMismatch,
         templateSpreadMapEntryElementKeyTypeMismatch,
         templateSpreadMapEntryElementValueTypeMismatch,
@@ -91,7 +89,8 @@
         IfElement,
         IfMapEntry,
         SpreadElement,
-        SpreadMapEntry;
+        SpreadMapEntry,
+        convertToElement;
 
 import 'implicit_type_argument.dart' show ImplicitTypeArgument;
 
diff --git a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
index ed8f7b2..dfa8437 100644
--- a/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/forwarding_listener.dart
@@ -224,6 +224,11 @@
   }
 
   @override
+  void beginThenControlFlow(Token token) {
+    listener?.beginThenControlFlow(token);
+  }
+
+  @override
   void beginIfStatement(Token token) {
     listener?.beginIfStatement(token);
   }
diff --git a/pkg/front_end/lib/src/fasta/parser/listener.dart b/pkg/front_end/lib/src/fasta/parser/listener.dart
index 8a24cdf..858b3b8 100644
--- a/pkg/front_end/lib/src/fasta/parser/listener.dart
+++ b/pkg/front_end/lib/src/fasta/parser/listener.dart
@@ -1115,6 +1115,10 @@
   /// Called before parsing an `if` control flow list, set, or map entry.
   void beginIfControlFlow(Token ifToken) {}
 
+  /// Called before parsing the `then` portion of an `if` control flow list,
+  /// set, or map entry.
+  void beginThenControlFlow(Token token) {}
+
   /// Called before parsing the `else` portion of an `if` control flow list,
   /// set, or map entry.
   void handleElseControlFlow(Token elseToken) {
diff --git a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
index 1ea0bf7..f5e4b8b 100644
--- a/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/literal_entry_info_impl.dart
@@ -144,7 +144,9 @@
     final ifToken = token.next;
     assert(optional('if', ifToken));
     parser.listener.beginIfControlFlow(ifToken);
-    return parser.ensureParenthesizedCondition(ifToken);
+    Token result = parser.ensureParenthesizedCondition(ifToken);
+    parser.listener.beginThenControlFlow(result);
+    return result;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/fasta/parser/parser.dart b/pkg/front_end/lib/src/fasta/parser/parser.dart
index 6ec8e5a..e716b34 100644
--- a/pkg/front_end/lib/src/fasta/parser/parser.dart
+++ b/pkg/front_end/lib/src/fasta/parser/parser.dart
@@ -2878,6 +2878,9 @@
       } else if (identical(value, 'factory')) {
         Token next2 = next.next;
         if (next2.isIdentifier || next2.isModifier) {
+          if (beforeType != token) {
+            reportRecoverableError(token, fasta.messageTypeBeforeFactory);
+          }
           token = parseFactoryMethod(token, beforeStart, externalToken,
               staticToken ?? covariantToken, varFinalOrConst);
           listener.endMember();
diff --git a/pkg/front_end/lib/src/scanner/errors.dart b/pkg/front_end/lib/src/scanner/errors.dart
index 6cdb878..4a7bb1d 100644
--- a/pkg/front_end/lib/src/scanner/errors.dart
+++ b/pkg/front_end/lib/src/scanner/errors.dart
@@ -63,7 +63,7 @@
       const ScannerErrorCode(
           'UNTERMINATED_MULTI_LINE_COMMENT', "Unterminated multi-line comment.",
           correction: "Try terminating the comment with '*/', or "
-              "removing any unbalanced occurances of '/*'"
+              "removing any unbalanced occurrences of '/*'"
               " (because comments nest in Dart).");
 
   static const ScannerErrorCode UNTERMINATED_STRING_LITERAL =
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 5a1995a..64141b8 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -66,12 +66,15 @@
 ConstEvalDeferredLibrary/example: Fail
 ConstEvalDuplicateElement/example: Fail
 ConstEvalDuplicateKey/example: Fail
+ConstEvalElementImplementsEqual/example: Fail
 ConstEvalFailedAssertion/example: Fail
 ConstEvalFailedAssertionWithMessage/example: Fail
 ConstEvalFreeTypeParameter/analyzerCode: Fail
 ConstEvalFreeTypeParameter/example: Fail
 ConstEvalInvalidBinaryOperandType/analyzerCode: Fail # CONST_EVAL_TYPE_NUM / CONST_EVAL_TYPE_BOOL
 ConstEvalInvalidBinaryOperandType/example: Fail
+ConstEvalInvalidEqualsOperandType/analyzerCode: Fail
+ConstEvalInvalidEqualsOperandType/example: Fail
 ConstEvalInvalidMethodInvocation/example: Fail
 ConstEvalInvalidPropertyGet/example: Fail
 ConstEvalInvalidStaticInvocation/example: Fail
@@ -82,6 +85,7 @@
 ConstEvalIterationInConstList/example: Fail
 ConstEvalIterationInConstMap/example: Fail
 ConstEvalIterationInConstSet/example: Fail
+ConstEvalKeyImplementsEqual/example: Fail
 ConstEvalNegativeShift/analyzerCode: Fail # http://dartbug.com/33481
 ConstEvalNegativeShift/example: Fail
 ConstEvalNonConstantLiteral/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 558bd5b..e633dfd 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -93,6 +93,14 @@
   template: "The key '#constant' conflicts with another existing key in the map."
   analyzerCode: EQUAL_KEYS_IN_CONST_MAP
 
+ConstEvalElementImplementsEqual:
+  template: "The element '#constant' does not have a primitive operator '=='."
+  analyzerCode: CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS
+
+ConstEvalKeyImplementsEqual:
+  template: "The key '#constant' does not have a primitive operator '=='."
+  analyzerCode: CONST_MAP_KEY_EXPRESSION_TYPE_IMPLEMENTS_EQUALS
+
 ConstEvalNonConstantLiteral:
   template: "Can't have a non-constant #string literal within a const context."
   analyzerCode: NON_CONSTANT_DEFAULT_VALUE
@@ -103,6 +111,9 @@
 ConstEvalInvalidBinaryOperandType:
   template: "Binary operator '#string' on '#constant' requires operand of type '#type', but was of type '#type2'."
 
+ConstEvalInvalidEqualsOperandType:
+  template: "Binary operator '==' requires receiver constant '#constant' of type 'Null', 'bool', 'int', 'double', or 'String', but was of type '#type'."
+
 ConstEvalZeroDivisor:
   template: "Binary operator '#string' on '#string2' requires non-zero divisor, but divisor was '0'."
   analyzerCode: CONST_EVAL_THROWS_IDBZE
@@ -626,6 +637,14 @@
   script:
     - "class C { factory const C() = prefix.B.foo; }"
 
+TypeBeforeFactory:
+  index: 97
+  template: "Factory constructors cannot have a return type."
+  tip: "Try removing the type appearing before 'factory'."
+  analyzerCode: ParserErrorCode.TYPE_BEFORE_FACTORY
+  script:
+    - "class C { T factory C() { return null; } }"
+
 ConstConstructorWithBody:
   template: "A const constructor can't have a body."
   tip: "Try removing either the 'const' keyword or the body."
@@ -669,7 +688,7 @@
 DuplicatedModifier:
   index: 70
   template: "The modifier '#lexeme' was already specified."
-  tip: "Try removing all but one occurance of the modifier."
+  tip: "Try removing all but one occurence of the modifier."
   analyzerCode: ParserErrorCode.DUPLICATED_MODIFIER
   script:
     - "class C { const const m; }"
@@ -2165,7 +2184,7 @@
 
 ImportAfterPart:
   index: 10
-  template: "Import directives must preceed part directives."
+  template: "Import directives must precede part directives."
   tip: "Try moving the import directives before the part directives."
   analyzerCode: ParserErrorCode.IMPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
   script:
@@ -2173,7 +2192,7 @@
 
 ExportAfterPart:
   index: 75
-  template: "Export directives must preceed part directives."
+  template: "Export directives must precede part directives."
   tip: "Try moving the export directives before the part directives."
   analyzerCode: ParserErrorCode.EXPORT_DIRECTIVE_AFTER_PART_DIRECTIVE
   script:
@@ -2463,7 +2482,7 @@
 
 MissingOperatorKeyword:
   index: 31
-  template: "Operator declarations must be preceeded by the keyword 'operator'."
+  template: "Operator declarations must be preceded by the keyword 'operator'."
   tip: "Try adding the keyword 'operator'."
   analyzerCode: ParserErrorCode.MISSING_KEYWORD_OPERATOR
   script:
diff --git a/pkg/front_end/pubspec.yaml b/pkg/front_end/pubspec.yaml
index a9c0c28..1bfa71e 100644
--- a/pkg/front_end/pubspec.yaml
+++ b/pkg/front_end/pubspec.yaml
@@ -8,14 +8,9 @@
 environment:
   sdk: '>=2.1.0-dev.5.0 <3.0.0'
 dependencies:
-  charcode: '^1.1.1'
-  convert: '^2.0.1'
-  crypto: '^2.0.2'
   kernel: 0.3.15
-  meta: '^1.1.1'
   package_config: '^1.0.1'
   path: '^1.3.9'
-  source_span: '^1.2.3'
   yaml: '^2.1.12'
 dev_dependencies:
   analyzer: 0.36.0
@@ -24,8 +19,6 @@
     path: ../build_integration
   dart_style: '^1.0.7'
   json_rpc_2: ^2.0.9
-  mockito: ^2.0.2
-  stream_channel: ^1.6.1
   test: ^1.3.4
   test_reflective_loader: ^0.1.0
   web_socket_channel: ^1.0.4
diff --git a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
index 3051815..fcaed11 100644
--- a/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/literal_entry_info_test.dart
@@ -206,6 +206,7 @@
         'handleNoArguments )',
         'handleSend a )',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         // nested for (b in c)
         'beginForControlFlow null for',
         'handleIdentifier b expression',
@@ -343,6 +344,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleLiteralInt 2',
         'endIfControlFlow 2',
         'handleLiteralList 1, [, null, ]',
@@ -357,6 +359,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleLiteralInt 2',
         'handleElseControlFlow else',
         'handleLiteralInt 5',
@@ -374,6 +377,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         // nested for (x in y)
         'beginForControlFlow null for',
         'handleIdentifier x expression',
@@ -407,6 +411,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         // nested for (a in b)
         'beginForControlFlow null for',
         'handleIdentifier a expression',
@@ -434,6 +439,7 @@
         'handleNoArguments )',
         'handleSend c )',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         // nested for (d in e)
         'beginForControlFlow null for',
         'handleIdentifier d expression',
@@ -468,6 +474,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleNoTypeArguments [',
         'handleLiteralInt 2',
         'handleLiteralList 1, [, null, ]',
@@ -485,6 +492,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleNoTypeArguments [',
         'handleLiteralInt 2',
         'handleLiteralList 1, [, null, ]',
@@ -764,6 +772,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleLiteralInt 2',
         'handleLiteralInt 3',
         'handleLiteralMapEntry :, ',
@@ -779,6 +788,7 @@
         'beginIfControlFlow if',
         'handleLiteralBool true',
         'handleParenthesizedCondition (',
+        'beginThenControlFlow )',
         'handleNoTypeArguments {',
         'handleLiteralInt 2',
         'handleLiteralInt 3',
@@ -877,6 +887,11 @@
   }
 
   @override
+  void beginThenControlFlow(Token token) {
+    calls.add('beginThenControlFlow $token');
+  }
+
+  @override
   void beginInitializedIdentifier(Token token) {
     calls.add('beginInitializedIdentifier $token');
   }
diff --git a/pkg/front_end/test/hot_reload_e2e_test.dart b/pkg/front_end/test/hot_reload_e2e_test.dart
index 7b50c3c..b90b143 100644
--- a/pkg/front_end/test/hot_reload_e2e_test.dart
+++ b/pkg/front_end/test/hot_reload_e2e_test.dart
@@ -103,6 +103,7 @@
     var vmArgs = [
       '--enable-vm-service=0', // Note: use 0 to avoid port collisions.
       '--pause_isolates_on_start',
+      '--disable-service-auth-codes',
       outputUri.toFilePath()
     ];
     vmArgs.add('$reloadCount');
diff --git a/pkg/front_end/testcases/control_flow_collection.dart.strong.expect b/pkg/front_end/testcases/control_flow_collection.dart.strong.expect
index 9fed289..8c19425 100644
--- a/pkg/front_end/testcases/control_flow_collection.dart.strong.expect
+++ b/pkg/front_end/testcases/control_flow_collection.dart.strong.expect
@@ -7,19 +7,19 @@
   final core::List<core::int> aList = block {
     final core::List<core::int> #t1 = <core::int>[];
     #t1.{core::List::add}(1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t1.{core::List::add}(2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t1.{core::List::add}(3);
     else
       #t1.{core::List::add}(1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t1.{core::List::add}(4);
     for (core::int i in <core::int>[5, 6, 7])
       #t1.{core::List::add}(i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t1.{core::List::add}(i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
@@ -27,19 +27,19 @@
   final core::Set<core::int> aSet = block {
     final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>();
     #t2.{core::Set::add}(1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t2.{core::Set::add}(2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t2.{core::Set::add}(3);
     else
       #t2.{core::Set::add}(1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t2.{core::Set::add}(4);
     for (core::int i in <core::int>[5, 6, 7])
       #t2.{core::Set::add}(i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t2.{core::Set::add}(i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t2.{core::Set::add}(i);
@@ -47,19 +47,19 @@
   final core::Map<core::int, core::int> aMap = block {
     final core::Map<core::int, core::int> #t3 = <core::int, core::int>{};
     #t3.{core::Map::[]=}(1, 1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t3.{core::Map::[]=}(2, 2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t3.{core::Map::[]=}(3, 3);
     else
       #t3.{core::Map::[]=}(1.{core::int::unary-}(), 1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t3.{core::Map::[]=}(4, 4);
     for (core::int i in <core::int>[5, 6, 7])
       #t3.{core::Map::[]=}(i, i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t3.{core::Map::[]=}(i, i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t3.{core::Map::[]=}(i, i);
diff --git a/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect b/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect
index 9fed289..8c19425 100644
--- a/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/control_flow_collection.dart.strong.transformed.expect
@@ -7,19 +7,19 @@
   final core::List<core::int> aList = block {
     final core::List<core::int> #t1 = <core::int>[];
     #t1.{core::List::add}(1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t1.{core::List::add}(2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t1.{core::List::add}(3);
     else
       #t1.{core::List::add}(1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t1.{core::List::add}(4);
     for (core::int i in <core::int>[5, 6, 7])
       #t1.{core::List::add}(i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t1.{core::List::add}(i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t1.{core::List::add}(i);
@@ -27,19 +27,19 @@
   final core::Set<core::int> aSet = block {
     final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>();
     #t2.{core::Set::add}(1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t2.{core::Set::add}(2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t2.{core::Set::add}(3);
     else
       #t2.{core::Set::add}(1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t2.{core::Set::add}(4);
     for (core::int i in <core::int>[5, 6, 7])
       #t2.{core::Set::add}(i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t2.{core::Set::add}(i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t2.{core::Set::add}(i);
@@ -47,19 +47,19 @@
   final core::Map<core::int, core::int> aMap = block {
     final core::Map<core::int, core::int> #t3 = <core::int, core::int>{};
     #t3.{core::Map::[]=}(1, 1);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t3.{core::Map::[]=}(2, 2);
-    if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
       #t3.{core::Map::[]=}(3, 3);
     else
       #t3.{core::Map::[]=}(1.{core::int::unary-}(), 1.{core::int::unary-}());
-    if(self::oracle())
-      if(self::oracle())
+    if(self::oracle() as{TypeError} core::bool)
+      if(self::oracle() as{TypeError} core::bool)
         #t3.{core::Map::[]=}(4, 4);
     for (core::int i in <core::int>[5, 6, 7])
       #t3.{core::Map::[]=}(i, i);
     for (core::int i in <core::int>[8, 9, 10])
-      if(self::oracle())
+      if(self::oracle() as{TypeError} core::bool)
         #t3.{core::Map::[]=}(i, i);
     for (core::int i = 11; i.{core::num::<=}(14); i = i.{core::num::+}(1))
       #t3.{core::Map::[]=}(i, i);
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart b/pkg/front_end/testcases/control_flow_collection_inference.dart
index 3d9520f..4a64f6a 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart
@@ -78,6 +78,9 @@
   List<int> list91 = [if (oracle("foo")) ...dynVar];
   Set<int> set91 = {if (oracle("foo")) ...dynVar, null};
   Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null};
+  List<int> list100 = [if (dynVar) 42];
+  Set<int> set100 = {if (dynVar) 42};
+  Map<int, int> map100 = {if (dynVar) 42: 42};
 }
 
 testIfElementErrors(Map<int, int> map) {
@@ -99,6 +102,20 @@
   <int>[if (oracle("foo")) 42 else ...map];
   <int>{if (oracle("foo")) ...map else 42, null};
   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
+
+  Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+  Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14};
+  Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+  Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42};
+  var map12 = {if (oracle("foo")) 42 else "bar": 3.14};
+  var map13 = {if (oracle("foo")) "bar": 3.14 else 42};
+  List<int> list20 = [if (42) 42];
+  Set<int> set20 = {if (42) 42};
+  Map<int, int> map30 = {if (42) 42: 42};
+  List<String> list40 = <String>[if (oracle("foo")) true else 42];
+  Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+  Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+  Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
 }
 
 testForElement(dynamic dynVar, List<int> listInt, List<double> listDouble, int
@@ -184,6 +201,9 @@
   List<int> list120 = [for (var i in dynVar) i];
   Set<int> set120 = {for (var i in dynVar) i, null};
   Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null};
+  List<int> list130 = [for (var i = 1; i < 2; i++) i];
+  Set<int> set130 = {for (var i = 1; i < 2; i++) i};
+  Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i};
 }
 
 testForElementErrors(Map<int, int> map, List<int> list) async {
@@ -237,4 +257,16 @@
   <String, int>{await for (int i in stream) "bar": i};
 }
 
+class A {}
+
+class B extends A {
+  int get foo => 42;
+}
+
+testPromotion(A a) {
+  List<int> list10 = [if (a is B) a.foo];
+  Set<int> set10 = {if (a is B) a.foo};
+  Map<int, int> map10 = {if (a is B) a.foo: a.foo};
+}
+
 main() {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect
new file mode 100644
index 0000000..3a1da21
--- /dev/null
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.hierarchy.expect
@@ -0,0 +1,55 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+A:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+B:
+  superclasses:
+    Object
+      -> A
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    B.foo
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect
index b94b0a3..ffd86f8 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.expect
@@ -598,108 +598,96 @@
 //   Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null};
 //                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:84:9: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:81:24: Error: Unexpected token 'if'.
+//   List<int> list100 = [if (dynVar) 42];
+//                        ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:82:22: Error: Unexpected token 'if'.
+//   Set<int> set100 = {if (dynVar) 42};
+//                      ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:83:27: Error: Unexpected token 'if'.
+//   Map<int, int> map100 = {if (dynVar) 42: 42};
+//                           ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'.
 //   <int>[if (oracle("foo")) "bar"];
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:85:9: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'.
 //   <int>{if (oracle("foo")) "bar", null};
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:17: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) ...["bar"]];
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...["bar"]];
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...["bar"], null};
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...["bar"], null};
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
-//                                    ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'.
-//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
-//                 ^^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:90:28: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) ...map];
+//   <int>[if (oracle("foo")) ...["bar"]];
 //                            ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:90:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...map];
+//   <int>[if (oracle("foo")) ...["bar"]];
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:91:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...map, null};
+//   <int>{if (oracle("foo")) ...["bar"], null};
 //                            ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:91:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...map, null};
+//   <int>{if (oracle("foo")) ...["bar"], null};
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:92:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
+//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                    ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:92:17: Error: Unexpected token 'if'.
+//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
+//                 ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:28: Error: Unexpected token '...'.
+//   <int>[if (oracle("foo")) ...map];
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:9: Error: Unexpected token 'if'.
+//   <int>[if (oracle("foo")) ...map];
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:28: Error: Unexpected token '...'.
+//   <int>{if (oracle("foo")) ...map, null};
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:9: Error: Unexpected token 'if'.
+//   <int>{if (oracle("foo")) ...map, null};
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:36: Error: Unexpected token '...'.
+//   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:12: Error: Unexpected token 'if'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //            ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:12: Error: Unexpected token 'if'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //            ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:20: Error: Unexpected token 'if'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:28: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:99:28: Error: Unexpected token '...'.
 //   <int>[if (oracle("foo")) ...map else 42];
 //                            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...map else 42];
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                                    ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:17: Error: Unexpected token 'if'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                 ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:99:36: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) 42 else ...map];
-//                                    ^^^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:99:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) 42 else ...map];
+//   <int>[if (oracle("foo")) ...map else 42];
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:100:28: Error: Unexpected token '...'.
@@ -710,980 +698,1092 @@
 //   <int>{if (oracle("foo")) ...map else 42, null};
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:51: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:36: Error: Unexpected token '...'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                 ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:36: Error: Unexpected token '...'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:9: Error: Unexpected token 'if'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:28: Error: Unexpected token '...'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:9: Error: Unexpected token 'if'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:51: Error: Unexpected token '...'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:106:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:25: Error: Unexpected token 'if'.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:107:34: Error: Unexpected token 'if'.
+//   Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:25: Error: Unexpected token 'if'.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:109:34: Error: Unexpected token 'if'.
+//   Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'if'.
+//   var map12 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'if'.
+//   var map13 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:112:23: Error: Unexpected token 'if'.
+//   List<int> list20 = [if (42) 42];
+//                       ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:113:21: Error: Unexpected token 'if'.
+//   Set<int> set20 = {if (42) 42};
+//                     ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:114:26: Error: Unexpected token 'if'.
+//   Map<int, int> map30 = {if (42) 42: 42};
+//                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:34: Error: Unexpected token 'if'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:32: Error: Unexpected token 'if'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:42: Error: Unexpected token 'if'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:42: Error: Unexpected token 'if'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:123:17: Error: Unexpected token 'for'.
 //   var list10 = [for (int i = 0; oracle("foo"); i++) 42];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:107:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:124:16: Error: Unexpected token 'for'.
 //   var set10 = {for (int i = 0; oracle("foo"); i++) 42, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:108:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'.
 //   var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:109:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:126:17: Error: Unexpected token 'for'.
 //   var list11 = [for (int i = 0; oracle("foo"); i++) dynVar];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:127:16: Error: Unexpected token 'for'.
 //   var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'.
 //   var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:112:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:129:17: Error: Unexpected token 'for'.
 //   var list12 = [for (int i = 0; oracle("foo"); i++) [42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:113:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:130:16: Error: Unexpected token 'for'.
 //   var set12 = {for (int i = 0; oracle("foo"); i++) [42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:114:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'.
 //   var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:132:53: Error: Unexpected token '...'.
 //   var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:115:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:132:17: Error: Unexpected token 'for'.
 //   var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:116:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:133:52: Error: Unexpected token '...'.
 //   var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:116:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:133:16: Error: Unexpected token 'for'.
 //   var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:117:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:134:52: Error: Unexpected token '...'.
 //   var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:117:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:134:16: Error: Unexpected token 'for'.
 //   var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:118:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:135:53: Error: Unexpected token '...'.
 //   var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:118:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:135:17: Error: Unexpected token 'for'.
 //   var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:119:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:136:52: Error: Unexpected token '...'.
 //   var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:119:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:136:16: Error: Unexpected token 'for'.
 //   var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:120:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:137:52: Error: Unexpected token '...'.
 //   var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:120:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:137:16: Error: Unexpected token 'for'.
 //   var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:121:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:138:53: Error: Unexpected token '...'.
 //   var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:121:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:138:17: Error: Unexpected token 'for'.
 //   var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:122:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:139:52: Error: Unexpected token '...'.
 //   var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:122:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:139:16: Error: Unexpected token 'for'.
 //   var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:123:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:140:52: Error: Unexpected token '...'.
 //   var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:123:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:140:16: Error: Unexpected token 'for'.
 //   var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:67: Error: Unexpected token '...'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:53: Error: Unexpected token 'if'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:17: Error: Unexpected token 'for'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:66: Error: Unexpected token '...'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:52: Error: Unexpected token 'if'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:16: Error: Unexpected token 'for'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:66: Error: Unexpected token '...'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:52: Error: Unexpected token 'if'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:16: Error: Unexpected token 'for'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:67: Error: Unexpected token '...'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:53: Error: Unexpected token 'if'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:17: Error: Unexpected token 'for'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:66: Error: Unexpected token '...'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:52: Error: Unexpected token 'if'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:16: Error: Unexpected token 'for'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:66: Error: Unexpected token '...'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:52: Error: Unexpected token 'if'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:16: Error: Unexpected token 'for'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:67: Error: Unexpected token '...'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Error: Unexpected token 'if'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:17: Error: Unexpected token 'for'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:66: Error: Unexpected token '...'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:52: Error: Unexpected token 'if'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:16: Error: Unexpected token 'for'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:66: Error: Unexpected token '...'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:52: Error: Unexpected token 'if'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:16: Error: Unexpected token 'for'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:133:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:150:65: Error: Unexpected token '...'.
 //   List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:133:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:150:29: Error: Unexpected token 'for'.
 //   List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:134:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:151:63: Error: Unexpected token '...'.
 //   Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:134:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:151:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:135:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:152:71: Error: Unexpected token '...'.
 //   Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:135:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:152:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:136:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:153:65: Error: Unexpected token '...'.
 //   List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:136:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:153:29: Error: Unexpected token 'for'.
 //   List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:137:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:154:63: Error: Unexpected token '...'.
 //   Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:137:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:154:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:79: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:79: Error: Unexpected token '...'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:65: Error: Unexpected token 'if'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:29: Error: Unexpected token 'for'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:77: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:77: Error: Unexpected token '...'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:85: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:85: Error: Unexpected token '...'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:141:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Error: Unexpected token '...'.
 //   List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:141:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:158:23: Error: Unexpected token 'for'.
 //   List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:142:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:159:57: Error: Unexpected token '...'.
 //   Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:142:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:159:21: Error: Unexpected token 'for'.
 //   Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:143:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:160:65: Error: Unexpected token '...'.
 //   Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null};
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:143:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:160:29: Error: Unexpected token 'for'.
 //   Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:144:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:161:59: Error: Unexpected token '...'.
 //   List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:144:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:161:23: Error: Unexpected token 'for'.
 //   List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:145:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:162:57: Error: Unexpected token '...'.
 //   Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:145:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:162:21: Error: Unexpected token 'for'.
 //   Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:73: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:73: Error: Unexpected token '...'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:59: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:59: Error: Unexpected token 'if'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                                                           ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:23: Error: Unexpected token 'for'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:71: Error: Unexpected token '...'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:57: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:57: Error: Unexpected token 'if'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                                                         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:21: Error: Unexpected token 'for'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:148:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:165:65: Error: Unexpected token '...'.
 //   List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:148:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:165:29: Error: Unexpected token 'for'.
 //   List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:149:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:166:63: Error: Unexpected token '...'.
 //   Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:149:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:166:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:150:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:167:71: Error: Unexpected token '...'.
 //   Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:150:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:167:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:79: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:79: Error: Unexpected token '...'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:65: Error: Unexpected token 'if'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:29: Error: Unexpected token 'for'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:77: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:77: Error: Unexpected token '...'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:85: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:85: Error: Unexpected token '...'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:154:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:171:29: Error: Unexpected token 'for'.
 //   List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:155:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:172:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:156:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:173:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:157:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:174:65: Error: Unexpected token 'if'.
 //   List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:157:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'.
 //   List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:158:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:175:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:158:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:175:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:159:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:176:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:159:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:176:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:160:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:177:53: Error: Unexpected token 'if'.
 //   var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:160:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:177:17: Error: Unexpected token 'for'.
 //   var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:161:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:178:52: Error: Unexpected token 'if'.
 //   var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:161:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:178:16: Error: Unexpected token 'for'.
 //   var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:162:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:179:52: Error: Unexpected token 'if'.
 //   var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:162:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:179:16: Error: Unexpected token 'for'.
 //   var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:67: Error: Unexpected token '...'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:83: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:83: Error: Unexpected token '...'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:53: Error: Unexpected token 'if'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:17: Error: Unexpected token 'for'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:66: Error: Unexpected token '...'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:82: Error: Unexpected token '...'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:52: Error: Unexpected token 'if'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:16: Error: Unexpected token 'for'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:66: Error: Unexpected token '...'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:87: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:87: Error: Unexpected token '...'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:52: Error: Unexpected token 'if'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:16: Error: Unexpected token 'for'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:67: Error: Unexpected token '...'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:83: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:83: Error: Unexpected token '...'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:53: Error: Unexpected token 'if'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:66: Error: Unexpected token '...'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:82: Error: Unexpected token '...'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:52: Error: Unexpected token 'if'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:16: Error: Unexpected token 'for'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:66: Error: Unexpected token '...'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:87: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:87: Error: Unexpected token '...'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:52: Error: Unexpected token 'if'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:16: Error: Unexpected token 'for'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:75: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:75: Error: Unexpected token '...'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:53: Error: Unexpected token 'if'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:17: Error: Unexpected token 'for'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:66: Error: Unexpected token '...'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:52: Error: Unexpected token 'if'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:16: Error: Unexpected token 'for'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:66: Error: Unexpected token '...'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:52: Error: Unexpected token 'if'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:16: Error: Unexpected token 'for'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:172:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:189:23: Error: Unexpected token 'for'.
 //   List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:173:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:190:21: Error: Unexpected token 'for'.
 //   Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:191:29: Error: Unexpected token 'for'.
 //   Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:192:59: Error: Unexpected token '...'.
 //   List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:175:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:192:23: Error: Unexpected token 'for'.
 //   List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:176:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:193:57: Error: Unexpected token '...'.
 //   Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:176:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:193:21: Error: Unexpected token 'for'.
 //   Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:177:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:194:65: Error: Unexpected token '...'.
 //   Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null};
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:177:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:194:29: Error: Unexpected token 'for'.
 //   Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:178:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:195:29: Error: Unexpected token 'for'.
 //   List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:179:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:196:27: Error: Unexpected token 'for'.
 //   Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:180:43: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:197:43: Error: Unexpected token 'for'.
 //   Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42};
 //                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:181:18: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:198:18: Error: Unexpected token 'for'.
 //   var list110 = [for (var i in [1, 2, 3]) i];
 //                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:182:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:199:17: Error: Unexpected token 'for'.
 //   var set110 = {for (var i in [1, 2, 3]) i, null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:200:17: Error: Unexpected token 'for'.
 //   var map110 = {for (var i in [1, 2, 3]) "bar": i, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:184:24: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:201:24: Error: Unexpected token 'for'.
 //   List<int> list120 = [for (var i in dynVar) i];
 //                        ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:185:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:202:22: Error: Unexpected token 'for'.
 //   Set<int> set120 = {for (var i in dynVar) i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:186:30: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:203:30: Error: Unexpected token 'for'.
 //   Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null};
 //                              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:190:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:204:24: Error: Unexpected token 'for'.
+//   List<int> list130 = [for (var i = 1; i < 2; i++) i];
+//                        ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:205:22: Error: Unexpected token 'for'.
+//   Set<int> set130 = {for (var i = 1; i < 2; i++) i};
+//                      ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:206:27: Error: Unexpected token 'for'.
+//   Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i};
+//                           ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:191:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:45: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:45: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:50: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:50: Error: Unexpected token '...'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:45: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:45: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:50: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:50: Error: Unexpected token '...'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:48: Error: Unexpected token 'if'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:12: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:12: Error: Unexpected token 'for'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:48: Error: Unexpected token 'if'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:12: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:12: Error: Unexpected token 'for'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:56: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:56: Error: Unexpected token 'if'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                        ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:20: Error: Unexpected token 'for'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:59: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:45: Error: Unexpected token 'if'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:59: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:45: Error: Unexpected token 'if'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:67: Error: Unexpected token '...'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:53: Error: Unexpected token 'if'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:17: Error: Unexpected token 'for'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:67: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:45: Error: Unexpected token 'if'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:67: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:45: Error: Unexpected token 'if'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:82: Error: Unexpected token '...'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:53: Error: Unexpected token 'if'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:17: Error: Unexpected token 'for'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:230:9: Error: Unexpected token 'for'.
 //   <int>[for (i in <int>[1]) i];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:231:9: Error: Unexpected token 'for'.
 //   <int>{for (i in <int>[1]) i, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:212:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:232:16: Error: Unexpected token 'for'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:214:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:234:17: Error: Unexpected token 'for'.
 //   var list10 = [for (var i in "not iterable") i];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:215:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:235:16: Error: Unexpected token 'for'.
 //   var set10 = {for (var i in "not iterable") i, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:216:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:236:16: Error: Unexpected token 'for'.
 //   var map10 = {for (var i in "not iterable") "bar": i, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:17: Error: Unexpected token 'for'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:16: Error: Unexpected token 'for'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:16: Error: Unexpected token 'for'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:220:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:240:23: Error: Unexpected token 'for'.
 //   var list30 = [await for (var i in "not stream") i];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:221:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:241:22: Error: Unexpected token 'for'.
 //   var set30 = {await for (var i in "not stream") i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:222:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:242:22: Error: Unexpected token 'for'.
 //   var map30 = {await for (var i in "not stream") "bar": i, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:23: Error: Unexpected token 'for'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:22: Error: Unexpected token 'for'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:22: Error: Unexpected token 'for'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var list50 = [await for (;;) 42];
 //                 ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:23: Error: Unexpected token 'for'.
 //   var list50 = [await for (;;) 42];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var set50 = {await for (;;) 42, null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:22: Error: Unexpected token 'for'.
 //   var set50 = {await for (;;) 42, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:22: Error: Unexpected token 'for'.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:229:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:249:17: Error: Unexpected token 'for'.
 //   var list60 = [for (; "not bool";) 42];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:230:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:250:16: Error: Unexpected token 'for'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:231:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:251:16: Error: Unexpected token 'for'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>[await for (int i in stream) i];
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:15: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:15: Error: Unexpected token 'for'.
 //   <int>[await for (int i in stream) i];
 //               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>{await for (int i in stream) i};
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:15: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:15: Error: Unexpected token 'for'.
 //   <int>{await for (int i in stream) i};
 //               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                                  ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:23: Error: Unexpected token 'for'.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                       ^^^
 //
+// pkg/front_end/testcases/control_flow_collection_inference.dart:267:23: Error: Unexpected token 'if'.
+//   List<int> list10 = [if (a is B) a.foo];
+//                       ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:268:21: Error: Unexpected token 'if'.
+//   Set<int> set10 = {if (a is B) a.foo};
+//                     ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:269:26: Error: Unexpected token 'if'.
+//   Map<int, int> map10 = {if (a is B) a.foo: a.foo};
+//                          ^^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
 static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic
   return true;
 static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic {
@@ -1758,6 +1858,9 @@
   core::List<core::int> list91 = <dynamic>[];
   core::Set<core::int> set91 = <dynamic>{null};
   core::Map<core::String, core::int> map91 = <dynamic, dynamic>{"baz": null};
+  core::List<core::int> list100 = <dynamic>[];
+  core::Set<core::int> set100 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map100 = <dynamic, dynamic>{};
 }
 static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic {
   <core::int>[];
@@ -1778,6 +1881,19 @@
   <core::int>[];
   <core::int>{null};
   <core::String, core::int>{"baz": null};
+  core::Set<dynamic> set10 = <dynamic, dynamic>{};
+  core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{};
+  core::Set<dynamic> set11 = <dynamic, dynamic>{};
+  core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{};
+  dynamic map12 = <dynamic, dynamic>{};
+  dynamic map13 = <dynamic, dynamic>{};
+  core::List<core::int> list20 = <dynamic>[];
+  core::Set<core::int> set20 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map30 = <dynamic, dynamic>{};
+  core::List<core::String> list40 = <core::String>[];
+  core::Set<core::String> set40 = <core::String>{};
+  core::Map<core::String, core::int> map40 = <core::String, core::int>{};
+  core::Map<core::int, core::String> map41 = <core::int, core::String>{};
 }
 static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic {
   dynamic list10 = <dynamic>[];
@@ -1861,6 +1977,9 @@
   core::List<core::int> list120 = <dynamic>[];
   core::Set<core::int> set120 = <dynamic>{null};
   core::Map<core::String, core::int> map120 = <dynamic, dynamic>{"baz": null};
+  core::List<core::int> list130 = <dynamic>[];
+  core::Set<core::int> set130 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map130 = <dynamic, dynamic>{};
 }
 static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async {
   <core::int>[];
@@ -1909,4 +2028,9 @@
   <core::int>{};
   <core::String, core::int>{};
 }
+static method testPromotion(self::A a) → dynamic {
+  core::List<core::int> list10 = <dynamic>[];
+  core::Set<core::int> set10 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map10 = <dynamic, dynamic>{};
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect
index 9fdaca1..d384c49 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.legacy.transformed.expect
@@ -598,108 +598,96 @@
 //   Map<String, int> map91 = {if (oracle("foo")) ...dynVar, "baz": null};
 //                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:84:9: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:81:24: Error: Unexpected token 'if'.
+//   List<int> list100 = [if (dynVar) 42];
+//                        ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:82:22: Error: Unexpected token 'if'.
+//   Set<int> set100 = {if (dynVar) 42};
+//                      ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:83:27: Error: Unexpected token 'if'.
+//   Map<int, int> map100 = {if (dynVar) 42: 42};
+//                           ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'.
 //   <int>[if (oracle("foo")) "bar"];
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:85:9: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'.
 //   <int>{if (oracle("foo")) "bar", null};
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:17: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) ...["bar"]];
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...["bar"]];
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...["bar"], null};
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...["bar"], null};
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
-//                                    ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:17: Error: Unexpected token 'if'.
-//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
-//                 ^^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:90:28: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) ...map];
+//   <int>[if (oracle("foo")) ...["bar"]];
 //                            ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:90:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...map];
+//   <int>[if (oracle("foo")) ...["bar"]];
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:91:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...map, null};
+//   <int>{if (oracle("foo")) ...["bar"], null};
 //                            ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:91:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...map, null};
+//   <int>{if (oracle("foo")) ...["bar"], null};
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:92:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
+//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                    ^^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:92:17: Error: Unexpected token 'if'.
+//   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
+//                 ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:28: Error: Unexpected token '...'.
+//   <int>[if (oracle("foo")) ...map];
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:9: Error: Unexpected token 'if'.
+//   <int>[if (oracle("foo")) ...map];
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:28: Error: Unexpected token '...'.
+//   <int>{if (oracle("foo")) ...map, null};
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:9: Error: Unexpected token 'if'.
+//   <int>{if (oracle("foo")) ...map, null};
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:36: Error: Unexpected token '...'.
+//   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:12: Error: Unexpected token 'if'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
 //            ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:12: Error: Unexpected token 'if'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
 //            ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:20: Error: Unexpected token 'if'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:28: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:99:28: Error: Unexpected token '...'.
 //   <int>[if (oracle("foo")) ...map else 42];
 //                            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) ...map else 42];
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:28: Error: Unexpected token '...'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//                            ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:9: Error: Unexpected token 'if'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//         ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:36: Error: Unexpected token '...'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                                    ^^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:17: Error: Unexpected token 'if'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                 ^^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:99:36: Error: Unexpected token '...'.
-//   <int>[if (oracle("foo")) 42 else ...map];
-//                                    ^^^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:99:9: Error: Unexpected token 'if'.
-//   <int>[if (oracle("foo")) 42 else ...map];
+//   <int>[if (oracle("foo")) ...map else 42];
 //         ^^
 //
 // pkg/front_end/testcases/control_flow_collection_inference.dart:100:28: Error: Unexpected token '...'.
@@ -710,980 +698,1092 @@
 //   <int>{if (oracle("foo")) ...map else 42, null};
 //         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:51: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:36: Error: Unexpected token '...'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                 ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:36: Error: Unexpected token '...'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//                                    ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:9: Error: Unexpected token 'if'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:28: Error: Unexpected token '...'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//                            ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:9: Error: Unexpected token 'if'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:51: Error: Unexpected token '...'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:17: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:17: Error: Unexpected token 'if'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:106:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:25: Error: Unexpected token 'if'.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:107:34: Error: Unexpected token 'if'.
+//   Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:25: Error: Unexpected token 'if'.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                         ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:109:34: Error: Unexpected token 'if'.
+//   Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'if'.
+//   var map12 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'if'.
+//   var map13 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:112:23: Error: Unexpected token 'if'.
+//   List<int> list20 = [if (42) 42];
+//                       ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:113:21: Error: Unexpected token 'if'.
+//   Set<int> set20 = {if (42) 42};
+//                     ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:114:26: Error: Unexpected token 'if'.
+//   Map<int, int> map30 = {if (42) 42: 42};
+//                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:34: Error: Unexpected token 'if'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                  ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:32: Error: Unexpected token 'if'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:42: Error: Unexpected token 'if'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:42: Error: Unexpected token 'if'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                          ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:123:17: Error: Unexpected token 'for'.
 //   var list10 = [for (int i = 0; oracle("foo"); i++) 42];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:107:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:124:16: Error: Unexpected token 'for'.
 //   var set10 = {for (int i = 0; oracle("foo"); i++) 42, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:108:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'.
 //   var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:109:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:126:17: Error: Unexpected token 'for'.
 //   var list11 = [for (int i = 0; oracle("foo"); i++) dynVar];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:110:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:127:16: Error: Unexpected token 'for'.
 //   var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:111:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'.
 //   var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:112:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:129:17: Error: Unexpected token 'for'.
 //   var list12 = [for (int i = 0; oracle("foo"); i++) [42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:113:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:130:16: Error: Unexpected token 'for'.
 //   var set12 = {for (int i = 0; oracle("foo"); i++) [42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:114:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'.
 //   var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:132:53: Error: Unexpected token '...'.
 //   var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:115:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:132:17: Error: Unexpected token 'for'.
 //   var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:116:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:133:52: Error: Unexpected token '...'.
 //   var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:116:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:133:16: Error: Unexpected token 'for'.
 //   var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:117:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:134:52: Error: Unexpected token '...'.
 //   var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:117:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:134:16: Error: Unexpected token 'for'.
 //   var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:118:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:135:53: Error: Unexpected token '...'.
 //   var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:118:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:135:17: Error: Unexpected token 'for'.
 //   var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:119:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:136:52: Error: Unexpected token '...'.
 //   var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:119:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:136:16: Error: Unexpected token 'for'.
 //   var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:120:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:137:52: Error: Unexpected token '...'.
 //   var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:120:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:137:16: Error: Unexpected token 'for'.
 //   var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:121:53: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:138:53: Error: Unexpected token '...'.
 //   var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]];
 //                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:121:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:138:17: Error: Unexpected token 'for'.
 //   var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:122:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:139:52: Error: Unexpected token '...'.
 //   var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:122:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:139:16: Error: Unexpected token 'for'.
 //   var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:123:52: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:140:52: Error: Unexpected token '...'.
 //   var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null};
 //                                                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:123:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:140:16: Error: Unexpected token 'for'.
 //   var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:67: Error: Unexpected token '...'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:53: Error: Unexpected token 'if'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:124:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:141:17: Error: Unexpected token 'for'.
 //   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:66: Error: Unexpected token '...'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:52: Error: Unexpected token 'if'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:125:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:142:16: Error: Unexpected token 'for'.
 //   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:66: Error: Unexpected token '...'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:52: Error: Unexpected token 'if'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:126:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:143:16: Error: Unexpected token 'for'.
 //   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:67: Error: Unexpected token '...'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:53: Error: Unexpected token 'if'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:127:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:144:17: Error: Unexpected token 'for'.
 //   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:66: Error: Unexpected token '...'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:52: Error: Unexpected token 'if'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:128:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:145:16: Error: Unexpected token 'for'.
 //   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:66: Error: Unexpected token '...'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:52: Error: Unexpected token 'if'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:129:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:146:16: Error: Unexpected token 'for'.
 //   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:67: Error: Unexpected token '...'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Error: Unexpected token 'if'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:130:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:147:17: Error: Unexpected token 'for'.
 //   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:66: Error: Unexpected token '...'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:52: Error: Unexpected token 'if'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:131:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:148:16: Error: Unexpected token 'for'.
 //   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:66: Error: Unexpected token '...'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:52: Error: Unexpected token 'if'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:132:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:149:16: Error: Unexpected token 'for'.
 //   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:133:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:150:65: Error: Unexpected token '...'.
 //   List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:133:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:150:29: Error: Unexpected token 'for'.
 //   List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:134:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:151:63: Error: Unexpected token '...'.
 //   Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:134:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:151:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:135:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:152:71: Error: Unexpected token '...'.
 //   Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:135:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:152:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:136:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:153:65: Error: Unexpected token '...'.
 //   List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:136:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:153:29: Error: Unexpected token 'for'.
 //   List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:137:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:154:63: Error: Unexpected token '...'.
 //   Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:137:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:154:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:79: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:79: Error: Unexpected token '...'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:65: Error: Unexpected token 'if'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:138:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:155:29: Error: Unexpected token 'for'.
 //   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:77: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:77: Error: Unexpected token '...'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:139:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:156:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:85: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:85: Error: Unexpected token '...'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:140:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:157:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:141:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Error: Unexpected token '...'.
 //   List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:141:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:158:23: Error: Unexpected token 'for'.
 //   List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:142:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:159:57: Error: Unexpected token '...'.
 //   Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:142:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:159:21: Error: Unexpected token 'for'.
 //   Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:143:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:160:65: Error: Unexpected token '...'.
 //   Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null};
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:143:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:160:29: Error: Unexpected token 'for'.
 //   Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:144:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:161:59: Error: Unexpected token '...'.
 //   List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:144:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:161:23: Error: Unexpected token 'for'.
 //   List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:145:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:162:57: Error: Unexpected token '...'.
 //   Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:145:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:162:21: Error: Unexpected token 'for'.
 //   Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:73: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:73: Error: Unexpected token '...'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:59: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:59: Error: Unexpected token 'if'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                                                           ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:146:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:163:23: Error: Unexpected token 'for'.
 //   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:71: Error: Unexpected token '...'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:57: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:57: Error: Unexpected token 'if'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                                                         ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:147:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:164:21: Error: Unexpected token 'for'.
 //   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:148:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:165:65: Error: Unexpected token '...'.
 //   List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:148:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:165:29: Error: Unexpected token 'for'.
 //   List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:149:63: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:166:63: Error: Unexpected token '...'.
 //   Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:149:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:166:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:150:71: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:167:71: Error: Unexpected token '...'.
 //   Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:150:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:167:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:79: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:79: Error: Unexpected token '...'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:65: Error: Unexpected token 'if'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:151:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:168:29: Error: Unexpected token 'for'.
 //   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:77: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:77: Error: Unexpected token '...'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:152:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:169:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:85: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:85: Error: Unexpected token '...'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:153:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:170:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:154:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:171:29: Error: Unexpected token 'for'.
 //   List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:155:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:172:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:156:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:173:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:157:65: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:174:65: Error: Unexpected token 'if'.
 //   List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []];
 //                                                                 ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:157:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'.
 //   List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:158:63: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:175:63: Error: Unexpected token 'if'.
 //   Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null};
 //                                                               ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:158:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:175:27: Error: Unexpected token 'for'.
 //   Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:159:71: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:176:71: Error: Unexpected token 'if'.
 //   Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null};
 //                                                                       ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:159:35: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:176:35: Error: Unexpected token 'for'.
 //   Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null};
 //                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:160:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:177:53: Error: Unexpected token 'if'.
 //   var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:160:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:177:17: Error: Unexpected token 'for'.
 //   var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:161:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:178:52: Error: Unexpected token 'if'.
 //   var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:161:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:178:16: Error: Unexpected token 'for'.
 //   var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:162:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:179:52: Error: Unexpected token 'if'.
 //   var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:162:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:179:16: Error: Unexpected token 'for'.
 //   var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:67: Error: Unexpected token '...'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:83: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:83: Error: Unexpected token '...'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:53: Error: Unexpected token 'if'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:163:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:180:17: Error: Unexpected token 'for'.
 //   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:66: Error: Unexpected token '...'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:82: Error: Unexpected token '...'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:52: Error: Unexpected token 'if'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:164:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:181:16: Error: Unexpected token 'for'.
 //   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:66: Error: Unexpected token '...'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:87: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:87: Error: Unexpected token '...'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:52: Error: Unexpected token 'if'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:165:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:182:16: Error: Unexpected token 'for'.
 //   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:67: Error: Unexpected token '...'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:83: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:83: Error: Unexpected token '...'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:53: Error: Unexpected token 'if'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:166:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'.
 //   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:66: Error: Unexpected token '...'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:82: Error: Unexpected token '...'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:52: Error: Unexpected token 'if'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:167:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:184:16: Error: Unexpected token 'for'.
 //   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:66: Error: Unexpected token '...'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:87: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:87: Error: Unexpected token '...'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                                                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:52: Error: Unexpected token 'if'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:168:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:185:16: Error: Unexpected token 'for'.
 //   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:75: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:75: Error: Unexpected token '...'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:53: Error: Unexpected token 'if'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:169:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:186:17: Error: Unexpected token 'for'.
 //   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:66: Error: Unexpected token '...'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:52: Error: Unexpected token 'if'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:170:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:187:16: Error: Unexpected token 'for'.
 //   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:66: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:66: Error: Unexpected token '...'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:52: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:52: Error: Unexpected token 'if'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                                                    ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:171:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:188:16: Error: Unexpected token 'for'.
 //   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:172:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:189:23: Error: Unexpected token 'for'.
 //   List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:173:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:190:21: Error: Unexpected token 'for'.
 //   Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:174:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:191:29: Error: Unexpected token 'for'.
 //   Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:192:59: Error: Unexpected token '...'.
 //   List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:175:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:192:23: Error: Unexpected token 'for'.
 //   List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:176:57: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:193:57: Error: Unexpected token '...'.
 //   Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null};
 //                                                         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:176:21: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:193:21: Error: Unexpected token 'for'.
 //   Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null};
 //                     ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:177:65: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:194:65: Error: Unexpected token '...'.
 //   Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null};
 //                                                                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:177:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:194:29: Error: Unexpected token 'for'.
 //   Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null};
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:178:29: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:195:29: Error: Unexpected token 'for'.
 //   List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42];
 //                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:179:27: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:196:27: Error: Unexpected token 'for'.
 //   Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42};
 //                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:180:43: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:197:43: Error: Unexpected token 'for'.
 //   Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42};
 //                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:181:18: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:198:18: Error: Unexpected token 'for'.
 //   var list110 = [for (var i in [1, 2, 3]) i];
 //                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:182:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:199:17: Error: Unexpected token 'for'.
 //   var set110 = {for (var i in [1, 2, 3]) i, null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:183:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:200:17: Error: Unexpected token 'for'.
 //   var map110 = {for (var i in [1, 2, 3]) "bar": i, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:184:24: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:201:24: Error: Unexpected token 'for'.
 //   List<int> list120 = [for (var i in dynVar) i];
 //                        ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:185:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:202:22: Error: Unexpected token 'for'.
 //   Set<int> set120 = {for (var i in dynVar) i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:186:30: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:203:30: Error: Unexpected token 'for'.
 //   Map<String, int> map120 = {for (var i in dynVar) "bar": i, "baz": null};
 //                              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:190:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:204:24: Error: Unexpected token 'for'.
+//   List<int> list130 = [for (var i = 1; i < 2; i++) i];
+//                        ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:205:22: Error: Unexpected token 'for'.
+//   Set<int> set130 = {for (var i = 1; i < 2; i++) i};
+//                      ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:206:27: Error: Unexpected token 'for'.
+//   Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i};
+//                           ^^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:191:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:45: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:45: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:50: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:50: Error: Unexpected token '...'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:45: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:45: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:45: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //                                             ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:50: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:50: Error: Unexpected token '...'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:14: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:14: Error: Unexpected token 'for'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:48: Error: Unexpected token 'if'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //                                                ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:12: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:12: Error: Unexpected token 'for'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
 //            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:48: Error: Unexpected token 'if'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //                                                ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:12: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:12: Error: Unexpected token 'for'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
 //            ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:56: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:56: Error: Unexpected token 'if'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                        ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:20: Error: Unexpected token 'for'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                    ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:59: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:45: Error: Unexpected token 'if'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:59: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:59: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                                           ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:45: Error: Unexpected token 'if'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:67: Error: Unexpected token '...'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:53: Error: Unexpected token 'if'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:17: Error: Unexpected token 'for'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:67: Error: Unexpected token '...'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:45: Error: Unexpected token 'if'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:9: Error: Unexpected token 'for'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:67: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:67: Error: Unexpected token '...'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                                                   ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:45: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:45: Error: Unexpected token 'if'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                             ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:9: Error: Unexpected token 'for'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:82: Error: Unexpected token '...'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:82: Error: Unexpected token '...'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                                                  ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:53: Error: Unexpected token 'if'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:53: Error: Unexpected token 'if'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                     ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:17: Error: Unexpected token 'for'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:210:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:230:9: Error: Unexpected token 'for'.
 //   <int>[for (i in <int>[1]) i];
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:211:9: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:231:9: Error: Unexpected token 'for'.
 //   <int>{for (i in <int>[1]) i, null};
 //         ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:212:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:232:16: Error: Unexpected token 'for'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	              ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:214:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:234:17: Error: Unexpected token 'for'.
 //   var list10 = [for (var i in "not iterable") i];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:215:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:235:16: Error: Unexpected token 'for'.
 //   var set10 = {for (var i in "not iterable") i, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:216:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:236:16: Error: Unexpected token 'for'.
 //   var map10 = {for (var i in "not iterable") "bar": i, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:17: Error: Unexpected token 'for'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:16: Error: Unexpected token 'for'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:16: Error: Unexpected token 'for'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:220:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:240:23: Error: Unexpected token 'for'.
 //   var list30 = [await for (var i in "not stream") i];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:221:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:241:22: Error: Unexpected token 'for'.
 //   var set30 = {await for (var i in "not stream") i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:222:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:242:22: Error: Unexpected token 'for'.
 //   var map30 = {await for (var i in "not stream") "bar": i, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:23: Error: Unexpected token 'for'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:22: Error: Unexpected token 'for'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:22: Error: Unexpected token 'for'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var list50 = [await for (;;) 42];
 //                 ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:23: Error: Unexpected token 'for'.
 //   var list50 = [await for (;;) 42];
 //                       ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var set50 = {await for (;;) 42, null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:22: Error: Unexpected token 'for'.
 //   var set50 = {await for (;;) 42, null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:22: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:22: Error: Unexpected token 'for'.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                      ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:229:17: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:249:17: Error: Unexpected token 'for'.
 //   var list60 = [for (; "not bool";) 42];
 //                 ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:230:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:250:16: Error: Unexpected token 'for'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:231:16: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:251:16: Error: Unexpected token 'for'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>[await for (int i in stream) i];
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:15: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:15: Error: Unexpected token 'for'.
 //   <int>[await for (int i in stream) i];
 //               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>{await for (int i in stream) i};
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:15: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:15: Error: Unexpected token 'for'.
 //   <int>{await for (int i in stream) i};
 //               ^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                                  ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:23: Error: Unexpected token 'for'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:23: Error: Unexpected token 'for'.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                       ^^^
 //
+// pkg/front_end/testcases/control_flow_collection_inference.dart:267:23: Error: Unexpected token 'if'.
+//   List<int> list10 = [if (a is B) a.foo];
+//                       ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:268:21: Error: Unexpected token 'if'.
+//   Set<int> set10 = {if (a is B) a.foo};
+//                     ^^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:269:26: Error: Unexpected token 'if'.
+//   Map<int, int> map10 = {if (a is B) a.foo: a.foo};
+//                          ^^
+//
 import self as self;
 import "dart:core" as core;
 import "dart:async" as asy;
 
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
 static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic
   return true;
 static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic {
@@ -1758,6 +1858,9 @@
   core::List<core::int> list91 = <dynamic>[];
   core::Set<core::int> set91 = <dynamic>{null};
   core::Map<core::String, core::int> map91 = <dynamic, dynamic>{"baz": null};
+  core::List<core::int> list100 = <dynamic>[];
+  core::Set<core::int> set100 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map100 = <dynamic, dynamic>{};
 }
 static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic {
   <core::int>[];
@@ -1778,6 +1881,19 @@
   <core::int>[];
   <core::int>{null};
   <core::String, core::int>{"baz": null};
+  core::Set<dynamic> set10 = <dynamic, dynamic>{};
+  core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{};
+  core::Set<dynamic> set11 = <dynamic, dynamic>{};
+  core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{};
+  dynamic map12 = <dynamic, dynamic>{};
+  dynamic map13 = <dynamic, dynamic>{};
+  core::List<core::int> list20 = <dynamic>[];
+  core::Set<core::int> set20 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map30 = <dynamic, dynamic>{};
+  core::List<core::String> list40 = <core::String>[];
+  core::Set<core::String> set40 = <core::String>{};
+  core::Map<core::String, core::int> map40 = <core::String, core::int>{};
+  core::Map<core::int, core::String> map41 = <core::int, core::String>{};
 }
 static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic {
   dynamic list10 = <dynamic>[];
@@ -1861,6 +1977,9 @@
   core::List<core::int> list120 = <dynamic>[];
   core::Set<core::int> set120 = <dynamic>{null};
   core::Map<core::String, core::int> map120 = <dynamic, dynamic>{"baz": null};
+  core::List<core::int> list130 = <dynamic>[];
+  core::Set<core::int> set130 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map130 = <dynamic, dynamic>{};
 }
 static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
@@ -1932,4 +2051,9 @@
   <core::int>{};
   <core::String, core::int>{};
 }
+static method testPromotion(self::A a) → dynamic {
+  core::List<core::int> list10 = <dynamic>[];
+  core::Set<core::int> set10 = <dynamic, dynamic>{};
+  core::Map<core::int, core::int> map10 = <dynamic, dynamic>{};
+}
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect
index ff425da..c40231f 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.outline.expect
@@ -3,6 +3,16 @@
 import "dart:core" as core;
 import "dart:async" as asy;
 
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    ;
+  get foo() → core::int
+    ;
+}
 static method oracle<T extends core::Object = dynamic>([self::oracle::T t]) → dynamic
   ;
 static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic
@@ -15,5 +25,7 @@
   ;
 static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic
   ;
+static method testPromotion(self::A a) → dynamic
+  ;
 static method main() → dynamic
   ;
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect
index 5d1a4bb..c3b0f74 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.expect
@@ -11,379 +11,466 @@
 //   var map82 = {if (oracle("foo")) ...mapToInt else ...dynVar, null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:44: Error: Expected ':' after this.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                            ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this.
+//   Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                                     ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:61: Error: Expected ':' after this.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
+//   Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+//   var map12 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                   ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+//   var map13 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                    ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) "bar"];
 //                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) "bar", null};
 //                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                                           ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-//   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
-//                                         ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) ...["bar"]];
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) ...["bar"], null};
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[if (oracle("foo")) ...map];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{if (oracle("foo")) ...map, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
 //                                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
-//            ^
+//                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>[if (oracle("foo")) 42 else 3.14];
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
-//            ^
+//                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>{if (oracle("foo")) 42 else 3.14, null};
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
-//                    ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[if (oracle("foo")) ...map else 42];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
-//  - 'Map' is from 'dart:core'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//                               ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
-//  - 'List' is from 'dart:core'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                                       ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
-//  - 'Map' is from 'dart:core'.
-//   <int>[if (oracle("foo")) 42 else ...map];
-//                                       ^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{if (oracle("foo")) ...map else 42, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+//  - 'List' is from 'dart:core'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+//  - 'Map' is from 'dart:core'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+//  - 'Map' is from 'dart:core'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                        ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                        ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   List<int> list20 = [if (42) 42];
+//                           ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   Set<int> set20 = {if (42) 42};
+//                         ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   Map<int, int> map30 = {if (42) 42: 42};
+//                              ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                                     ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                                   ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                                                           ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                                                 ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                                                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var list50 = [await for (;;) 42];
 //                 ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var set50 = {await for (;;) 42, null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                  ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-//   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
-//              ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
-//                                                ^
+//                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
-//                                                ^
+//                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
-//                    ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var list10 = [for (var i in "not iterable") i];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var set10 = {for (var i in "not iterable") i, null};
 //                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var map10 = {for (var i in "not iterable") "bar": i, "baz": null};
 //                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var list30 = [await for (var i in "not stream") i];
 //                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var set30 = {await for (var i in "not stream") i, null};
 //                                    ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var map30 = {await for (var i in "not stream") "bar": i, "baz": null};
 //                                    ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                          ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var list60 = [for (; "not bool";) 42];
 //                        ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>[await for (int i in stream) i];
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>{await for (int i in stream) i};
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                                  ^^
@@ -393,198 +480,210 @@
 import "dart:collection" as col;
 import "dart:async" as asy;
 
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
 static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic
   return true;
 static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic {
   core::List<core::int> list10 = block {
     final core::List<core::int> #t1 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t1.{core::List::add}(42);
   } =>#t1;
   core::Set<core::int> set10 = block {
     final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t2.{core::Set::add}(42);
     #t2.{core::Set::add}(null);
   } =>#t2;
   core::Map<core::String, core::int> map10 = block {
     final core::Map<core::String, core::int> #t3 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t3.{core::Map::[]=}("bar", 42);
     #t3.{core::Map::[]=}("baz", null);
   } =>#t3;
   core::List<dynamic> list11 = block {
     final core::List<dynamic> #t4 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t4.{core::List::add}(dynVar);
   } =>#t4;
   core::Set<dynamic> set11 = block {
     final core::Set<dynamic> #t5 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t5.{core::Set::add}(dynVar);
     #t5.{core::Set::add}(null);
   } =>#t5;
   core::Map<core::String, dynamic> map11 = block {
     final core::Map<core::String, dynamic> #t6 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t6.{core::Map::[]=}("bar", dynVar);
     #t6.{core::Map::[]=}("baz", null);
   } =>#t6;
   core::List<core::List<core::int>> list12 = block {
     final core::List<core::List<core::int>> #t7 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t7.{core::List::add}(<core::int>[42]);
   } =>#t7;
   core::Set<core::List<core::int>> set12 = block {
     final core::Set<core::List<core::int>> #t8 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t8.{core::Set::add}(<core::int>[42]);
     #t8.{core::Set::add}(null);
   } =>#t8;
   core::Map<core::String, core::List<core::int>> map12 = block {
     final core::Map<core::String, core::List<core::int>> #t9 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t9.{core::Map::[]=}("bar", <core::int>[42]);
     #t9.{core::Map::[]=}("baz", null);
   } =>#t9;
   core::List<core::int> list20 = block {
     final core::List<core::int> #t10 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t11 in <core::int>[42])
         #t10.{core::List::add}(#t11);
   } =>#t10;
   core::Set<core::int> set20 = block {
     final core::Set<core::int> #t12 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t13 in <core::int>[42])
         #t12.{core::Set::add}(#t13);
     #t12.{core::Set::add}(null);
   } =>#t12;
   core::Map<core::String, core::int> map20 = block {
     final core::Map<core::String, core::int> #t14 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::int> #t15 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
         #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
     #t14.{core::Map::[]=}("baz", null);
   } =>#t14;
   core::List<dynamic> list21 = block {
     final core::List<dynamic> #t16 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t17 in <dynamic>[dynVar])
         #t16.{core::List::add}(#t17);
   } =>#t16;
   core::Set<dynamic> set21 = block {
     final core::Set<dynamic> #t18 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t19 in <dynamic>[dynVar])
         #t18.{core::Set::add}(#t19);
     #t18.{core::Set::add}(null);
   } =>#t18;
   core::Map<core::String, dynamic> map21 = block {
     final core::Map<core::String, dynamic> #t20 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, dynamic> #t21 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
     #t20.{core::Map::[]=}("baz", null);
   } =>#t20;
   core::List<core::List<core::int>> list22 = block {
     final core::List<core::List<core::int>> #t22 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t23 in <core::List<core::int>>[<core::int>[42]])
         #t22.{core::List::add}(#t23);
   } =>#t22;
   core::Set<core::List<core::int>> set22 = block {
     final core::Set<core::List<core::int>> #t24 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t25 in <core::List<core::int>>[<core::int>[42]])
         #t24.{core::Set::add}(#t25);
     #t24.{core::Set::add}(null);
   } =>#t24;
   core::Map<core::String, core::List<core::int>> map22 = block {
     final core::Map<core::String, core::List<core::int>> #t26 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::List<core::int>> #t27 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
         #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
     #t26.{core::Map::[]=}("baz", null);
   } =>#t26;
   core::List<core::int> list30 = block {
     final core::List<core::int> #t28 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t29 in <core::int>[42])
           #t28.{core::List::add}(#t29);
   } =>#t28;
   core::Set<core::int> set30 = block {
     final core::Set<core::int> #t30 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t31 in <core::int>[42])
           #t30.{core::Set::add}(#t31);
     #t30.{core::Set::add}(null);
   } =>#t30;
   core::Map<core::String, core::int> map30 = block {
     final core::Map<core::String, core::int> #t32 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::int> #t33 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
           #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
     #t32.{core::Map::[]=}("baz", null);
   } =>#t32;
   core::List<dynamic> list31 = block {
     final core::List<dynamic> #t34 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final dynamic #t35 in <dynamic>[dynVar])
           #t34.{core::List::add}(#t35);
   } =>#t34;
   core::Set<dynamic> set31 = block {
     final core::Set<dynamic> #t36 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final dynamic #t37 in <dynamic>[dynVar])
           #t36.{core::Set::add}(#t37);
     #t36.{core::Set::add}(null);
   } =>#t36;
   core::Map<core::String, dynamic> map31 = block {
     final core::Map<core::String, dynamic> #t38 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, dynamic> #t39 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
           #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
     #t38.{core::Map::[]=}("baz", null);
   } =>#t38;
   core::List<core::List<core::int>> list33 = block {
     final core::List<core::List<core::int>> #t40 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t41 in <core::List<core::int>>[<core::int>[42]])
           #t40.{core::List::add}(#t41);
   } =>#t40;
   core::Set<core::List<core::int>> set33 = block {
     final core::Set<core::List<core::int>> #t42 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t43 in <core::List<core::int>>[<core::int>[42]])
           #t42.{core::Set::add}(#t43);
     #t42.{core::Set::add}(null);
   } =>#t42;
   core::Map<core::String, core::List<core::int>> map33 = block {
     final core::Map<core::String, core::List<core::int>> #t44 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t45 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
           #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
     #t44.{core::Map::[]=}("baz", null);
   } =>#t44;
   core::List<core::List<core::int>> list40 = block {
     final core::List<core::List<core::int>> #t46 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t47 in <core::List<core::int>>[<core::int>[]])
         #t46.{core::List::add}(#t47);
   } =>#t46;
   core::Set<core::List<core::int>> set40 = block {
     final core::Set<core::List<core::int>> #t48 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t49 in <core::List<core::int>>[<core::int>[]])
         #t48.{core::Set::add}(#t49);
     #t48.{core::Set::add}(null);
@@ -594,173 +693,173 @@
                                  ^";
   core::List<core::List<core::int>> list41 = block {
     final core::List<core::List<core::int>> #t50 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t51 in let final core::Set<core::List<core::int>> #t52 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t53 = #t52.{core::Set::add}(<core::int>[]) in #t52)
         #t50.{core::List::add}(#t51);
   } =>#t50;
   core::Set<core::List<core::int>> set41 = block {
     final core::Set<core::List<core::int>> #t54 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t55 in let final core::Set<core::List<core::int>> #t56 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t57 = #t56.{core::Set::add}(<core::int>[]) in #t56)
         #t54.{core::Set::add}(#t55);
     #t54.{core::Set::add}(null);
   } =>#t54;
   core::List<core::List<core::int>> list42 = block {
     final core::List<core::List<core::int>> #t58 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t59 in <core::List<core::int>>[<core::int>[]])
           #t58.{core::List::add}(#t59);
   } =>#t58;
   core::Set<core::List<core::int>> set42 = block {
     final core::Set<core::List<core::int>> #t60 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t61 in <core::List<core::int>>[<core::int>[]])
           #t60.{core::Set::add}(#t61);
     #t60.{core::Set::add}(null);
   } =>#t60;
   core::Map<core::String, core::List<core::int>> map42 = block {
     final core::Map<core::String, core::List<core::int>> #t62 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t63 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
           #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
     #t62.{core::Map::[]=}("baz", null);
   } =>#t62;
   core::List<core::int> list50 = block {
     final core::List<core::int> #t64 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t65 in <core::int>[])
         #t64.{core::List::add}(#t65);
   } =>#t64;
   core::Set<core::int> set50 = block {
     final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t67 in <core::int>[])
         #t66.{core::Set::add}(#t67);
     #t66.{core::Set::add}(null);
   } =>#t66;
   core::Map<core::String, core::int> map50 = block {
     final core::Map<core::String, core::int> #t68 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::int> #t69 in <core::String, core::int>{}.{core::Map::entries})
         #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
     #t68.{core::Map::[]=}("baz", null);
   } =>#t68;
   core::List<core::int> list51 = block {
     final core::List<core::int> #t70 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t71 in let final core::Set<core::int> #t72 = col::LinkedHashSet::•<core::int>() in #t72)
         #t70.{core::List::add}(#t71);
   } =>#t70;
   core::Set<core::int> set51 = block {
     final core::Set<core::int> #t73 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t74 in let final core::Set<core::int> #t75 = col::LinkedHashSet::•<core::int>() in #t75)
         #t73.{core::Set::add}(#t74);
     #t73.{core::Set::add}(null);
   } =>#t73;
   core::List<core::int> list52 = block {
     final core::List<core::int> #t76 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t77 in <core::int>[])
           #t76.{core::List::add}(#t77);
   } =>#t76;
   core::Set<core::int> set52 = block {
     final core::Set<core::int> #t78 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t79 in <core::int>[])
           #t78.{core::Set::add}(#t79);
     #t78.{core::Set::add}(null);
   } =>#t78;
   core::Map<core::String, core::int> map52 = block {
     final core::Map<core::String, core::int> #t80 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::int> #t81 in <core::String, core::int>{}.{core::Map::entries})
           #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
     #t80.{core::Map::[]=}("baz", null);
   } =>#t80;
   core::List<core::List<core::int>> list60 = block {
     final core::List<core::List<core::int>> #t82 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t83 in <core::List<core::int>>[<core::int>[]])
         #t82.{core::List::add}(#t83);
   } =>#t82;
   core::Set<core::List<core::int>> set60 = block {
     final core::Set<core::List<core::int>> #t84 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t85 in <core::List<core::int>>[<core::int>[]])
         #t84.{core::Set::add}(#t85);
     #t84.{core::Set::add}(null);
   } =>#t84;
   core::Map<core::String, core::List<core::int>> map60 = block {
     final core::Map<core::String, core::List<core::int>> #t86 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::List<core::int>> #t87 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
     #t86.{core::Map::[]=}("baz", null);
   } =>#t86;
   core::List<core::List<core::int>> list61 = block {
     final core::List<core::List<core::int>> #t88 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t89 in <core::List<core::int>>[<core::int>[]])
           #t88.{core::List::add}(#t89);
   } =>#t88;
   core::Set<core::List<core::int>> set61 = block {
     final core::Set<core::List<core::int>> #t90 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t91 in <core::List<core::int>>[<core::int>[]])
           #t90.{core::Set::add}(#t91);
     #t90.{core::Set::add}(null);
   } =>#t90;
   core::Map<core::String, core::List<core::int>> map61 = block {
     final core::Map<core::String, core::List<core::int>> #t92 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t93 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
           #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
     #t92.{core::Map::[]=}("baz", null);
   } =>#t92;
   core::List<core::List<core::int>> list70 = block {
     final core::List<core::List<core::int>> #t94 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t94.{core::List::add}(<core::int>[]);
   } =>#t94;
   core::Set<core::List<core::int>> set70 = block {
     final core::Set<core::List<core::int>> #t95 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t95.{core::Set::add}(<core::int>[]);
     #t95.{core::Set::add}(null);
   } =>#t95;
   core::List<core::List<core::int>> list71 = block {
     final core::List<core::List<core::int>> #t96 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         #t96.{core::List::add}(<core::int>[]);
   } =>#t96;
   core::Set<core::List<core::int>> set71 = block {
     final core::Set<core::List<core::int>> #t97 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         #t97.{core::Set::add}(<core::int>[]);
     #t97.{core::Set::add}(null);
   } =>#t97;
   core::List<core::num> list80 = block {
     final core::List<core::num> #t98 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t98.{core::List::add}(42);
     else
       #t98.{core::List::add}(3.14);
   } =>#t98;
   core::Set<core::num> set80 = block {
     final core::Set<core::num> #t99 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t99.{core::Set::add}(42);
     else
       #t99.{core::Set::add}(3.14);
@@ -768,7 +867,7 @@
   } =>#t99;
   core::Map<core::String, core::num> map80 = block {
     final core::Map<core::String, core::num> #t100 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t100.{core::Map::[]=}("bar", 42);
     else
       #t100.{core::Map::[]=}("bar", 3.14);
@@ -776,7 +875,7 @@
   } =>#t100;
   core::List<core::num> list81 = block {
     final core::List<core::num> #t101 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t102 in listInt)
         #t101.{core::List::add}(#t102);
     else
@@ -785,7 +884,7 @@
   } =>#t101;
   core::Set<core::num> set81 = block {
     final core::Set<core::num> #t104 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t105 in listInt)
         #t104.{core::Set::add}(#t105);
     else
@@ -795,7 +894,7 @@
   } =>#t104;
   core::Map<core::String, core::num> map81 = block {
     final core::Map<core::String, core::num> #t107 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::num> #t108 in mapToInt.{core::Map::entries})
         #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value});
     else
@@ -805,7 +904,7 @@
   } =>#t107;
   core::List<dynamic> list82 = block {
     final core::List<dynamic> #t110 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t111 in listInt)
         #t110.{core::List::add}(#t111);
     else
@@ -814,7 +913,7 @@
   } =>#t110;
   core::Set<dynamic> set82 = block {
     final core::Set<dynamic> #t113 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t114 in listInt)
         #t113.{core::Set::add}(#t114);
     else
@@ -824,7 +923,7 @@
   } =>#t113;
   core::Set<dynamic> map82 = block {
     final core::Set<dynamic> #t116 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t116.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
@@ -836,7 +935,7 @@
   } =>#t116;
   core::List<core::num> list83 = block {
     final core::List<core::num> #t118 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t118.{core::List::add}(42);
     else
       for (final core::num #t119 in listDouble)
@@ -844,7 +943,7 @@
   } =>#t118;
   core::Set<core::num> set83 = block {
     final core::Set<core::num> #t120 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t121 in listInt)
         #t120.{core::Set::add}(#t121);
     else
@@ -853,7 +952,7 @@
   } =>#t120;
   core::Map<core::String, core::num> map83 = block {
     final core::Map<core::String, core::num> #t122 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::num> #t123 in mapToInt.{core::Map::entries})
         #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value});
     else
@@ -862,24 +961,24 @@
   } =>#t122;
   core::List<core::int> list90 = block {
     final core::List<core::int> #t124 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t124.{core::List::add}(dynVar as{TypeError} core::int);
   } =>#t124;
   core::Set<core::int> set90 = block {
     final core::Set<core::int> #t125 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t125.{core::Set::add}(dynVar as{TypeError} core::int);
     #t125.{core::Set::add}(null);
   } =>#t125;
   core::Map<core::String, core::int> map90 = block {
     final core::Map<core::String, core::int> #t126 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t126.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
     #t126.{core::Map::[]=}("baz", null);
   } =>#t126;
   core::List<core::int> list91 = block {
     final core::List<core::int> #t127 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t128 in dynVar as{TypeError} core::Iterable<dynamic>) {
         final core::int #t129 = #t128 as{TypeError} core::int;
         #t127.{core::List::add}(#t129);
@@ -887,7 +986,7 @@
   } =>#t127;
   core::Set<core::int> set91 = block {
     final core::Set<core::int> #t130 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t131 in dynVar as{TypeError} core::Iterable<dynamic>) {
         final core::int #t132 = #t131 as{TypeError} core::int;
         #t130.{core::Set::add}(#t132);
@@ -896,7 +995,7 @@
   } =>#t130;
   core::Map<core::String, core::int> map91 = block {
     final core::Map<core::String, core::int> #t133 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<dynamic, dynamic> #t134 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
         final core::String #t135 = #t134.{core::MapEntry::key} as{TypeError} core::String;
         final core::int #t136 = #t134.{core::MapEntry::value} as{TypeError} core::int;
@@ -904,1081 +1003,1311 @@
       }
     #t133.{core::Map::[]=}("baz", null);
   } =>#t133;
+  core::List<core::int> list100 = block {
+    final core::List<core::int> #t137 = <core::int>[];
+    if(dynVar as{TypeError} core::bool)
+      #t137.{core::List::add}(42);
+  } =>#t137;
+  core::Set<core::int> set100 = block {
+    final core::Set<core::int> #t138 = col::LinkedHashSet::•<core::int>();
+    if(dynVar as{TypeError} core::bool)
+      #t138.{core::Set::add}(42);
+  } =>#t138;
+  core::Map<core::int, core::int> map100 = block {
+    final core::Map<core::int, core::int> #t139 = <core::int, core::int>{};
+    if(dynVar as{TypeError} core::bool)
+      #t139.{core::Map::[]=}(42, 42);
+  } =>#t139;
 }
 static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic {
-  <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int>[if (oracle(\"foo\")) \"bar\"];
-                           ^"];
-  let final core::Set<core::int> #t137 = col::LinkedHashSet::•<core::int>() in let final dynamic #t138 = #t137.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int>{if (oracle(\"foo\")) \"bar\", null};
-                           ^") in let final dynamic #t139 = #t137.{core::Set::add}(null) in #t137;
-  <core::String, core::int>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
-                                        ^", "baz": null};
   block {
     final core::List<core::int> #t140 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      for (final core::int #t141 in <core::int>[let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int>[if (oracle(\"foo\")) \"bar\"];
+                           ^" in "bar" as{TypeError} core::int);
+  } =>#t140;
+  block {
+    final core::Set<core::int> #t142 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int>{if (oracle(\"foo\")) \"bar\", null};
+                           ^" in "bar" as{TypeError} core::int);
+    #t142.{core::Set::add}(null);
+  } =>#t142;
+  block {
+    final core::Map<core::String, core::int> #t144 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
+                                          ^" in "bar" as{TypeError} core::int);
+    #t144.{core::Map::[]=}("baz", null);
+  } =>#t144;
+  block {
+    final core::List<core::int> #t146 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::int #t147 in <core::int>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
                                ^" in "bar" as{TypeError} core::int])
-        #t140.{core::List::add}(#t141);
-  } =>#t140;
+        #t146.{core::List::add}(#t147);
+  } =>#t146;
   block {
-    final core::Set<core::int> #t143 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      for (final core::int #t144 in <core::int>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int> #t149 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::int #t150 in <core::int>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
                                ^" in "bar" as{TypeError} core::int])
-        #t143.{core::Set::add}(#t144);
-    #t143.{core::Set::add}(null);
-  } =>#t143;
+        #t149.{core::Set::add}(#t150);
+    #t149.{core::Set::add}(null);
+  } =>#t149;
   block {
-    final core::Map<core::String, core::int> #t146 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      for (final core::MapEntry<core::String, core::int> #t147 in <core::String, core::int>{"bar": let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String, core::int> #t152 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::MapEntry<core::String, core::int> #t153 in <core::String, core::int>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int}.{core::Map::entries})
-        #t146.{core::Map::[]=}(#t147.{core::MapEntry::key}, #t147.{core::MapEntry::value});
-    #t146.{core::Map::[]=}("baz", null);
-  } =>#t146;
+        #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value});
+    #t152.{core::Map::[]=}("baz", null);
+  } =>#t152;
   block {
-    final core::List<core::int> #t149 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t149.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::List<core::int> #t155 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t155.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
-                              ^" as{TypeError} core::int);
-  } =>#t149;
+                              ^");
+  } =>#t155;
   block {
-    final core::Set<core::int> #t150 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t150.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t156 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t156.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
-                              ^" as{TypeError} core::int);
-    #t150.{core::Set::add}(null);
-  } =>#t150;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+                              ^");
+    #t156.{core::Set::add}(null);
+  } =>#t156;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
-                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
-  <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+  block {
+    final core::List<core::String> #t157 = <core::String>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
-           ^"];
-  let final core::Set<core::String> #t151 = col::LinkedHashSet::•<core::String>() in let final dynamic #t152 = #t151.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                              ^" in 42 as{TypeError} core::String);
+    else
+      #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>[if (oracle(\"foo\")) 42 else 3.14];
+                                      ^" in 3.14 as{TypeError} core::String);
+  } =>#t157;
+  block {
+    final core::Set<core::String> #t160 = col::LinkedHashSet::•<core::String>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
-           ^") in let final dynamic #t153 = #t151.{core::Set::add}(null) in #t151;
-  <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                              ^" in 42 as{TypeError} core::String);
+    else
+      #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>{if (oracle(\"foo\")) 42 else 3.14, null};
+                                      ^" in 3.14 as{TypeError} core::String);
+    #t160.{core::Set::add}(null);
+  } =>#t160;
+  block {
+    final core::Map<core::String, core::String> #t163 = <core::String, core::String>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
-                   ^", "baz": null};
+                                             ^" in 42 as{TypeError} core::String);
+    else
+      #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
+                                                            ^" in 3.14 as{TypeError} core::String);
+    #t163.{core::Map::[]=}("baz", null);
+  } =>#t163;
   block {
-    final core::List<core::int> #t154 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t154.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::List<core::int> #t166 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t166.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t154.{core::List::add}(42 as{TypeError} core::int);
-  } =>#t154;
+      #t166.{core::List::add}(42);
+  } =>#t166;
   block {
-    final core::Set<core::int> #t155 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t155.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t167 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t167.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t155.{core::Set::add}(42 as{TypeError} core::int);
-    #t155.{core::Set::add}(null);
-  } =>#t155;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t167.{core::Set::add}(42);
+    #t167.{core::Set::add}(null);
+  } =>#t167;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
-                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int> #t156 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t156.{core::List::add}(42 as{TypeError} core::int);
+    final core::List<core::int> #t168 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t168.{core::List::add}(42);
     else
-      #t156.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t168.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
-                                      ^" as{TypeError} core::int);
-  } =>#t156;
+                                      ^");
+  } =>#t168;
   block {
-    final core::Set<core::int> #t157 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t157.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t169.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t157.{core::Set::add}(42 as{TypeError} core::int);
-    #t157.{core::Set::add}(null);
-  } =>#t157;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t169.{core::Set::add}(42);
+    #t169.{core::Set::add}(null);
+  } =>#t169;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
-                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
                                                      ^": null};
+  core::Set<dynamic> set10 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  Set<dynamic> set10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                       ^";
+  core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this.
+  Map<dynamic, dynamic> map10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                                                    ^": null};
+  core::Set<dynamic> set11 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  Set<dynamic> set11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                       ^";
+  core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
+  Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                                                                     ^": null};
+  core::Map<<BottomType>, core::Null> map12 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+  var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                                  ^": null};
+  core::Map<<BottomType>, core::Null> map13 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+  var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                                                   ^": null};
+  core::List<core::int> list20 = block {
+    final core::List<core::int> #t170 = <core::int>[];
+    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  List<int> list20 = [if (42) 42];
+                          ^" in 42 as{TypeError} core::bool)
+      #t170.{core::List::add}(42);
+  } =>#t170;
+  core::Set<core::int> set20 = block {
+    final core::Set<core::int> #t172 = col::LinkedHashSet::•<core::int>();
+    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  Set<int> set20 = {if (42) 42};
+                        ^" in 42 as{TypeError} core::bool)
+      #t172.{core::Set::add}(42);
+  } =>#t172;
+  core::Map<core::int, core::int> map30 = block {
+    final core::Map<core::int, core::int> #t174 = <core::int, core::int>{};
+    if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  Map<int, int> map30 = {if (42) 42: 42};
+                             ^" in 42 as{TypeError} core::bool)
+      #t174.{core::Map::[]=}(42, 42);
+  } =>#t174;
+  core::List<core::String> list40 = block {
+    final core::List<core::String> #t176 = <core::String>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
+                                                    ^" in true as{TypeError} core::String);
+    else
+      #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
+                                                              ^" in 42 as{TypeError} core::String);
+  } =>#t176;
+  core::Set<core::String> set40 = block {
+    final core::Set<core::String> #t179 = col::LinkedHashSet::•<core::String>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
+                                                  ^" in true as{TypeError} core::String);
+    else
+      #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
+                                                            ^" in 42 as{TypeError} core::String);
+  } =>#t179;
+  core::Map<core::String, core::int> map40 = block {
+    final core::Map<core::String, core::int> #t182 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
+                                                            ^" in true as{TypeError} core::String, 42);
+    else
+      #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
+                                                                          ^" in 42 as{TypeError} core::String, 42);
+  } =>#t182;
+  core::Map<core::int, core::String> map41 = block {
+    final core::Map<core::int, core::String> #t185 = <core::int, core::String>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
+                                                                ^" in true as{TypeError} core::String);
+    else
+      #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
+                                                                              ^" in 42 as{TypeError} core::String);
+  } =>#t185;
 }
 static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic {
   core::List<core::int> list10 = block {
-    final core::List<core::int> #t158 = <core::int>[];
+    final core::List<core::int> #t188 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t158.{core::List::add}(42);
-  } =>#t158;
+      #t188.{core::List::add}(42);
+  } =>#t188;
   core::Set<core::int> set10 = block {
-    final core::Set<core::int> #t159 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t189 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t159.{core::Set::add}(42);
-    #t159.{core::Set::add}(null);
-  } =>#t159;
-  core::Map<core::String, core::int> map10 = block {
-    final core::Map<core::String, core::int> #t160 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t160.{core::Map::[]=}("bar", 42);
-    #t160.{core::Map::[]=}("baz", null);
-  } =>#t160;
-  core::List<dynamic> list11 = block {
-    final core::List<dynamic> #t161 = <dynamic>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t161.{core::List::add}(dynVar);
-  } =>#t161;
-  core::Set<dynamic> set11 = block {
-    final core::Set<dynamic> #t162 = col::LinkedHashSet::•<dynamic>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t162.{core::Set::add}(dynVar);
-    #t162.{core::Set::add}(null);
-  } =>#t162;
-  core::Map<core::String, dynamic> map11 = block {
-    final core::Map<core::String, dynamic> #t163 = <core::String, dynamic>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t163.{core::Map::[]=}("bar", dynVar);
-    #t163.{core::Map::[]=}("baz", null);
-  } =>#t163;
-  core::List<core::List<core::int>> list12 = block {
-    final core::List<core::List<core::int>> #t164 = <core::List<core::int>>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t164.{core::List::add}(<core::int>[42]);
-  } =>#t164;
-  core::Set<core::List<core::int>> set12 = block {
-    final core::Set<core::List<core::int>> #t165 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t165.{core::Set::add}(<core::int>[42]);
-    #t165.{core::Set::add}(null);
-  } =>#t165;
-  core::Map<core::String, core::List<core::int>> map12 = block {
-    final core::Map<core::String, core::List<core::int>> #t166 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t166.{core::Map::[]=}("bar", <core::int>[42]);
-    #t166.{core::Map::[]=}("baz", null);
-  } =>#t166;
-  core::List<core::int> list20 = block {
-    final core::List<core::int> #t167 = <core::int>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t168 in <core::int>[42])
-        #t167.{core::List::add}(#t168);
-  } =>#t167;
-  core::Set<core::int> set20 = block {
-    final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t170 in <core::int>[42])
-        #t169.{core::Set::add}(#t170);
-    #t169.{core::Set::add}(null);
-  } =>#t169;
-  core::Map<core::String, core::int> map20 = block {
-    final core::Map<core::String, core::int> #t171 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::int> #t172 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
-        #t171.{core::Map::[]=}(#t172.{core::MapEntry::key}, #t172.{core::MapEntry::value});
-    #t171.{core::Map::[]=}("baz", null);
-  } =>#t171;
-  core::List<dynamic> list21 = block {
-    final core::List<dynamic> #t173 = <dynamic>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t174 in <dynamic>[dynVar])
-        #t173.{core::List::add}(#t174);
-  } =>#t173;
-  core::Set<dynamic> set21 = block {
-    final core::Set<dynamic> #t175 = col::LinkedHashSet::•<dynamic>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t176 in <dynamic>[dynVar])
-        #t175.{core::Set::add}(#t176);
-    #t175.{core::Set::add}(null);
-  } =>#t175;
-  core::Map<core::String, dynamic> map21 = block {
-    final core::Map<core::String, dynamic> #t177 = <core::String, dynamic>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, dynamic> #t178 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
-        #t177.{core::Map::[]=}(#t178.{core::MapEntry::key}, #t178.{core::MapEntry::value});
-    #t177.{core::Map::[]=}("baz", null);
-  } =>#t177;
-  core::List<core::List<core::int>> list22 = block {
-    final core::List<core::List<core::int>> #t179 = <core::List<core::int>>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t180 in <core::List<core::int>>[<core::int>[42]])
-        #t179.{core::List::add}(#t180);
-  } =>#t179;
-  core::Set<core::List<core::int>> set22 = block {
-    final core::Set<core::List<core::int>> #t181 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t182 in <core::List<core::int>>[<core::int>[42]])
-        #t181.{core::Set::add}(#t182);
-    #t181.{core::Set::add}(null);
-  } =>#t181;
-  core::Map<core::String, core::List<core::int>> map22 = block {
-    final core::Map<core::String, core::List<core::int>> #t183 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t184 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
-        #t183.{core::Map::[]=}(#t184.{core::MapEntry::key}, #t184.{core::MapEntry::value});
-    #t183.{core::Map::[]=}("baz", null);
-  } =>#t183;
-  core::List<core::int> list30 = block {
-    final core::List<core::int> #t185 = <core::int>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t186 in <core::int>[42])
-          #t185.{core::List::add}(#t186);
-  } =>#t185;
-  core::Set<core::int> set30 = block {
-    final core::Set<core::int> #t187 = col::LinkedHashSet::•<core::int>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t188 in <core::int>[42])
-          #t187.{core::Set::add}(#t188);
-    #t187.{core::Set::add}(null);
-  } =>#t187;
-  core::Map<core::String, core::int> map30 = block {
-    final core::Map<core::String, core::int> #t189 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::int> #t190 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
-          #t189.{core::Map::[]=}(#t190.{core::MapEntry::key}, #t190.{core::MapEntry::value});
-    #t189.{core::Map::[]=}("baz", null);
+      #t189.{core::Set::add}(42);
+    #t189.{core::Set::add}(null);
   } =>#t189;
-  core::List<dynamic> list31 = block {
+  core::Map<core::String, core::int> map10 = block {
+    final core::Map<core::String, core::int> #t190 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t190.{core::Map::[]=}("bar", 42);
+    #t190.{core::Map::[]=}("baz", null);
+  } =>#t190;
+  core::List<dynamic> list11 = block {
     final core::List<dynamic> #t191 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t192 in <dynamic>[dynVar])
-          #t191.{core::List::add}(#t192);
+      #t191.{core::List::add}(dynVar);
   } =>#t191;
-  core::Set<dynamic> set31 = block {
-    final core::Set<dynamic> #t193 = col::LinkedHashSet::•<dynamic>();
+  core::Set<dynamic> set11 = block {
+    final core::Set<dynamic> #t192 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t194 in <dynamic>[dynVar])
-          #t193.{core::Set::add}(#t194);
-    #t193.{core::Set::add}(null);
+      #t192.{core::Set::add}(dynVar);
+    #t192.{core::Set::add}(null);
+  } =>#t192;
+  core::Map<core::String, dynamic> map11 = block {
+    final core::Map<core::String, dynamic> #t193 = <core::String, dynamic>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t193.{core::Map::[]=}("bar", dynVar);
+    #t193.{core::Map::[]=}("baz", null);
   } =>#t193;
-  core::Map<core::String, dynamic> map31 = block {
-    final core::Map<core::String, dynamic> #t195 = <core::String, dynamic>{};
+  core::List<core::List<core::int>> list12 = block {
+    final core::List<core::List<core::int>> #t194 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, dynamic> #t196 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t195.{core::Map::[]=}(#t196.{core::MapEntry::key}, #t196.{core::MapEntry::value});
-    #t195.{core::Map::[]=}("baz", null);
+      #t194.{core::List::add}(<core::int>[42]);
+  } =>#t194;
+  core::Set<core::List<core::int>> set12 = block {
+    final core::Set<core::List<core::int>> #t195 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t195.{core::Set::add}(<core::int>[42]);
+    #t195.{core::Set::add}(null);
   } =>#t195;
-  core::List<core::List<core::int>> list33 = block {
-    final core::List<core::List<core::int>> #t197 = <core::List<core::int>>[];
+  core::Map<core::String, core::List<core::int>> map12 = block {
+    final core::Map<core::String, core::List<core::int>> #t196 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t198 in <core::List<core::int>>[<core::int>[42]])
-          #t197.{core::List::add}(#t198);
+      #t196.{core::Map::[]=}("bar", <core::int>[42]);
+    #t196.{core::Map::[]=}("baz", null);
+  } =>#t196;
+  core::List<core::int> list20 = block {
+    final core::List<core::int> #t197 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::int #t198 in <core::int>[42])
+        #t197.{core::List::add}(#t198);
   } =>#t197;
-  core::Set<core::List<core::int>> set33 = block {
-    final core::Set<core::List<core::int>> #t199 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::int> set20 = block {
+    final core::Set<core::int> #t199 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t200 in <core::List<core::int>>[<core::int>[42]])
-          #t199.{core::Set::add}(#t200);
+      for (final core::int #t200 in <core::int>[42])
+        #t199.{core::Set::add}(#t200);
     #t199.{core::Set::add}(null);
   } =>#t199;
-  core::Map<core::String, core::List<core::int>> map33 = block {
-    final core::Map<core::String, core::List<core::int>> #t201 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, core::int> map20 = block {
+    final core::Map<core::String, core::int> #t201 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t202 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
-          #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
+      for (final core::MapEntry<core::String, core::int> #t202 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
+        #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
     #t201.{core::Map::[]=}("baz", null);
   } =>#t201;
-  core::List<core::List<core::int>> list40 = block {
-    final core::List<core::List<core::int>> #t203 = <core::List<core::int>>[];
+  core::List<dynamic> list21 = block {
+    final core::List<dynamic> #t203 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t204 in <core::List<core::int>>[<core::int>[]])
+      for (final dynamic #t204 in <dynamic>[dynVar])
         #t203.{core::List::add}(#t204);
   } =>#t203;
-  core::Set<core::List<core::int>> set40 = block {
-    final core::Set<core::List<core::int>> #t205 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<dynamic> set21 = block {
+    final core::Set<dynamic> #t205 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t206 in <core::List<core::int>>[<core::int>[]])
+      for (final dynamic #t206 in <dynamic>[dynVar])
         #t205.{core::Set::add}(#t206);
     #t205.{core::Set::add}(null);
   } =>#t205;
-  core::Map<core::String, core::List<core::int>> map40 = block {
-    final core::Map<core::String, core::List<core::int>> #t207 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, dynamic> map21 = block {
+    final core::Map<core::String, dynamic> #t207 = <core::String, dynamic>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t208 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+      for (final core::MapEntry<core::String, dynamic> #t208 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
         #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value});
     #t207.{core::Map::[]=}("baz", null);
   } =>#t207;
-  core::List<core::List<core::int>> list41 = block {
+  core::List<core::List<core::int>> list22 = block {
     final core::List<core::List<core::int>> #t209 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t210 in let final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t212 = #t211.{core::Set::add}(<core::int>[]) in #t211)
+      for (final core::List<core::int> #t210 in <core::List<core::int>>[<core::int>[42]])
         #t209.{core::List::add}(#t210);
   } =>#t209;
-  core::Set<core::List<core::int>> set41 = block {
-    final core::Set<core::List<core::int>> #t213 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::List<core::int>> set22 = block {
+    final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t214 in let final core::Set<core::List<core::int>> #t215 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t216 = #t215.{core::Set::add}(<core::int>[]) in #t215)
-        #t213.{core::Set::add}(#t214);
-    #t213.{core::Set::add}(null);
+      for (final core::List<core::int> #t212 in <core::List<core::int>>[<core::int>[42]])
+        #t211.{core::Set::add}(#t212);
+    #t211.{core::Set::add}(null);
+  } =>#t211;
+  core::Map<core::String, core::List<core::int>> map22 = block {
+    final core::Map<core::String, core::List<core::int>> #t213 = <core::String, core::List<core::int>>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String, core::List<core::int>> #t214 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
+        #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value});
+    #t213.{core::Map::[]=}("baz", null);
   } =>#t213;
-  core::List<core::List<core::int>> list42 = block {
-    final core::List<core::List<core::int>> #t217 = <core::List<core::int>>[];
+  core::List<core::int> list30 = block {
+    final core::List<core::int> #t215 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t218 in <core::List<core::int>>[<core::int>[]])
-          #t217.{core::List::add}(#t218);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t216 in <core::int>[42])
+          #t215.{core::List::add}(#t216);
+  } =>#t215;
+  core::Set<core::int> set30 = block {
+    final core::Set<core::int> #t217 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t218 in <core::int>[42])
+          #t217.{core::Set::add}(#t218);
+    #t217.{core::Set::add}(null);
   } =>#t217;
-  core::Set<core::List<core::int>> set42 = block {
-    final core::Set<core::List<core::int>> #t219 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Map<core::String, core::int> map30 = block {
+    final core::Map<core::String, core::int> #t219 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t220 in <core::List<core::int>>[<core::int>[]])
-          #t219.{core::Set::add}(#t220);
-    #t219.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::int> #t220 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
+          #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
+    #t219.{core::Map::[]=}("baz", null);
   } =>#t219;
-  core::Map<core::String, core::List<core::int>> map42 = block {
-    final core::Map<core::String, core::List<core::int>> #t221 = <core::String, core::List<core::int>>{};
+  core::List<dynamic> list31 = block {
+    final core::List<dynamic> #t221 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t222 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-          #t221.{core::Map::[]=}(#t222.{core::MapEntry::key}, #t222.{core::MapEntry::value});
-    #t221.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t222 in <dynamic>[dynVar])
+          #t221.{core::List::add}(#t222);
   } =>#t221;
-  core::List<core::int> list50 = block {
-    final core::List<core::int> #t223 = <core::int>[];
+  core::Set<dynamic> set31 = block {
+    final core::Set<dynamic> #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t224 in <core::int>[])
-        #t223.{core::List::add}(#t224);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t224 in <dynamic>[dynVar])
+          #t223.{core::Set::add}(#t224);
+    #t223.{core::Set::add}(null);
   } =>#t223;
-  core::Set<core::int> set50 = block {
-    final core::Set<core::int> #t225 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, dynamic> map31 = block {
+    final core::Map<core::String, dynamic> #t225 = <core::String, dynamic>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t226 in <core::int>[])
-        #t225.{core::Set::add}(#t226);
-    #t225.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, dynamic> #t226 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
+    #t225.{core::Map::[]=}("baz", null);
   } =>#t225;
-  core::Map<core::String, core::int> map50 = block {
-    final core::Map<core::String, core::int> #t227 = <core::String, core::int>{};
+  core::List<core::List<core::int>> list33 = block {
+    final core::List<core::List<core::int>> #t227 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::int> #t228 in <core::String, core::int>{}.{core::Map::entries})
-        #t227.{core::Map::[]=}(#t228.{core::MapEntry::key}, #t228.{core::MapEntry::value});
-    #t227.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t228 in <core::List<core::int>>[<core::int>[42]])
+          #t227.{core::List::add}(#t228);
   } =>#t227;
-  core::List<core::int> list51 = block {
-    final core::List<core::int> #t229 = <core::int>[];
+  core::Set<core::List<core::int>> set33 = block {
+    final core::Set<core::List<core::int>> #t229 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t230 in let final core::Set<core::int> #t231 = col::LinkedHashSet::•<core::int>() in #t231)
-        #t229.{core::List::add}(#t230);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t230 in <core::List<core::int>>[<core::int>[42]])
+          #t229.{core::Set::add}(#t230);
+    #t229.{core::Set::add}(null);
   } =>#t229;
-  core::Set<core::int> set51 = block {
-    final core::Set<core::int> #t232 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, core::List<core::int>> map33 = block {
+    final core::Map<core::String, core::List<core::int>> #t231 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t233 in let final core::Set<core::int> #t234 = col::LinkedHashSet::•<core::int>() in #t234)
-        #t232.{core::Set::add}(#t233);
-    #t232.{core::Set::add}(null);
-  } =>#t232;
-  core::List<core::int> list52 = block {
-    final core::List<core::int> #t235 = <core::int>[];
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t232 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
+          #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value});
+    #t231.{core::Map::[]=}("baz", null);
+  } =>#t231;
+  core::List<core::List<core::int>> list40 = block {
+    final core::List<core::List<core::int>> #t233 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t236 in <core::int>[])
-          #t235.{core::List::add}(#t236);
+      for (final core::List<core::int> #t234 in <core::List<core::int>>[<core::int>[]])
+        #t233.{core::List::add}(#t234);
+  } =>#t233;
+  core::Set<core::List<core::int>> set40 = block {
+    final core::Set<core::List<core::int>> #t235 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::List<core::int> #t236 in <core::List<core::int>>[<core::int>[]])
+        #t235.{core::Set::add}(#t236);
+    #t235.{core::Set::add}(null);
   } =>#t235;
-  core::Set<core::int> set52 = block {
-    final core::Set<core::int> #t237 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, core::List<core::int>> map40 = block {
+    final core::Map<core::String, core::List<core::int>> #t237 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t238 in <core::int>[])
-          #t237.{core::Set::add}(#t238);
-    #t237.{core::Set::add}(null);
+      for (final core::MapEntry<core::String, core::List<core::int>> #t238 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+        #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value});
+    #t237.{core::Map::[]=}("baz", null);
   } =>#t237;
-  core::List<core::List<core::int>> list60 = block {
+  core::List<core::List<core::int>> list41 = block {
     final core::List<core::List<core::int>> #t239 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t240 in <core::List<core::int>>[<core::int>[]])
+      for (final core::List<core::int> #t240 in let final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t242 = #t241.{core::Set::add}(<core::int>[]) in #t241)
         #t239.{core::List::add}(#t240);
   } =>#t239;
-  core::Set<core::List<core::int>> set60 = block {
-    final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::List<core::int>> set41 = block {
+    final core::Set<core::List<core::int>> #t243 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t242 in <core::List<core::int>>[<core::int>[]])
-        #t241.{core::Set::add}(#t242);
-    #t241.{core::Set::add}(null);
-  } =>#t241;
-  core::Map<core::String, core::List<core::int>> map60 = block {
-    final core::Map<core::String, core::List<core::int>> #t243 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t244 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-        #t243.{core::Map::[]=}(#t244.{core::MapEntry::key}, #t244.{core::MapEntry::value});
-    #t243.{core::Map::[]=}("baz", null);
+      for (final core::List<core::int> #t244 in let final core::Set<core::List<core::int>> #t245 = col::LinkedHashSet::•<core::List<core::int>>() in let final dynamic #t246 = #t245.{core::Set::add}(<core::int>[]) in #t245)
+        #t243.{core::Set::add}(#t244);
+    #t243.{core::Set::add}(null);
   } =>#t243;
-  core::List<core::List<core::int>> list61 = block {
-    final core::List<core::List<core::int>> #t245 = <core::List<core::int>>[];
+  core::List<core::List<core::int>> list42 = block {
+    final core::List<core::List<core::int>> #t247 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t246 in <core::List<core::int>>[<core::int>[]])
-          #t245.{core::List::add}(#t246);
-  } =>#t245;
-  core::Set<core::List<core::int>> set61 = block {
-    final core::Set<core::List<core::int>> #t247 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t248 in <core::List<core::int>>[<core::int>[]])
-          #t247.{core::Set::add}(#t248);
-    #t247.{core::Set::add}(null);
+          #t247.{core::List::add}(#t248);
   } =>#t247;
-  core::Map<core::String, core::List<core::int>> map61 = block {
-    final core::Map<core::String, core::List<core::int>> #t249 = <core::String, core::List<core::int>>{};
+  core::Set<core::List<core::int>> set42 = block {
+    final core::Set<core::List<core::int>> #t249 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t250 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-          #t249.{core::Map::[]=}(#t250.{core::MapEntry::key}, #t250.{core::MapEntry::value});
-    #t249.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t250 in <core::List<core::int>>[<core::int>[]])
+          #t249.{core::Set::add}(#t250);
+    #t249.{core::Set::add}(null);
   } =>#t249;
-  core::List<core::List<core::int>> list70 = block {
-    final core::List<core::List<core::int>> #t251 = <core::List<core::int>>[];
+  core::Map<core::String, core::List<core::int>> map42 = block {
+    final core::Map<core::String, core::List<core::int>> #t251 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t251.{core::List::add}(<core::int>[]);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t252 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+          #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value});
+    #t251.{core::Map::[]=}("baz", null);
   } =>#t251;
-  core::Set<core::List<core::int>> set70 = block {
-    final core::Set<core::List<core::int>> #t252 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::List<core::int> list50 = block {
+    final core::List<core::int> #t253 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t252.{core::Set::add}(<core::int>[]);
-    #t252.{core::Set::add}(null);
-  } =>#t252;
-  core::Map<core::String, core::List<core::int>> map70 = block {
-    final core::Map<core::String, core::List<core::int>> #t253 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t253.{core::Map::[]=}("bar", <core::int>[]);
-    #t253.{core::Map::[]=}("baz", null);
+      for (final core::int #t254 in <core::int>[])
+        #t253.{core::List::add}(#t254);
   } =>#t253;
-  core::List<core::List<core::int>> list71 = block {
-    final core::List<core::List<core::int>> #t254 = <core::List<core::int>>[];
+  core::Set<core::int> set50 = block {
+    final core::Set<core::int> #t255 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t254.{core::List::add}(<core::int>[]);
-  } =>#t254;
-  core::Set<core::List<core::int>> set71 = block {
-    final core::Set<core::List<core::int>> #t255 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t255.{core::Set::add}(<core::int>[]);
+      for (final core::int #t256 in <core::int>[])
+        #t255.{core::Set::add}(#t256);
     #t255.{core::Set::add}(null);
   } =>#t255;
-  core::Map<core::String, core::List<core::int>> map71 = block {
-    final core::Map<core::String, core::List<core::int>> #t256 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, core::int> map50 = block {
+    final core::Map<core::String, core::int> #t257 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t256.{core::Map::[]=}("bar", <core::int>[]);
-    #t256.{core::Map::[]=}("baz", null);
-  } =>#t256;
-  core::List<core::num> list80 = block {
-    final core::List<core::num> #t257 = <core::num>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t257.{core::List::add}(42);
-      else
-        #t257.{core::List::add}(3.14);
+      for (final core::MapEntry<core::String, core::int> #t258 in <core::String, core::int>{}.{core::Map::entries})
+        #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value});
+    #t257.{core::Map::[]=}("baz", null);
   } =>#t257;
-  core::Set<core::num> set80 = block {
-    final core::Set<core::num> #t258 = col::LinkedHashSet::•<core::num>();
+  core::List<core::int> list51 = block {
+    final core::List<core::int> #t259 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t258.{core::Set::add}(42);
-      else
-        #t258.{core::Set::add}(3.14);
-    #t258.{core::Set::add}(null);
-  } =>#t258;
-  core::Map<core::String, core::num> map80 = block {
-    final core::Map<core::String, core::num> #t259 = <core::String, core::num>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t259.{core::Map::[]=}("bar", 42);
-      else
-        #t259.{core::Map::[]=}("bar", 3.14);
-    #t259.{core::Map::[]=}("baz", null);
+      for (final core::int #t260 in let final core::Set<core::int> #t261 = col::LinkedHashSet::•<core::int>() in #t261)
+        #t259.{core::List::add}(#t260);
   } =>#t259;
-  core::List<core::num> list81 = block {
-    final core::List<core::num> #t260 = <core::num>[];
+  core::Set<core::int> set51 = block {
+    final core::Set<core::int> #t262 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t261 in listInt)
-          #t260.{core::List::add}(#t261);
-      else
-        for (final core::num #t262 in listDouble)
-          #t260.{core::List::add}(#t262);
-  } =>#t260;
-  core::Set<core::num> set81 = block {
-    final core::Set<core::num> #t263 = col::LinkedHashSet::•<core::num>();
+      for (final core::int #t263 in let final core::Set<core::int> #t264 = col::LinkedHashSet::•<core::int>() in #t264)
+        #t262.{core::Set::add}(#t263);
+    #t262.{core::Set::add}(null);
+  } =>#t262;
+  core::List<core::int> list52 = block {
+    final core::List<core::int> #t265 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t264 in listInt)
-          #t263.{core::Set::add}(#t264);
-      else
-        for (final core::num #t265 in listDouble)
-          #t263.{core::Set::add}(#t265);
-    #t263.{core::Set::add}(null);
-  } =>#t263;
-  core::Map<core::String, core::num> map81 = block {
-    final core::Map<core::String, core::num> #t266 = <core::String, core::num>{};
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t266 in <core::int>[])
+          #t265.{core::List::add}(#t266);
+  } =>#t265;
+  core::Set<core::int> set52 = block {
+    final core::Set<core::int> #t267 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::num> #t267 in mapStringInt.{core::Map::entries})
-          #t266.{core::Map::[]=}(#t267.{core::MapEntry::key}, #t267.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<core::String, core::num> #t268 in mapStringDouble.{core::Map::entries})
-          #t266.{core::Map::[]=}(#t268.{core::MapEntry::key}, #t268.{core::MapEntry::value});
-    #t266.{core::Map::[]=}("baz", null);
-  } =>#t266;
-  core::List<dynamic> list82 = block {
-    final core::List<dynamic> #t269 = <dynamic>[];
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t268 in <core::int>[])
+          #t267.{core::Set::add}(#t268);
+    #t267.{core::Set::add}(null);
+  } =>#t267;
+  core::List<core::List<core::int>> list60 = block {
+    final core::List<core::List<core::int>> #t269 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t270 in listInt)
-          #t269.{core::List::add}(#t270);
-      else
-        for (final dynamic #t271 in dynVar as{TypeError} core::Iterable<dynamic>)
-          #t269.{core::List::add}(#t271);
+      for (final core::List<core::int> #t270 in <core::List<core::int>>[<core::int>[]])
+        #t269.{core::List::add}(#t270);
   } =>#t269;
-  core::Set<dynamic> set82 = block {
-    final core::Set<dynamic> #t272 = col::LinkedHashSet::•<dynamic>();
+  core::Set<core::List<core::int>> set60 = block {
+    final core::Set<core::List<core::int>> #t271 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t273 in listInt)
-          #t272.{core::Set::add}(#t273);
-      else
-        for (final dynamic #t274 in dynVar as{TypeError} core::Iterable<dynamic>)
-          #t272.{core::Set::add}(#t274);
-    #t272.{core::Set::add}(null);
-  } =>#t272;
-  core::Map<dynamic, dynamic> map82 = block {
-    final core::Map<dynamic, dynamic> #t275 = <dynamic, dynamic>{};
+      for (final core::List<core::int> #t272 in <core::List<core::int>>[<core::int>[]])
+        #t271.{core::Set::add}(#t272);
+    #t271.{core::Set::add}(null);
+  } =>#t271;
+  core::Map<core::String, core::List<core::int>> map60 = block {
+    final core::Map<core::String, core::List<core::int>> #t273 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<dynamic, dynamic> #t276 in mapStringInt.{core::Map::entries})
-          #t275.{core::Map::[]=}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<dynamic, dynamic> #t277 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
-          #t275.{core::Map::[]=}(#t277.{core::MapEntry::key}, #t277.{core::MapEntry::value});
-    #t275.{core::Map::[]=}("baz", null);
+      for (final core::MapEntry<core::String, core::List<core::int>> #t274 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+        #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
+    #t273.{core::Map::[]=}("baz", null);
+  } =>#t273;
+  core::List<core::List<core::int>> list61 = block {
+    final core::List<core::List<core::int>> #t275 = <core::List<core::int>>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t276 in <core::List<core::int>>[<core::int>[]])
+          #t275.{core::List::add}(#t276);
   } =>#t275;
-  core::List<core::num> list83 = block {
-    final core::List<core::num> #t278 = <core::num>[];
+  core::Set<core::List<core::int>> set61 = block {
+    final core::Set<core::List<core::int>> #t277 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t278.{core::List::add}(42);
-      else
-        for (final core::num #t279 in listDouble)
-          #t278.{core::List::add}(#t279);
-  } =>#t278;
-  core::Set<core::num> set83 = block {
-    final core::Set<core::num> #t280 = col::LinkedHashSet::•<core::num>();
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t278 in <core::List<core::int>>[<core::int>[]])
+          #t277.{core::Set::add}(#t278);
+    #t277.{core::Set::add}(null);
+  } =>#t277;
+  core::Map<core::String, core::List<core::int>> map61 = block {
+    final core::Map<core::String, core::List<core::int>> #t279 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t281 in listInt)
-          #t280.{core::Set::add}(#t281);
-      else
-        #t280.{core::Set::add}(3.14);
-    #t280.{core::Set::add}(null);
-  } =>#t280;
-  core::Map<core::String, core::num> map83 = block {
-    final core::Map<core::String, core::num> #t282 = <core::String, core::num>{};
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t280 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+          #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value});
+    #t279.{core::Map::[]=}("baz", null);
+  } =>#t279;
+  core::List<core::List<core::int>> list70 = block {
+    final core::List<core::List<core::int>> #t281 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::num> #t283 in mapStringInt.{core::Map::entries})
-          #t282.{core::Map::[]=}(#t283.{core::MapEntry::key}, #t283.{core::MapEntry::value});
-      else
-        #t282.{core::Map::[]=}("bar", 3.14);
-    #t282.{core::Map::[]=}("baz", null);
+      #t281.{core::List::add}(<core::int>[]);
+  } =>#t281;
+  core::Set<core::List<core::int>> set70 = block {
+    final core::Set<core::List<core::int>> #t282 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t282.{core::Set::add}(<core::int>[]);
+    #t282.{core::Set::add}(null);
   } =>#t282;
-  core::List<core::int> list90 = block {
-    final core::List<core::int> #t284 = <core::int>[];
+  core::Map<core::String, core::List<core::int>> map70 = block {
+    final core::Map<core::String, core::List<core::int>> #t283 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t284.{core::List::add}(dynVar as{TypeError} core::int);
+      #t283.{core::Map::[]=}("bar", <core::int>[]);
+    #t283.{core::Map::[]=}("baz", null);
+  } =>#t283;
+  core::List<core::List<core::int>> list71 = block {
+    final core::List<core::List<core::int>> #t284 = <core::List<core::int>>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t284.{core::List::add}(<core::int>[]);
   } =>#t284;
-  core::Set<core::int> set90 = block {
-    final core::Set<core::int> #t285 = col::LinkedHashSet::•<core::int>();
+  core::Set<core::List<core::int>> set71 = block {
+    final core::Set<core::List<core::int>> #t285 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t285.{core::Set::add}(dynVar as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t285.{core::Set::add}(<core::int>[]);
     #t285.{core::Set::add}(null);
   } =>#t285;
-  core::Map<core::String, core::int> map90 = block {
-    final core::Map<core::String, core::int> #t286 = <core::String, core::int>{};
+  core::Map<core::String, core::List<core::int>> map71 = block {
+    final core::Map<core::String, core::List<core::int>> #t286 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t286.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t286.{core::Map::[]=}("bar", <core::int>[]);
     #t286.{core::Map::[]=}("baz", null);
   } =>#t286;
-  core::List<core::int> list91 = block {
-    final core::List<core::int> #t287 = <core::int>[];
+  core::List<core::num> list80 = block {
+    final core::List<core::num> #t287 = <core::num>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t288 in dynVar as{TypeError} core::Iterable<dynamic>) {
-        final core::int #t289 = #t288 as{TypeError} core::int;
-        #t287.{core::List::add}(#t289);
-      }
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t287.{core::List::add}(42);
+      else
+        #t287.{core::List::add}(3.14);
   } =>#t287;
-  core::Set<core::int> set91 = block {
-    final core::Set<core::int> #t290 = col::LinkedHashSet::•<core::int>();
+  core::Set<core::num> set80 = block {
+    final core::Set<core::num> #t288 = col::LinkedHashSet::•<core::num>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t291 in dynVar as{TypeError} core::Iterable<dynamic>) {
-        final core::int #t292 = #t291 as{TypeError} core::int;
-        #t290.{core::Set::add}(#t292);
-      }
-    #t290.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t288.{core::Set::add}(42);
+      else
+        #t288.{core::Set::add}(3.14);
+    #t288.{core::Set::add}(null);
+  } =>#t288;
+  core::Map<core::String, core::num> map80 = block {
+    final core::Map<core::String, core::num> #t289 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t289.{core::Map::[]=}("bar", 42);
+      else
+        #t289.{core::Map::[]=}("bar", 3.14);
+    #t289.{core::Map::[]=}("baz", null);
+  } =>#t289;
+  core::List<core::num> list81 = block {
+    final core::List<core::num> #t290 = <core::num>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t291 in listInt)
+          #t290.{core::List::add}(#t291);
+      else
+        for (final core::num #t292 in listDouble)
+          #t290.{core::List::add}(#t292);
   } =>#t290;
-  core::Map<core::String, core::int> map91 = block {
-    final core::Map<core::String, core::int> #t293 = <core::String, core::int>{};
+  core::Set<core::num> set81 = block {
+    final core::Set<core::num> #t293 = col::LinkedHashSet::•<core::num>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, dynamic> #t294 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
-        final core::String #t295 = #t294.{core::MapEntry::key} as{TypeError} core::String;
-        final core::int #t296 = #t294.{core::MapEntry::value} as{TypeError} core::int;
-        #t293.{core::Map::[]=}(#t295, #t296);
-      }
-    #t293.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t294 in listInt)
+          #t293.{core::Set::add}(#t294);
+      else
+        for (final core::num #t295 in listDouble)
+          #t293.{core::Set::add}(#t295);
+    #t293.{core::Set::add}(null);
   } =>#t293;
-  core::List<core::int> list100 = block {
-    final core::List<core::int> #t297 = <core::int>[];
-    for (final dynamic #t298 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t297.{core::List::add}(42);
-  } =>#t297;
-  core::Set<core::int> set100 = block {
-    final core::Set<core::int> #t299 = col::LinkedHashSet::•<core::int>();
-    for (final dynamic #t300 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t299.{core::Set::add}(42);
+  core::Map<core::String, core::num> map81 = block {
+    final core::Map<core::String, core::num> #t296 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::num> #t297 in mapStringInt.{core::Map::entries})
+          #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<core::String, core::num> #t298 in mapStringDouble.{core::Map::entries})
+          #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value});
+    #t296.{core::Map::[]=}("baz", null);
+  } =>#t296;
+  core::List<dynamic> list82 = block {
+    final core::List<dynamic> #t299 = <dynamic>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t300 in listInt)
+          #t299.{core::List::add}(#t300);
+      else
+        for (final dynamic #t301 in dynVar as{TypeError} core::Iterable<dynamic>)
+          #t299.{core::List::add}(#t301);
   } =>#t299;
-  core::Map<core::String, core::int> map100 = block {
-    final core::Map<core::String, core::int> #t301 = <core::String, core::int>{};
-    for (final dynamic #t302 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t301.{core::Map::[]=}("bar", 42);
-  } =>#t301;
-  core::List<core::int> list110 = block {
-    final core::List<core::int> #t303 = <core::int>[];
-    for (core::int i in <core::int>[1, 2, 3])
-      #t303.{core::List::add}(i);
-  } =>#t303;
-  core::Set<core::int> set110 = block {
-    final core::Set<core::int> #t304 = col::LinkedHashSet::•<core::int>();
-    for (core::int i in <core::int>[1, 2, 3])
-      #t304.{core::Set::add}(i);
-    #t304.{core::Set::add}(null);
-  } =>#t304;
-  core::Map<core::String, core::int> map110 = block {
-    final core::Map<core::String, core::int> #t305 = <core::String, core::int>{};
-    for (core::int i in <core::int>[1, 2, 3])
-      #t305.{core::Map::[]=}("bar", i);
+  core::Set<dynamic> set82 = block {
+    final core::Set<dynamic> #t302 = col::LinkedHashSet::•<dynamic>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t303 in listInt)
+          #t302.{core::Set::add}(#t303);
+      else
+        for (final dynamic #t304 in dynVar as{TypeError} core::Iterable<dynamic>)
+          #t302.{core::Set::add}(#t304);
+    #t302.{core::Set::add}(null);
+  } =>#t302;
+  core::Map<dynamic, dynamic> map82 = block {
+    final core::Map<dynamic, dynamic> #t305 = <dynamic, dynamic>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<dynamic, dynamic> #t306 in mapStringInt.{core::Map::entries})
+          #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<dynamic, dynamic> #t307 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
+          #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value});
     #t305.{core::Map::[]=}("baz", null);
   } =>#t305;
-  core::List<core::int> list120 = block {
-    final core::List<core::int> #t306 = <core::int>[];
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t306.{core::List::add}(i as{TypeError} core::int);
-  } =>#t306;
-  core::Set<core::int> set120 = block {
-    final core::Set<core::int> #t307 = col::LinkedHashSet::•<core::int>();
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t307.{core::Set::add}(i as{TypeError} core::int);
-    #t307.{core::Set::add}(null);
-  } =>#t307;
-  core::Map<core::String, core::int> map120 = block {
-    final core::Map<core::String, core::int> #t308 = <core::String, core::int>{};
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t308.{core::Map::[]=}("bar", i as{TypeError} core::int);
-    #t308.{core::Map::[]=}("baz", null);
+  core::List<core::num> list83 = block {
+    final core::List<core::num> #t308 = <core::num>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t308.{core::List::add}(42);
+      else
+        for (final core::num #t309 in listDouble)
+          #t308.{core::List::add}(#t309);
   } =>#t308;
+  core::Set<core::num> set83 = block {
+    final core::Set<core::num> #t310 = col::LinkedHashSet::•<core::num>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t311 in listInt)
+          #t310.{core::Set::add}(#t311);
+      else
+        #t310.{core::Set::add}(3.14);
+    #t310.{core::Set::add}(null);
+  } =>#t310;
+  core::Map<core::String, core::num> map83 = block {
+    final core::Map<core::String, core::num> #t312 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::num> #t313 in mapStringInt.{core::Map::entries})
+          #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value});
+      else
+        #t312.{core::Map::[]=}("bar", 3.14);
+    #t312.{core::Map::[]=}("baz", null);
+  } =>#t312;
+  core::List<core::int> list90 = block {
+    final core::List<core::int> #t314 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t314.{core::List::add}(dynVar as{TypeError} core::int);
+  } =>#t314;
+  core::Set<core::int> set90 = block {
+    final core::Set<core::int> #t315 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t315.{core::Set::add}(dynVar as{TypeError} core::int);
+    #t315.{core::Set::add}(null);
+  } =>#t315;
+  core::Map<core::String, core::int> map90 = block {
+    final core::Map<core::String, core::int> #t316 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t316.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
+    #t316.{core::Map::[]=}("baz", null);
+  } =>#t316;
+  core::List<core::int> list91 = block {
+    final core::List<core::int> #t317 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final dynamic #t318 in dynVar as{TypeError} core::Iterable<dynamic>) {
+        final core::int #t319 = #t318 as{TypeError} core::int;
+        #t317.{core::List::add}(#t319);
+      }
+  } =>#t317;
+  core::Set<core::int> set91 = block {
+    final core::Set<core::int> #t320 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final dynamic #t321 in dynVar as{TypeError} core::Iterable<dynamic>) {
+        final core::int #t322 = #t321 as{TypeError} core::int;
+        #t320.{core::Set::add}(#t322);
+      }
+    #t320.{core::Set::add}(null);
+  } =>#t320;
+  core::Map<core::String, core::int> map91 = block {
+    final core::Map<core::String, core::int> #t323 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::MapEntry<dynamic, dynamic> #t324 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
+        final core::String #t325 = #t324.{core::MapEntry::key} as{TypeError} core::String;
+        final core::int #t326 = #t324.{core::MapEntry::value} as{TypeError} core::int;
+        #t323.{core::Map::[]=}(#t325, #t326);
+      }
+    #t323.{core::Map::[]=}("baz", null);
+  } =>#t323;
+  core::List<core::int> list100 = block {
+    final core::List<core::int> #t327 = <core::int>[];
+    for (final core::int #t328 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t327.{core::List::add}(42);
+  } =>#t327;
+  core::Set<core::int> set100 = block {
+    final core::Set<core::int> #t329 = col::LinkedHashSet::•<core::int>();
+    for (final core::int #t330 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t329.{core::Set::add}(42);
+  } =>#t329;
+  core::Map<core::String, core::int> map100 = block {
+    final core::Map<core::String, core::int> #t331 = <core::String, core::int>{};
+    for (final core::int #t332 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t331.{core::Map::[]=}("bar", 42);
+  } =>#t331;
+  core::List<core::int> list110 = block {
+    final core::List<core::int> #t333 = <core::int>[];
+    for (core::int i in <core::int>[1, 2, 3])
+      #t333.{core::List::add}(i);
+  } =>#t333;
+  core::Set<core::int> set110 = block {
+    final core::Set<core::int> #t334 = col::LinkedHashSet::•<core::int>();
+    for (core::int i in <core::int>[1, 2, 3])
+      #t334.{core::Set::add}(i);
+    #t334.{core::Set::add}(null);
+  } =>#t334;
+  core::Map<core::String, core::int> map110 = block {
+    final core::Map<core::String, core::int> #t335 = <core::String, core::int>{};
+    for (core::int i in <core::int>[1, 2, 3])
+      #t335.{core::Map::[]=}("bar", i);
+    #t335.{core::Map::[]=}("baz", null);
+  } =>#t335;
+  core::List<core::int> list120 = block {
+    final core::List<core::int> #t336 = <core::int>[];
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t336.{core::List::add}(i as{TypeError} core::int);
+  } =>#t336;
+  core::Set<core::int> set120 = block {
+    final core::Set<core::int> #t337 = col::LinkedHashSet::•<core::int>();
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t337.{core::Set::add}(i as{TypeError} core::int);
+    #t337.{core::Set::add}(null);
+  } =>#t337;
+  core::Map<core::String, core::int> map120 = block {
+    final core::Map<core::String, core::int> #t338 = <core::String, core::int>{};
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t338.{core::Map::[]=}("bar", i as{TypeError} core::int);
+    #t338.{core::Map::[]=}("baz", null);
+  } =>#t338;
+  core::List<core::int> list130 = block {
+    final core::List<core::int> #t339 = <core::int>[];
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t339.{core::List::add}(i);
+  } =>#t339;
+  core::Set<core::int> set130 = block {
+    final core::Set<core::int> #t340 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t340.{core::Set::add}(i);
+  } =>#t340;
+  core::Map<core::int, core::int> map130 = block {
+    final core::Map<core::int, core::int> #t341 = <core::int, core::int>{};
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t341.{core::Map::[]=}(i, i);
+  } =>#t341;
 }
 static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic async {
-  <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+  block {
+    final core::List<core::int> #t342 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
-                                            ^"];
-  let final core::Set<core::int> #t309 = col::LinkedHashSet::•<core::int>() in let final dynamic #t310 = #t309.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                            ^" in "bar" as{TypeError} core::int);
+  } =>#t342;
+  block {
+    final core::Set<core::int> #t344 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
-                                            ^") in let final dynamic #t311 = #t309.{core::Set::add}(null) in #t309;
-  <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-             ^": invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-             ^", let final<BottomType> #t312 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                               ^" in "baz" as{TypeError} core::int: null};
+                                            ^" in "bar" as{TypeError} core::int);
+    #t344.{core::Set::add}(null);
+  } =>#t344;
   block {
-    final core::List<core::int> #t313 = <core::int>[];
+    final core::Map<core::int, core::int> #t346 = <core::int, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t314 in <core::int>[let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                 ^" in "bar" as{TypeError} core::int, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                        ^" in "bar" as{TypeError} core::int);
+    #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                               ^" in "baz" as{TypeError} core::int, null);
+  } =>#t346;
+  block {
+    final core::List<core::int> #t350 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::int #t351 in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
                                                 ^" in "bar" as{TypeError} core::int])
-        #t313.{core::List::add}(#t314);
-  } =>#t313;
+        #t350.{core::List::add}(#t351);
+  } =>#t350;
   block {
-    final core::Set<core::int> #t316 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t353 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t317 in <core::int>[let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::int #t354 in <core::int>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
                                                 ^" in "bar" as{TypeError} core::int])
-        #t316.{core::Set::add}(#t317);
-    #t316.{core::Set::add}(null);
-  } =>#t316;
+        #t353.{core::Set::add}(#t354);
+    #t353.{core::Set::add}(null);
+  } =>#t353;
   block {
-    final core::Map<core::int, core::int> #t319 = <core::int, core::int>{};
+    final core::Map<core::int, core::int> #t356 = <core::int, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::int, core::int> #t320 in <core::int, core::int>{let final<BottomType> #t321 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+      for (final core::MapEntry<core::int, core::int> #t357 in <core::int, core::int>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int: let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int}.{core::Map::entries})
-        #t319.{core::Map::[]=}(#t320.{core::MapEntry::key}, #t320.{core::MapEntry::value});
-    #t319.{core::Map::[]=}(let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+        #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value});
+    #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int, null);
-  } =>#t319;
+  } =>#t356;
   block {
-    final core::List<core::int> #t324 = <core::int>[];
+    final core::List<core::int> #t361 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t324.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t361.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
-                                               ^" as{TypeError} core::int);
-  } =>#t324;
+                                               ^");
+  } =>#t361;
   block {
-    final core::Set<core::int> #t325 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t362 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t325.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t362.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
-                                               ^" as{TypeError} core::int);
-    #t325.{core::Set::add}(null);
-  } =>#t325;
-  <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                               ^");
+    #t362.{core::Set::add}(null);
+  } =>#t362;
+  <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
-                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
-  <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+  block {
+    final core::List<core::String> #t363 = <core::String>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
-                                               ^"];
-  let final core::Set<core::String> #t326 = col::LinkedHashSet::•<core::String>() in let final dynamic #t327 = #t326.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                                                             ^" in 42 as{TypeError} core::String);
+      else
+        #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
+                                                                     ^" in 3.14 as{TypeError} core::String);
+  } =>#t363;
+  block {
+    final core::Set<core::String> #t366 = col::LinkedHashSet::•<core::String>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
-                                               ^") in let final dynamic #t328 = #t326.{core::Set::add}(null) in #t326;
-  <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                                                             ^" in 42 as{TypeError} core::String);
+      else
+        #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
+                                                                     ^" in 3.14 as{TypeError} core::String);
+    #t366.{core::Set::add}(null);
+  } =>#t366;
+  block {
+    final core::Map<core::String, core::String> #t369 = <core::String, core::String>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
-                   ^", "baz": null};
+                                                                            ^" in 42 as{TypeError} core::String);
+      else
+        #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
+                                                                                           ^" in 3.14 as{TypeError} core::String);
+    #t369.{core::Map::[]=}("baz", null);
+  } =>#t369;
   block {
-    final core::List<core::int> #t329 = <core::int>[];
+    final core::List<core::int> #t372 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t329.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t372.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
-                                                             ^" as{TypeError} core::int);
+                                                             ^");
       else
-        #t329.{core::List::add}(42 as{TypeError} core::int);
-  } =>#t329;
+        #t372.{core::List::add}(42);
+  } =>#t372;
   block {
-    final core::Set<core::int> #t330 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t373 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t330.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t373.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
-                                                             ^" as{TypeError} core::int);
+                                                             ^");
       else
-        #t330.{core::Set::add}(42 as{TypeError} core::int);
-    #t330.{core::Set::add}(null);
-  } =>#t330;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+        #t373.{core::Set::add}(42);
+    #t373.{core::Set::add}(null);
+  } =>#t373;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
-                                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
   block {
-    final core::List<core::int> #t331 = <core::int>[];
+    final core::List<core::int> #t374 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t331.{core::List::add}(42 as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t374.{core::List::add}(42);
       else
-        #t331.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t374.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
-                                                                     ^" as{TypeError} core::int);
-  } =>#t331;
+                                                                     ^");
+  } =>#t374;
   block {
-    final core::Set<core::int> #t332 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t332.{core::Set::add}(42 as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t375.{core::Set::add}(42);
       else
-        #t332.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+        #t375.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
-                                                                     ^" as{TypeError} core::int);
-    #t332.{core::Set::add}(null);
-  } =>#t332;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                     ^");
+    #t375.{core::Set::add}(null);
+  } =>#t375;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
-                                                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
                                                                                     ^": null};
   final core::int i = 0;
   block {
-    final core::List<core::int> #t333 = <core::int>[];
-    for (final core::int #t334 in <core::int>[1]) {
-      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'.
+    final core::List<core::int> #t376 = <core::int>[];
+    for (final core::int #t377 in <core::int>[1]) {
+      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-      #t333.{core::List::add}(i);
+      #t376.{core::List::add}(i);
     }
-  } =>#t333;
+  } =>#t376;
   block {
-    final core::Set<core::int> #t335 = col::LinkedHashSet::•<core::int>();
-    for (final core::int #t336 in <core::int>[1]) {
-      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'.
+    final core::Set<core::int> #t378 = col::LinkedHashSet::•<core::int>();
+    for (final core::int #t379 in <core::int>[1]) {
+      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-      #t335.{core::Set::add}(i);
+      #t378.{core::Set::add}(i);
     }
-    #t335.{core::Set::add}(null);
-  } =>#t335;
+    #t378.{core::Set::add}(null);
+  } =>#t378;
   block {
-    final core::Map<core::String, core::int> #t337 = <core::String, core::int>{};
-    for (final core::int #t338 in <core::int>[1]) {
-      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'.
+    final core::Map<core::String, core::int> #t380 = <core::String, core::int>{};
+    for (final core::int #t381 in <core::int>[1]) {
+      invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-      #t337.{core::Map::[]=}("bar", i);
+      #t380.{core::Map::[]=}("bar", i);
     }
-    #t337.{core::Map::[]=}("baz", null);
-  } =>#t337;
+    #t380.{core::Map::[]=}("baz", null);
+  } =>#t380;
   core::List<dynamic> list10 = block {
-    final core::List<dynamic> #t339 = <dynamic>[];
-    for (dynamic i in let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::List<dynamic> #t382 = <dynamic>[];
+    for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-      #t339.{core::List::add}(i);
-  } =>#t339;
+      #t382.{core::List::add}(i);
+  } =>#t382;
   core::Set<dynamic> set10 = block {
-    final core::Set<dynamic> #t341 = col::LinkedHashSet::•<dynamic>();
-    for (dynamic i in let final<BottomType> #t342 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Set<dynamic> #t384 = col::LinkedHashSet::•<dynamic>();
+    for (dynamic i in let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-      #t341.{core::Set::add}(i);
-    #t341.{core::Set::add}(null);
-  } =>#t341;
+      #t384.{core::Set::add}(i);
+    #t384.{core::Set::add}(null);
+  } =>#t384;
   core::Map<core::String, dynamic> map10 = block {
-    final core::Map<core::String, dynamic> #t343 = <core::String, dynamic>{};
-    for (dynamic i in let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+    final core::Map<core::String, dynamic> #t386 = <core::String, dynamic>{};
+    for (dynamic i in let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-      #t343.{core::Map::[]=}("bar", i);
-    #t343.{core::Map::[]=}("baz", null);
-  } =>#t343;
+      #t386.{core::Map::[]=}("bar", i);
+    #t386.{core::Map::[]=}("baz", null);
+  } =>#t386;
   core::List<core::int> list20 = block {
-    final core::List<core::int> #t345 = <core::int>[];
-    for (core::int i in <core::int>[let final<BottomType> #t346 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int> #t388 = <core::int>[];
+    for (core::int i in <core::int>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int, let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int])
-      #t345.{core::List::add}(i);
-  } =>#t345;
+      #t388.{core::List::add}(i);
+  } =>#t388;
   core::Set<core::int> set20 = block {
-    final core::Set<core::int> #t348 = col::LinkedHashSet::•<core::int>();
-    for (core::int i in <core::int>[let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int> #t391 = col::LinkedHashSet::•<core::int>();
+    for (core::int i in <core::int>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int])
-      #t348.{core::Set::add}(i);
-    #t348.{core::Set::add}(null);
-  } =>#t348;
+      #t391.{core::Set::add}(i);
+    #t391.{core::Set::add}(null);
+  } =>#t391;
   core::Map<core::String, core::int> map20 = block {
-    final core::Map<core::String, core::int> #t351 = <core::String, core::int>{};
-    for (core::int i in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String, core::int> #t394 = <core::String, core::int>{};
+    for (core::int i in <core::int>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int])
-      #t351.{core::Map::[]=}("bar", i);
-    #t351.{core::Map::[]=}("baz", null);
-  } =>#t351;
+      #t394.{core::Map::[]=}("bar", i);
+    #t394.{core::Map::[]=}("baz", null);
+  } =>#t394;
   core::List<dynamic> list30 = block {
-    final core::List<dynamic> #t354 = <dynamic>[];
-    await for (dynamic i in let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::List<dynamic> #t397 = <dynamic>[];
+    await for (dynamic i in let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-      #t354.{core::List::add}(i);
-  } =>#t354;
+      #t397.{core::List::add}(i);
+  } =>#t397;
   core::Set<dynamic> set30 = block {
-    final core::Set<dynamic> #t356 = col::LinkedHashSet::•<dynamic>();
-    await for (dynamic i in let final<BottomType> #t357 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Set<dynamic> #t399 = col::LinkedHashSet::•<dynamic>();
+    await for (dynamic i in let final<BottomType> #t400 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-      #t356.{core::Set::add}(i);
-    #t356.{core::Set::add}(null);
-  } =>#t356;
+      #t399.{core::Set::add}(i);
+    #t399.{core::Set::add}(null);
+  } =>#t399;
   core::Map<core::String, dynamic> map30 = block {
-    final core::Map<core::String, dynamic> #t358 = <core::String, dynamic>{};
-    await for (dynamic i in let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+    final core::Map<core::String, dynamic> #t401 = <core::String, dynamic>{};
+    await for (dynamic i in let final<BottomType> #t402 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>)
-      #t358.{core::Map::[]=}("bar", i);
-    #t358.{core::Map::[]=}("baz", null);
-  } =>#t358;
+      #t401.{core::Map::[]=}("bar", i);
+    #t401.{core::Map::[]=}("baz", null);
+  } =>#t401;
   core::List<core::int> list40 = block {
-    final core::List<core::int> #t360 = <core::int>[];
-    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t361 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::List<core::int> #t403 = <core::int>[];
+    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t404 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t362 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t405 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int]))
-      #t360.{core::List::add}(i);
-  } =>#t360;
+      #t403.{core::List::add}(i);
+  } =>#t403;
   core::Set<core::int> set40 = block {
-    final core::Set<core::int> #t363 = col::LinkedHashSet::•<core::int>();
-    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int> #t406 = col::LinkedHashSet::•<core::int>();
+    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t407 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int]))
-      #t363.{core::Set::add}(i);
-    #t363.{core::Set::add}(null);
-  } =>#t363;
+      #t406.{core::Set::add}(i);
+    #t406.{core::Set::add}(null);
+  } =>#t406;
   core::Map<core::String, core::int> map40 = block {
-    final core::Map<core::String, core::int> #t366 = <core::String, core::int>{};
-    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String, core::int> #t409 = <core::String, core::int>{};
+    await for (core::int i in asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t410 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t411 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int]))
-      #t366.{core::Map::[]=}("bar", i);
-    #t366.{core::Map::[]=}("baz", null);
-  } =>#t366;
+      #t409.{core::Map::[]=}("bar", i);
+    #t409.{core::Map::[]=}("baz", null);
+  } =>#t409;
   core::List<core::int> list50 = block {
-    final core::List<core::int> #t369 = <core::int>[];
+    final core::List<core::int> #t412 = <core::int>[];
     for (; ; )
-      #t369.{core::List::add}(42);
-  } =>#t369;
+      #t412.{core::List::add}(42);
+  } =>#t412;
   core::Set<core::int> set50 = block {
-    final core::Set<core::int> #t370 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t413 = col::LinkedHashSet::•<core::int>();
     for (; ; )
-      #t370.{core::Set::add}(42);
-    #t370.{core::Set::add}(null);
-  } =>#t370;
+      #t413.{core::Set::add}(42);
+    #t413.{core::Set::add}(null);
+  } =>#t413;
   core::Map<core::String, core::int> map50 = block {
-    final core::Map<core::String, core::int> #t371 = <core::String, core::int>{};
+    final core::Map<core::String, core::int> #t414 = <core::String, core::int>{};
     for (; ; )
-      #t371.{core::Map::[]=}("bar", 42);
-    #t371.{core::Map::[]=}("baz", null);
-  } =>#t371;
+      #t414.{core::Map::[]=}("bar", 42);
+    #t414.{core::Map::[]=}("baz", null);
+  } =>#t414;
   core::List<core::int> list60 = block {
-    final core::List<core::int> #t372 = <core::int>[];
-    for (; let final<BottomType> #t373 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::List<core::int> #t415 = <core::int>[];
+    for (; let final<BottomType> #t416 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool; )
-      #t372.{core::List::add}(42);
-  } =>#t372;
+      #t415.{core::List::add}(42);
+  } =>#t415;
   core::Set<core::int> set60 = block {
-    final core::Set<core::int> #t374 = col::LinkedHashSet::•<core::int>();
-    for (; let final<BottomType> #t375 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Set<core::int> #t417 = col::LinkedHashSet::•<core::int>();
+    for (; let final<BottomType> #t418 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool; )
-      #t374.{core::Set::add}(42);
-    #t374.{core::Set::add}(null);
-  } =>#t374;
+      #t417.{core::Set::add}(42);
+    #t417.{core::Set::add}(null);
+  } =>#t417;
   core::Map<core::String, core::int> map60 = block {
-    final core::Map<core::String, core::int> #t376 = <core::String, core::int>{};
-    for (; let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+    final core::Map<core::String, core::int> #t419 = <core::String, core::int>{};
+    for (; let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool; )
-      #t376.{core::Map::[]=}("bar", 42);
-    #t376.{core::Map::[]=}("baz", null);
-  } =>#t376;
+      #t419.{core::Map::[]=}("bar", 42);
+    #t419.{core::Map::[]=}("baz", null);
+  } =>#t419;
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic {
   block {
-    final core::List<core::int> #t378 = <core::int>[];
+    final core::List<core::int> #t421 = <core::int>[];
     await for (core::int i in stream)
-      #t378.{core::List::add}(i);
-  } =>#t378;
+      #t421.{core::List::add}(i);
+  } =>#t421;
   block {
-    final core::Set<core::int> #t379 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t422 = col::LinkedHashSet::•<core::int>();
     await for (core::int i in stream)
-      #t379.{core::Set::add}(i);
-  } =>#t379;
+      #t422.{core::Set::add}(i);
+  } =>#t422;
   block {
-    final core::Map<core::String, core::int> #t380 = <core::String, core::int>{};
+    final core::Map<core::String, core::int> #t423 = <core::String, core::int>{};
     await for (core::int i in stream)
-      #t380.{core::Map::[]=}("bar", i);
-  } =>#t380;
+      #t423.{core::Map::[]=}("bar", i);
+  } =>#t423;
+}
+static method testPromotion(self::A a) → dynamic {
+  core::List<core::int> list10 = block {
+    final core::List<core::int> #t424 = <core::int>[];
+    if(a is self::B)
+      #t424.{core::List::add}(a{self::B}.{self::B::foo});
+  } =>#t424;
+  core::Set<core::int> set10 = block {
+    final core::Set<core::int> #t425 = col::LinkedHashSet::•<core::int>();
+    if(a is self::B)
+      #t425.{core::Set::add}(a{self::B}.{self::B::foo});
+  } =>#t425;
+  core::Map<core::int, core::int> map10 = block {
+    final core::Map<core::int, core::int> #t426 = <core::int, core::int>{};
+    if(a is self::B)
+      #t426.{core::Map::[]=}(a{self::B}.{self::B::foo}, a{self::B}.{self::B::foo});
+  } =>#t426;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
index 14b2064..3c4ea93 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.strong.transformed.expect
@@ -11,379 +11,466 @@
 //   var map82 = {if (oracle("foo")) ...mapToInt else ...dynVar, null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:44: Error: Expected ':' after this.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                            ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this.
+//   Map<dynamic, dynamic> map10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                                     ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:61: Error: Expected ':' after this.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
+//   Map<dynamic, dynamic> map11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+//   var map12 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                                   ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+//   var map13 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                                                    ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) "bar"];
 //                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) "bar", null};
 //                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
 //                                           ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-//   <String, int>{if (oracle("foo")) "bar": "bar", "baz": null};
-//                                         ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[if (oracle("foo")) ...["bar"]];
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{if (oracle("foo")) ...["bar"], null};
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <String, int>{if (oracle("foo")) ...{"bar": "bar"}, "baz": null};
 //                                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[if (oracle("foo")) ...map];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{if (oracle("foo")) ...map, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{if (oracle("foo")) ...["bar"], "baz": null};
 //                                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[if (oracle("foo")) 42 else 3.14];
-//            ^
+//                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>[if (oracle("foo")) 42 else 3.14];
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{if (oracle("foo")) 42 else 3.14, null};
-//            ^
+//                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>{if (oracle("foo")) 42 else 3.14, null};
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
 //                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   <String, String>{if (oracle("foo")) "bar": 42 else "baz": 3.14, "baz": null};
-//                    ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[if (oracle("foo")) ...map else 42];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
-//  - 'Map' is from 'dart:core'.
-//   <int>{if (oracle("foo")) ...map else 42, null};
-//                               ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
-//  - 'List' is from 'dart:core'.
-//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
-//                                       ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
-//  - 'Map' is from 'dart:core'.
-//   <int>[if (oracle("foo")) 42 else ...map];
-//                                       ^
-//
 // pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{if (oracle("foo")) ...map else 42, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+//  - 'List' is from 'dart:core'.
+//   <String, int>{if (oracle("foo")) ...[42] else "bar": 42, "baz": null};
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+//  - 'Map' is from 'dart:core'.
+//   <int>[if (oracle("foo")) 42 else ...map];
+//                                       ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+//  - 'Map' is from 'dart:core'.
+//   <int>{if (oracle("foo")) ...map else 42, null};
+//                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{if (oracle("foo")) "bar": 42 else ...[42], "baz": null};
 //                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+//   Set<dynamic> set10 = {if (oracle("foo")) 42 else "bar": 3.14};
+//                        ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+//   Set<dynamic> set11 = {if (oracle("foo")) "bar": 3.14 else 42};
+//                        ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   List<int> list20 = [if (42) 42];
+//                           ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   Set<int> set20 = {if (42) 42};
+//                         ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+// Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+//   Map<int, int> map30 = {if (42) 42: 42};
+//                              ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                                     ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   List<String> list40 = <String>[if (oracle("foo")) true else 42];
+//                                                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                                   ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Set<String> set40 = <String>{if (oracle("foo")) true else 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                                             ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<String, int> map40 = <String, int>{if (oracle("foo")) true: 42 else 42: 42};
+//                                                                           ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                                                 ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   Map<int, String> map41 = <int, String>{if (oracle("foo")) 42: true else 42: 42};
+//                                                                               ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
 //   <int>[for (i in <int>[1]) i];
 //              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
 //   <int>{for (i in <int>[1]) i, null};
 //              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
 // 	<String, int>{for (i in <int>[1]) "bar": i, "baz": null};
 // 	                   ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:226:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:246:17: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var list50 = [await for (;;) 42];
 //                 ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:227:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:247:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var set50 = {await for (;;) 42, null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:228:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:248:16: Error: The keyword 'await' isn't allowed for a normal 'for' statement.
 // Try removing the keyword, or use a for-each statement.
 //   var map50 = {await for (;;) "bar": 42, "baz": null};
 //                ^^^^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
 //                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
 //                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                  ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-// Try changing the type of the left hand side, or casting the right hand side to 'int'.
-//   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
-//              ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
 //                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
 //                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
 //                                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) ...map];
 //                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
 //                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
 //                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
-//                                                ^
+//                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
-//                                                ^
+//                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// Try changing the type of the left hand side, or casting the right hand side to 'String'.
+//   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
+//                                                                      ^
+//
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                             ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
 // Try changing the type of the left hand side, or casting the right hand side to 'String'.
 //   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
 //                                                                                            ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
-//                    ^
-//
-// pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
 //                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
 //                                                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
 //  - 'Map' is from 'dart:core'.
 //   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
 //                                                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
 //  - 'List' is from 'dart:core'.
 //   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
 //                                                                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var list10 = [for (var i in "not iterable") i];
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var set10 = {for (var i in "not iterable") i, null};
 //                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
 //  - 'Iterable' is from 'dart:core'.
 //   var map10 = {for (var i in "not iterable") "bar": i, "baz": null};
 //                              ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list20 = [for (int i in ["not", "int"]) i];
 //                                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set20 = {for (int i in ["not", "int"]) i, null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                               ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map20 = {for (int i in ["not", "int"]) "bar": i, "baz": null};
 //                                      ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var list30 = [await for (var i in "not stream") i];
 //                                     ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var set30 = {await for (var i in "not stream") i, null};
 //                                    ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
 //  - 'Stream' is from 'dart:async'.
 //   var map30 = {await for (var i in "not stream") "bar": i, "baz": null};
 //                                    ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                          ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var list40 = [await for (int i in Stream.fromIterable(["not", "int"])) i];
 //                                                                 ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var set40 = {await for (int i in Stream.fromIterable(["not", "int"])) i, null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                         ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 // Try changing the type of the left hand side, or casting the right hand side to 'int'.
 //   var map40 = {await for (int i in Stream.fromIterable(["not", "int"])) "bar": i, "baz": null};
 //                                                                ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var list60 = [for (; "not bool";) 42];
 //                        ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var set60 = {for (; "not bool";) 42, null};
 //                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 // Try changing the type of the left hand side, or casting the right hand side to 'bool'.
 //   var map60 = {for (; "not bool";) "bar": 42, "baz": null};
 //                       ^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:235:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:255:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>[await for (int i in stream) i];
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:236:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:256:26: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <int>{await for (int i in stream) i};
 //                          ^^
 //
-// pkg/front_end/testcases/control_flow_collection_inference.dart:237:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
+// pkg/front_end/testcases/control_flow_collection_inference.dart:257:34: Error: The asynchronous for-in can only be used in functions marked with 'async' or 'async*'.
 // Try marking the function body with either 'async' or 'async*', or removing the 'await' before the for loop.
 //   <String, int>{await for (int i in stream) "bar": i};
 //                                  ^^
@@ -393,198 +480,210 @@
 import "dart:collection" as col;
 import "dart:async" as asy;
 
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class B extends self::A {
+  synthetic constructor •() → self::B
+    : super self::A::•()
+    ;
+  get foo() → core::int
+    return 42;
+}
 static method oracle<T extends core::Object = dynamic>([self::oracle::T t = null]) → dynamic
   return true;
 static method testIfElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::Map<core::String, core::int> mapToInt, core::Map<core::String, core::double> mapToDouble) → dynamic {
   core::List<core::int> list10 = block {
     final core::List<core::int> #t1 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t1.{core::List::add}(42);
   } =>#t1;
   core::Set<core::int> set10 = block {
     final core::Set<core::int> #t2 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t2.{core::Set::add}(42);
     #t2.{core::Set::add}(null);
   } =>#t2;
   core::Map<core::String, core::int> map10 = block {
     final core::Map<core::String, core::int> #t3 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t3.{core::Map::[]=}("bar", 42);
     #t3.{core::Map::[]=}("baz", null);
   } =>#t3;
   core::List<dynamic> list11 = block {
     final core::List<dynamic> #t4 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t4.{core::List::add}(dynVar);
   } =>#t4;
   core::Set<dynamic> set11 = block {
     final core::Set<dynamic> #t5 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t5.{core::Set::add}(dynVar);
     #t5.{core::Set::add}(null);
   } =>#t5;
   core::Map<core::String, dynamic> map11 = block {
     final core::Map<core::String, dynamic> #t6 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t6.{core::Map::[]=}("bar", dynVar);
     #t6.{core::Map::[]=}("baz", null);
   } =>#t6;
   core::List<core::List<core::int>> list12 = block {
     final core::List<core::List<core::int>> #t7 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t7.{core::List::add}(<core::int>[42]);
   } =>#t7;
   core::Set<core::List<core::int>> set12 = block {
     final core::Set<core::List<core::int>> #t8 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t8.{core::Set::add}(<core::int>[42]);
     #t8.{core::Set::add}(null);
   } =>#t8;
   core::Map<core::String, core::List<core::int>> map12 = block {
     final core::Map<core::String, core::List<core::int>> #t9 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t9.{core::Map::[]=}("bar", <core::int>[42]);
     #t9.{core::Map::[]=}("baz", null);
   } =>#t9;
   core::List<core::int> list20 = block {
     final core::List<core::int> #t10 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t11 in <core::int>[42])
         #t10.{core::List::add}(#t11);
   } =>#t10;
   core::Set<core::int> set20 = block {
     final core::Set<core::int> #t12 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t13 in <core::int>[42])
         #t12.{core::Set::add}(#t13);
     #t12.{core::Set::add}(null);
   } =>#t12;
   core::Map<core::String, core::int> map20 = block {
     final core::Map<core::String, core::int> #t14 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::int> #t15 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
         #t14.{core::Map::[]=}(#t15.{core::MapEntry::key}, #t15.{core::MapEntry::value});
     #t14.{core::Map::[]=}("baz", null);
   } =>#t14;
   core::List<dynamic> list21 = block {
     final core::List<dynamic> #t16 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t17 in <dynamic>[dynVar])
         #t16.{core::List::add}(#t17);
   } =>#t16;
   core::Set<dynamic> set21 = block {
     final core::Set<dynamic> #t18 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t19 in <dynamic>[dynVar])
         #t18.{core::Set::add}(#t19);
     #t18.{core::Set::add}(null);
   } =>#t18;
   core::Map<core::String, dynamic> map21 = block {
     final core::Map<core::String, dynamic> #t20 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, dynamic> #t21 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
         #t20.{core::Map::[]=}(#t21.{core::MapEntry::key}, #t21.{core::MapEntry::value});
     #t20.{core::Map::[]=}("baz", null);
   } =>#t20;
   core::List<core::List<core::int>> list22 = block {
     final core::List<core::List<core::int>> #t22 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t23 in <core::List<core::int>>[<core::int>[42]])
         #t22.{core::List::add}(#t23);
   } =>#t22;
   core::Set<core::List<core::int>> set22 = block {
     final core::Set<core::List<core::int>> #t24 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t25 in <core::List<core::int>>[<core::int>[42]])
         #t24.{core::Set::add}(#t25);
     #t24.{core::Set::add}(null);
   } =>#t24;
   core::Map<core::String, core::List<core::int>> map22 = block {
     final core::Map<core::String, core::List<core::int>> #t26 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::List<core::int>> #t27 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
         #t26.{core::Map::[]=}(#t27.{core::MapEntry::key}, #t27.{core::MapEntry::value});
     #t26.{core::Map::[]=}("baz", null);
   } =>#t26;
   core::List<core::int> list30 = block {
     final core::List<core::int> #t28 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t29 in <core::int>[42])
           #t28.{core::List::add}(#t29);
   } =>#t28;
   core::Set<core::int> set30 = block {
     final core::Set<core::int> #t30 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t31 in <core::int>[42])
           #t30.{core::Set::add}(#t31);
     #t30.{core::Set::add}(null);
   } =>#t30;
   core::Map<core::String, core::int> map30 = block {
     final core::Map<core::String, core::int> #t32 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::int> #t33 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
           #t32.{core::Map::[]=}(#t33.{core::MapEntry::key}, #t33.{core::MapEntry::value});
     #t32.{core::Map::[]=}("baz", null);
   } =>#t32;
   core::List<dynamic> list31 = block {
     final core::List<dynamic> #t34 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final dynamic #t35 in <dynamic>[dynVar])
           #t34.{core::List::add}(#t35);
   } =>#t34;
   core::Set<dynamic> set31 = block {
     final core::Set<dynamic> #t36 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final dynamic #t37 in <dynamic>[dynVar])
           #t36.{core::Set::add}(#t37);
     #t36.{core::Set::add}(null);
   } =>#t36;
   core::Map<core::String, dynamic> map31 = block {
     final core::Map<core::String, dynamic> #t38 = <core::String, dynamic>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, dynamic> #t39 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
           #t38.{core::Map::[]=}(#t39.{core::MapEntry::key}, #t39.{core::MapEntry::value});
     #t38.{core::Map::[]=}("baz", null);
   } =>#t38;
   core::List<core::List<core::int>> list33 = block {
     final core::List<core::List<core::int>> #t40 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t41 in <core::List<core::int>>[<core::int>[42]])
           #t40.{core::List::add}(#t41);
   } =>#t40;
   core::Set<core::List<core::int>> set33 = block {
     final core::Set<core::List<core::int>> #t42 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t43 in <core::List<core::int>>[<core::int>[42]])
           #t42.{core::Set::add}(#t43);
     #t42.{core::Set::add}(null);
   } =>#t42;
   core::Map<core::String, core::List<core::int>> map33 = block {
     final core::Map<core::String, core::List<core::int>> #t44 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t45 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
           #t44.{core::Map::[]=}(#t45.{core::MapEntry::key}, #t45.{core::MapEntry::value});
     #t44.{core::Map::[]=}("baz", null);
   } =>#t44;
   core::List<core::List<core::int>> list40 = block {
     final core::List<core::List<core::int>> #t46 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t47 in <core::List<core::int>>[<core::int>[]])
         #t46.{core::List::add}(#t47);
   } =>#t46;
   core::Set<core::List<core::int>> set40 = block {
     final core::Set<core::List<core::int>> #t48 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t49 in <core::List<core::int>>[<core::int>[]])
         #t48.{core::Set::add}(#t49);
     #t48.{core::Set::add}(null);
@@ -594,173 +693,173 @@
                                  ^";
   core::List<core::List<core::int>> list41 = block {
     final core::List<core::List<core::int>> #t50 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t51 in let final core::Set<core::List<core::int>> #t52 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t53 = #t52.{core::Set::add}(<core::int>[]) in #t52)
         #t50.{core::List::add}(#t51);
   } =>#t50;
   core::Set<core::List<core::int>> set41 = block {
     final core::Set<core::List<core::int>> #t54 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t55 in let final core::Set<core::List<core::int>> #t56 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t57 = #t56.{core::Set::add}(<core::int>[]) in #t56)
         #t54.{core::Set::add}(#t55);
     #t54.{core::Set::add}(null);
   } =>#t54;
   core::List<core::List<core::int>> list42 = block {
     final core::List<core::List<core::int>> #t58 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t59 in <core::List<core::int>>[<core::int>[]])
           #t58.{core::List::add}(#t59);
   } =>#t58;
   core::Set<core::List<core::int>> set42 = block {
     final core::Set<core::List<core::int>> #t60 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t61 in <core::List<core::int>>[<core::int>[]])
           #t60.{core::Set::add}(#t61);
     #t60.{core::Set::add}(null);
   } =>#t60;
   core::Map<core::String, core::List<core::int>> map42 = block {
     final core::Map<core::String, core::List<core::int>> #t62 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t63 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
           #t62.{core::Map::[]=}(#t63.{core::MapEntry::key}, #t63.{core::MapEntry::value});
     #t62.{core::Map::[]=}("baz", null);
   } =>#t62;
   core::List<core::int> list50 = block {
     final core::List<core::int> #t64 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t65 in <core::int>[])
         #t64.{core::List::add}(#t65);
   } =>#t64;
   core::Set<core::int> set50 = block {
     final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t67 in <core::int>[])
         #t66.{core::Set::add}(#t67);
     #t66.{core::Set::add}(null);
   } =>#t66;
   core::Map<core::String, core::int> map50 = block {
     final core::Map<core::String, core::int> #t68 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::int> #t69 in <core::String, core::int>{}.{core::Map::entries})
         #t68.{core::Map::[]=}(#t69.{core::MapEntry::key}, #t69.{core::MapEntry::value});
     #t68.{core::Map::[]=}("baz", null);
   } =>#t68;
   core::List<core::int> list51 = block {
     final core::List<core::int> #t70 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t71 in let final core::Set<core::int> #t72 = col::LinkedHashSet::•<core::int>() in #t72)
         #t70.{core::List::add}(#t71);
   } =>#t70;
   core::Set<core::int> set51 = block {
     final core::Set<core::int> #t73 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::int #t74 in let final core::Set<core::int> #t75 = col::LinkedHashSet::•<core::int>() in #t75)
         #t73.{core::Set::add}(#t74);
     #t73.{core::Set::add}(null);
   } =>#t73;
   core::List<core::int> list52 = block {
     final core::List<core::int> #t76 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t77 in <core::int>[])
           #t76.{core::List::add}(#t77);
   } =>#t76;
   core::Set<core::int> set52 = block {
     final core::Set<core::int> #t78 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::int #t79 in <core::int>[])
           #t78.{core::Set::add}(#t79);
     #t78.{core::Set::add}(null);
   } =>#t78;
   core::Map<core::String, core::int> map52 = block {
     final core::Map<core::String, core::int> #t80 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::int> #t81 in <core::String, core::int>{}.{core::Map::entries})
           #t80.{core::Map::[]=}(#t81.{core::MapEntry::key}, #t81.{core::MapEntry::value});
     #t80.{core::Map::[]=}("baz", null);
   } =>#t80;
   core::List<core::List<core::int>> list60 = block {
     final core::List<core::List<core::int>> #t82 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t83 in <core::List<core::int>>[<core::int>[]])
         #t82.{core::List::add}(#t83);
   } =>#t82;
   core::Set<core::List<core::int>> set60 = block {
     final core::Set<core::List<core::int>> #t84 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::List<core::int> #t85 in <core::List<core::int>>[<core::int>[]])
         #t84.{core::Set::add}(#t85);
     #t84.{core::Set::add}(null);
   } =>#t84;
   core::Map<core::String, core::List<core::int>> map60 = block {
     final core::Map<core::String, core::List<core::int>> #t86 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::List<core::int>> #t87 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
         #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
     #t86.{core::Map::[]=}("baz", null);
   } =>#t86;
   core::List<core::List<core::int>> list61 = block {
     final core::List<core::List<core::int>> #t88 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t89 in <core::List<core::int>>[<core::int>[]])
           #t88.{core::List::add}(#t89);
   } =>#t88;
   core::Set<core::List<core::int>> set61 = block {
     final core::Set<core::List<core::int>> #t90 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t91 in <core::List<core::int>>[<core::int>[]])
           #t90.{core::Set::add}(#t91);
     #t90.{core::Set::add}(null);
   } =>#t90;
   core::Map<core::String, core::List<core::int>> map61 = block {
     final core::Map<core::String, core::List<core::int>> #t92 = <core::String, core::List<core::int>>{};
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::MapEntry<core::String, core::List<core::int>> #t93 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
           #t92.{core::Map::[]=}(#t93.{core::MapEntry::key}, #t93.{core::MapEntry::value});
     #t92.{core::Map::[]=}("baz", null);
   } =>#t92;
   core::List<core::List<core::int>> list70 = block {
     final core::List<core::List<core::int>> #t94 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t94.{core::List::add}(<core::int>[]);
   } =>#t94;
   core::Set<core::List<core::int>> set70 = block {
     final core::Set<core::List<core::int>> #t95 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t95.{core::Set::add}(<core::int>[]);
     #t95.{core::Set::add}(null);
   } =>#t95;
   core::List<core::List<core::int>> list71 = block {
     final core::List<core::List<core::int>> #t96 = <core::List<core::int>>[];
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         #t96.{core::List::add}(<core::int>[]);
   } =>#t96;
   core::Set<core::List<core::int>> set71 = block {
     final core::Set<core::List<core::int>> #t97 = col::LinkedHashSet::•<core::List<core::int>>();
-    if(self::oracle<core::String>("foo"))
-      if(self::oracle<dynamic>())
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         #t97.{core::Set::add}(<core::int>[]);
     #t97.{core::Set::add}(null);
   } =>#t97;
   core::List<core::num> list80 = block {
     final core::List<core::num> #t98 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t98.{core::List::add}(42);
     else
       #t98.{core::List::add}(3.14);
   } =>#t98;
   core::Set<core::num> set80 = block {
     final core::Set<core::num> #t99 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t99.{core::Set::add}(42);
     else
       #t99.{core::Set::add}(3.14);
@@ -768,7 +867,7 @@
   } =>#t99;
   core::Map<core::String, core::num> map80 = block {
     final core::Map<core::String, core::num> #t100 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t100.{core::Map::[]=}("bar", 42);
     else
       #t100.{core::Map::[]=}("bar", 3.14);
@@ -776,7 +875,7 @@
   } =>#t100;
   core::List<core::num> list81 = block {
     final core::List<core::num> #t101 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t102 in listInt)
         #t101.{core::List::add}(#t102);
     else
@@ -785,7 +884,7 @@
   } =>#t101;
   core::Set<core::num> set81 = block {
     final core::Set<core::num> #t104 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t105 in listInt)
         #t104.{core::Set::add}(#t105);
     else
@@ -795,7 +894,7 @@
   } =>#t104;
   core::Map<core::String, core::num> map81 = block {
     final core::Map<core::String, core::num> #t107 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::num> #t108 in mapToInt.{core::Map::entries})
         #t107.{core::Map::[]=}(#t108.{core::MapEntry::key}, #t108.{core::MapEntry::value});
     else
@@ -805,7 +904,7 @@
   } =>#t107;
   core::List<dynamic> list82 = block {
     final core::List<dynamic> #t110 = <dynamic>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t111 in listInt)
         #t110.{core::List::add}(#t111);
     else
@@ -814,7 +913,7 @@
   } =>#t110;
   core::Set<dynamic> set82 = block {
     final core::Set<dynamic> #t113 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t114 in listInt)
         #t113.{core::Set::add}(#t114);
     else
@@ -824,7 +923,7 @@
   } =>#t113;
   core::Set<dynamic> map82 = block {
     final core::Set<dynamic> #t116 = col::LinkedHashSet::•<dynamic>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t116.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:71:38: Error: Unexpected type 'Map<String, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   var map82 = {if (oracle(\"foo\")) ...mapToInt else ...dynVar, null};
@@ -836,7 +935,7 @@
   } =>#t116;
   core::List<core::num> list83 = block {
     final core::List<core::num> #t118 = <core::num>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t118.{core::List::add}(42);
     else
       for (final core::num #t119 in listDouble)
@@ -844,7 +943,7 @@
   } =>#t118;
   core::Set<core::num> set83 = block {
     final core::Set<core::num> #t120 = col::LinkedHashSet::•<core::num>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::num #t121 in listInt)
         #t120.{core::Set::add}(#t121);
     else
@@ -853,7 +952,7 @@
   } =>#t120;
   core::Map<core::String, core::num> map83 = block {
     final core::Map<core::String, core::num> #t122 = <core::String, core::num>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<core::String, core::num> #t123 in mapToInt.{core::Map::entries})
         #t122.{core::Map::[]=}(#t123.{core::MapEntry::key}, #t123.{core::MapEntry::value});
     else
@@ -862,24 +961,24 @@
   } =>#t122;
   core::List<core::int> list90 = block {
     final core::List<core::int> #t124 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t124.{core::List::add}(dynVar as{TypeError} core::int);
   } =>#t124;
   core::Set<core::int> set90 = block {
     final core::Set<core::int> #t125 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t125.{core::Set::add}(dynVar as{TypeError} core::int);
     #t125.{core::Set::add}(null);
   } =>#t125;
   core::Map<core::String, core::int> map90 = block {
     final core::Map<core::String, core::int> #t126 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       #t126.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
     #t126.{core::Map::[]=}("baz", null);
   } =>#t126;
   core::List<core::int> list91 = block {
     final core::List<core::int> #t127 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t128 in dynVar as{TypeError} core::Iterable<dynamic>) {
         final core::int #t129 = #t128 as{TypeError} core::int;
         #t127.{core::List::add}(#t129);
@@ -887,7 +986,7 @@
   } =>#t127;
   core::Set<core::int> set91 = block {
     final core::Set<core::int> #t130 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final dynamic #t131 in dynVar as{TypeError} core::Iterable<dynamic>) {
         final core::int #t132 = #t131 as{TypeError} core::int;
         #t130.{core::Set::add}(#t132);
@@ -896,7 +995,7 @@
   } =>#t130;
   core::Map<core::String, core::int> map91 = block {
     final core::Map<core::String, core::int> #t133 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
       for (final core::MapEntry<dynamic, dynamic> #t134 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
         final core::String #t135 = #t134.{core::MapEntry::key} as{TypeError} core::String;
         final core::int #t136 = #t134.{core::MapEntry::value} as{TypeError} core::int;
@@ -904,719 +1003,886 @@
       }
     #t133.{core::Map::[]=}("baz", null);
   } =>#t133;
+  core::List<core::int> list100 = block {
+    final core::List<core::int> #t137 = <core::int>[];
+    if(dynVar as{TypeError} core::bool)
+      #t137.{core::List::add}(42);
+  } =>#t137;
+  core::Set<core::int> set100 = block {
+    final core::Set<core::int> #t138 = col::LinkedHashSet::•<core::int>();
+    if(dynVar as{TypeError} core::bool)
+      #t138.{core::Set::add}(42);
+  } =>#t138;
+  core::Map<core::int, core::int> map100 = block {
+    final core::Map<core::int, core::int> #t139 = <core::int, core::int>{};
+    if(dynVar as{TypeError} core::bool)
+      #t139.{core::Map::[]=}(42, 42);
+  } =>#t139;
 }
 static method testIfElementErrors(core::Map<core::int, core::int> map) → dynamic {
-  <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:84:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int>[if (oracle(\"foo\")) \"bar\"];
-                           ^"];
-  let final core::Set<core::int> #t137 = col::LinkedHashSet::•<core::int>() in let final core::bool #t138 = #t137.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:85:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int>{if (oracle(\"foo\")) \"bar\", null};
-                           ^") in let final core::bool #t139 = #t137.{core::Set::add}(null) in #t137;
-  <core::String, core::int>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:86:41: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
-                                        ^", "baz": null};
   block {
     final core::List<core::int> #t140 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      for (final core::int #t141 in <core::int>[let final<BottomType> #t142 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t140.{core::List::add}(let final<BottomType> #t141 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:87:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int>[if (oracle(\"foo\")) \"bar\"];
+                           ^" in "bar" as{TypeError} core::int);
+  } =>#t140;
+  block {
+    final core::Set<core::int> #t142 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t142.{core::Set::add}(let final<BottomType> #t143 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:28: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int>{if (oracle(\"foo\")) \"bar\", null};
+                           ^" in "bar" as{TypeError} core::int);
+    #t142.{core::Set::add}(null);
+  } =>#t142;
+  block {
+    final core::Map<core::String, core::int> #t144 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t144.{core::Map::[]=}("bar", let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:43: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <String, int>{if (oracle(\"foo\")) \"bar\": \"bar\", \"baz\": null};
+                                          ^" in "bar" as{TypeError} core::int);
+    #t144.{core::Map::[]=}("baz", null);
+  } =>#t144;
+  block {
+    final core::List<core::int> #t146 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::int #t147 in <core::int>[let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[if (oracle(\"foo\")) ...[\"bar\"]];
                                ^" in "bar" as{TypeError} core::int])
-        #t140.{core::List::add}(#t141);
-  } =>#t140;
+        #t146.{core::List::add}(#t147);
+  } =>#t146;
   block {
-    final core::Set<core::int> #t143 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      for (final core::int #t144 in <core::int>[let final<BottomType> #t145 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:88:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Set<core::int> #t149 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::int #t150 in <core::int>[let final<BottomType> #t151 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{if (oracle(\"foo\")) ...[\"bar\"], null};
                                ^" in "bar" as{TypeError} core::int])
-        #t143.{core::Set::add}(#t144);
-    #t143.{core::Set::add}(null);
-  } =>#t143;
+        #t149.{core::Set::add}(#t150);
+    #t149.{core::Set::add}(null);
+  } =>#t149;
   block {
-    final core::Map<core::String, core::int> #t146 = <core::String, core::int>{};
-    if(self::oracle<core::String>("foo"))
-      for (final core::MapEntry<core::String, core::int> #t147 in <core::String, core::int>{"bar": let final<BottomType> #t148 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:89:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+    final core::Map<core::String, core::int> #t152 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      for (final core::MapEntry<core::String, core::int> #t153 in <core::String, core::int>{"bar": let final<BottomType> #t154 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:47: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <String, int>{if (oracle(\"foo\")) ...{\"bar\": \"bar\"}, \"baz\": null};
                                               ^" in "bar" as{TypeError} core::int}.{core::Map::entries})
-        #t146.{core::Map::[]=}(#t147.{core::MapEntry::key}, #t147.{core::MapEntry::value});
-    #t146.{core::Map::[]=}("baz", null);
-  } =>#t146;
+        #t152.{core::Map::[]=}(#t153.{core::MapEntry::key}, #t153.{core::MapEntry::value});
+    #t152.{core::Map::[]=}("baz", null);
+  } =>#t152;
   block {
-    final core::List<core::int> #t149 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t149.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:90:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::List<core::int> #t155 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t155.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map];
-                              ^" as{TypeError} core::int);
-  } =>#t149;
+                              ^");
+  } =>#t155;
   block {
-    final core::Set<core::int> #t150 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t150.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:91:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t156 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t156.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map, null};
-                              ^" as{TypeError} core::int);
-    #t150.{core::Set::add}(null);
-  } =>#t150;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+                              ^");
+    #t156.{core::Set::add}(null);
+  } =>#t156;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
-                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:92:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:39: Error: Unexpected type 'List<String>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[\"bar\"], \"baz\": null};
                                       ^": null};
-  <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:93:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+  block {
+    final core::List<core::String> #t157 = <core::String>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t157.{core::List::add}(let final<BottomType> #t158 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[if (oracle(\"foo\")) 42 else 3.14];
-           ^"];
-  let final core::Set<core::String> #t151 = col::LinkedHashSet::•<core::String>() in let final core::bool #t152 = #t151.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:94:12: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                              ^" in 42 as{TypeError} core::String);
+    else
+      #t157.{core::List::add}(let final<BottomType> #t159 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>[if (oracle(\"foo\")) 42 else 3.14];
+                                      ^" in 3.14 as{TypeError} core::String);
+  } =>#t157;
+  block {
+    final core::Set<core::String> #t160 = col::LinkedHashSet::•<core::String>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t160.{core::Set::add}(let final<BottomType> #t161 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{if (oracle(\"foo\")) 42 else 3.14, null};
-           ^") in let final core::bool #t153 = #t151.{core::Set::add}(null) in #t151;
-  <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:95:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                              ^" in 42 as{TypeError} core::String);
+    else
+      #t160.{core::Set::add}(let final<BottomType> #t162 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:39: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>{if (oracle(\"foo\")) 42 else 3.14, null};
+                                      ^" in 3.14 as{TypeError} core::String);
+    #t160.{core::Set::add}(null);
+  } =>#t160;
+  block {
+    final core::Map<core::String, core::String> #t163 = <core::String, core::String>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t163.{core::Map::[]=}("bar", let final<BottomType> #t164 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:46: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
-                   ^", "baz": null};
+                                             ^" in 42 as{TypeError} core::String);
+    else
+      #t163.{core::Map::[]=}("baz", let final<BottomType> #t165 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:61: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String, String>{if (oracle(\"foo\")) \"bar\": 42 else \"baz\": 3.14, \"baz\": null};
+                                                            ^" in 3.14 as{TypeError} core::String);
+    #t163.{core::Map::[]=}("baz", null);
+  } =>#t163;
   block {
-    final core::List<core::int> #t154 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t154.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:96:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::List<core::int> #t166 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t166.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) ...map else 42];
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t154.{core::List::add}(42 as{TypeError} core::int);
-  } =>#t154;
+      #t166.{core::List::add}(42);
+  } =>#t166;
   block {
-    final core::Set<core::int> #t155 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t155.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:97:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t167 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t167.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t155.{core::Set::add}(42 as{TypeError} core::int);
-    #t155.{core::Set::add}(null);
-  } =>#t155;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t167.{core::Set::add}(42);
+    #t167.{core::Set::add}(null);
+  } =>#t167;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
-                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:98:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                      ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:39: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) ...[42] else \"bar\": 42, \"baz\": null};
                                       ^": null};
   block {
-    final core::List<core::int> #t156 = <core::int>[];
-    if(self::oracle<core::String>("foo"))
-      #t156.{core::List::add}(42 as{TypeError} core::int);
+    final core::List<core::int> #t168 = <core::int>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t168.{core::List::add}(42);
     else
-      #t156.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:99:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+      #t168.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:102:39: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[if (oracle(\"foo\")) 42 else ...map];
-                                      ^" as{TypeError} core::int);
-  } =>#t156;
+                                      ^");
+  } =>#t168;
   block {
-    final core::Set<core::int> #t157 = col::LinkedHashSet::•<core::int>();
-    if(self::oracle<core::String>("foo"))
-      #t157.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:100:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+    final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t169.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:103:31: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{if (oracle(\"foo\")) ...map else 42, null};
-                              ^" as{TypeError} core::int);
+                              ^");
     else
-      #t157.{core::Set::add}(42 as{TypeError} core::int);
-    #t157.{core::Set::add}(null);
-  } =>#t157;
-  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+      #t169.{core::Set::add}(42);
+    #t169.{core::Set::add}(null);
+  } =>#t169;
+  <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
-                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:101:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:104:54: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{if (oracle(\"foo\")) \"bar\": 42 else ...[42], \"baz\": null};
                                                      ^": null};
+  core::Set<dynamic> set10 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:106:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  Set<dynamic> set10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                       ^";
+  core::Map<dynamic, dynamic> map10 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:107:53: Error: Expected ':' after this.
+  Map<dynamic, dynamic> map10 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                                                    ^": null};
+  core::Set<dynamic> set11 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:108:24: Error: Both Iterable and Map spread elements encountered in ambiguous literal.
+  Set<dynamic> set11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                       ^";
+  core::Map<dynamic, dynamic> map11 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:109:70: Error: Expected ':' after this.
+  Map<dynamic, dynamic> map11 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                                                                     ^": null};
+  core::Map<<BottomType>, core::Null> map12 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:110:35: Error: Expected ':' after this.
+  var map12 = {if (oracle(\"foo\")) 42 else \"bar\": 3.14};
+                                  ^": null};
+  core::Map<<BottomType>, core::Null> map13 = <<BottomType>, core::Null>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:111:52: Error: Expected ':' after this.
+  var map13 = {if (oracle(\"foo\")) \"bar\": 3.14 else 42};
+                                                   ^": null};
+  core::List<core::int> list20 = block {
+    final core::List<core::int> #t170 = <core::int>[];
+    if(let final<BottomType> #t171 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:112:27: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  List<int> list20 = [if (42) 42];
+                          ^" in 42 as{TypeError} core::bool)
+      #t170.{core::List::add}(42);
+  } =>#t170;
+  core::Set<core::int> set20 = block {
+    final core::Set<core::int> #t172 = col::LinkedHashSet::•<core::int>();
+    if(let final<BottomType> #t173 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:113:25: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  Set<int> set20 = {if (42) 42};
+                        ^" in 42 as{TypeError} core::bool)
+      #t172.{core::Set::add}(42);
+  } =>#t172;
+  core::Map<core::int, core::int> map30 = block {
+    final core::Map<core::int, core::int> #t174 = <core::int, core::int>{};
+    if(let final<BottomType> #t175 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:114:30: Error: A value of type 'int' can't be assigned to a variable of type 'bool'.
+Try changing the type of the left hand side, or casting the right hand side to 'bool'.
+  Map<int, int> map30 = {if (42) 42: 42};
+                             ^" in 42 as{TypeError} core::bool)
+      #t174.{core::Map::[]=}(42, 42);
+  } =>#t174;
+  core::List<core::String> list40 = block {
+    final core::List<core::String> #t176 = <core::String>[];
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t176.{core::List::add}(let final<BottomType> #t177 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:53: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
+                                                    ^" in true as{TypeError} core::String);
+    else
+      #t176.{core::List::add}(let final<BottomType> #t178 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:115:63: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  List<String> list40 = <String>[if (oracle(\"foo\")) true else 42];
+                                                              ^" in 42 as{TypeError} core::String);
+  } =>#t176;
+  core::Set<core::String> set40 = block {
+    final core::Set<core::String> #t179 = col::LinkedHashSet::•<core::String>();
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t179.{core::Set::add}(let final<BottomType> #t180 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:51: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
+                                                  ^" in true as{TypeError} core::String);
+    else
+      #t179.{core::Set::add}(let final<BottomType> #t181 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:116:61: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Set<String> set40 = <String>{if (oracle(\"foo\")) true else 42};
+                                                            ^" in 42 as{TypeError} core::String);
+  } =>#t179;
+  core::Map<core::String, core::int> map40 = block {
+    final core::Map<core::String, core::int> #t182 = <core::String, core::int>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t182.{core::Map::[]=}(let final<BottomType> #t183 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:61: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
+                                                            ^" in true as{TypeError} core::String, 42);
+    else
+      #t182.{core::Map::[]=}(let final<BottomType> #t184 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:117:75: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<String, int> map40 = <String, int>{if (oracle(\"foo\")) true: 42 else 42: 42};
+                                                                          ^" in 42 as{TypeError} core::String, 42);
+  } =>#t182;
+  core::Map<core::int, core::String> map41 = block {
+    final core::Map<core::int, core::String> #t185 = <core::int, core::String>{};
+    if(self::oracle<core::String>("foo") as{TypeError} core::bool)
+      #t185.{core::Map::[]=}(42, let final<BottomType> #t186 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:65: Error: A value of type 'bool' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
+                                                                ^" in true as{TypeError} core::String);
+    else
+      #t185.{core::Map::[]=}(42, let final<BottomType> #t187 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:118:79: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  Map<int, String> map41 = <int, String>{if (oracle(\"foo\")) 42: true else 42: 42};
+                                                                              ^" in 42 as{TypeError} core::String);
+  } =>#t185;
 }
 static method testForElement(dynamic dynVar, core::List<core::int> listInt, core::List<core::double> listDouble, core::int index, core::Map<core::String, core::int> mapStringInt, core::Map<core::String, core::double> mapStringDouble) → dynamic {
   core::List<core::int> list10 = block {
-    final core::List<core::int> #t158 = <core::int>[];
+    final core::List<core::int> #t188 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t158.{core::List::add}(42);
-  } =>#t158;
+      #t188.{core::List::add}(42);
+  } =>#t188;
   core::Set<core::int> set10 = block {
-    final core::Set<core::int> #t159 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t189 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t159.{core::Set::add}(42);
-    #t159.{core::Set::add}(null);
-  } =>#t159;
-  core::Map<core::String, core::int> map10 = block {
-    final core::Map<core::String, core::int> #t160 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t160.{core::Map::[]=}("bar", 42);
-    #t160.{core::Map::[]=}("baz", null);
-  } =>#t160;
-  core::List<dynamic> list11 = block {
-    final core::List<dynamic> #t161 = <dynamic>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t161.{core::List::add}(dynVar);
-  } =>#t161;
-  core::Set<dynamic> set11 = block {
-    final core::Set<dynamic> #t162 = col::LinkedHashSet::•<dynamic>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t162.{core::Set::add}(dynVar);
-    #t162.{core::Set::add}(null);
-  } =>#t162;
-  core::Map<core::String, dynamic> map11 = block {
-    final core::Map<core::String, dynamic> #t163 = <core::String, dynamic>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t163.{core::Map::[]=}("bar", dynVar);
-    #t163.{core::Map::[]=}("baz", null);
-  } =>#t163;
-  core::List<core::List<core::int>> list12 = block {
-    final core::List<core::List<core::int>> #t164 = <core::List<core::int>>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t164.{core::List::add}(<core::int>[42]);
-  } =>#t164;
-  core::Set<core::List<core::int>> set12 = block {
-    final core::Set<core::List<core::int>> #t165 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t165.{core::Set::add}(<core::int>[42]);
-    #t165.{core::Set::add}(null);
-  } =>#t165;
-  core::Map<core::String, core::List<core::int>> map12 = block {
-    final core::Map<core::String, core::List<core::int>> #t166 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t166.{core::Map::[]=}("bar", <core::int>[42]);
-    #t166.{core::Map::[]=}("baz", null);
-  } =>#t166;
-  core::List<core::int> list20 = block {
-    final core::List<core::int> #t167 = <core::int>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t168 in <core::int>[42])
-        #t167.{core::List::add}(#t168);
-  } =>#t167;
-  core::Set<core::int> set20 = block {
-    final core::Set<core::int> #t169 = col::LinkedHashSet::•<core::int>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t170 in <core::int>[42])
-        #t169.{core::Set::add}(#t170);
-    #t169.{core::Set::add}(null);
-  } =>#t169;
-  core::Map<core::String, core::int> map20 = block {
-    final core::Map<core::String, core::int> #t171 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::int> #t172 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
-        #t171.{core::Map::[]=}(#t172.{core::MapEntry::key}, #t172.{core::MapEntry::value});
-    #t171.{core::Map::[]=}("baz", null);
-  } =>#t171;
-  core::List<dynamic> list21 = block {
-    final core::List<dynamic> #t173 = <dynamic>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t174 in <dynamic>[dynVar])
-        #t173.{core::List::add}(#t174);
-  } =>#t173;
-  core::Set<dynamic> set21 = block {
-    final core::Set<dynamic> #t175 = col::LinkedHashSet::•<dynamic>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t176 in <dynamic>[dynVar])
-        #t175.{core::Set::add}(#t176);
-    #t175.{core::Set::add}(null);
-  } =>#t175;
-  core::Map<core::String, dynamic> map21 = block {
-    final core::Map<core::String, dynamic> #t177 = <core::String, dynamic>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, dynamic> #t178 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
-        #t177.{core::Map::[]=}(#t178.{core::MapEntry::key}, #t178.{core::MapEntry::value});
-    #t177.{core::Map::[]=}("baz", null);
-  } =>#t177;
-  core::List<core::List<core::int>> list22 = block {
-    final core::List<core::List<core::int>> #t179 = <core::List<core::int>>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t180 in <core::List<core::int>>[<core::int>[42]])
-        #t179.{core::List::add}(#t180);
-  } =>#t179;
-  core::Set<core::List<core::int>> set22 = block {
-    final core::Set<core::List<core::int>> #t181 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t182 in <core::List<core::int>>[<core::int>[42]])
-        #t181.{core::Set::add}(#t182);
-    #t181.{core::Set::add}(null);
-  } =>#t181;
-  core::Map<core::String, core::List<core::int>> map22 = block {
-    final core::Map<core::String, core::List<core::int>> #t183 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t184 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
-        #t183.{core::Map::[]=}(#t184.{core::MapEntry::key}, #t184.{core::MapEntry::value});
-    #t183.{core::Map::[]=}("baz", null);
-  } =>#t183;
-  core::List<core::int> list30 = block {
-    final core::List<core::int> #t185 = <core::int>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t186 in <core::int>[42])
-          #t185.{core::List::add}(#t186);
-  } =>#t185;
-  core::Set<core::int> set30 = block {
-    final core::Set<core::int> #t187 = col::LinkedHashSet::•<core::int>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t188 in <core::int>[42])
-          #t187.{core::Set::add}(#t188);
-    #t187.{core::Set::add}(null);
-  } =>#t187;
-  core::Map<core::String, core::int> map30 = block {
-    final core::Map<core::String, core::int> #t189 = <core::String, core::int>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::int> #t190 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
-          #t189.{core::Map::[]=}(#t190.{core::MapEntry::key}, #t190.{core::MapEntry::value});
-    #t189.{core::Map::[]=}("baz", null);
+      #t189.{core::Set::add}(42);
+    #t189.{core::Set::add}(null);
   } =>#t189;
-  core::List<dynamic> list31 = block {
+  core::Map<core::String, core::int> map10 = block {
+    final core::Map<core::String, core::int> #t190 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t190.{core::Map::[]=}("bar", 42);
+    #t190.{core::Map::[]=}("baz", null);
+  } =>#t190;
+  core::List<dynamic> list11 = block {
     final core::List<dynamic> #t191 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t192 in <dynamic>[dynVar])
-          #t191.{core::List::add}(#t192);
+      #t191.{core::List::add}(dynVar);
   } =>#t191;
-  core::Set<dynamic> set31 = block {
-    final core::Set<dynamic> #t193 = col::LinkedHashSet::•<dynamic>();
+  core::Set<dynamic> set11 = block {
+    final core::Set<dynamic> #t192 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t194 in <dynamic>[dynVar])
-          #t193.{core::Set::add}(#t194);
-    #t193.{core::Set::add}(null);
+      #t192.{core::Set::add}(dynVar);
+    #t192.{core::Set::add}(null);
+  } =>#t192;
+  core::Map<core::String, dynamic> map11 = block {
+    final core::Map<core::String, dynamic> #t193 = <core::String, dynamic>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t193.{core::Map::[]=}("bar", dynVar);
+    #t193.{core::Map::[]=}("baz", null);
   } =>#t193;
-  core::Map<core::String, dynamic> map31 = block {
-    final core::Map<core::String, dynamic> #t195 = <core::String, dynamic>{};
+  core::List<core::List<core::int>> list12 = block {
+    final core::List<core::List<core::int>> #t194 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, dynamic> #t196 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
-          #t195.{core::Map::[]=}(#t196.{core::MapEntry::key}, #t196.{core::MapEntry::value});
-    #t195.{core::Map::[]=}("baz", null);
+      #t194.{core::List::add}(<core::int>[42]);
+  } =>#t194;
+  core::Set<core::List<core::int>> set12 = block {
+    final core::Set<core::List<core::int>> #t195 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t195.{core::Set::add}(<core::int>[42]);
+    #t195.{core::Set::add}(null);
   } =>#t195;
-  core::List<core::List<core::int>> list33 = block {
-    final core::List<core::List<core::int>> #t197 = <core::List<core::int>>[];
+  core::Map<core::String, core::List<core::int>> map12 = block {
+    final core::Map<core::String, core::List<core::int>> #t196 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t198 in <core::List<core::int>>[<core::int>[42]])
-          #t197.{core::List::add}(#t198);
+      #t196.{core::Map::[]=}("bar", <core::int>[42]);
+    #t196.{core::Map::[]=}("baz", null);
+  } =>#t196;
+  core::List<core::int> list20 = block {
+    final core::List<core::int> #t197 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::int #t198 in <core::int>[42])
+        #t197.{core::List::add}(#t198);
   } =>#t197;
-  core::Set<core::List<core::int>> set33 = block {
-    final core::Set<core::List<core::int>> #t199 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::int> set20 = block {
+    final core::Set<core::int> #t199 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t200 in <core::List<core::int>>[<core::int>[42]])
-          #t199.{core::Set::add}(#t200);
+      for (final core::int #t200 in <core::int>[42])
+        #t199.{core::Set::add}(#t200);
     #t199.{core::Set::add}(null);
   } =>#t199;
-  core::Map<core::String, core::List<core::int>> map33 = block {
-    final core::Map<core::String, core::List<core::int>> #t201 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, core::int> map20 = block {
+    final core::Map<core::String, core::int> #t201 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t202 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
-          #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
+      for (final core::MapEntry<core::String, core::int> #t202 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
+        #t201.{core::Map::[]=}(#t202.{core::MapEntry::key}, #t202.{core::MapEntry::value});
     #t201.{core::Map::[]=}("baz", null);
   } =>#t201;
-  core::List<core::List<core::int>> list40 = block {
-    final core::List<core::List<core::int>> #t203 = <core::List<core::int>>[];
+  core::List<dynamic> list21 = block {
+    final core::List<dynamic> #t203 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t204 in <core::List<core::int>>[<core::int>[]])
+      for (final dynamic #t204 in <dynamic>[dynVar])
         #t203.{core::List::add}(#t204);
   } =>#t203;
-  core::Set<core::List<core::int>> set40 = block {
-    final core::Set<core::List<core::int>> #t205 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<dynamic> set21 = block {
+    final core::Set<dynamic> #t205 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t206 in <core::List<core::int>>[<core::int>[]])
+      for (final dynamic #t206 in <dynamic>[dynVar])
         #t205.{core::Set::add}(#t206);
     #t205.{core::Set::add}(null);
   } =>#t205;
-  core::Map<core::String, core::List<core::int>> map40 = block {
-    final core::Map<core::String, core::List<core::int>> #t207 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, dynamic> map21 = block {
+    final core::Map<core::String, dynamic> #t207 = <core::String, dynamic>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t208 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+      for (final core::MapEntry<core::String, dynamic> #t208 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
         #t207.{core::Map::[]=}(#t208.{core::MapEntry::key}, #t208.{core::MapEntry::value});
     #t207.{core::Map::[]=}("baz", null);
   } =>#t207;
-  core::List<core::List<core::int>> list41 = block {
+  core::List<core::List<core::int>> list22 = block {
     final core::List<core::List<core::int>> #t209 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t210 in let final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t212 = #t211.{core::Set::add}(<core::int>[]) in #t211)
+      for (final core::List<core::int> #t210 in <core::List<core::int>>[<core::int>[42]])
         #t209.{core::List::add}(#t210);
   } =>#t209;
-  core::Set<core::List<core::int>> set41 = block {
-    final core::Set<core::List<core::int>> #t213 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::List<core::int>> set22 = block {
+    final core::Set<core::List<core::int>> #t211 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t214 in let final core::Set<core::List<core::int>> #t215 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t216 = #t215.{core::Set::add}(<core::int>[]) in #t215)
-        #t213.{core::Set::add}(#t214);
-    #t213.{core::Set::add}(null);
+      for (final core::List<core::int> #t212 in <core::List<core::int>>[<core::int>[42]])
+        #t211.{core::Set::add}(#t212);
+    #t211.{core::Set::add}(null);
+  } =>#t211;
+  core::Map<core::String, core::List<core::int>> map22 = block {
+    final core::Map<core::String, core::List<core::int>> #t213 = <core::String, core::List<core::int>>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::MapEntry<core::String, core::List<core::int>> #t214 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
+        #t213.{core::Map::[]=}(#t214.{core::MapEntry::key}, #t214.{core::MapEntry::value});
+    #t213.{core::Map::[]=}("baz", null);
   } =>#t213;
-  core::List<core::List<core::int>> list42 = block {
-    final core::List<core::List<core::int>> #t217 = <core::List<core::int>>[];
+  core::List<core::int> list30 = block {
+    final core::List<core::int> #t215 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t218 in <core::List<core::int>>[<core::int>[]])
-          #t217.{core::List::add}(#t218);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t216 in <core::int>[42])
+          #t215.{core::List::add}(#t216);
+  } =>#t215;
+  core::Set<core::int> set30 = block {
+    final core::Set<core::int> #t217 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t218 in <core::int>[42])
+          #t217.{core::Set::add}(#t218);
+    #t217.{core::Set::add}(null);
   } =>#t217;
-  core::Set<core::List<core::int>> set42 = block {
-    final core::Set<core::List<core::int>> #t219 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Map<core::String, core::int> map30 = block {
+    final core::Map<core::String, core::int> #t219 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t220 in <core::List<core::int>>[<core::int>[]])
-          #t219.{core::Set::add}(#t220);
-    #t219.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::int> #t220 in <core::String, core::int>{"bar": 42}.{core::Map::entries})
+          #t219.{core::Map::[]=}(#t220.{core::MapEntry::key}, #t220.{core::MapEntry::value});
+    #t219.{core::Map::[]=}("baz", null);
   } =>#t219;
-  core::Map<core::String, core::List<core::int>> map42 = block {
-    final core::Map<core::String, core::List<core::int>> #t221 = <core::String, core::List<core::int>>{};
+  core::List<dynamic> list31 = block {
+    final core::List<dynamic> #t221 = <dynamic>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t222 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-          #t221.{core::Map::[]=}(#t222.{core::MapEntry::key}, #t222.{core::MapEntry::value});
-    #t221.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t222 in <dynamic>[dynVar])
+          #t221.{core::List::add}(#t222);
   } =>#t221;
-  core::List<core::int> list50 = block {
-    final core::List<core::int> #t223 = <core::int>[];
+  core::Set<dynamic> set31 = block {
+    final core::Set<dynamic> #t223 = col::LinkedHashSet::•<dynamic>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t224 in <core::int>[])
-        #t223.{core::List::add}(#t224);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t224 in <dynamic>[dynVar])
+          #t223.{core::Set::add}(#t224);
+    #t223.{core::Set::add}(null);
   } =>#t223;
-  core::Set<core::int> set50 = block {
-    final core::Set<core::int> #t225 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, dynamic> map31 = block {
+    final core::Map<core::String, dynamic> #t225 = <core::String, dynamic>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t226 in <core::int>[])
-        #t225.{core::Set::add}(#t226);
-    #t225.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, dynamic> #t226 in <core::String, dynamic>{"bar": dynVar}.{core::Map::entries})
+          #t225.{core::Map::[]=}(#t226.{core::MapEntry::key}, #t226.{core::MapEntry::value});
+    #t225.{core::Map::[]=}("baz", null);
   } =>#t225;
-  core::Map<core::String, core::int> map50 = block {
-    final core::Map<core::String, core::int> #t227 = <core::String, core::int>{};
+  core::List<core::List<core::int>> list33 = block {
+    final core::List<core::List<core::int>> #t227 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::int> #t228 in <core::String, core::int>{}.{core::Map::entries})
-        #t227.{core::Map::[]=}(#t228.{core::MapEntry::key}, #t228.{core::MapEntry::value});
-    #t227.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t228 in <core::List<core::int>>[<core::int>[42]])
+          #t227.{core::List::add}(#t228);
   } =>#t227;
-  core::List<core::int> list51 = block {
-    final core::List<core::int> #t229 = <core::int>[];
+  core::Set<core::List<core::int>> set33 = block {
+    final core::Set<core::List<core::int>> #t229 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t230 in let final core::Set<core::int> #t231 = col::LinkedHashSet::•<core::int>() in #t231)
-        #t229.{core::List::add}(#t230);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t230 in <core::List<core::int>>[<core::int>[42]])
+          #t229.{core::Set::add}(#t230);
+    #t229.{core::Set::add}(null);
   } =>#t229;
-  core::Set<core::int> set51 = block {
-    final core::Set<core::int> #t232 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, core::List<core::int>> map33 = block {
+    final core::Map<core::String, core::List<core::int>> #t231 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::int #t233 in let final core::Set<core::int> #t234 = col::LinkedHashSet::•<core::int>() in #t234)
-        #t232.{core::Set::add}(#t233);
-    #t232.{core::Set::add}(null);
-  } =>#t232;
-  core::List<core::int> list52 = block {
-    final core::List<core::int> #t235 = <core::int>[];
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t232 in <core::String, core::List<core::int>>{"bar": <core::int>[42]}.{core::Map::entries})
+          #t231.{core::Map::[]=}(#t232.{core::MapEntry::key}, #t232.{core::MapEntry::value});
+    #t231.{core::Map::[]=}("baz", null);
+  } =>#t231;
+  core::List<core::List<core::int>> list40 = block {
+    final core::List<core::List<core::int>> #t233 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t236 in <core::int>[])
-          #t235.{core::List::add}(#t236);
+      for (final core::List<core::int> #t234 in <core::List<core::int>>[<core::int>[]])
+        #t233.{core::List::add}(#t234);
+  } =>#t233;
+  core::Set<core::List<core::int>> set40 = block {
+    final core::Set<core::List<core::int>> #t235 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::List<core::int> #t236 in <core::List<core::int>>[<core::int>[]])
+        #t235.{core::Set::add}(#t236);
+    #t235.{core::Set::add}(null);
   } =>#t235;
-  core::Set<core::int> set52 = block {
-    final core::Set<core::int> #t237 = col::LinkedHashSet::•<core::int>();
+  core::Map<core::String, core::List<core::int>> map40 = block {
+    final core::Map<core::String, core::List<core::int>> #t237 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::int #t238 in <core::int>[])
-          #t237.{core::Set::add}(#t238);
-    #t237.{core::Set::add}(null);
+      for (final core::MapEntry<core::String, core::List<core::int>> #t238 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+        #t237.{core::Map::[]=}(#t238.{core::MapEntry::key}, #t238.{core::MapEntry::value});
+    #t237.{core::Map::[]=}("baz", null);
   } =>#t237;
-  core::List<core::List<core::int>> list60 = block {
+  core::List<core::List<core::int>> list41 = block {
     final core::List<core::List<core::int>> #t239 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t240 in <core::List<core::int>>[<core::int>[]])
+      for (final core::List<core::int> #t240 in let final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t242 = #t241.{core::Set::add}(<core::int>[]) in #t241)
         #t239.{core::List::add}(#t240);
   } =>#t239;
-  core::Set<core::List<core::int>> set60 = block {
-    final core::Set<core::List<core::int>> #t241 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::Set<core::List<core::int>> set41 = block {
+    final core::Set<core::List<core::int>> #t243 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::List<core::int> #t242 in <core::List<core::int>>[<core::int>[]])
-        #t241.{core::Set::add}(#t242);
-    #t241.{core::Set::add}(null);
-  } =>#t241;
-  core::Map<core::String, core::List<core::int>> map60 = block {
-    final core::Map<core::String, core::List<core::int>> #t243 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<core::String, core::List<core::int>> #t244 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-        #t243.{core::Map::[]=}(#t244.{core::MapEntry::key}, #t244.{core::MapEntry::value});
-    #t243.{core::Map::[]=}("baz", null);
+      for (final core::List<core::int> #t244 in let final core::Set<core::List<core::int>> #t245 = col::LinkedHashSet::•<core::List<core::int>>() in let final core::bool #t246 = #t245.{core::Set::add}(<core::int>[]) in #t245)
+        #t243.{core::Set::add}(#t244);
+    #t243.{core::Set::add}(null);
   } =>#t243;
-  core::List<core::List<core::int>> list61 = block {
-    final core::List<core::List<core::int>> #t245 = <core::List<core::int>>[];
+  core::List<core::List<core::int>> list42 = block {
+    final core::List<core::List<core::int>> #t247 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::List<core::int> #t246 in <core::List<core::int>>[<core::int>[]])
-          #t245.{core::List::add}(#t246);
-  } =>#t245;
-  core::Set<core::List<core::int>> set61 = block {
-    final core::Set<core::List<core::int>> #t247 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
         for (final core::List<core::int> #t248 in <core::List<core::int>>[<core::int>[]])
-          #t247.{core::Set::add}(#t248);
-    #t247.{core::Set::add}(null);
+          #t247.{core::List::add}(#t248);
   } =>#t247;
-  core::Map<core::String, core::List<core::int>> map61 = block {
-    final core::Map<core::String, core::List<core::int>> #t249 = <core::String, core::List<core::int>>{};
+  core::Set<core::List<core::int>> set42 = block {
+    final core::Set<core::List<core::int>> #t249 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::List<core::int>> #t250 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
-          #t249.{core::Map::[]=}(#t250.{core::MapEntry::key}, #t250.{core::MapEntry::value});
-    #t249.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t250 in <core::List<core::int>>[<core::int>[]])
+          #t249.{core::Set::add}(#t250);
+    #t249.{core::Set::add}(null);
   } =>#t249;
-  core::List<core::List<core::int>> list70 = block {
-    final core::List<core::List<core::int>> #t251 = <core::List<core::int>>[];
+  core::Map<core::String, core::List<core::int>> map42 = block {
+    final core::Map<core::String, core::List<core::int>> #t251 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t251.{core::List::add}(<core::int>[]);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t252 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+          #t251.{core::Map::[]=}(#t252.{core::MapEntry::key}, #t252.{core::MapEntry::value});
+    #t251.{core::Map::[]=}("baz", null);
   } =>#t251;
-  core::Set<core::List<core::int>> set70 = block {
-    final core::Set<core::List<core::int>> #t252 = col::LinkedHashSet::•<core::List<core::int>>();
+  core::List<core::int> list50 = block {
+    final core::List<core::int> #t253 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t252.{core::Set::add}(<core::int>[]);
-    #t252.{core::Set::add}(null);
-  } =>#t252;
-  core::Map<core::String, core::List<core::int>> map70 = block {
-    final core::Map<core::String, core::List<core::int>> #t253 = <core::String, core::List<core::int>>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t253.{core::Map::[]=}("bar", <core::int>[]);
-    #t253.{core::Map::[]=}("baz", null);
+      for (final core::int #t254 in <core::int>[])
+        #t253.{core::List::add}(#t254);
   } =>#t253;
-  core::List<core::List<core::int>> list71 = block {
-    final core::List<core::List<core::int>> #t254 = <core::List<core::int>>[];
+  core::Set<core::int> set50 = block {
+    final core::Set<core::int> #t255 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t254.{core::List::add}(<core::int>[]);
-  } =>#t254;
-  core::Set<core::List<core::int>> set71 = block {
-    final core::Set<core::List<core::int>> #t255 = col::LinkedHashSet::•<core::List<core::int>>();
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t255.{core::Set::add}(<core::int>[]);
+      for (final core::int #t256 in <core::int>[])
+        #t255.{core::Set::add}(#t256);
     #t255.{core::Set::add}(null);
   } =>#t255;
-  core::Map<core::String, core::List<core::int>> map71 = block {
-    final core::Map<core::String, core::List<core::int>> #t256 = <core::String, core::List<core::int>>{};
+  core::Map<core::String, core::int> map50 = block {
+    final core::Map<core::String, core::int> #t257 = <core::String, core::int>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t256.{core::Map::[]=}("bar", <core::int>[]);
-    #t256.{core::Map::[]=}("baz", null);
-  } =>#t256;
-  core::List<core::num> list80 = block {
-    final core::List<core::num> #t257 = <core::num>[];
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t257.{core::List::add}(42);
-      else
-        #t257.{core::List::add}(3.14);
+      for (final core::MapEntry<core::String, core::int> #t258 in <core::String, core::int>{}.{core::Map::entries})
+        #t257.{core::Map::[]=}(#t258.{core::MapEntry::key}, #t258.{core::MapEntry::value});
+    #t257.{core::Map::[]=}("baz", null);
   } =>#t257;
-  core::Set<core::num> set80 = block {
-    final core::Set<core::num> #t258 = col::LinkedHashSet::•<core::num>();
+  core::List<core::int> list51 = block {
+    final core::List<core::int> #t259 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t258.{core::Set::add}(42);
-      else
-        #t258.{core::Set::add}(3.14);
-    #t258.{core::Set::add}(null);
-  } =>#t258;
-  core::Map<core::String, core::num> map80 = block {
-    final core::Map<core::String, core::num> #t259 = <core::String, core::num>{};
-    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t259.{core::Map::[]=}("bar", 42);
-      else
-        #t259.{core::Map::[]=}("bar", 3.14);
-    #t259.{core::Map::[]=}("baz", null);
+      for (final core::int #t260 in let final core::Set<core::int> #t261 = col::LinkedHashSet::•<core::int>() in #t261)
+        #t259.{core::List::add}(#t260);
   } =>#t259;
-  core::List<core::num> list81 = block {
-    final core::List<core::num> #t260 = <core::num>[];
+  core::Set<core::int> set51 = block {
+    final core::Set<core::int> #t262 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t261 in listInt)
-          #t260.{core::List::add}(#t261);
-      else
-        for (final core::num #t262 in listDouble)
-          #t260.{core::List::add}(#t262);
-  } =>#t260;
-  core::Set<core::num> set81 = block {
-    final core::Set<core::num> #t263 = col::LinkedHashSet::•<core::num>();
+      for (final core::int #t263 in let final core::Set<core::int> #t264 = col::LinkedHashSet::•<core::int>() in #t264)
+        #t262.{core::Set::add}(#t263);
+    #t262.{core::Set::add}(null);
+  } =>#t262;
+  core::List<core::int> list52 = block {
+    final core::List<core::int> #t265 = <core::int>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t264 in listInt)
-          #t263.{core::Set::add}(#t264);
-      else
-        for (final core::num #t265 in listDouble)
-          #t263.{core::Set::add}(#t265);
-    #t263.{core::Set::add}(null);
-  } =>#t263;
-  core::Map<core::String, core::num> map81 = block {
-    final core::Map<core::String, core::num> #t266 = <core::String, core::num>{};
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t266 in <core::int>[])
+          #t265.{core::List::add}(#t266);
+  } =>#t265;
+  core::Set<core::int> set52 = block {
+    final core::Set<core::int> #t267 = col::LinkedHashSet::•<core::int>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::num> #t267 in mapStringInt.{core::Map::entries})
-          #t266.{core::Map::[]=}(#t267.{core::MapEntry::key}, #t267.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<core::String, core::num> #t268 in mapStringDouble.{core::Map::entries})
-          #t266.{core::Map::[]=}(#t268.{core::MapEntry::key}, #t268.{core::MapEntry::value});
-    #t266.{core::Map::[]=}("baz", null);
-  } =>#t266;
-  core::List<dynamic> list82 = block {
-    final core::List<dynamic> #t269 = <dynamic>[];
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::int #t268 in <core::int>[])
+          #t267.{core::Set::add}(#t268);
+    #t267.{core::Set::add}(null);
+  } =>#t267;
+  core::List<core::List<core::int>> list60 = block {
+    final core::List<core::List<core::int>> #t269 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t270 in listInt)
-          #t269.{core::List::add}(#t270);
-      else
-        for (final dynamic #t271 in dynVar as{TypeError} core::Iterable<dynamic>)
-          #t269.{core::List::add}(#t271);
+      for (final core::List<core::int> #t270 in <core::List<core::int>>[<core::int>[]])
+        #t269.{core::List::add}(#t270);
   } =>#t269;
-  core::Set<dynamic> set82 = block {
-    final core::Set<dynamic> #t272 = col::LinkedHashSet::•<dynamic>();
+  core::Set<core::List<core::int>> set60 = block {
+    final core::Set<core::List<core::int>> #t271 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final dynamic #t273 in listInt)
-          #t272.{core::Set::add}(#t273);
-      else
-        for (final dynamic #t274 in dynVar as{TypeError} core::Iterable<dynamic>)
-          #t272.{core::Set::add}(#t274);
-    #t272.{core::Set::add}(null);
-  } =>#t272;
-  core::Map<dynamic, dynamic> map82 = block {
-    final core::Map<dynamic, dynamic> #t275 = <dynamic, dynamic>{};
+      for (final core::List<core::int> #t272 in <core::List<core::int>>[<core::int>[]])
+        #t271.{core::Set::add}(#t272);
+    #t271.{core::Set::add}(null);
+  } =>#t271;
+  core::Map<core::String, core::List<core::int>> map60 = block {
+    final core::Map<core::String, core::List<core::int>> #t273 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<dynamic, dynamic> #t276 in mapStringInt.{core::Map::entries})
-          #t275.{core::Map::[]=}(#t276.{core::MapEntry::key}, #t276.{core::MapEntry::value});
-      else
-        for (final core::MapEntry<dynamic, dynamic> #t277 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
-          #t275.{core::Map::[]=}(#t277.{core::MapEntry::key}, #t277.{core::MapEntry::value});
-    #t275.{core::Map::[]=}("baz", null);
+      for (final core::MapEntry<core::String, core::List<core::int>> #t274 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+        #t273.{core::Map::[]=}(#t274.{core::MapEntry::key}, #t274.{core::MapEntry::value});
+    #t273.{core::Map::[]=}("baz", null);
+  } =>#t273;
+  core::List<core::List<core::int>> list61 = block {
+    final core::List<core::List<core::int>> #t275 = <core::List<core::int>>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t276 in <core::List<core::int>>[<core::int>[]])
+          #t275.{core::List::add}(#t276);
   } =>#t275;
-  core::List<core::num> list83 = block {
-    final core::List<core::num> #t278 = <core::num>[];
+  core::Set<core::List<core::int>> set61 = block {
+    final core::Set<core::List<core::int>> #t277 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        #t278.{core::List::add}(42);
-      else
-        for (final core::num #t279 in listDouble)
-          #t278.{core::List::add}(#t279);
-  } =>#t278;
-  core::Set<core::num> set83 = block {
-    final core::Set<core::num> #t280 = col::LinkedHashSet::•<core::num>();
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::List<core::int> #t278 in <core::List<core::int>>[<core::int>[]])
+          #t277.{core::Set::add}(#t278);
+    #t277.{core::Set::add}(null);
+  } =>#t277;
+  core::Map<core::String, core::List<core::int>> map61 = block {
+    final core::Map<core::String, core::List<core::int>> #t279 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::num #t281 in listInt)
-          #t280.{core::Set::add}(#t281);
-      else
-        #t280.{core::Set::add}(3.14);
-    #t280.{core::Set::add}(null);
-  } =>#t280;
-  core::Map<core::String, core::num> map83 = block {
-    final core::Map<core::String, core::num> #t282 = <core::String, core::num>{};
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::List<core::int>> #t280 in <core::String, core::List<core::int>>{"bar": <core::int>[]}.{core::Map::entries})
+          #t279.{core::Map::[]=}(#t280.{core::MapEntry::key}, #t280.{core::MapEntry::value});
+    #t279.{core::Map::[]=}("baz", null);
+  } =>#t279;
+  core::List<core::List<core::int>> list70 = block {
+    final core::List<core::List<core::int>> #t281 = <core::List<core::int>>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      if(self::oracle<dynamic>())
-        for (final core::MapEntry<core::String, core::num> #t283 in mapStringInt.{core::Map::entries})
-          #t282.{core::Map::[]=}(#t283.{core::MapEntry::key}, #t283.{core::MapEntry::value});
-      else
-        #t282.{core::Map::[]=}("bar", 3.14);
-    #t282.{core::Map::[]=}("baz", null);
+      #t281.{core::List::add}(<core::int>[]);
+  } =>#t281;
+  core::Set<core::List<core::int>> set70 = block {
+    final core::Set<core::List<core::int>> #t282 = col::LinkedHashSet::•<core::List<core::int>>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t282.{core::Set::add}(<core::int>[]);
+    #t282.{core::Set::add}(null);
   } =>#t282;
-  core::List<core::int> list90 = block {
-    final core::List<core::int> #t284 = <core::int>[];
+  core::Map<core::String, core::List<core::int>> map70 = block {
+    final core::Map<core::String, core::List<core::int>> #t283 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t284.{core::List::add}(dynVar as{TypeError} core::int);
+      #t283.{core::Map::[]=}("bar", <core::int>[]);
+    #t283.{core::Map::[]=}("baz", null);
+  } =>#t283;
+  core::List<core::List<core::int>> list71 = block {
+    final core::List<core::List<core::int>> #t284 = <core::List<core::int>>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t284.{core::List::add}(<core::int>[]);
   } =>#t284;
-  core::Set<core::int> set90 = block {
-    final core::Set<core::int> #t285 = col::LinkedHashSet::•<core::int>();
+  core::Set<core::List<core::int>> set71 = block {
+    final core::Set<core::List<core::int>> #t285 = col::LinkedHashSet::•<core::List<core::int>>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t285.{core::Set::add}(dynVar as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t285.{core::Set::add}(<core::int>[]);
     #t285.{core::Set::add}(null);
   } =>#t285;
-  core::Map<core::String, core::int> map90 = block {
-    final core::Map<core::String, core::int> #t286 = <core::String, core::int>{};
+  core::Map<core::String, core::List<core::int>> map71 = block {
+    final core::Map<core::String, core::List<core::int>> #t286 = <core::String, core::List<core::int>>{};
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      #t286.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t286.{core::Map::[]=}("bar", <core::int>[]);
     #t286.{core::Map::[]=}("baz", null);
   } =>#t286;
-  core::List<core::int> list91 = block {
-    final core::List<core::int> #t287 = <core::int>[];
+  core::List<core::num> list80 = block {
+    final core::List<core::num> #t287 = <core::num>[];
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t288 in dynVar as{TypeError} core::Iterable<dynamic>) {
-        final core::int #t289 = #t288 as{TypeError} core::int;
-        #t287.{core::List::add}(#t289);
-      }
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t287.{core::List::add}(42);
+      else
+        #t287.{core::List::add}(3.14);
   } =>#t287;
-  core::Set<core::int> set91 = block {
-    final core::Set<core::int> #t290 = col::LinkedHashSet::•<core::int>();
+  core::Set<core::num> set80 = block {
+    final core::Set<core::num> #t288 = col::LinkedHashSet::•<core::num>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final dynamic #t291 in dynVar as{TypeError} core::Iterable<dynamic>) {
-        final core::int #t292 = #t291 as{TypeError} core::int;
-        #t290.{core::Set::add}(#t292);
-      }
-    #t290.{core::Set::add}(null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t288.{core::Set::add}(42);
+      else
+        #t288.{core::Set::add}(3.14);
+    #t288.{core::Set::add}(null);
+  } =>#t288;
+  core::Map<core::String, core::num> map80 = block {
+    final core::Map<core::String, core::num> #t289 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t289.{core::Map::[]=}("bar", 42);
+      else
+        #t289.{core::Map::[]=}("bar", 3.14);
+    #t289.{core::Map::[]=}("baz", null);
+  } =>#t289;
+  core::List<core::num> list81 = block {
+    final core::List<core::num> #t290 = <core::num>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t291 in listInt)
+          #t290.{core::List::add}(#t291);
+      else
+        for (final core::num #t292 in listDouble)
+          #t290.{core::List::add}(#t292);
   } =>#t290;
-  core::Map<core::String, core::int> map91 = block {
-    final core::Map<core::String, core::int> #t293 = <core::String, core::int>{};
+  core::Set<core::num> set81 = block {
+    final core::Set<core::num> #t293 = col::LinkedHashSet::•<core::num>();
     for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-      for (final core::MapEntry<dynamic, dynamic> #t294 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
-        final core::String #t295 = #t294.{core::MapEntry::key} as{TypeError} core::String;
-        final core::int #t296 = #t294.{core::MapEntry::value} as{TypeError} core::int;
-        #t293.{core::Map::[]=}(#t295, #t296);
-      }
-    #t293.{core::Map::[]=}("baz", null);
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t294 in listInt)
+          #t293.{core::Set::add}(#t294);
+      else
+        for (final core::num #t295 in listDouble)
+          #t293.{core::Set::add}(#t295);
+    #t293.{core::Set::add}(null);
   } =>#t293;
-  core::List<core::int> list100 = block {
-    final core::List<core::int> #t297 = <core::int>[];
-    for (final dynamic #t298 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t297.{core::List::add}(42);
-  } =>#t297;
-  core::Set<core::int> set100 = block {
-    final core::Set<core::int> #t299 = col::LinkedHashSet::•<core::int>();
-    for (final dynamic #t300 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t299.{core::Set::add}(42);
+  core::Map<core::String, core::num> map81 = block {
+    final core::Map<core::String, core::num> #t296 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::num> #t297 in mapStringInt.{core::Map::entries})
+          #t296.{core::Map::[]=}(#t297.{core::MapEntry::key}, #t297.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<core::String, core::num> #t298 in mapStringDouble.{core::Map::entries})
+          #t296.{core::Map::[]=}(#t298.{core::MapEntry::key}, #t298.{core::MapEntry::value});
+    #t296.{core::Map::[]=}("baz", null);
+  } =>#t296;
+  core::List<dynamic> list82 = block {
+    final core::List<dynamic> #t299 = <dynamic>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t300 in listInt)
+          #t299.{core::List::add}(#t300);
+      else
+        for (final dynamic #t301 in dynVar as{TypeError} core::Iterable<dynamic>)
+          #t299.{core::List::add}(#t301);
   } =>#t299;
-  core::Map<core::String, core::int> map100 = block {
-    final core::Map<core::String, core::int> #t301 = <core::String, core::int>{};
-    for (final dynamic #t302 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
-      #t301.{core::Map::[]=}("bar", 42);
-  } =>#t301;
-  core::List<core::int> list110 = block {
-    final core::List<core::int> #t303 = <core::int>[];
-    for (core::int i in <core::int>[1, 2, 3])
-      #t303.{core::List::add}(i);
-  } =>#t303;
-  core::Set<core::int> set110 = block {
-    final core::Set<core::int> #t304 = col::LinkedHashSet::•<core::int>();
-    for (core::int i in <core::int>[1, 2, 3])
-      #t304.{core::Set::add}(i);
-    #t304.{core::Set::add}(null);
-  } =>#t304;
-  core::Map<core::String, core::int> map110 = block {
-    final core::Map<core::String, core::int> #t305 = <core::String, core::int>{};
-    for (core::int i in <core::int>[1, 2, 3])
-      #t305.{core::Map::[]=}("bar", i);
+  core::Set<dynamic> set82 = block {
+    final core::Set<dynamic> #t302 = col::LinkedHashSet::•<dynamic>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final dynamic #t303 in listInt)
+          #t302.{core::Set::add}(#t303);
+      else
+        for (final dynamic #t304 in dynVar as{TypeError} core::Iterable<dynamic>)
+          #t302.{core::Set::add}(#t304);
+    #t302.{core::Set::add}(null);
+  } =>#t302;
+  core::Map<dynamic, dynamic> map82 = block {
+    final core::Map<dynamic, dynamic> #t305 = <dynamic, dynamic>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<dynamic, dynamic> #t306 in mapStringInt.{core::Map::entries})
+          #t305.{core::Map::[]=}(#t306.{core::MapEntry::key}, #t306.{core::MapEntry::value});
+      else
+        for (final core::MapEntry<dynamic, dynamic> #t307 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries})
+          #t305.{core::Map::[]=}(#t307.{core::MapEntry::key}, #t307.{core::MapEntry::value});
     #t305.{core::Map::[]=}("baz", null);
   } =>#t305;
-  core::List<core::int> list120 = block {
-    final core::List<core::int> #t306 = <core::int>[];
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t306.{core::List::add}(i as{TypeError} core::int);
-  } =>#t306;
-  core::Set<core::int> set120 = block {
-    final core::Set<core::int> #t307 = col::LinkedHashSet::•<core::int>();
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t307.{core::Set::add}(i as{TypeError} core::int);
-    #t307.{core::Set::add}(null);
-  } =>#t307;
-  core::Map<core::String, core::int> map120 = block {
-    final core::Map<core::String, core::int> #t308 = <core::String, core::int>{};
-    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
-      #t308.{core::Map::[]=}("bar", i as{TypeError} core::int);
-    #t308.{core::Map::[]=}("baz", null);
+  core::List<core::num> list83 = block {
+    final core::List<core::num> #t308 = <core::num>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        #t308.{core::List::add}(42);
+      else
+        for (final core::num #t309 in listDouble)
+          #t308.{core::List::add}(#t309);
   } =>#t308;
+  core::Set<core::num> set83 = block {
+    final core::Set<core::num> #t310 = col::LinkedHashSet::•<core::num>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::num #t311 in listInt)
+          #t310.{core::Set::add}(#t311);
+      else
+        #t310.{core::Set::add}(3.14);
+    #t310.{core::Set::add}(null);
+  } =>#t310;
+  core::Map<core::String, core::num> map83 = block {
+    final core::Map<core::String, core::num> #t312 = <core::String, core::num>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      if(self::oracle<dynamic>() as{TypeError} core::bool)
+        for (final core::MapEntry<core::String, core::num> #t313 in mapStringInt.{core::Map::entries})
+          #t312.{core::Map::[]=}(#t313.{core::MapEntry::key}, #t313.{core::MapEntry::value});
+      else
+        #t312.{core::Map::[]=}("bar", 3.14);
+    #t312.{core::Map::[]=}("baz", null);
+  } =>#t312;
+  core::List<core::int> list90 = block {
+    final core::List<core::int> #t314 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t314.{core::List::add}(dynVar as{TypeError} core::int);
+  } =>#t314;
+  core::Set<core::int> set90 = block {
+    final core::Set<core::int> #t315 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t315.{core::Set::add}(dynVar as{TypeError} core::int);
+    #t315.{core::Set::add}(null);
+  } =>#t315;
+  core::Map<core::String, core::int> map90 = block {
+    final core::Map<core::String, core::int> #t316 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      #t316.{core::Map::[]=}("bar", dynVar as{TypeError} core::int);
+    #t316.{core::Map::[]=}("baz", null);
+  } =>#t316;
+  core::List<core::int> list91 = block {
+    final core::List<core::int> #t317 = <core::int>[];
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final dynamic #t318 in dynVar as{TypeError} core::Iterable<dynamic>) {
+        final core::int #t319 = #t318 as{TypeError} core::int;
+        #t317.{core::List::add}(#t319);
+      }
+  } =>#t317;
+  core::Set<core::int> set91 = block {
+    final core::Set<core::int> #t320 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final dynamic #t321 in dynVar as{TypeError} core::Iterable<dynamic>) {
+        final core::int #t322 = #t321 as{TypeError} core::int;
+        #t320.{core::Set::add}(#t322);
+      }
+    #t320.{core::Set::add}(null);
+  } =>#t320;
+  core::Map<core::String, core::int> map91 = block {
+    final core::Map<core::String, core::int> #t323 = <core::String, core::int>{};
+    for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+      for (final core::MapEntry<dynamic, dynamic> #t324 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
+        final core::String #t325 = #t324.{core::MapEntry::key} as{TypeError} core::String;
+        final core::int #t326 = #t324.{core::MapEntry::value} as{TypeError} core::int;
+        #t323.{core::Map::[]=}(#t325, #t326);
+      }
+    #t323.{core::Map::[]=}("baz", null);
+  } =>#t323;
+  core::List<core::int> list100 = block {
+    final core::List<core::int> #t327 = <core::int>[];
+    for (final core::int #t328 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t327.{core::List::add}(42);
+  } =>#t327;
+  core::Set<core::int> set100 = block {
+    final core::Set<core::int> #t329 = col::LinkedHashSet::•<core::int>();
+    for (final core::int #t330 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t329.{core::Set::add}(42);
+  } =>#t329;
+  core::Map<core::String, core::int> map100 = block {
+    final core::Map<core::String, core::int> #t331 = <core::String, core::int>{};
+    for (final core::int #t332 = index = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; index = index.{core::num::+}(1))
+      #t331.{core::Map::[]=}("bar", 42);
+  } =>#t331;
+  core::List<core::int> list110 = block {
+    final core::List<core::int> #t333 = <core::int>[];
+    for (core::int i in <core::int>[1, 2, 3])
+      #t333.{core::List::add}(i);
+  } =>#t333;
+  core::Set<core::int> set110 = block {
+    final core::Set<core::int> #t334 = col::LinkedHashSet::•<core::int>();
+    for (core::int i in <core::int>[1, 2, 3])
+      #t334.{core::Set::add}(i);
+    #t334.{core::Set::add}(null);
+  } =>#t334;
+  core::Map<core::String, core::int> map110 = block {
+    final core::Map<core::String, core::int> #t335 = <core::String, core::int>{};
+    for (core::int i in <core::int>[1, 2, 3])
+      #t335.{core::Map::[]=}("bar", i);
+    #t335.{core::Map::[]=}("baz", null);
+  } =>#t335;
+  core::List<core::int> list120 = block {
+    final core::List<core::int> #t336 = <core::int>[];
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t336.{core::List::add}(i as{TypeError} core::int);
+  } =>#t336;
+  core::Set<core::int> set120 = block {
+    final core::Set<core::int> #t337 = col::LinkedHashSet::•<core::int>();
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t337.{core::Set::add}(i as{TypeError} core::int);
+    #t337.{core::Set::add}(null);
+  } =>#t337;
+  core::Map<core::String, core::int> map120 = block {
+    final core::Map<core::String, core::int> #t338 = <core::String, core::int>{};
+    for (dynamic i in dynVar as{TypeError} core::Iterable<dynamic>)
+      #t338.{core::Map::[]=}("bar", i as{TypeError} core::int);
+    #t338.{core::Map::[]=}("baz", null);
+  } =>#t338;
+  core::List<core::int> list130 = block {
+    final core::List<core::int> #t339 = <core::int>[];
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t339.{core::List::add}(i);
+  } =>#t339;
+  core::Set<core::int> set130 = block {
+    final core::Set<core::int> #t340 = col::LinkedHashSet::•<core::int>();
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t340.{core::Set::add}(i);
+  } =>#t340;
+  core::Map<core::int, core::int> map130 = block {
+    final core::Map<core::int, core::int> #t341 = <core::int, core::int>{};
+    for (core::int i = 1; i.{core::num::<}(2); i = i.{core::num::+}(1))
+      #t341.{core::Map::[]=}(i, i);
+  } =>#t341;
 }
 static method testForElementErrors(core::Map<core::int, core::int> map, core::List<core::int> list) → dynamic /* originally async */ {
   final asy::_AsyncAwaitCompleter<dynamic> :async_completer = new asy::_AsyncAwaitCompleter::•<dynamic>();
@@ -1634,249 +1900,295 @@
     try {
       #L1:
       {
-        <core::int>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:190:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+        block {
+          final core::List<core::int> #t342 = <core::int>[];
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            #t342.{core::List::add}(let final<BottomType> #t343 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) \"bar\"];
-                                            ^"];
-        let final core::Set<core::int> #t309 = col::LinkedHashSet::•<core::int>() in let final core::bool #t310 = #t309.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:191:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                            ^" in "bar" as{TypeError} core::int);
+        } =>#t342;
+        block {
+          final core::Set<core::int> #t344 = col::LinkedHashSet::•<core::int>();
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            #t344.{core::Set::add}(let final<BottomType> #t345 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:45: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\", null};
-                                            ^") in let final core::bool #t311 = #t309.{core::Set::add}(null) in #t309;
-        <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-             ^": invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:14: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-             ^", let final<BottomType> #t312 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:192:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
-Try changing the type of the left hand side, or casting the right hand side to 'int'.
-  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
-                                                               ^" in "baz" as{TypeError} core::int: null};
+                                            ^" in "bar" as{TypeError} core::int);
+          #t344.{core::Set::add}(null);
+        } =>#t344;
         block {
-          final core::List<core::int> #t313 = <core::int>[];
+          final core::Map<core::int, core::int> #t346 = <core::int, core::int>{};
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            for (final core::int #t314 in <core::int>[let final<BottomType> #t315 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:193:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            #t346.{core::Map::[]=}(let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:50: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                 ^" in "bar" as{TypeError} core::int, let final<BottomType> #t348 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                        ^" in "bar" as{TypeError} core::int);
+          #t346.{core::Map::[]=}(let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+Try changing the type of the left hand side, or casting the right hand side to 'int'.
+  <int, int>{for (int i = 0; oracle(\"foo\"); i++) \"bar\": \"bar\", \"baz\": null};
+                                                               ^" in "baz" as{TypeError} core::int, null);
+        } =>#t346;
+        block {
+          final core::List<core::int> #t350 = <core::int>[];
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            for (final core::int #t351 in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:213:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"]];
                                                 ^" in "bar" as{TypeError} core::int])
-              #t313.{core::List::add}(#t314);
-        } =>#t313;
+              #t350.{core::List::add}(#t351);
+        } =>#t350;
         block {
-          final core::Set<core::int> #t316 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t353 = col::LinkedHashSet::•<core::int>();
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            for (final core::int #t317 in <core::int>[let final<BottomType> #t318 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:194:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            for (final core::int #t354 in <core::int>[let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:49: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...[\"bar\"], null};
                                                 ^" in "bar" as{TypeError} core::int])
-              #t316.{core::Set::add}(#t317);
-          #t316.{core::Set::add}(null);
-        } =>#t316;
+              #t353.{core::Set::add}(#t354);
+          #t353.{core::Set::add}(null);
+        } =>#t353;
         block {
-          final core::Map<core::int, core::int> #t319 = <core::int, core::int>{};
+          final core::Map<core::int, core::int> #t356 = <core::int, core::int>{};
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            for (final core::MapEntry<core::int, core::int> #t320 in <core::int, core::int>{let final<BottomType> #t321 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+            for (final core::MapEntry<core::int, core::int> #t357 in <core::int, core::int>{let final<BottomType> #t358 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:54: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
-                                                     ^" in "bar" as{TypeError} core::int: let final<BottomType> #t322 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                     ^" in "bar" as{TypeError} core::int: let final<BottomType> #t359 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:61: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                             ^" in "bar" as{TypeError} core::int}.{core::Map::entries})
-              #t319.{core::Map::[]=}(#t320.{core::MapEntry::key}, #t320.{core::MapEntry::value});
-          #t319.{core::Map::[]=}(let final<BottomType> #t323 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:195:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+              #t356.{core::Map::[]=}(#t357.{core::MapEntry::key}, #t357.{core::MapEntry::value});
+          #t356.{core::Map::[]=}(let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:69: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...{\"bar\": \"bar\"}, \"baz\": null};
                                                                     ^" in "baz" as{TypeError} core::int, null);
-        } =>#t319;
+        } =>#t356;
         block {
-          final core::List<core::int> #t324 = <core::int>[];
+          final core::List<core::int> #t361 = <core::int>[];
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            #t324.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:196:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t361.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) ...map];
-                                               ^" as{TypeError} core::int);
-        } =>#t324;
+                                               ^");
+        } =>#t361;
         block {
-          final core::Set<core::int> #t325 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t362 = col::LinkedHashSet::•<core::int>();
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            #t325.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:197:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            #t362.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:48: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) ...map, null};
-                                               ^" as{TypeError} core::int);
-          #t325.{core::Set::add}(null);
-        } =>#t325;
-        <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                               ^");
+          #t362.{core::Set::add}(null);
+        } =>#t362;
+        <core::int, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
-                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:198:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:53: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <int, int>{for (int i = 0; oracle(\"foo\"); i++) ...list, 42: null};
                                                     ^": null};
-        <core::String>[invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:199:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+        block {
+          final core::List<core::String> #t363 = <core::String>[];
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t363.{core::List::add}(let final<BottomType> #t364 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
-                                               ^"];
-        let final core::Set<core::String> #t326 = col::LinkedHashSet::•<core::String>() in let final core::bool #t327 = #t326.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:200:48: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                                                             ^" in 42 as{TypeError} core::String);
+            else
+              #t363.{core::List::add}(let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14];
+                                                                     ^" in 3.14 as{TypeError} core::String);
+        } =>#t363;
+        block {
+          final core::Set<core::String> #t366 = col::LinkedHashSet::•<core::String>();
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t366.{core::Set::add}(let final<BottomType> #t367 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:62: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
-                                               ^") in let final core::bool #t328 = #t326.{core::Set::add}(null) in #t326;
-        <core::String, core::String>{null: invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:201:20: Error: A value of type 'num' can't be assigned to a variable of type 'String'.
+                                                             ^" in 42 as{TypeError} core::String);
+            else
+              #t366.{core::Set::add}(let final<BottomType> #t368 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:70: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else 3.14, null};
+                                                                     ^" in 3.14 as{TypeError} core::String);
+          #t366.{core::Set::add}(null);
+        } =>#t366;
+        block {
+          final core::Map<core::String, core::String> #t369 = <core::String, core::String>{};
+          for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t369.{core::Map::[]=}("bar", let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:77: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
 Try changing the type of the left hand side, or casting the right hand side to 'String'.
   <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
-                   ^", "baz": null};
+                                                                            ^" in 42 as{TypeError} core::String);
+            else
+              #t369.{core::Map::[]=}("bar", let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:92: Error: A value of type 'double' can't be assigned to a variable of type 'String'.
+Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  <String, String>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else \"bar\": 3.14, \"baz\": null};
+                                                                                           ^" in 3.14 as{TypeError} core::String);
+          #t369.{core::Map::[]=}("baz", null);
+        } =>#t369;
         block {
-          final core::List<core::int> #t329 = <core::int>[];
+          final core::List<core::int> #t372 = <core::int>[];
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            if(self::oracle<dynamic>())
-              #t329.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:202:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t372.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42];
-                                                             ^" as{TypeError} core::int);
+                                                             ^");
             else
-              #t329.{core::List::add}(42 as{TypeError} core::int);
-        } =>#t329;
+              #t372.{core::List::add}(42);
+        } =>#t372;
         block {
-          final core::Set<core::int> #t330 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t373 = col::LinkedHashSet::•<core::int>();
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            if(self::oracle<dynamic>())
-              #t330.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:203:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t373.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:62: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...map else 42, null};
-                                                             ^" as{TypeError} core::int);
+                                                             ^");
             else
-              #t330.{core::Set::add}(42 as{TypeError} core::int);
-          #t330.{core::Set::add}(null);
-        } =>#t330;
-        <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+              #t373.{core::Set::add}(42);
+          #t373.{core::Set::add}(null);
+        } =>#t373;
+        <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
-                                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:204:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                     ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:70: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) ...list else \"bar\": 42, \"baz\": null};
                                                                      ^": null};
         block {
-          final core::List<core::int> #t331 = <core::int>[];
+          final core::List<core::int> #t374 = <core::int>[];
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            if(self::oracle<dynamic>())
-              #t331.{core::List::add}(42 as{TypeError} core::int);
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t374.{core::List::add}(42);
             else
-              #t331.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:205:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t374.{core::List::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>[for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map];
-                                                                     ^" as{TypeError} core::int);
-        } =>#t331;
+                                                                     ^");
+        } =>#t374;
         block {
-          final core::Set<core::int> #t332 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>();
           for (core::int i = 0; self::oracle<core::String>("foo") as{TypeError} core::bool; i = i.{core::num::+}(1))
-            if(self::oracle<dynamic>())
-              #t332.{core::Set::add}(42 as{TypeError} core::int);
+            if(self::oracle<dynamic>() as{TypeError} core::bool)
+              #t375.{core::Set::add}(42);
             else
-              #t332.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:206:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
+              #t375.{core::Set::add}(invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:226:70: Error: Unexpected type 'Map<int, int>' of a spread.  Expected 'dynamic' or an Iterable.
  - 'Map' is from 'dart:core'.
   <int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) 42 else ...map, null};
-                                                                     ^" as{TypeError} core::int);
-          #t332.{core::Set::add}(null);
-        } =>#t332;
-        <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                     ^");
+          #t375.{core::Set::add}(null);
+        } =>#t375;
+        <core::String, core::int>{invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
-                                                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:207:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
+                                                                                    ^": null, invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:227:85: Error: Unexpected type 'List<int>' of a map spread entry.  Expected 'dynamic' or a Map.
  - 'List' is from 'dart:core'.
   <String, int>{for (int i = 0; oracle(\"foo\"); i++) if (oracle()) \"bar\": 42 else ...list, \"baz\": null};
                                                                                     ^": null};
         final core::int i = 0;
         block {
-          final core::List<core::int> #t333 = <core::int>[];
-          for (final core::int #t334 in <core::int>[1]) {
-            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:210:14: Error: Setter not found: 'i'.
+          final core::List<core::int> #t376 = <core::int>[];
+          for (final core::int #t377 in <core::int>[1]) {
+            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:14: Error: Setter not found: 'i'.
   <int>[for (i in <int>[1]) i];
              ^";
-            #t333.{core::List::add}(i);
+            #t376.{core::List::add}(i);
           }
-        } =>#t333;
+        } =>#t376;
         block {
-          final core::Set<core::int> #t335 = col::LinkedHashSet::•<core::int>();
-          for (final core::int #t336 in <core::int>[1]) {
-            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:211:14: Error: Setter not found: 'i'.
+          final core::Set<core::int> #t378 = col::LinkedHashSet::•<core::int>();
+          for (final core::int #t379 in <core::int>[1]) {
+            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:14: Error: Setter not found: 'i'.
   <int>{for (i in <int>[1]) i, null};
              ^";
-            #t335.{core::Set::add}(i);
+            #t378.{core::Set::add}(i);
           }
-          #t335.{core::Set::add}(null);
-        } =>#t335;
+          #t378.{core::Set::add}(null);
+        } =>#t378;
         block {
-          final core::Map<core::String, core::int> #t337 = <core::String, core::int>{};
-          for (final core::int #t338 in <core::int>[1]) {
-            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:212:21: Error: Setter not found: 'i'.
+          final core::Map<core::String, core::int> #t380 = <core::String, core::int>{};
+          for (final core::int #t381 in <core::int>[1]) {
+            invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:232:21: Error: Setter not found: 'i'.
 \t<String, int>{for (i in <int>[1]) \"bar\": i, \"baz\": null};
 \t                   ^";
-            #t337.{core::Map::[]=}("bar", i);
+            #t380.{core::Map::[]=}("bar", i);
           }
-          #t337.{core::Map::[]=}("baz", null);
-        } =>#t337;
+          #t380.{core::Map::[]=}("baz", null);
+        } =>#t380;
         core::List<dynamic> list10 = block {
-          final core::List<dynamic> #t339 = <dynamic>[];
-          for (dynamic i in let final<BottomType> #t340 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:214:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+          final core::List<dynamic> #t382 = <dynamic>[];
+          for (dynamic i in let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:234:31: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var list10 = [for (var i in \"not iterable\") i];
                               ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-            #t339.{core::List::add}(i);
-        } =>#t339;
+            #t382.{core::List::add}(i);
+        } =>#t382;
         core::Set<dynamic> set10 = block {
-          final core::Set<dynamic> #t341 = col::LinkedHashSet::•<dynamic>();
-          for (dynamic i in let final<BottomType> #t342 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:215:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+          final core::Set<dynamic> #t384 = col::LinkedHashSet::•<dynamic>();
+          for (dynamic i in let final<BottomType> #t385 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:235:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var set10 = {for (var i in \"not iterable\") i, null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-            #t341.{core::Set::add}(i);
-          #t341.{core::Set::add}(null);
-        } =>#t341;
+            #t384.{core::Set::add}(i);
+          #t384.{core::Set::add}(null);
+        } =>#t384;
         core::Map<core::String, dynamic> map10 = block {
-          final core::Map<core::String, dynamic> #t343 = <core::String, dynamic>{};
-          for (dynamic i in let final<BottomType> #t344 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:216:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
+          final core::Map<core::String, dynamic> #t386 = <core::String, dynamic>{};
+          for (dynamic i in let final<BottomType> #t387 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:236:30: Error: The type 'String' used in the 'for' loop must implement 'Iterable<dynamic>'.
  - 'Iterable' is from 'dart:core'.
   var map10 = {for (var i in \"not iterable\") \"bar\": i, \"baz\": null};
                              ^" in "not iterable" as{TypeError} core::Iterable<dynamic>)
-            #t343.{core::Map::[]=}("bar", i);
-          #t343.{core::Map::[]=}("baz", null);
-        } =>#t343;
+            #t386.{core::Map::[]=}("bar", i);
+          #t386.{core::Map::[]=}("baz", null);
+        } =>#t386;
         core::List<core::int> list20 = block {
-          final core::List<core::int> #t345 = <core::int>[];
-          for (core::int i in <core::int>[let final<BottomType> #t346 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::List<core::int> #t388 = <core::int>[];
+          for (core::int i in <core::int>[let final<BottomType> #t389 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:32: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
-                               ^" in "not" as{TypeError} core::int, let final<BottomType> #t347 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:217:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                               ^" in "not" as{TypeError} core::int, let final<BottomType> #t390 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:237:39: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list20 = [for (int i in [\"not\", \"int\"]) i];
                                       ^" in "int" as{TypeError} core::int])
-            #t345.{core::List::add}(i);
-        } =>#t345;
+            #t388.{core::List::add}(i);
+        } =>#t388;
         core::Set<core::int> set20 = block {
-          final core::Set<core::int> #t348 = col::LinkedHashSet::•<core::int>();
-          for (core::int i in <core::int>[let final<BottomType> #t349 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::Set<core::int> #t391 = col::LinkedHashSet::•<core::int>();
+          for (core::int i in <core::int>[let final<BottomType> #t392 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
-                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t350 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:218:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:238:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set20 = {for (int i in [\"not\", \"int\"]) i, null};
                                      ^" in "int" as{TypeError} core::int])
-            #t348.{core::Set::add}(i);
-          #t348.{core::Set::add}(null);
-        } =>#t348;
+            #t391.{core::Set::add}(i);
+          #t391.{core::Set::add}(null);
+        } =>#t391;
         core::Map<core::String, core::int> map20 = block {
-          final core::Map<core::String, core::int> #t351 = <core::String, core::int>{};
-          for (core::int i in <core::int>[let final<BottomType> #t352 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          final core::Map<core::String, core::int> #t394 = <core::String, core::int>{};
+          for (core::int i in <core::int>[let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:31: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
-                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t353 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:219:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                              ^" in "not" as{TypeError} core::int, let final<BottomType> #t396 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:239:38: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map20 = {for (int i in [\"not\", \"int\"]) \"bar\": i, \"baz\": null};
                                      ^" in "int" as{TypeError} core::int])
-            #t351.{core::Map::[]=}("bar", i);
-          #t351.{core::Map::[]=}("baz", null);
-        } =>#t351;
-        final core::List<dynamic> #t354 = <dynamic>[];
+            #t394.{core::Map::[]=}("bar", i);
+          #t394.{core::Map::[]=}("baz", null);
+        } =>#t394;
+        final core::List<dynamic> #t397 = <dynamic>[];
         {
-          dynamic :stream = let final<BottomType> #t355 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:220:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          dynamic :stream = let final<BottomType> #t398 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:240:37: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var list30 = [await for (var i in \"not stream\") i];
                                     ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
@@ -1886,25 +2198,25 @@
           try
             #L2:
             while (true) {
-              dynamic #t356 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t357 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t399 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t400 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t354.{core::List::add}(i);
+                #t397.{core::List::add}(i);
               }
               else
                 break #L2;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t358 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t401 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<dynamic> list30 = block {} =>#t354;
-        final core::Set<dynamic> #t359 = col::LinkedHashSet::•<dynamic>();
+        core::List<dynamic> list30 = block {} =>#t397;
+        final core::Set<dynamic> #t402 = col::LinkedHashSet::•<dynamic>();
         {
-          dynamic :stream = let final<BottomType> #t360 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:221:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          dynamic :stream = let final<BottomType> #t403 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:241:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var set30 = {await for (var i in \"not stream\") i, null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
@@ -1914,27 +2226,27 @@
           try
             #L3:
             while (true) {
-              dynamic #t361 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t362 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t404 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t405 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t359.{core::Set::add}(i);
+                #t402.{core::Set::add}(i);
               }
               else
                 break #L3;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t363 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t406 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<dynamic> set30 = block {
-          #t359.{core::Set::add}(null);
-        } =>#t359;
-        final core::Map<core::String, dynamic> #t364 = <core::String, dynamic>{};
+          #t402.{core::Set::add}(null);
+        } =>#t402;
+        final core::Map<core::String, dynamic> #t407 = <core::String, dynamic>{};
         {
-          dynamic :stream = let final<BottomType> #t365 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:222:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
+          dynamic :stream = let final<BottomType> #t408 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:242:36: Error: The type 'String' used in the 'for' loop must implement 'Stream<dynamic>'.
  - 'Stream' is from 'dart:async'.
   var map30 = {await for (var i in \"not stream\") \"bar\": i, \"baz\": null};
                                    ^" in "not stream" as{TypeError} asy::Stream<dynamic>;
@@ -1944,30 +2256,30 @@
           try
             #L4:
             while (true) {
-              dynamic #t366 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t367 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t409 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t410 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 dynamic i = :for-iterator.{asy::_StreamIterator::current};
-                #t364.{core::Map::[]=}("bar", i);
+                #t407.{core::Map::[]=}("bar", i);
               }
               else
                 break #L4;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t368 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t411 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String, dynamic> map30 = block {
-          #t364.{core::Map::[]=}("baz", null);
-        } =>#t364;
-        final core::List<core::int> #t369 = <core::int>[];
+          #t407.{core::Map::[]=}("baz", null);
+        } =>#t407;
+        final core::List<core::int> #t412 = <core::int>[];
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t370 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t413 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:58: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
-                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t371 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:223:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                         ^" in "not" as{TypeError} core::int, let final<BottomType> #t414 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:243:65: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var list40 = [await for (int i in Stream.fromIterable([\"not\", \"int\"])) i];
                                                                 ^" in "int" as{TypeError} core::int]);
@@ -1977,28 +2289,28 @@
           try
             #L5:
             while (true) {
-              dynamic #t372 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t373 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t415 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t416 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 core::int i = :for-iterator.{asy::_StreamIterator::current};
-                #t369.{core::List::add}(i);
+                #t412.{core::List::add}(i);
               }
               else
                 break #L5;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t374 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t417 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
-        core::List<core::int> list40 = block {} =>#t369;
-        final core::Set<core::int> #t375 = col::LinkedHashSet::•<core::int>();
+        core::List<core::int> list40 = block {} =>#t412;
+        final core::Set<core::int> #t418 = col::LinkedHashSet::•<core::int>();
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t376 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t419 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t377 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:224:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t420 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:244:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var set40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) i, null};
                                                                ^" in "int" as{TypeError} core::int]);
@@ -2008,30 +2320,30 @@
           try
             #L6:
             while (true) {
-              dynamic #t378 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t379 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t421 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t422 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 core::int i = :for-iterator.{asy::_StreamIterator::current};
-                #t375.{core::Set::add}(i);
+                #t418.{core::Set::add}(i);
               }
               else
                 break #L6;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t380 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t423 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Set<core::int> set40 = block {
-          #t375.{core::Set::add}(null);
-        } =>#t375;
-        final core::Map<core::String, core::int> #t381 = <core::String, core::int>{};
+          #t418.{core::Set::add}(null);
+        } =>#t418;
+        final core::Map<core::String, core::int> #t424 = <core::String, core::int>{};
         {
-          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t382 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+          dynamic :stream = asy::Stream::fromIterable<core::int>(<core::int>[let final<BottomType> #t425 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:57: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
-                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t383 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:225:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
+                                                        ^" in "not" as{TypeError} core::int, let final<BottomType> #t426 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:245:64: Error: A value of type 'String' can't be assigned to a variable of type 'int'.
 Try changing the type of the left hand side, or casting the right hand side to 'int'.
   var map40 = {await for (int i in Stream.fromIterable([\"not\", \"int\"])) \"bar\": i, \"baz\": null};
                                                                ^" in "int" as{TypeError} core::int]);
@@ -2041,67 +2353,67 @@
           try
             #L7:
             while (true) {
-              dynamic #t384 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
-              [yield] let dynamic #t385 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
+              dynamic #t427 = :product-mode ?{dynamic} null : asy::_asyncStarMoveNextHelper(:stream);
+              [yield] let dynamic #t428 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::moveNext}(), :async_op_then, :async_op_error, :async_op) in null;
               if(:result) {
                 core::int i = :for-iterator.{asy::_StreamIterator::current};
-                #t381.{core::Map::[]=}("bar", i);
+                #t424.{core::Map::[]=}("bar", i);
               }
               else
                 break #L7;
             }
           finally
             if(!:for-iterator.{asy::_StreamIterator::_subscription}.{core::Object::==}(null)) {
-              [yield] let dynamic #t386 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
+              [yield] let dynamic #t429 = asy::_awaitHelper(:for-iterator.{asy::_StreamIterator::cancel}(), :async_op_then, :async_op_error, :async_op) in null;
               :result;
             }
         }
         core::Map<core::String, core::int> map40 = block {
-          #t381.{core::Map::[]=}("baz", null);
-        } =>#t381;
+          #t424.{core::Map::[]=}("baz", null);
+        } =>#t424;
         core::List<core::int> list50 = block {
-          final core::List<core::int> #t387 = <core::int>[];
+          final core::List<core::int> #t430 = <core::int>[];
           for (; ; )
-            #t387.{core::List::add}(42);
-        } =>#t387;
+            #t430.{core::List::add}(42);
+        } =>#t430;
         core::Set<core::int> set50 = block {
-          final core::Set<core::int> #t388 = col::LinkedHashSet::•<core::int>();
+          final core::Set<core::int> #t431 = col::LinkedHashSet::•<core::int>();
           for (; ; )
-            #t388.{core::Set::add}(42);
-          #t388.{core::Set::add}(null);
-        } =>#t388;
+            #t431.{core::Set::add}(42);
+          #t431.{core::Set::add}(null);
+        } =>#t431;
         core::Map<core::String, core::int> map50 = block {
-          final core::Map<core::String, core::int> #t389 = <core::String, core::int>{};
+          final core::Map<core::String, core::int> #t432 = <core::String, core::int>{};
           for (; ; )
-            #t389.{core::Map::[]=}("bar", 42);
-          #t389.{core::Map::[]=}("baz", null);
-        } =>#t389;
+            #t432.{core::Map::[]=}("bar", 42);
+          #t432.{core::Map::[]=}("baz", null);
+        } =>#t432;
         core::List<core::int> list60 = block {
-          final core::List<core::int> #t390 = <core::int>[];
-          for (; let final<BottomType> #t391 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:229:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::List<core::int> #t433 = <core::int>[];
+          for (; let final<BottomType> #t434 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:249:24: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var list60 = [for (; \"not bool\";) 42];
                        ^" in "not bool" as{TypeError} core::bool; )
-            #t390.{core::List::add}(42);
-        } =>#t390;
+            #t433.{core::List::add}(42);
+        } =>#t433;
         core::Set<core::int> set60 = block {
-          final core::Set<core::int> #t392 = col::LinkedHashSet::•<core::int>();
-          for (; let final<BottomType> #t393 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:230:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Set<core::int> #t435 = col::LinkedHashSet::•<core::int>();
+          for (; let final<BottomType> #t436 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:250:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var set60 = {for (; \"not bool\";) 42, null};
                       ^" in "not bool" as{TypeError} core::bool; )
-            #t392.{core::Set::add}(42);
-          #t392.{core::Set::add}(null);
-        } =>#t392;
+            #t435.{core::Set::add}(42);
+          #t435.{core::Set::add}(null);
+        } =>#t435;
         core::Map<core::String, core::int> map60 = block {
-          final core::Map<core::String, core::int> #t394 = <core::String, core::int>{};
-          for (; let final<BottomType> #t395 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:231:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
+          final core::Map<core::String, core::int> #t437 = <core::String, core::int>{};
+          for (; let final<BottomType> #t438 = invalid-expression "pkg/front_end/testcases/control_flow_collection_inference.dart:251:23: Error: A value of type 'String' can't be assigned to a variable of type 'bool'.
 Try changing the type of the left hand side, or casting the right hand side to 'bool'.
   var map60 = {for (; \"not bool\";) \"bar\": 42, \"baz\": null};
                       ^" in "not bool" as{TypeError} core::bool; )
-            #t394.{core::Map::[]=}("bar", 42);
-          #t394.{core::Map::[]=}("baz", null);
-        } =>#t394;
+            #t437.{core::Map::[]=}("bar", 42);
+          #t437.{core::Map::[]=}("baz", null);
+        } =>#t437;
       }
       asy::_completeOnAsyncReturn(:async_completer, :return_value);
       return;
@@ -2117,19 +2429,36 @@
 }
 static method testForElementErrorsNotAsync(asy::Stream<core::int> stream) → dynamic {
   block {
-    final core::List<core::int> #t396 = <core::int>[];
+    final core::List<core::int> #t439 = <core::int>[];
     await for (core::int i in stream)
-      #t396.{core::List::add}(i);
-  } =>#t396;
+      #t439.{core::List::add}(i);
+  } =>#t439;
   block {
-    final core::Set<core::int> #t397 = col::LinkedHashSet::•<core::int>();
+    final core::Set<core::int> #t440 = col::LinkedHashSet::•<core::int>();
     await for (core::int i in stream)
-      #t397.{core::Set::add}(i);
-  } =>#t397;
+      #t440.{core::Set::add}(i);
+  } =>#t440;
   block {
-    final core::Map<core::String, core::int> #t398 = <core::String, core::int>{};
+    final core::Map<core::String, core::int> #t441 = <core::String, core::int>{};
     await for (core::int i in stream)
-      #t398.{core::Map::[]=}("bar", i);
-  } =>#t398;
+      #t441.{core::Map::[]=}("bar", i);
+  } =>#t441;
+}
+static method testPromotion(self::A a) → dynamic {
+  core::List<core::int> list10 = block {
+    final core::List<core::int> #t442 = <core::int>[];
+    if(a is self::B)
+      #t442.{core::List::add}(a{self::B}.{self::B::foo});
+  } =>#t442;
+  core::Set<core::int> set10 = block {
+    final core::Set<core::int> #t443 = col::LinkedHashSet::•<core::int>();
+    if(a is self::B)
+      #t443.{core::Set::add}(a{self::B}.{self::B::foo});
+  } =>#t443;
+  core::Map<core::int, core::int> map10 = block {
+    final core::Map<core::int, core::int> #t444 = <core::int, core::int>{};
+    if(a is self::B)
+      #t444.{core::Map::[]=}(a{self::B}.{self::B::foo}, a{self::B}.{self::B::foo});
+  } =>#t444;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect b/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect
index 1ac72fb..648acdc 100644
--- a/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect
+++ b/pkg/front_end/testcases/control_flow_collection_inference.dart.type_promotion.expect
@@ -1,288 +1,306 @@
-pkg/front_end/testcases/control_flow_collection_inference.dart:106:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:123:49: Context: Write to i@7018
   var list10 = [for (int i = 0; oracle("foo"); i++) 42];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:107:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:124:48: Context: Write to i@7018
   var set10 = {for (int i = 0; oracle("foo"); i++) 42, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:108:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:125:48: Context: Write to i@7018
   var map10 = {for (int i = 0; oracle("foo"); i++) "bar": 42, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:109:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:126:49: Context: Write to i@7018
   var list11 = [for (int i = 0; oracle("foo"); i++) dynVar];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:110:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:127:48: Context: Write to i@7018
   var set11 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:111:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:128:48: Context: Write to i@7018
   var map11 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:112:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:129:49: Context: Write to i@7018
   var list12 = [for (int i = 0; oracle("foo"); i++) [42]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:113:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:130:48: Context: Write to i@7018
   var set12 = {for (int i = 0; oracle("foo"); i++) [42], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:114:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:131:48: Context: Write to i@7018
   var map12 = {for (int i = 0; oracle("foo"); i++) "bar": [42], "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:115:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:132:49: Context: Write to i@7018
   var list20 = [for (int i = 0; oracle("foo"); i++) ...[42]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:116:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:133:48: Context: Write to i@7018
   var set20 = {for (int i = 0; oracle("foo"); i++) ...[42], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:117:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:134:48: Context: Write to i@7018
   var map20 = {for (int i = 0; oracle("foo"); i++) ...{"bar": 42}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:118:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:135:49: Context: Write to i@7018
   var list21 = [for (int i = 0; oracle("foo"); i++) ...[dynVar]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:119:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:136:48: Context: Write to i@7018
   var set21 = {for (int i = 0; oracle("foo"); i++) ...[dynVar], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:120:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:137:48: Context: Write to i@7018
   var map21 = {for (int i = 0; oracle("foo"); i++) ...{"bar": dynVar}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:121:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:138:49: Context: Write to i@7018
   var list22 = [for (int i = 0; oracle("foo"); i++) ...[[42]]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:122:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:139:48: Context: Write to i@7018
   var set22 = {for (int i = 0; oracle("foo"); i++) ...[[42]], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:123:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:140:48: Context: Write to i@7018
   var map22 = {for (int i = 0; oracle("foo"); i++) ...{"bar": [42]}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:124:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:141:49: Context: Write to i@7018
   var list30 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:125:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:142:48: Context: Write to i@7018
   var set30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[42], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:126:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:143:48: Context: Write to i@7018
   var map30 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": 42}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:127:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:144:49: Context: Write to i@7018
   var list31 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:128:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:145:48: Context: Write to i@7018
   var set31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[dynVar], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:129:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:146:48: Context: Write to i@7018
   var map31 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": dynVar}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:130:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:147:49: Context: Write to i@7018
   var list33 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]]];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:131:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:148:48: Context: Write to i@7018
   var set33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[42]], null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:132:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:149:48: Context: Write to i@7018
   var map33 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": [42]}, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:133:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:150:61: Context: Write to i@7018
   List<List<int>> list40 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:134:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:151:59: Context: Write to i@7018
   Set<List<int>> set40 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:135:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:152:67: Context: Write to i@7018
   Map<String, List<int>> map40 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:136:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:153:61: Context: Write to i@7018
   List<List<int>> list41 = [for (int i = 0; oracle("foo"); i++) ...{[]}];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:137:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:154:59: Context: Write to i@7018
   Set<List<int>> set41 = {for (int i = 0; oracle("foo"); i++) ...{[]}, null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:138:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:155:61: Context: Write to i@7018
   List<List<int>> list42 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:139:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:156:59: Context: Write to i@7018
   Set<List<int>> set42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:140:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:157:67: Context: Write to i@7018
   Map<String, List<int>> map42 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:141:55: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:158:55: Context: Write to i@7018
   List<int> list50 = [for (int i = 0; oracle("foo"); i++) ...[]];
                                                       ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:142:53: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:159:53: Context: Write to i@7018
   Set<int> set50 = {for (int i = 0; oracle("foo"); i++) ...[], null};
                                                     ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:143:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:160:61: Context: Write to i@7018
   Map<String, int> map50 = {for (int i = 0; oracle("foo"); i++) ...{}, "baz": null};
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:144:55: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:161:55: Context: Write to i@7018
   List<int> list51 = [for (int i = 0; oracle("foo"); i++) ...{}];
                                                       ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:145:53: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:162:53: Context: Write to i@7018
   Set<int> set51 = {for (int i = 0; oracle("foo"); i++) ...{}, null};
                                                     ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:146:55: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:163:55: Context: Write to i@7018
   List<int> list52 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[]];
                                                       ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:147:53: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:164:53: Context: Write to i@7018
   Set<int> set52 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[], null};
                                                     ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:148:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:165:61: Context: Write to i@7018
   List<List<int>> list60 = [for (int i = 0; oracle("foo"); i++) ...[[]]];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:149:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:166:59: Context: Write to i@7018
   Set<List<int>> set60 = {for (int i = 0; oracle("foo"); i++) ...[[]], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:150:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:167:67: Context: Write to i@7018
   Map<String, List<int>> map60 = {for (int i = 0; oracle("foo"); i++) ...{"bar": []}, "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:151:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:168:61: Context: Write to i@7018
   List<List<int>> list61 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]]];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:152:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:169:59: Context: Write to i@7018
   Set<List<int>> set61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...[[]], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:153:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:170:67: Context: Write to i@7018
   Map<String, List<int>> map61 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...{"bar": []}, "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:154:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:171:61: Context: Write to i@7018
   List<List<int>> list70 = [for (int i = 0; oracle("foo"); i++) []];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:155:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:172:59: Context: Write to i@7018
   Set<List<int>> set70 = {for (int i = 0; oracle("foo"); i++) [], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:156:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:173:67: Context: Write to i@7018
   Map<String, List<int>> map70 = {for (int i = 0; oracle("foo"); i++) "bar": [], "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:157:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:174:61: Context: Write to i@7018
   List<List<int>> list71 = [for (int i = 0; oracle("foo"); i++) if (oracle()) []];
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:158:59: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:175:59: Context: Write to i@7018
   Set<List<int>> set71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) [], null};
                                                           ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:159:67: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:176:67: Context: Write to i@7018
   Map<String, List<int>> map71 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": [], "baz": null};
                                                                   ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:160:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:177:49: Context: Write to i@7018
   var list80 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:161:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:178:48: Context: Write to i@7018
   var set80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:162:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:179:48: Context: Write to i@7018
   var map80 = {for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:163:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:180:49: Context: Write to i@7018
   var list81 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:164:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:181:48: Context: Write to i@7018
   var set81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...listDouble, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:165:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:182:48: Context: Write to i@7018
   var map81 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...mapStringDouble, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:166:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:183:49: Context: Write to i@7018
   var list82 = [for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:167:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:184:48: Context: Write to i@7018
   var set82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else ...dynVar, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:168:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:185:48: Context: Write to i@7018
   var map82 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else ...dynVar, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:169:49: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:186:49: Context: Write to i@7018
   var list83 = [for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...listDouble];
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:170:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:187:48: Context: Write to i@7018
   var set83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...listInt else 3.14, null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:171:48: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:188:48: Context: Write to i@7018
   var map83 = {for (int i = 0; oracle("foo"); i++) if (oracle()) ...mapStringInt else "bar": 3.14, "baz": null};
                                                ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:172:55: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:189:55: Context: Write to i@7018
   List<int> list90 = [for (int i = 0; oracle("foo"); i++) dynVar];
                                                       ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:173:53: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:190:53: Context: Write to i@7018
   Set<int> set90 = {for (int i = 0; oracle("foo"); i++) dynVar, null};
                                                     ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:174:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:191:61: Context: Write to i@7018
   Map<String, int> map90 = {for (int i = 0; oracle("foo"); i++) "bar": dynVar, "baz": null};
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:175:55: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:192:55: Context: Write to i@7018
   List<int> list91 = [for (int i = 0; oracle("foo"); i++) ...dynVar];
                                                       ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:176:53: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:193:53: Context: Write to i@7018
   Set<int> set91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, null};
                                                     ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:177:61: Context: Write to i@6094
+pkg/front_end/testcases/control_flow_collection_inference.dart:194:61: Context: Write to i@7018
   Map<String, int> map91 = {for (int i = 0; oracle("foo"); i++) ...dynVar, "baz": null};
                                                             ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:178:40: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:195:40: Context: Write to index@6916
   List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42];
                                        ^
-pkg/front_end/testcases/control_flow_collection_inference.dart:178:65: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:195:65: Context: Write to index@6916
   List<int> list100 = <int>[for (index = 0; oracle("foo"); index++) 42];
                                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:179:38: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:196:38: Context: Write to index@6916
   Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42};
                                      ^
-pkg/front_end/testcases/control_flow_collection_inference.dart:179:63: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:196:63: Context: Write to index@6916
   Set<int> set100 = <int>{for (index = 0; oracle("foo"); index++) 42};
                                                               ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:180:54: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:197:54: Context: Write to index@6916
   Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42};
                                                      ^
-pkg/front_end/testcases/control_flow_collection_inference.dart:180:79: Context: Write to index@5992
+pkg/front_end/testcases/control_flow_collection_inference.dart:197:79: Context: Write to index@6916
   Map<String, int> map100 = <String, int>{for (index = 0; oracle("foo"); index++) "bar": 42};
                                                                               ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:190:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:204:48: Context: Write to i@7018
+  List<int> list130 = [for (var i = 1; i < 2; i++) i];
+                                               ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:205:46: Context: Write to i@7018
+  Set<int> set130 = {for (var i = 1; i < 2; i++) i};
+                                             ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:206:51: Context: Write to i@7018
+  Map<int, int> map130 = {for (var i = 1; i < 2; i++) i: i};
+                                                  ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:210:41: Context: Write to i@13789
   <int>[for (int i = 0; oracle("foo"); i++) "bar"];
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:191:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:211:41: Context: Write to i@13789
   <int>{for (int i = 0; oracle("foo"); i++) "bar", null};
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:192:46: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:212:46: Context: Write to i@13789
   <int, int>{for (int i = 0; oracle("foo"); i++) "bar": "bar", "baz": null};
                                              ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:193:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:213:41: Context: Write to i@13789
   <int>[for (int i = 0; oracle("foo"); i++) ...["bar"]];
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:194:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:214:41: Context: Write to i@13789
   <int>{for (int i = 0; oracle("foo"); i++) ...["bar"], null};
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:195:46: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:215:46: Context: Write to i@13789
   <int, int>{for (int i = 0; oracle("foo"); i++) ...{"bar": "bar"}, "baz": null};
                                              ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:196:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:216:41: Context: Write to i@13789
   <int>[for (int i = 0; oracle("foo"); i++) ...map];
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:197:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:217:41: Context: Write to i@13789
   <int>{for (int i = 0; oracle("foo"); i++) ...map, null};
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:198:46: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:218:46: Context: Write to i@13789
   <int, int>{for (int i = 0; oracle("foo"); i++) ...list, 42: null};
                                              ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:199:44: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:219:44: Context: Write to i@13789
   <String>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14];
                                            ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:200:44: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:220:44: Context: Write to i@13789
   <String>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else 3.14, null};
                                            ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:201:52: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:221:52: Context: Write to i@13789
   <String, String>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else "bar": 3.14, "baz": null};
                                                    ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:202:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:222:41: Context: Write to i@13789
   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42];
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:203:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:223:41: Context: Write to i@13789
   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...map else 42, null};
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:204:49: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:224:49: Context: Write to i@13789
   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) ...list else "bar": 42, "baz": null};
                                                 ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:205:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:225:41: Context: Write to i@13789
   <int>[for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map];
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:206:41: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:226:41: Context: Write to i@13789
   <int>{for (int i = 0; oracle("foo"); i++) if (oracle()) 42 else ...map, null};
                                         ^^
-pkg/front_end/testcases/control_flow_collection_inference.dart:207:49: Context: Write to i@12696
+pkg/front_end/testcases/control_flow_collection_inference.dart:227:49: Context: Write to i@13789
   <String, int>{for (int i = 0; oracle("foo"); i++) if (oracle()) "bar": 42 else ...list, "baz": null};
                                                 ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:267:29: Context: Possible promotion of a@16609
+  List<int> list10 = [if (a is B) a.foo];
+                            ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:268:27: Context: Possible promotion of a@16609
+  Set<int> set10 = {if (a is B) a.foo};
+                          ^^
+pkg/front_end/testcases/control_flow_collection_inference.dart:269:32: Context: Possible promotion of a@16609
+  Map<int, int> map10 = {if (a is B) a.foo: a.foo};
+                               ^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
index f1e837f..86ec30f 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.expect
@@ -2,12 +2,12 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
index f1e837f..86ec30f 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.legacy.transformed.expect
@@ -2,12 +2,12 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
index 63f345e..1933ac0 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.outline.expect
@@ -2,12 +2,12 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
diff --git a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
index a51c4ba..6e8d2d8 100644
--- a/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
+++ b/pkg/front_end/testcases/duplicated_declarations.dart.strong.expect
@@ -2,12 +2,12 @@
 //
 // Problems in library:
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:7:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
 //
-// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must preceed part directives.
+// pkg/front_end/testcases/duplicated_declarations.dart:9:1: Error: Import directives must precede part directives.
 // Try moving the import directives before the part directives.
 // import 'duplicated_declarations_lib.dart' as Typedef;
 // ^^^^^^
diff --git a/pkg/front_end/testcases/legacy.status b/pkg/front_end/testcases/legacy.status
index 2489f9f..7fadc91 100644
--- a/pkg/front_end/testcases/legacy.status
+++ b/pkg/front_end/testcases/legacy.status
@@ -113,6 +113,7 @@
 regress/issue_35259: RuntimeError # Expected
 regress/issue_35260: RuntimeError # Expected
 regress/issue_35266: RuntimeError # Expected
+regress/issue_36400: RuntimeError
 reject_generic_function_types_in_bounds: RuntimeError # Expected
 runtime_checks/implicit_downcast_constructor_initializer: RuntimeError # Test exercises strong mode semantics
 runtime_checks/implicit_downcast_do: RuntimeError # Test exercises strong mode semantics
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
index 8130bfc..35b1ddf 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.expect
@@ -6,7 +6,7 @@
 //   var f = Map<A, B> {};
 //                  ^
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
 // Try adding the keyword 'operator'.
 //   var f = Map<A, B> {};
 //                   ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
index 8130bfc..35b1ddf 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.legacy.transformed.expect
@@ -6,7 +6,7 @@
 //   var f = Map<A, B> {};
 //                  ^
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
 // Try adding the keyword 'operator'.
 //   var f = Map<A, B> {};
 //                   ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
index 31866e5..368d30d 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.outline.expect
@@ -6,7 +6,7 @@
 //   var f = Map<A, B> {};
 //                  ^
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
 // Try adding the keyword 'operator'.
 //   var f = Map<A, B> {};
 //                   ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
index f9e661a..e6f0d60 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.expect
@@ -6,7 +6,7 @@
 //   var f = Map<A, B> {};
 //                  ^
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
 // Try adding the keyword 'operator'.
 //   var f = Map<A, B> {};
 //                   ^
diff --git a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
index f9e661a..e6f0d60 100644
--- a/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/regress/issue_31155.dart.strong.transformed.expect
@@ -6,7 +6,7 @@
 //   var f = Map<A, B> {};
 //                  ^
 //
-// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceeded by the keyword 'operator'.
+// pkg/front_end/testcases/regress/issue_31155.dart:11:19: Error: Operator declarations must be preceded by the keyword 'operator'.
 // Try adding the keyword 'operator'.
 //   var f = Map<A, B> {};
 //                   ^
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart b/pkg/front_end/testcases/regress/issue_36400.dart
new file mode 100644
index 0000000..33c29d6
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.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.
+
+class Test {
+  Test factory Test() {
+    return null;
+  }
+}
+
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect b/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect
new file mode 100644
index 0000000..6dc337c
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.hierarchy.expect
@@ -0,0 +1,36 @@
+Object:
+  superclasses:
+  interfaces:
+  classMembers:
+    Object._haveSameRuntimeType
+    Object.toString
+    Object.runtimeType
+    Object._toString
+    Object._simpleInstanceOf
+    Object._hashCodeRnd
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._objectHashCode
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
+
+Test:
+  superclasses:
+    Object
+  interfaces:
+  classMembers:
+    Object.toString
+    Object.runtimeType
+    Object._simpleInstanceOf
+    Object._instanceOf
+    Object.noSuchMethod
+    Object._identityHashCode
+    Object.hashCode
+    Object._simpleInstanceOfFalse
+    Object._simpleInstanceOfTrue
+    Object.==
+  classSetters:
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect
new file mode 100644
index 0000000..e63b720
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type.
+// Try removing the type appearing before 'factory'.
+//   Test factory Test() {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Test extends core::Object {
+  static factory •() → self::Test {
+    return null;
+  }
+}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect
new file mode 100644
index 0000000..e63b720
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.legacy.transformed.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type.
+// Try removing the type appearing before 'factory'.
+//   Test factory Test() {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Test extends core::Object {
+  static factory •() → self::Test {
+    return null;
+  }
+}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect b/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect
new file mode 100644
index 0000000..2f39e53
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.outline.expect
@@ -0,0 +1,16 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type.
+// Try removing the type appearing before 'factory'.
+//   Test factory Test() {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Test extends core::Object {
+  static factory •() → self::Test
+    ;
+}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect b/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect
new file mode 100644
index 0000000..e63b720
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.strong.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type.
+// Try removing the type appearing before 'factory'.
+//   Test factory Test() {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Test extends core::Object {
+  static factory •() → self::Test {
+    return null;
+  }
+}
diff --git a/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect b/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect
new file mode 100644
index 0000000..e63b720
--- /dev/null
+++ b/pkg/front_end/testcases/regress/issue_36400.dart.strong.transformed.expect
@@ -0,0 +1,17 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/regress/issue_36400.dart:6:3: Error: Factory constructors cannot have a return type.
+// Try removing the type appearing before 'factory'.
+//   Test factory Test() {
+//   ^^^^
+//
+import self as self;
+import "dart:core" as core;
+
+class Test extends core::Object {
+  static factory •() → self::Test {
+    return null;
+  }
+}
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
index 7599faa..27a3664 100644
--- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
+++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.expect
@@ -69,20 +69,10 @@
 //     spread];
 //     ^
 //
-// pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//     spread];
-//     ^
-//
 // pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
 //   Set<String> set60 = <String>{... spread};
 //                                    ^
 //
-// pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   Set<String> set60 = <String>{... spread};
-//                                    ^
-//
 // pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
 //  mapSpread};
 //  ^
@@ -310,18 +300,12 @@
   core::Map<dynamic, dynamic> map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:109:2: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
  notSpreadFunction};
  ^": null};
-  core::List<core::String> lhs60 = <core::String>[let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  core::List<core::String> lhs60 = <core::String>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
     spread];
-    ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
-    spread];
-    ^" as{TypeError} core::String];
-  core::Set<core::String> set60 = let final core::Set<core::String> #t65 = col::LinkedHashSet::•<core::String>() in let final dynamic #t66 = #t65.{core::Set::add}(let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+    ^"];
+  core::Set<core::String> set60 = let final core::Set<core::String> #t64 = col::LinkedHashSet::•<core::String>() in let final dynamic #t65 = #t64.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{... spread};
-                                   ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
-  Set<String> set60 = <String>{... spread};
-                                   ^" as{TypeError} core::String) in #t65;
+                                   ^") in #t64;
   core::Map<core::int, core::int> map60 = <core::int, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
  mapSpread};
  ^": null};
@@ -330,91 +314,91 @@
  ^"};
   core::List<core::int> lhs70 = <core::int>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:122:31: Error: Can't spread a value with static type Null.
   List<int> lhs70 = <int>[... null];
-                              ^" as{TypeError} core::int];
-  core::Set<core::int> set70 = let final core::Set<core::int> #t68 = col::LinkedHashSet::•<core::int>() in let final dynamic #t69 = #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null.
+                              ^"];
+  core::Set<core::int> set70 = let final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>() in let final dynamic #t67 = #t66.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null.
   Set<int> set70 = <int>{... null};
-                             ^" as{TypeError} core::int) in #t68;
+                             ^") in #t66;
   core::Set<dynamic> set71ambiguous = block {
-    final core::Set<dynamic> #t70 = col::LinkedHashSet::•<dynamic>();
-    #t70.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this.
+    final core::Set<dynamic> #t68 = col::LinkedHashSet::•<dynamic>();
+    #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this.
     {... null, ... /*@typeArgs=dynamic*/
          ^");
-    for (final dynamic #t71 in <dynamic>[]) {
-      final dynamic #t72 = #t71 as{TypeError} dynamic;
-      #t70.{core::Set::add}(#t72);
+    for (final dynamic #t69 in <dynamic>[]) {
+      final dynamic #t70 = #t69 as{TypeError} dynamic;
+      #t68.{core::Set::add}(#t70);
     }
-  } =>#t70;
+  } =>#t68;
   core::Map<core::String, core::int> map70 = <core::String, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:131:5: Error: Can't spread a value with static type Null.
     null};
     ^": null};
   core::List<core::int> lhs80 = block {
-    final core::List<core::int> #t73 = <core::int>[];
-    final dynamic #t74 = null;
-    if(!#t74.{core::Object::==}(null))
-      for (final core::int #t75 in #t74)
-        #t73.{core::List::add}(#t75);
-  } =>#t73;
+    final core::List<core::int> #t71 = <core::int>[];
+    final dynamic #t72 = null;
+    if(!#t72.{core::Object::==}(null))
+      for (final core::int #t73 in #t72)
+        #t71.{core::List::add}(#t73);
+  } =>#t71;
   core::Set<core::int> set80 = block {
-    final core::Set<core::int> #t76 = col::LinkedHashSet::•<core::int>();
-    final dynamic #t77 = null;
-    if(!#t77.{core::Object::==}(null))
-      for (final core::int #t78 in #t77)
-        #t76.{core::Set::add}(#t78);
-  } =>#t76;
+    final core::Set<core::int> #t74 = col::LinkedHashSet::•<core::int>();
+    final dynamic #t75 = null;
+    if(!#t75.{core::Object::==}(null))
+      for (final core::int #t76 in #t75)
+        #t74.{core::Set::add}(#t76);
+  } =>#t74;
   core::Set<dynamic> set81ambiguous = block {
-    final core::Set<dynamic> #t79 = col::LinkedHashSet::•<dynamic>();
-    final dynamic #t80 = null;
-    if(!#t80.{core::Object::==}(null))
-      for (final dynamic #t81 in #t80) {
-        final dynamic #t82 = #t81 as{TypeError} dynamic;
-        #t79.{core::Set::add}(#t82);
+    final core::Set<dynamic> #t77 = col::LinkedHashSet::•<dynamic>();
+    final dynamic #t78 = null;
+    if(!#t78.{core::Object::==}(null))
+      for (final dynamic #t79 in #t78) {
+        final dynamic #t80 = #t79 as{TypeError} dynamic;
+        #t77.{core::Set::add}(#t80);
       }
-    for (final dynamic #t83 in <dynamic>[]) {
-      final dynamic #t84 = #t83 as{TypeError} dynamic;
-      #t79.{core::Set::add}(#t84);
+    for (final dynamic #t81 in <dynamic>[]) {
+      final dynamic #t82 = #t81 as{TypeError} dynamic;
+      #t77.{core::Set::add}(#t82);
     }
-  } =>#t79;
+  } =>#t77;
   core::Map<core::String, core::int> map80 = block {
-    final core::Map<core::String, core::int> #t85 = <core::String, core::int>{};
-    final core::Map<dynamic, dynamic> #t86 = null;
-    if(!#t86.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t87 in #t86.{core::Map::entries})
-        #t85.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
-  } =>#t85;
+    final core::Map<core::String, core::int> #t83 = <core::String, core::int>{};
+    final core::Map<dynamic, dynamic> #t84 = null;
+    if(!#t84.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t85 in #t84.{core::Map::entries})
+        #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
+  } =>#t83;
   core::Map<core::String, core::int> map90 = block {
-    final core::Map<core::String, core::int> #t88 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t89 in self::bar<core::String, core::int>().{core::Map::entries})
-      #t88.{core::Map::[]=}(#t89.{core::MapEntry::key}, #t89.{core::MapEntry::value});
-  } =>#t88;
+    final core::Map<core::String, core::int> #t86 = <core::String, core::int>{};
+    for (final core::MapEntry<core::String, core::int> #t87 in self::bar<core::String, core::int>().{core::Map::entries})
+      #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
+  } =>#t86;
   core::List<core::int> list100 = block {
-    final core::List<core::int> #t90 = <core::int>[];
-    for (final dynamic #t91 in listNum) {
-      final core::int #t92 = #t91 as{TypeError} core::int;
-      #t90.{core::List::add}(#t92);
+    final core::List<core::int> #t88 = <core::int>[];
+    for (final dynamic #t89 in listNum) {
+      final core::int #t90 = #t89 as{TypeError} core::int;
+      #t88.{core::List::add}(#t90);
     }
-  } =>#t90;
+  } =>#t88;
   core::Map<core::num, core::int> map100 = block {
-    final core::Map<core::num, core::int> #t93 = <core::num, core::int>{};
-    for (final core::MapEntry<dynamic, dynamic> #t94 in mapIntNum.{core::Map::entries}) {
-      final core::num #t95 = #t94.{core::MapEntry::key} as{TypeError} core::num;
-      final core::int #t96 = #t94.{core::MapEntry::value} as{TypeError} core::int;
-      #t93.{core::Map::[]=}(#t95, #t96);
+    final core::Map<core::num, core::int> #t91 = <core::num, core::int>{};
+    for (final core::MapEntry<dynamic, dynamic> #t92 in mapIntNum.{core::Map::entries}) {
+      final core::num #t93 = #t92.{core::MapEntry::key} as{TypeError} core::num;
+      final core::int #t94 = #t92.{core::MapEntry::value} as{TypeError} core::int;
+      #t91.{core::Map::[]=}(#t93, #t94);
     }
-  } =>#t93;
+  } =>#t91;
   core::List<core::int> list110 = block {
-    final core::List<core::int> #t97 = <core::int>[];
-    for (final dynamic #t98 in dynVar as{TypeError} core::Iterable<dynamic>) {
-      final core::int #t99 = #t98 as{TypeError} core::int;
-      #t97.{core::List::add}(#t99);
+    final core::List<core::int> #t95 = <core::int>[];
+    for (final dynamic #t96 in dynVar as{TypeError} core::Iterable<dynamic>) {
+      final core::int #t97 = #t96 as{TypeError} core::int;
+      #t95.{core::List::add}(#t97);
     }
-  } =>#t97;
+  } =>#t95;
   core::Map<core::num, core::int> map110 = block {
-    final core::Map<core::num, core::int> #t100 = <core::num, core::int>{};
-    for (final core::MapEntry<dynamic, dynamic> #t101 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
-      final core::num #t102 = #t101.{core::MapEntry::key} as{TypeError} core::num;
-      final core::int #t103 = #t101.{core::MapEntry::value} as{TypeError} core::int;
-      #t100.{core::Map::[]=}(#t102, #t103);
+    final core::Map<core::num, core::int> #t98 = <core::num, core::int>{};
+    for (final core::MapEntry<dynamic, dynamic> #t99 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
+      final core::num #t100 = #t99.{core::MapEntry::key} as{TypeError} core::num;
+      final core::int #t101 = #t99.{core::MapEntry::value} as{TypeError} core::int;
+      #t98.{core::Map::[]=}(#t100, #t101);
     }
-  } =>#t100;
+  } =>#t98;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
index 3262225..838f328 100644
--- a/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/spread_collection_inference.dart.strong.transformed.expect
@@ -69,20 +69,10 @@
 //     spread];
 //     ^
 //
-// pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//     spread];
-//     ^
-//
 // pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
 //   Set<String> set60 = <String>{... spread};
 //                                    ^
 //
-// pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-// Try changing the type of the left hand side, or casting the right hand side to 'String'.
-//   Set<String> set60 = <String>{... spread};
-//                                    ^
-//
 // pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
 //  mapSpread};
 //  ^
@@ -310,18 +300,12 @@
   core::Map<dynamic, dynamic> map50 = <dynamic, dynamic>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:109:2: Error: Unexpected type 'int Function()' of a map spread entry.  Expected 'dynamic' or a Map.
  notSpreadFunction};
  ^": null};
-  core::List<core::String> lhs60 = <core::String>[let final<BottomType> #t64 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+  core::List<core::String> lhs60 = <core::String>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
     spread];
-    ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:112:5: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
-    spread];
-    ^" as{TypeError} core::String];
-  core::Set<core::String> set60 = let final core::Set<core::String> #t65 = col::LinkedHashSet::•<core::String>() in let final core::bool #t66 = #t65.{core::Set::add}(let final<BottomType> #t67 = invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: A value of type 'int' can't be assigned to a variable of type 'String'.
-Try changing the type of the left hand side, or casting the right hand side to 'String'.
+    ^"];
+  core::Set<core::String> set60 = let final core::Set<core::String> #t64 = col::LinkedHashSet::•<core::String>() in let final core::bool #t65 = #t64.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
   Set<String> set60 = <String>{... spread};
-                                   ^" in invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:114:36: Error: Can't assign spread elements of type 'int' to collection elements of type 'String'.
-  Set<String> set60 = <String>{... spread};
-                                   ^" as{TypeError} core::String) in #t65;
+                                   ^") in #t64;
   core::Map<core::int, core::int> map60 = <core::int, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:117:2: Error: Can't assign spread entry keys of type 'String' to map entry keys of type 'int'.
  mapSpread};
  ^": null};
@@ -330,91 +314,91 @@
  ^"};
   core::List<core::int> lhs70 = <core::int>[invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:122:31: Error: Can't spread a value with static type Null.
   List<int> lhs70 = <int>[... null];
-                              ^" as{TypeError} core::int];
-  core::Set<core::int> set70 = let final core::Set<core::int> #t68 = col::LinkedHashSet::•<core::int>() in let final core::bool #t69 = #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null.
+                              ^"];
+  core::Set<core::int> set70 = let final core::Set<core::int> #t66 = col::LinkedHashSet::•<core::int>() in let final core::bool #t67 = #t66.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:124:30: Error: Can't spread a value with static type Null.
   Set<int> set70 = <int>{... null};
-                             ^" as{TypeError} core::int) in #t68;
+                             ^") in #t66;
   core::Set<dynamic> set71ambiguous = block {
-    final core::Set<dynamic> #t70 = col::LinkedHashSet::•<dynamic>();
-    #t70.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this.
+    final core::Set<dynamic> #t68 = col::LinkedHashSet::•<dynamic>();
+    #t68.{core::Set::add}(invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:127:10: Error: Expected ',' before this.
     {... null, ... /*@typeArgs=dynamic*/
          ^");
-    for (final dynamic #t71 in <dynamic>[]) {
-      final dynamic #t72 = #t71 as{TypeError} dynamic;
-      #t70.{core::Set::add}(#t72);
+    for (final dynamic #t69 in <dynamic>[]) {
+      final dynamic #t70 = #t69 as{TypeError} dynamic;
+      #t68.{core::Set::add}(#t70);
     }
-  } =>#t70;
+  } =>#t68;
   core::Map<core::String, core::int> map70 = <core::String, core::int>{invalid-expression "pkg/front_end/testcases/spread_collection_inference.dart:131:5: Error: Can't spread a value with static type Null.
     null};
     ^": null};
   core::List<core::int> lhs80 = block {
-    final core::List<core::int> #t73 = <core::int>[];
-    final dynamic #t74 = null;
-    if(!#t74.{core::Object::==}(null))
-      for (final core::int #t75 in #t74)
-        #t73.{core::List::add}(#t75);
-  } =>#t73;
+    final core::List<core::int> #t71 = <core::int>[];
+    final dynamic #t72 = null;
+    if(!#t72.{core::Object::==}(null))
+      for (final core::int #t73 in #t72)
+        #t71.{core::List::add}(#t73);
+  } =>#t71;
   core::Set<core::int> set80 = block {
-    final core::Set<core::int> #t76 = col::LinkedHashSet::•<core::int>();
-    final dynamic #t77 = null;
-    if(!#t77.{core::Object::==}(null))
-      for (final core::int #t78 in #t77)
-        #t76.{core::Set::add}(#t78);
-  } =>#t76;
+    final core::Set<core::int> #t74 = col::LinkedHashSet::•<core::int>();
+    final dynamic #t75 = null;
+    if(!#t75.{core::Object::==}(null))
+      for (final core::int #t76 in #t75)
+        #t74.{core::Set::add}(#t76);
+  } =>#t74;
   core::Set<dynamic> set81ambiguous = block {
-    final core::Set<dynamic> #t79 = col::LinkedHashSet::•<dynamic>();
-    final dynamic #t80 = null;
-    if(!#t80.{core::Object::==}(null))
-      for (final dynamic #t81 in #t80) {
-        final dynamic #t82 = #t81 as{TypeError} dynamic;
-        #t79.{core::Set::add}(#t82);
+    final core::Set<dynamic> #t77 = col::LinkedHashSet::•<dynamic>();
+    final dynamic #t78 = null;
+    if(!#t78.{core::Object::==}(null))
+      for (final dynamic #t79 in #t78) {
+        final dynamic #t80 = #t79 as{TypeError} dynamic;
+        #t77.{core::Set::add}(#t80);
       }
-    for (final dynamic #t83 in <dynamic>[]) {
-      final dynamic #t84 = #t83 as{TypeError} dynamic;
-      #t79.{core::Set::add}(#t84);
+    for (final dynamic #t81 in <dynamic>[]) {
+      final dynamic #t82 = #t81 as{TypeError} dynamic;
+      #t77.{core::Set::add}(#t82);
     }
-  } =>#t79;
+  } =>#t77;
   core::Map<core::String, core::int> map80 = block {
-    final core::Map<core::String, core::int> #t85 = <core::String, core::int>{};
-    final core::Map<dynamic, dynamic> #t86 = null;
-    if(!#t86.{core::Object::==}(null))
-      for (final core::MapEntry<core::String, core::int> #t87 in #t86.{core::Map::entries})
-        #t85.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
-  } =>#t85;
+    final core::Map<core::String, core::int> #t83 = <core::String, core::int>{};
+    final core::Map<dynamic, dynamic> #t84 = null;
+    if(!#t84.{core::Object::==}(null))
+      for (final core::MapEntry<core::String, core::int> #t85 in #t84.{core::Map::entries})
+        #t83.{core::Map::[]=}(#t85.{core::MapEntry::key}, #t85.{core::MapEntry::value});
+  } =>#t83;
   core::Map<core::String, core::int> map90 = block {
-    final core::Map<core::String, core::int> #t88 = <core::String, core::int>{};
-    for (final core::MapEntry<core::String, core::int> #t89 in self::bar<core::String, core::int>().{core::Map::entries})
-      #t88.{core::Map::[]=}(#t89.{core::MapEntry::key}, #t89.{core::MapEntry::value});
-  } =>#t88;
+    final core::Map<core::String, core::int> #t86 = <core::String, core::int>{};
+    for (final core::MapEntry<core::String, core::int> #t87 in self::bar<core::String, core::int>().{core::Map::entries})
+      #t86.{core::Map::[]=}(#t87.{core::MapEntry::key}, #t87.{core::MapEntry::value});
+  } =>#t86;
   core::List<core::int> list100 = block {
-    final core::List<core::int> #t90 = <core::int>[];
-    for (final dynamic #t91 in listNum) {
-      final core::int #t92 = #t91 as{TypeError} core::int;
-      #t90.{core::List::add}(#t92);
+    final core::List<core::int> #t88 = <core::int>[];
+    for (final dynamic #t89 in listNum) {
+      final core::int #t90 = #t89 as{TypeError} core::int;
+      #t88.{core::List::add}(#t90);
     }
-  } =>#t90;
+  } =>#t88;
   core::Map<core::num, core::int> map100 = block {
-    final core::Map<core::num, core::int> #t93 = <core::num, core::int>{};
-    for (final core::MapEntry<dynamic, dynamic> #t94 in mapIntNum.{core::Map::entries}) {
-      final core::num #t95 = #t94.{core::MapEntry::key} as{TypeError} core::num;
-      final core::int #t96 = #t94.{core::MapEntry::value} as{TypeError} core::int;
-      #t93.{core::Map::[]=}(#t95, #t96);
+    final core::Map<core::num, core::int> #t91 = <core::num, core::int>{};
+    for (final core::MapEntry<dynamic, dynamic> #t92 in mapIntNum.{core::Map::entries}) {
+      final core::num #t93 = #t92.{core::MapEntry::key} as{TypeError} core::num;
+      final core::int #t94 = #t92.{core::MapEntry::value} as{TypeError} core::int;
+      #t91.{core::Map::[]=}(#t93, #t94);
     }
-  } =>#t93;
+  } =>#t91;
   core::List<core::int> list110 = block {
-    final core::List<core::int> #t97 = <core::int>[];
-    for (final dynamic #t98 in dynVar as{TypeError} core::Iterable<dynamic>) {
-      final core::int #t99 = #t98 as{TypeError} core::int;
-      #t97.{core::List::add}(#t99);
+    final core::List<core::int> #t95 = <core::int>[];
+    for (final dynamic #t96 in dynVar as{TypeError} core::Iterable<dynamic>) {
+      final core::int #t97 = #t96 as{TypeError} core::int;
+      #t95.{core::List::add}(#t97);
     }
-  } =>#t97;
+  } =>#t95;
   core::Map<core::num, core::int> map110 = block {
-    final core::Map<core::num, core::int> #t100 = <core::num, core::int>{};
-    for (final core::MapEntry<dynamic, dynamic> #t101 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
-      final core::num #t102 = #t101.{core::MapEntry::key} as{TypeError} core::num;
-      final core::int #t103 = #t101.{core::MapEntry::value} as{TypeError} core::int;
-      #t100.{core::Map::[]=}(#t102, #t103);
+    final core::Map<core::num, core::int> #t98 = <core::num, core::int>{};
+    for (final core::MapEntry<dynamic, dynamic> #t99 in (dynVar as{TypeError} core::Map<dynamic, dynamic>).{core::Map::entries}) {
+      final core::num #t100 = #t99.{core::MapEntry::key} as{TypeError} core::num;
+      final core::int #t101 = #t99.{core::MapEntry::value} as{TypeError} core::int;
+      #t98.{core::Map::[]=}(#t100, #t101);
     }
-  } =>#t100;
+  } =>#t98;
 }
 static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index d6443fb..7b802de 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -141,6 +141,7 @@
 regress/issue_35259: RuntimeError # Expected
 regress/issue_35260: RuntimeError # Expected
 regress/issue_35266: RuntimeError # Expected
+regress/issue_36400: RuntimeError
 reject_generic_function_types_in_bounds: RuntimeError # Expected
 runtime_checks_new/contravariant_generic_return_with_compound_assign_implicit_downcast: RuntimeError
 runtime_checks_new/mixin_forwarding_stub_field: TypeCheckError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 8e6529f..9da7144 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -919,6 +919,7 @@
 regress/issue_35260: TextSerializationFailure # Was: RuntimeError # Expected
 regress/issue_35266: TextSerializationFailure # Was: RuntimeError # Expected
 regress/issue_35900: TextSerializationFailure
+regress/issue_36400: TextSerializationFailure
 reject_generic_function_types_in_bounds: TextSerializationFailure # Was: RuntimeError # Expected
 return_with_unknown_type_in_context: TextSerializationFailure # Was: Pass
 runtime_checks/call_kinds: TextSerializationFailure # Was: Pass
diff --git a/pkg/kernel/bin/transform.dart b/pkg/kernel/bin/transform.dart
index d0019c3..f384400 100755
--- a/pkg/kernel/bin/transform.dart
+++ b/pkg/kernel/bin/transform.dart
@@ -102,7 +102,8 @@
     case 'constants':
       final VmConstantsBackend backend = new VmConstantsBackend(coreTypes);
       component = constants.transformComponent(
-          component, backend, defines, const constants.SimpleErrorReporter());
+          component, backend, defines, const constants.SimpleErrorReporter(),
+          enableAsserts: true);
       break;
     case 'methodcall':
       component =
diff --git a/pkg/kernel/binary.md b/pkg/kernel/binary.md
index 91d9ae1..76c12be 100644
--- a/pkg/kernel/binary.md
+++ b/pkg/kernel/binary.md
@@ -139,7 +139,7 @@
 
 type ComponentFile {
   UInt32 magic = 0x90ABCDEF;
-  UInt32 formatVersion = 22;
+  UInt32 formatVersion = 23;
   List<String> problemsAsJson; // Described in problems.md.
   Library[] libraries;
   UriSource sourceMap;
@@ -720,6 +720,15 @@
   List<Expression> maps;
 }
 
+type InstanceCreation extends Expression {
+  Byte tag = 114;
+  FileOffset fileOffset;
+  CanonicalNameReference class;
+  List<DartType> typeArguments;
+  List<[FieldReference, Expression]> fieldValues;
+  List<AssertStatement> asserts;
+}
+
 type IsExpression extends Expression {
   Byte tag = 37;
   FileOffset fileOffset;
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index 8e41e89..140a9e4 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -2211,6 +2211,9 @@
     while (type is TypeParameterType) {
       type = (type as TypeParameterType).parameter.bound;
     }
+    if (type == types.nullType) {
+      return superclass.bottomType;
+    }
     if (type is InterfaceType) {
       var upcastType = types.getTypeAsInstanceOf(type, superclass);
       if (upcastType != null) return upcastType;
@@ -3314,6 +3317,56 @@
   }
 }
 
+/// Create an instance directly from the field values.
+///
+/// This expression arises from const constructor calls when one or more field
+/// initializing expressions, field initializers or assert initializers contain
+/// unevaluated expressions. They only ever occur within unevaluated constants
+/// in constant expressions.
+class InstanceCreation extends Expression {
+  final Reference classReference;
+  final List<DartType> typeArguments;
+  final Map<Reference, Expression> fieldValues;
+  final List<AssertStatement> asserts;
+
+  InstanceCreation(
+      this.classReference, this.typeArguments, this.fieldValues, this.asserts);
+
+  Class get classNode => classReference.asClass;
+
+  DartType getStaticType(TypeEnvironment types) {
+    return typeArguments.isEmpty
+        ? classNode.rawType
+        : new InterfaceType(classNode, typeArguments);
+  }
+
+  accept(ExpressionVisitor v) => v.visitInstanceCreation(this);
+  accept1(ExpressionVisitor1 v, arg) => v.visitInstanceCreation(this, arg);
+
+  visitChildren(Visitor v) {
+    classReference.asClass.acceptReference(v);
+    visitList(typeArguments, v);
+    for (final Reference reference in fieldValues.keys) {
+      reference.asField.acceptReference(v);
+    }
+    for (final Expression value in fieldValues.values) {
+      value.accept(v);
+    }
+    visitList(asserts, v);
+  }
+
+  transformChildren(Transformer v) {
+    fieldValues.forEach((Reference fieldRef, Expression value) {
+      Expression transformed = value.accept(v);
+      if (transformed != null && !identical(value, transformed)) {
+        fieldValues[fieldRef] = transformed;
+        transformed.parent = this;
+      }
+    });
+    transformList(asserts, v, this);
+  }
+}
+
 /// Expression of form `x is T`.
 class IsExpression extends Expression {
   Expression operand;
@@ -3443,7 +3496,7 @@
 class NullLiteral extends BasicLiteral {
   Object get value => null;
 
-  DartType getStaticType(TypeEnvironment types) => const BottomType();
+  DartType getStaticType(TypeEnvironment types) => types.nullType;
 
   accept(ExpressionVisitor v) => v.visitNullLiteral(this);
   accept1(ExpressionVisitor1 v, arg) => v.visitNullLiteral(this, arg);
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 6306cef..ad088c0 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -1534,6 +1534,26 @@
         return new MapConcatenation(readExpressionList(),
             keyType: keyType, valueType: valueType)
           ..fileOffset = offset;
+      case Tag.InstanceCreation:
+        int offset = readOffset();
+        Reference classReference = readClassReference();
+        List<DartType> typeArguments = readDartTypeList();
+        int fieldValueCount = readUInt();
+        Map<Reference, Expression> fieldValues = <Reference, Expression>{};
+        for (int i = 0; i < fieldValueCount; i++) {
+          final Reference fieldRef =
+              readCanonicalNameReference().getReference();
+          final Expression value = readExpression();
+          fieldValues[fieldRef] = value;
+        }
+        int assertCount = readUInt();
+        List<AssertStatement> asserts = new List<AssertStatement>(assertCount);
+        for (int i = 0; i < assertCount; i++) {
+          asserts[i] = readStatement();
+        }
+        return new InstanceCreation(
+            classReference, typeArguments, fieldValues, asserts)
+          ..fileOffset = offset;
       case Tag.IsExpression:
         int offset = readOffset();
         return new IsExpression(readExpression(), readDartType())
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index a0619f6..2b9baba 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -1503,6 +1503,20 @@
   }
 
   @override
+  void visitInstanceCreation(InstanceCreation node) {
+    writeByte(Tag.InstanceCreation);
+    writeOffset(node.fileOffset);
+    writeNonNullReference(node.classReference);
+    writeNodeList(node.typeArguments);
+    writeUInt30(node.fieldValues.length);
+    node.fieldValues.forEach((Reference fieldRef, Expression value) {
+      writeNonNullReference(fieldRef);
+      writeNode(value);
+    });
+    writeNodeList(node.asserts);
+  }
+
+  @override
   void visitIsExpression(IsExpression node) {
     writeByte(Tag.IsExpression);
     writeOffset(node.fileOffset);
diff --git a/pkg/kernel/lib/binary/tag.dart b/pkg/kernel/lib/binary/tag.dart
index 9650fa7..42200e1 100644
--- a/pkg/kernel/lib/binary/tag.dart
+++ b/pkg/kernel/lib/binary/tag.dart
@@ -53,6 +53,7 @@
   static const int ListConcatenation = 111;
   static const int SetConcatenation = 112;
   static const int MapConcatenation = 113;
+  static const int InstanceCreation = 114;
   static const int IsExpression = 37;
   static const int AsExpression = 38;
   static const int StringLiteral = 39;
@@ -129,6 +130,7 @@
   /// 111 is occupied by [ListConcatenation] (expression).
   /// 112 is occupied by [SetConcatenation] (expression).
   /// 113 is occupied by [MapConcatenation] (expression).
+  /// 114 is occupied by [InstanceCreation] (expression).
 
   static const int SpecializedTagHighBit = 0x80; // 10000000
   static const int SpecializedTagMask = 0xF8; // 11111000
@@ -145,7 +147,7 @@
   /// Internal version of kernel binary format.
   /// Bump it when making incompatible changes in kernel binaries.
   /// Keep in sync with runtime/vm/kernel_binary.h, pkg/kernel/binary.md.
-  static const int BinaryFormatVersion = 22;
+  static const int BinaryFormatVersion = 23;
 }
 
 abstract class ConstantTag {
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index 4105a43..fd3bb4d 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -205,6 +205,18 @@
         keyType: visitType(node.keyType), valueType: visitType(node.valueType));
   }
 
+  visitInstanceCreation(InstanceCreation node) {
+    final Map<Reference, Expression> fieldValues = <Reference, Expression>{};
+    node.fieldValues.forEach((Reference fieldRef, Expression value) {
+      fieldValues[fieldRef] = clone(value);
+    });
+    return new InstanceCreation(
+        node.classReference,
+        node.typeArguments.map(visitType).toList(),
+        fieldValues,
+        node.asserts.map(clone).toList());
+  }
+
   visitIsExpression(IsExpression node) {
     return new IsExpression(clone(node.operand), visitType(node.type));
   }
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 8d957f4..5862b83 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -1302,6 +1302,39 @@
     }
   }
 
+  visitInstanceCreation(InstanceCreation node) {
+    write('${node.classNode}');
+    if (node.typeArguments.isNotEmpty) {
+      writeSymbol('<');
+      writeList(node.typeArguments, writeType);
+      writeSymbol('>');
+    }
+    write(' {');
+    bool first = true;
+    node.fieldValues.forEach((Reference fieldRef, Expression value) {
+      if (!first) {
+        writeComma();
+      }
+      write('${fieldRef.asField.name}: ');
+      writeExpression(value);
+      first = false;
+    });
+    for (AssertStatement assert_ in node.asserts) {
+      if (!first) {
+        writeComma();
+      }
+      write('assert(');
+      writeExpression(assert_.condition);
+      if (assert_.message != null) {
+        writeComma();
+        writeExpression(assert_.message);
+      }
+      write(')');
+    }
+
+    write('}');
+  }
+
   visitIsExpression(IsExpression node) {
     writeExpression(node.operand, Precedence.BITWISE_OR);
     writeSpaced('is');
@@ -2014,10 +2047,10 @@
     node.fieldValues.forEach((Reference fieldRef, Constant constant) {
       final String name = syntheticNames.nameConstant(constant);
       if (!first) {
-        first = false;
         sb.write(', ');
       }
       sb.write('${fieldRef.asField.name}: $name');
+      first = false;
     });
     sb.write('}');
     endLine(sb.toString());
diff --git a/pkg/kernel/lib/text/text_serialization_verifier.dart b/pkg/kernel/lib/text/text_serialization_verifier.dart
index b9f2662..3fed367 100644
--- a/pkg/kernel/lib/text/text_serialization_verifier.dart
+++ b/pkg/kernel/lib/text/text_serialization_verifier.dart
@@ -390,6 +390,12 @@
   }
 
   @override
+  void visitInstanceCreation(InstanceCreation node) {
+    storeLastSeenUriAndOffset(node);
+    node.visitChildren(this);
+  }
+
+  @override
   void visitSymbolConstant(SymbolConstant node) {
     storeLastSeenUriAndOffset(node);
     node.visitChildren(this);
diff --git a/pkg/kernel/lib/transformations/async.dart b/pkg/kernel/lib/transformations/async.dart
index dbdca9b..3ea9fe2 100644
--- a/pkg/kernel/lib/transformations/async.dart
+++ b/pkg/kernel/lib/transformations/async.dart
@@ -90,13 +90,11 @@
   /// surrounding context.
   Expression rewrite(Expression expression, List<Statement> outer) {
     assert(statements.isEmpty);
-    assert(nameIndex == 0);
     var saved = seenAwait;
     seenAwait = false;
     Expression result = expression.accept(this);
     outer.addAll(statements.reversed);
     statements.clear();
-    nameIndex = 0;
     seenAwait = seenAwait || saved;
     return result;
   }
diff --git a/pkg/kernel/lib/type_checker.dart b/pkg/kernel/lib/type_checker.dart
index 7f04bce..f81ec66 100644
--- a/pkg/kernel/lib/type_checker.dart
+++ b/pkg/kernel/lib/type_checker.dart
@@ -713,6 +713,18 @@
   }
 
   @override
+  DartType visitInstanceCreation(InstanceCreation node) {
+    Substitution substitution = Substitution.fromPairs(
+        node.classNode.typeParameters, node.typeArguments);
+    node.fieldValues.forEach((Reference fieldRef, Expression value) {
+      DartType fieldType = substitution.substituteType(fieldRef.asField.type);
+      DartType valueType = visitExpression(value);
+      checkAssignable(node, fieldType, valueType);
+    });
+    return new InterfaceType(node.classNode, node.typeArguments);
+  }
+
+  @override
   DartType visitStringLiteral(StringLiteral node) {
     return environment.stringType;
   }
diff --git a/pkg/kernel/lib/visitor.dart b/pkg/kernel/lib/visitor.dart
index 388f3cf..b1a9938 100644
--- a/pkg/kernel/lib/visitor.dart
+++ b/pkg/kernel/lib/visitor.dart
@@ -41,6 +41,7 @@
   R visitListConcatenation(ListConcatenation node) => defaultExpression(node);
   R visitSetConcatenation(SetConcatenation node) => defaultExpression(node);
   R visitMapConcatenation(MapConcatenation node) => defaultExpression(node);
+  R visitInstanceCreation(InstanceCreation node) => defaultExpression(node);
   R visitIsExpression(IsExpression node) => defaultExpression(node);
   R visitAsExpression(AsExpression node) => defaultExpression(node);
   R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node);
@@ -167,6 +168,7 @@
   R visitListConcatenation(ListConcatenation node) => defaultExpression(node);
   R visitSetConcatenation(SetConcatenation node) => defaultExpression(node);
   R visitMapConcatenation(MapConcatenation node) => defaultExpression(node);
+  R visitInstanceCreation(InstanceCreation node) => defaultExpression(node);
   R visitIsExpression(IsExpression node) => defaultExpression(node);
   R visitAsExpression(AsExpression node) => defaultExpression(node);
   R visitSymbolLiteral(SymbolLiteral node) => defaultExpression(node);
@@ -510,6 +512,8 @@
       defaultExpression(node, arg);
   R visitMapConcatenation(MapConcatenation node, T arg) =>
       defaultExpression(node, arg);
+  R visitInstanceCreation(InstanceCreation node, T arg) =>
+      defaultExpression(node, arg);
   R visitIsExpression(IsExpression node, T arg) => defaultExpression(node, arg);
   R visitAsExpression(AsExpression node, T arg) => defaultExpression(node, arg);
   R visitSymbolLiteral(SymbolLiteral node, T arg) =>
diff --git a/pkg/vm/bin/compare_sizes.dart b/pkg/vm/bin/compare_sizes.dart
index 691566e..6c41417 100644
--- a/pkg/vm/bin/compare_sizes.dart
+++ b/pkg/vm/bin/compare_sizes.dart
@@ -157,6 +157,7 @@
         }
         return sb.toString() + '\n' + sb.toString();
     }
+    return null; // Make analyzer happy.
   }
 }
 
@@ -209,6 +210,7 @@
         final diff = width - value.length;
         return ' ' * (diff ~/ 2) + value + (' ' * (diff - diff ~/ 2));
     }
+    return null; // Make analyzer happy.
   }
 
   int get length => value.length;
diff --git a/pkg/vm/lib/bytecode/assembler.dart b/pkg/vm/lib/bytecode/assembler.dart
index a8d8cb0..0686cd6 100644
--- a/pkg/vm/lib/bytecode/assembler.dart
+++ b/pkg/vm/lib/bytecode/assembler.dart
@@ -423,4 +423,9 @@
   void emitEntryOptional(int ra, int rb, int rc) {
     emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
   }
+
+  void emitAllocateClosure(int rd) {
+    emitSourcePosition();
+    emitWord(_encodeD(Opcode.kAllocateClosure, rd));
+  }
 }
diff --git a/pkg/vm/lib/bytecode/constant_pool.dart b/pkg/vm/lib/bytecode/constant_pool.dart
index 18b1ac1..3e204ae 100644
--- a/pkg/vm/lib/bytecode/constant_pool.dart
+++ b/pkg/vm/lib/bytecode/constant_pool.dart
@@ -4,8 +4,6 @@
 
 library vm.bytecode.constant_pool;
 
-import 'dart:typed_data';
-
 import 'package:kernel/ast.dart' hide MapEntry;
 
 import 'dbc.dart' show constantPoolIndexLimit, BytecodeLimitExceededException;
@@ -33,39 +31,6 @@
   Byte tag;
 }
 
-type ConstantNull extends ConstantPoolEntry {
-  Byte tag = 1;
-}
-
-type ConstantString extends ConstantPoolEntry {
-  Byte tag = 2;
-  PackedString value;
-}
-
-type ConstantInt extends ConstantPoolEntry {
-  Byte tag = 3;
-  UInt32 low;
-  UInt32 high;
-}
-
-type ConstantDouble extends ConstantPoolEntry {
-  Byte tag = 4;
-  UInt32 low;
-  UInt32 high;
-}
-
-type ConstantBool extends ConstantPoolEntry {
-  Byte tag = 5;
-  Byte flag;
-}
-
-type ConstantArgDesc extends ConstantPoolEntry {
-  Byte tag = 6;
-  UInt numArguments;
-  UInt numTypeArgs;
-  List<PackedString> names;
-}
-
 enum InvocationKind {
   method, // x.foo(...) or foo(...)
   getter, // x.foo
@@ -80,12 +45,6 @@
   ConstantIndex argDesc;
 }
 
-type ConstantStaticICData extends ConstantPoolEntry {
-  Byte tag = 8;
-  PackedObject target;
-  ConstantIndex argDesc;
-}
-
 type ConstantStaticField extends ConstantPoolEntry {
   Byte tag = 9;
   PackedObject field;
@@ -107,40 +66,11 @@
   PackedObject class;
 }
 
-type ConstantTearOff extends ConstantPoolEntry {
-  Byte tag = 13;
-  PackedObject target;
-}
-
 type ConstantType extends ConstantPoolEntry {
   Byte tag = 14;
   PackedObject type;
 }
 
-type ConstantTypeArguments extends ConstantPoolEntry {
-  Byte tag = 15;
-  List<PackedObject> types;
-}
-
-type ConstantList extends ConstantPoolEntry {
-  Byte tag = 16;
-  PackedObject typeArg;
-  List<ConstantIndex> entries;
-}
-
-type ConstantInstance extends ConstantPoolEntry {
-  Byte tag = 17;
-  PackedObject class;
-  ConstantIndex typeArguments;
-  List<Pair<PackedObject, ConstantIndex>> fieldValues;
-}
-
-type ConstantTypeArgumentsForInstanceAllocation extends ConstantPoolEntry {
-  Byte tag = 18;
-  PackedObject instantiatingClass;
-  List<PackedObject> types;
-}
-
 type ConstantClosureFunction extends ConstantPoolEntry {
   Byte tag = 19;
   UInt closureIndex;
@@ -159,30 +89,10 @@
   Byte tag = 22;
 }
 
-type ConstantPartialTearOffInstantiation extends ConstantPoolEntry {
-  Byte tag = 23;
-  ConstantIndex tearOffConstant;
-  ConstantIndex typeArguments;
-}
-
 type ConstantEmptyTypeArguments extends ConstantPoolEntry {
   Byte tag = 24;
 }
 
-type ConstantSymbol extends ConstantPoolEntry {
-  Byte tag = 25;
-  PackedObject name;
-}
-
-// Occupies 2 entries in the constant pool.
-type ConstantInterfaceCallV1 extends ConstantPoolEntry {
-  Byte tag = 26;
-  Byte flags(invocationKindBit0, invocationKindBit1);
-             // Where invocationKind is index into InvocationKind.
-  PackedObject targetName;
-  ConstantIndex argDesc;
-}
-
 type ConstantObjectRef extends ConstantPoolEntry {
   Byte tag = 27;
   PackedObject object;
@@ -206,32 +116,32 @@
 
 enum ConstantTag {
   kInvalid,
-  kNull, // TODO(alexmarkov): obsolete, remove
-  kString, // TODO(alexmarkov): obsolete, remove
-  kInt, // TODO(alexmarkov): obsolete, remove
-  kDouble, // TODO(alexmarkov): obsolete, remove
-  kBool, // TODO(alexmarkov): obsolete, remove
-  kArgDesc, // TODO(alexmarkov): obsolete, remove
+  kUnused1,
+  kUnused2,
+  kUnused3,
+  kUnused4,
+  kUnused5,
+  kUnused6,
   kICData,
-  kStaticICData, // TODO(alexmarkov): obsolete, remove
+  kUnused7,
   kStaticField,
   kInstanceField,
   kClass,
   kTypeArgumentsField,
-  kTearOff, // TODO(alexmarkov): obsolete, remove
+  kUnused8,
   kType,
-  kTypeArguments, // TODO(alexmarkov): obsolete, remove
-  kList, // TODO(alexmarkov): obsolete, remove
-  kInstance, // TODO(alexmarkov): obsolete, remove
-  kTypeArgumentsForInstanceAllocation, // TODO(alexmarkov): obsolete, remove
+  kUnused9,
+  kUnused10,
+  kUnused11,
+  kUnused12,
   kClosureFunction,
   kEndClosureFunctionScope,
   kNativeEntry,
   kSubtypeTestCache,
-  kPartialTearOffInstantiation, // TODO(alexmarkov): obsolete, remove
+  kUnused13,
   kEmptyTypeArguments,
-  kSymbol, // TODO(alexmarkov): obsolete, remove
-  kInterfaceCallV1, // TODO(alexmarkov): obsolete, remove
+  kUnused14,
+  kUnused15,
   kObjectRef,
   kDirectCall,
   kInterfaceCall,
@@ -261,22 +171,8 @@
     switch (tag) {
       case ConstantTag.kInvalid:
         break;
-      case ConstantTag.kNull:
-        return new ConstantNull.read(reader);
-      case ConstantTag.kString:
-        return new ConstantString.read(reader);
-      case ConstantTag.kInt:
-        return new ConstantInt.read(reader);
-      case ConstantTag.kDouble:
-        return new ConstantDouble.read(reader);
-      case ConstantTag.kBool:
-        return new ConstantBool.read(reader);
       case ConstantTag.kICData:
         return new ConstantICData.read(reader);
-      case ConstantTag.kStaticICData:
-        return new ConstantStaticICData.read(reader);
-      case ConstantTag.kArgDesc:
-        return new ConstantArgDesc.read(reader);
       case ConstantTag.kStaticField:
         return new ConstantStaticField.read(reader);
       case ConstantTag.kInstanceField:
@@ -285,18 +181,8 @@
         return new ConstantClass.read(reader);
       case ConstantTag.kTypeArgumentsField:
         return new ConstantTypeArgumentsField.read(reader);
-      case ConstantTag.kTearOff:
-        return new ConstantTearOff.read(reader);
       case ConstantTag.kType:
         return new ConstantType.read(reader);
-      case ConstantTag.kTypeArguments:
-        return new ConstantTypeArguments.read(reader);
-      case ConstantTag.kList:
-        return new ConstantList.read(reader);
-      case ConstantTag.kInstance:
-        return new ConstantInstance.read(reader);
-      case ConstantTag.kTypeArgumentsForInstanceAllocation:
-        return new ConstantTypeArgumentsForInstanceAllocation.read(reader);
       case ConstantTag.kClosureFunction:
         return new ConstantClosureFunction.read(reader);
       case ConstantTag.kEndClosureFunctionScope:
@@ -305,225 +191,36 @@
         return new ConstantNativeEntry.read(reader);
       case ConstantTag.kSubtypeTestCache:
         return new ConstantSubtypeTestCache.read(reader);
-      case ConstantTag.kPartialTearOffInstantiation:
-        return new ConstantPartialTearOffInstantiation.read(reader);
       case ConstantTag.kEmptyTypeArguments:
         return new ConstantEmptyTypeArguments.read(reader);
-      case ConstantTag.kSymbol:
-        return new ConstantSymbol.read(reader);
-      case ConstantTag.kInterfaceCallV1:
-        return new ConstantInterfaceCallV1.read(reader);
       case ConstantTag.kObjectRef:
         return new ConstantObjectRef.read(reader);
       case ConstantTag.kDirectCall:
         return new ConstantDirectCall.read(reader);
       case ConstantTag.kInterfaceCall:
         return new ConstantInterfaceCall.read(reader);
+      // Make analyzer happy.
+      case ConstantTag.kUnused1:
+      case ConstantTag.kUnused2:
+      case ConstantTag.kUnused3:
+      case ConstantTag.kUnused4:
+      case ConstantTag.kUnused5:
+      case ConstantTag.kUnused6:
+      case ConstantTag.kUnused7:
+      case ConstantTag.kUnused8:
+      case ConstantTag.kUnused9:
+      case ConstantTag.kUnused10:
+      case ConstantTag.kUnused11:
+      case ConstantTag.kUnused12:
+      case ConstantTag.kUnused13:
+      case ConstantTag.kUnused14:
+      case ConstantTag.kUnused15:
+        break;
     }
     throw 'Unexpected constant tag $tag';
   }
 }
 
-class ConstantNull extends ConstantPoolEntry {
-  const ConstantNull();
-
-  @override
-  ConstantTag get tag => ConstantTag.kNull;
-
-  @override
-  void writeValue(BufferedWriter writer) {}
-
-  ConstantNull.read(BufferedReader reader);
-
-  @override
-  String toString() => 'Null';
-
-  @override
-  int get hashCode => 1961;
-
-  @override
-  bool operator ==(other) => other is ConstantNull;
-}
-
-class ConstantString extends ConstantPoolEntry {
-  final String value;
-
-  ConstantString(this.value);
-  ConstantString.fromLiteral(StringLiteral literal) : this(literal.value);
-
-  @override
-  ConstantTag get tag => ConstantTag.kString;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedStringReference(value);
-  }
-
-  ConstantString.read(BufferedReader reader)
-      : value = reader.readPackedStringReference();
-
-  @override
-  String toString() => 'String \'$value\'';
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantString && this.value == other.value;
-}
-
-class ConstantInt extends ConstantPoolEntry {
-  final int value;
-
-  ConstantInt(this.value);
-
-  @override
-  ConstantTag get tag => ConstantTag.kInt;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    // TODO(alexmarkov): more efficient encoding
-    writer.writeUInt32(value & 0xffffffff);
-    writer.writeUInt32((value >> 32) & 0xffffffff);
-  }
-
-  ConstantInt.read(BufferedReader reader)
-      : value = reader.readUInt32() | (reader.readUInt32() << 32);
-
-  @override
-  String toString() => 'Int $value';
-
-  @override
-  int get hashCode => value;
-
-  @override
-  bool operator ==(other) => other is ConstantInt && this.value == other.value;
-}
-
-class ConstantDouble extends ConstantPoolEntry {
-  final double value;
-
-  ConstantDouble(this.value);
-
-  @override
-  ConstantTag get tag => ConstantTag.kDouble;
-
-  static int doubleToIntBits(double value) {
-    final buf = new ByteData(8);
-    buf.setFloat64(0, value, Endian.host);
-    return buf.getInt64(0, Endian.host);
-  }
-
-  static double intBitsToDouble(int bits) {
-    final buf = new ByteData(8);
-    buf.setInt64(0, bits, Endian.host);
-    return buf.getFloat64(0, Endian.host);
-  }
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    // TODO(alexmarkov): more efficient encoding
-    int bits = doubleToIntBits(value);
-    writer.writeUInt32(bits & 0xffffffff);
-    writer.writeUInt32((bits >> 32) & 0xffffffff);
-  }
-
-  ConstantDouble.read(BufferedReader reader)
-      : value =
-            intBitsToDouble(reader.readUInt32() | (reader.readUInt32() << 32));
-
-  @override
-  String toString() => 'Double $value';
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantDouble && value.compareTo(other.value) == 0;
-}
-
-class ConstantBool extends ConstantPoolEntry {
-  final bool value;
-
-  ConstantBool(this.value);
-  ConstantBool.fromLiteral(BoolLiteral literal) : this(literal.value);
-
-  @override
-  ConstantTag get tag => ConstantTag.kBool;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writeByte(value ? 1 : 0);
-  }
-
-  ConstantBool.read(BufferedReader reader) : value = reader.readByte() != 0;
-
-  @override
-  String toString() => 'Bool $value';
-
-  @override
-  int get hashCode => value.hashCode;
-
-  @override
-  bool operator ==(other) => other is ConstantBool && this.value == other.value;
-}
-
-class ConstantArgDesc extends ConstantPoolEntry {
-  final int numArguments;
-  final int numTypeArgs;
-  final List<String> argNames;
-
-  ConstantArgDesc(this.numArguments, this.numTypeArgs, this.argNames);
-
-  ConstantArgDesc.fromArguments(
-      Arguments args, bool hasReceiver, bool isFactory)
-      : this(
-            args.positional.length +
-                args.named.length +
-                (hasReceiver ? 1 : 0) +
-                // VM expects that type arguments vector passed to a factory
-                // constructor is counted in numArguments, and not counted in
-                // numTypeArgs.
-                // TODO(alexmarkov): Clean this up.
-                (isFactory ? 1 : 0),
-            isFactory ? 0 : args.types.length,
-            new List<String>.from(args.named.map((ne) => ne.name)));
-
-  @override
-  ConstantTag get tag => ConstantTag.kArgDesc;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedUInt30(numArguments);
-    writer.writePackedUInt30(numTypeArgs);
-    writer.writePackedUInt30(argNames.length);
-    argNames.forEach(writer.writePackedStringReference);
-  }
-
-  ConstantArgDesc.read(BufferedReader reader)
-      : numArguments = reader.readPackedUInt30(),
-        numTypeArgs = reader.readPackedUInt30(),
-        argNames = new List<String>.generate(reader.readPackedUInt30(),
-            (_) => reader.readPackedStringReference());
-
-  @override
-  String toString() =>
-      'ArgDesc num-args $numArguments, num-type-args $numTypeArgs, names $argNames';
-
-  @override
-  int get hashCode => _combineHashes(
-      _combineHashes(numArguments, numTypeArgs), listHashCode(argNames));
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantArgDesc &&
-      this.numArguments == other.numArguments &&
-      this.numTypeArgs == other.numTypeArgs &&
-      listEquals(this.argNames, other.argNames);
-}
-
 enum InvocationKind { method, getter, setter }
 
 String _invocationKindToString(InvocationKind kind) {
@@ -587,40 +284,6 @@
   bool operator ==(other) => identical(this, other);
 }
 
-class ConstantStaticICData extends ConstantPoolEntry {
-  final ObjectHandle target;
-  final int argDescConstantIndex;
-
-  ConstantStaticICData(this.target, this.argDescConstantIndex);
-
-  @override
-  ConstantTag get tag => ConstantTag.kStaticICData;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(target);
-    writer.writePackedUInt30(argDescConstantIndex);
-  }
-
-  ConstantStaticICData.read(BufferedReader reader)
-      : target = reader.readPackedObject(),
-        argDescConstantIndex = reader.readPackedUInt30();
-
-  @override
-  String toString() => 'StaticICData '
-      'target \'$target\', arg-desc CP#$argDescConstantIndex';
-
-  // ConstantStaticICData entries are created per call site and should not be
-  // merged, so ConstantStaticICData class uses identity [hashCode] and
-  // [operator ==].
-
-  @override
-  int get hashCode => identityHashCode(this);
-
-  @override
-  bool operator ==(other) => identical(this, other);
-}
-
 class ConstantStaticField extends ConstantPoolEntry {
   final ObjectHandle field;
 
@@ -732,33 +395,6 @@
       this.classHandle == other.classHandle;
 }
 
-class ConstantTearOff extends ConstantPoolEntry {
-  final ObjectHandle procedure;
-
-  ConstantTearOff(this.procedure);
-
-  @override
-  ConstantTag get tag => ConstantTag.kTearOff;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(procedure);
-  }
-
-  ConstantTearOff.read(BufferedReader reader)
-      : procedure = reader.readPackedObject();
-
-  @override
-  String toString() => 'TearOff $procedure';
-
-  @override
-  int get hashCode => procedure.hashCode;
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantTearOff && this.procedure == other.procedure;
-}
-
 class ConstantType extends ConstantPoolEntry {
   final ObjectHandle type;
 
@@ -784,158 +420,6 @@
   bool operator ==(other) => other is ConstantType && this.type == other.type;
 }
 
-class ConstantTypeArguments extends ConstantPoolEntry {
-  final List<ObjectHandle> typeArgs;
-
-  ConstantTypeArguments(this.typeArgs);
-
-  @override
-  ConstantTag get tag => ConstantTag.kTypeArguments;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedList(typeArgs);
-  }
-
-  ConstantTypeArguments.read(BufferedReader reader)
-      : typeArgs = reader.readPackedList();
-
-  @override
-  String toString() => 'TypeArgs $typeArgs';
-
-  @override
-  int get hashCode => listHashCode(typeArgs);
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantTypeArguments &&
-      listEquals(this.typeArgs, other.typeArgs);
-}
-
-class ConstantList extends ConstantPoolEntry {
-  final ObjectHandle typeArg;
-  final List<int> entries;
-
-  ConstantList(this.typeArg, this.entries);
-
-  @override
-  ConstantTag get tag => ConstantTag.kList;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(typeArg);
-    writer.writePackedUInt30(entries.length);
-    entries.forEach(writer.writePackedUInt30);
-  }
-
-  ConstantList.read(BufferedReader reader)
-      : typeArg = reader.readPackedObject(),
-        entries = new List<int>.generate(
-            reader.readPackedUInt30(), (_) => reader.readPackedUInt30());
-
-  @override
-  String toString() => 'List type-arg $typeArg, entries CP# $entries';
-
-  @override
-  int get hashCode => typeArg.hashCode ^ listHashCode(entries);
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantList &&
-      this.typeArg == other.typeArg &&
-      listEquals(this.entries, other.entries);
-}
-
-class ConstantInstance extends ConstantPoolEntry {
-  final ObjectHandle classHandle;
-  final int _typeArgumentsConstantIndex;
-  final Map<ObjectHandle, int> _fieldValues;
-
-  ConstantInstance(
-      this.classHandle, this._typeArgumentsConstantIndex, this._fieldValues);
-
-  @override
-  ConstantTag get tag => ConstantTag.kInstance;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(classHandle);
-    writer.writePackedUInt30(_typeArgumentsConstantIndex);
-    writer.writePackedUInt30(_fieldValues.length);
-    _fieldValues.forEach((ObjectHandle field, int valueIndex) {
-      writer.writePackedObject(field);
-      writer.writePackedUInt30(valueIndex);
-    });
-  }
-
-  ConstantInstance.read(BufferedReader reader)
-      : classHandle = reader.readPackedObject(),
-        _typeArgumentsConstantIndex = reader.readPackedUInt30(),
-        _fieldValues = new Map<ObjectHandle, int>() {
-    final fieldValuesLen = reader.readPackedUInt30();
-    for (int i = 0; i < fieldValuesLen; i++) {
-      final field = reader.readPackedObject();
-      final valueIndex = reader.readPackedUInt30();
-      _fieldValues[field] = valueIndex;
-    }
-  }
-
-  @override
-  String toString() {
-    final values = _fieldValues.map<String, String>(
-        (ObjectHandle field, int valueIndex) =>
-            new MapEntry(field.toString(), 'CP#$valueIndex'));
-    return 'Instance $classHandle type-args CP#$_typeArgumentsConstantIndex $values';
-  }
-
-  @override
-  int get hashCode => _combineHashes(
-      _combineHashes(classHandle.hashCode, _typeArgumentsConstantIndex),
-      mapHashCode(_fieldValues));
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantInstance &&
-      this.classHandle == other.classHandle &&
-      this._typeArgumentsConstantIndex == other._typeArgumentsConstantIndex &&
-      mapEquals(this._fieldValues, other._fieldValues);
-}
-
-class ConstantTypeArgumentsForInstanceAllocation extends ConstantPoolEntry {
-  final ObjectHandle instantiatingClass;
-  final List<ObjectHandle> typeArgs;
-
-  ConstantTypeArgumentsForInstanceAllocation(
-      this.instantiatingClass, this.typeArgs);
-
-  @override
-  ConstantTag get tag => ConstantTag.kTypeArgumentsForInstanceAllocation;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(instantiatingClass);
-    writer.writePackedList(typeArgs);
-  }
-
-  ConstantTypeArgumentsForInstanceAllocation.read(BufferedReader reader)
-      : instantiatingClass = reader.readPackedObject(),
-        typeArgs = reader.readPackedList();
-
-  @override
-  String toString() =>
-      'TypeArgumentsForInstanceAllocation $instantiatingClass $typeArgs';
-
-  @override
-  int get hashCode =>
-      _combineHashes(instantiatingClass.hashCode, listHashCode(typeArgs));
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantTypeArgumentsForInstanceAllocation &&
-      this.instantiatingClass == other.instantiatingClass &&
-      listEquals(this.typeArgs, other.typeArgs);
-}
-
 class ConstantClosureFunction extends ConstantPoolEntry {
   final int closureIndex;
 
@@ -1037,42 +521,6 @@
   bool operator ==(other) => identical(this, other);
 }
 
-class ConstantPartialTearOffInstantiation extends ConstantPoolEntry {
-  final int tearOffConstantIndex;
-  final int typeArgumentsConstantIndex;
-
-  ConstantPartialTearOffInstantiation(
-      this.tearOffConstantIndex, this.typeArgumentsConstantIndex);
-
-  @override
-  ConstantTag get tag => ConstantTag.kPartialTearOffInstantiation;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedUInt30(tearOffConstantIndex);
-    writer.writePackedUInt30(typeArgumentsConstantIndex);
-  }
-
-  ConstantPartialTearOffInstantiation.read(BufferedReader reader)
-      : tearOffConstantIndex = reader.readPackedUInt30(),
-        typeArgumentsConstantIndex = reader.readPackedUInt30();
-
-  @override
-  String toString() {
-    return 'PartialTearOffInstantiation tear-off CP#$tearOffConstantIndex type-args CP#$typeArgumentsConstantIndex';
-  }
-
-  @override
-  int get hashCode =>
-      _combineHashes(tearOffConstantIndex, typeArgumentsConstantIndex);
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantPartialTearOffInstantiation &&
-      this.tearOffConstantIndex == other.tearOffConstantIndex &&
-      this.typeArgumentsConstantIndex == other.typeArgumentsConstantIndex;
-}
-
 class ConstantEmptyTypeArguments extends ConstantPoolEntry {
   const ConstantEmptyTypeArguments();
 
@@ -1094,75 +542,6 @@
   bool operator ==(other) => other is ConstantEmptyTypeArguments;
 }
 
-class ConstantSymbol extends ConstantPoolEntry {
-  final ObjectHandle name;
-
-  ConstantSymbol(this.name);
-
-  @override
-  ConstantTag get tag => ConstantTag.kSymbol;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writePackedObject(name);
-  }
-
-  ConstantSymbol.read(BufferedReader reader) : name = reader.readPackedObject();
-
-  @override
-  String toString() => 'Symbol $name';
-
-  @override
-  int get hashCode => name.hashCode;
-
-  @override
-  bool operator ==(other) => other is ConstantSymbol && this.name == other.name;
-}
-
-class ConstantInterfaceCallV1 extends ConstantPoolEntry {
-  final InvocationKind invocationKind;
-  final ObjectHandle targetName;
-  final int argDescConstantIndex;
-
-  ConstantInterfaceCallV1(
-      this.invocationKind, this.targetName, this.argDescConstantIndex);
-
-  // Reserve 1 extra slot for arguments descriptor, following target name slot.
-  int get numReservedEntries => 1;
-
-  @override
-  ConstantTag get tag => ConstantTag.kInterfaceCallV1;
-
-  @override
-  void writeValue(BufferedWriter writer) {
-    writer.writeByte(invocationKind.index);
-    writer.writePackedObject(targetName);
-    writer.writePackedUInt30(argDescConstantIndex);
-  }
-
-  ConstantInterfaceCallV1.read(BufferedReader reader)
-      : invocationKind = InvocationKind.values[reader.readByte()],
-        targetName = reader.readPackedObject(),
-        argDescConstantIndex = reader.readPackedUInt30();
-
-  @override
-  String toString() => 'InterfaceCallV1 '
-      '${_invocationKindToString(invocationKind)}'
-      'target-name $targetName, arg-desc CP#$argDescConstantIndex';
-
-  @override
-  int get hashCode => _combineHashes(
-      _combineHashes(invocationKind.index, targetName.hashCode),
-      argDescConstantIndex);
-
-  @override
-  bool operator ==(other) =>
-      other is ConstantInterfaceCallV1 &&
-      this.invocationKind == other.invocationKind &&
-      this.targetName == other.targetName &&
-      this.argDescConstantIndex == other.argDescConstantIndex;
-}
-
 class ConstantObjectRef extends ConstantPoolEntry {
   final ObjectHandle object;
 
diff --git a/pkg/vm/lib/bytecode/dbc.dart b/pkg/vm/lib/bytecode/dbc.dart
index f9b3aa8..8702add 100644
--- a/pkg/vm/lib/bytecode/dbc.dart
+++ b/pkg/vm/lib/bytecode/dbc.dart
@@ -10,7 +10,7 @@
 /// Before bumping current bytecode version format, make sure that
 /// all users have switched to a VM which is able to consume new
 /// version of bytecode.
-const int currentBytecodeFormatVersion = 3;
+const int currentBytecodeFormatVersion = 4;
 
 /// Version of experimental / bleeding edge bytecode format.
 /// Produced by bytecode generator when --use-future-bytecode-format
@@ -123,6 +123,8 @@
   kCompareIntLe,
 
   kDirectCall,
+
+  kAllocateClosure,
 }
 
 enum Encoding {
@@ -300,6 +302,8 @@
       Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
   Opcode.kDirectCall: const Format(
       Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
+  Opcode.kAllocateClosure: const Format(
+      Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
 };
 
 // Should match constant in runtime/vm/stack_frame_dbc.h.
diff --git a/pkg/vm/lib/bytecode/gen_bytecode.dart b/pkg/vm/lib/bytecode/gen_bytecode.dart
index 6770f3a..0e54ba3 100644
--- a/pkg/vm/lib/bytecode/gen_bytecode.dart
+++ b/pkg/vm/lib/bytecode/gen_bytecode.dart
@@ -1745,10 +1745,7 @@
 
   void _genAllocateClosureInstance(
       TreeNode node, int closureFunctionIndex, FunctionNode function) {
-    // TODO(alexmarkov): Consider adding a bytecode to allocate closure.
-
-    assert(closureClass.typeParameters.isEmpty);
-    asm.emitAllocate(cp.addClass(closureClass));
+    asm.emitAllocateClosure(closureFunctionIndex);
 
     final int temp = locals.tempIndexInFrame(node);
     asm.emitStoreLocal(temp);
@@ -2151,19 +2148,22 @@
 
     _genTypeArguments([node.typeArgument]);
 
-    _genDupTOS(locals.tempIndexInFrame(node));
+    if (node.expressions.isEmpty) {
+      asm.emitPushConstant(
+          cp.addObjectRef(new ListConstant(const DynamicType(), const [])));
+    } else {
+      _genDupTOS(locals.tempIndexInFrame(node));
+      _genPushInt(node.expressions.length);
+      asm.emitCreateArrayTOS();
+      final int temp = locals.tempIndexInFrame(node);
+      asm.emitStoreLocal(temp);
 
-    // TODO(alexmarkov): gen more efficient code for empty array
-    _genPushInt(node.expressions.length);
-    asm.emitCreateArrayTOS();
-    final int temp = locals.tempIndexInFrame(node);
-    asm.emitStoreLocal(temp);
-
-    for (int i = 0; i < node.expressions.length; i++) {
-      asm.emitPush(temp);
-      _genPushInt(i);
-      _generateNode(node.expressions[i]);
-      asm.emitStoreIndexedTOS();
+      for (int i = 0; i < node.expressions.length; i++) {
+        asm.emitPush(temp);
+        _genPushInt(i);
+        _generateNode(node.expressions[i]);
+        asm.emitStoreIndexedTOS();
+      }
     }
 
     // List._fromLiteral is a factory constructor.
@@ -2702,6 +2702,14 @@
   }
 
   @override
+  visitBlockExpression(BlockExpression node) {
+    _enterScope(node);
+    _generateNodeList(node.body.statements);
+    _generateNode(node.value);
+    _leaveScope();
+  }
+
+  @override
   visitBreakStatement(BreakStatement node) {
     final targetLabel = labeledStatements[node.target] ??
         (throw 'Target label ${node.target} was not registered for break $node');
diff --git a/pkg/vm/lib/bytecode/local_vars.dart b/pkg/vm/lib/bytecode/local_vars.dart
index d365fd2..5d3862d 100644
--- a/pkg/vm/lib/bytecode/local_vars.dart
+++ b/pkg/vm/lib/bytecode/local_vars.dart
@@ -598,6 +598,16 @@
   }
 
   @override
+  visitBlockExpression(BlockExpression node) {
+    // Not using _visitWithScope as Block inside BlockExpression does not have
+    // a scope.
+    _enterScope(node);
+    visitList(node.body.statements, this);
+    node.value.accept(this);
+    _leaveScope();
+  }
+
+  @override
   visitAssertBlock(AssertBlock node) {
     _visitWithScope(node);
   }
@@ -1037,6 +1047,15 @@
   }
 
   @override
+  visitBlockExpression(BlockExpression node) {
+    // Not using _visit as Block inside BlockExpression does not have a scope.
+    _enterScope(node);
+    visitList(node.body.statements, this);
+    node.value.accept(this);
+    _leaveScope();
+  }
+
+  @override
   visitAssertBlock(AssertBlock node) {
     _visit(node, scope: true);
   }
diff --git a/pkg/vm/lib/kernel_front_end.dart b/pkg/vm/lib/kernel_front_end.dart
index 28d0cd0..dfc4b67 100644
--- a/pkg/vm/lib/kernel_front_end.dart
+++ b/pkg/vm/lib/kernel_front_end.dart
@@ -57,6 +57,8 @@
     show transformComponent;
 import 'transformations/no_dynamic_invocations_annotator.dart'
     as no_dynamic_invocations_annotator show transformComponent;
+import 'transformations/protobuf_aware_treeshaker/transformer.dart'
+    as protobuf_tree_shaker;
 import 'transformations/type_flow/transformer.dart' as globalTypeFlow
     show transformComponent;
 import 'transformations/obfuscation_prohibitions_annotator.dart'
@@ -93,6 +95,9 @@
       help:
           'Enable global type flow analysis and related transformations in AOT mode.',
       defaultsTo: true);
+  args.addFlag('protobuf-tree-shaker',
+      help: 'Enable protobuf tree shaker transformation in AOT mode.',
+      defaultsTo: false);
   args.addMultiOption('define',
       abbr: 'D',
       help: 'The values for the environment constants (e.g. -Dkey=value).');
@@ -118,6 +123,8 @@
       help: 'Generate bytecode in the bleeding edge format', defaultsTo: false);
   args.addMultiOption('enable-experiment',
       help: 'Comma separated list of experimental features to enable.');
+  args.addFlag('help',
+      abbr: 'h', negatable: false, help: 'Print this help message.');
 }
 
 /// Create ArgParser and populate it with options consumed by [runCompiler].
@@ -136,6 +143,11 @@
 Future<int> runCompiler(ArgResults options, String usage) async {
   final String platformKernel = options['platform'];
 
+  if (options['help']) {
+    print(usage);
+    return successExitCode;
+  }
+
   if ((options.rest.length != 1) || (platformKernel == null)) {
     print(usage);
     return badUsageExitCode;
@@ -159,6 +171,7 @@
   final bool useFutureBytecodeFormat = options['use-future-bytecode-format'];
   final bool enableAsserts = options['enable-asserts'];
   final bool enableConstantEvaluation = options['enable-constant-evaluation'];
+  final bool useProtobufTreeShaker = options['protobuf-tree-shaker'];
   final bool splitOutputByPackages = options['split-output-by-packages'];
   final bool showBytecodeSizeStat = options['show-bytecode-size-stat'];
   final List<String> experimentalFlags = options['enable-experiment'];
@@ -217,7 +230,8 @@
       dropAST: dropAST && !splitOutputByPackages,
       useFutureBytecodeFormat: useFutureBytecodeFormat,
       enableAsserts: enableAsserts,
-      enableConstantEvaluation: enableConstantEvaluation);
+      enableConstantEvaluation: enableConstantEvaluation,
+      useProtobufTreeShaker: useProtobufTreeShaker);
 
   errorPrinter.printCompilationMessages();
 
@@ -276,30 +290,36 @@
     bool dropAST: false,
     bool useFutureBytecodeFormat: false,
     bool enableAsserts: false,
-    bool enableConstantEvaluation: true}) async {
+    bool enableConstantEvaluation: true,
+    bool useProtobufTreeShaker: false}) async {
   // Replace error handler to detect if there are compilation errors.
   final errorDetector =
       new ErrorDetector(previousErrorHandler: options.onDiagnostic);
   options.onDiagnostic = errorDetector;
 
-  final component = await kernelForProgram(source, options);
-
-  // If we don't default back to the current VM we'll add environment defines
-  // for the core libraries.
-  if (component != null && environmentDefines != null) {
-    if (environmentDefines['dart.vm.product'] == 'true') {
-      environmentDefines['dart.developer.causal_async_stacks'] = 'false';
-    }
-    environmentDefines['dart.isVM'] = 'true';
-    for (final library in component.libraries) {
-      if (library.importUri.scheme == 'dart') {
-        final path = library.importUri.path;
-        if (!path.startsWith('_')) {
-          environmentDefines['dart.library.${path}'] = 'true';
-        }
+  // TODO(alexmarkov): move this logic into VmTarget and call from front-end
+  // in order to have the same defines when compiling platform.
+  assert(environmentDefines != null);
+  if (environmentDefines['dart.vm.product'] == 'true') {
+    environmentDefines['dart.developer.causal_async_stacks'] = 'false';
+  }
+  environmentDefines['dart.isVM'] = 'true';
+  // TODO(dartbug.com/36460): Derive dart.library.* definitions from platform.
+  for (String library in options.target.extraRequiredLibraries) {
+    Uri libraryUri = Uri.parse(library);
+    if (libraryUri.scheme == 'dart') {
+      final path = libraryUri.path;
+      if (!path.startsWith('_')) {
+        environmentDefines['dart.library.${path}'] = 'true';
       }
     }
   }
+  // dart:core is not mentioned in Target.extraRequiredLibraries.
+  environmentDefines['dart.library.core'] = 'true';
+
+  options.environmentDefines = environmentDefines;
+
+  final component = await kernelForProgram(source, options);
 
   // Run global transformations only if component is correct.
   if (aot && component != null) {
@@ -311,6 +331,7 @@
         environmentDefines,
         enableAsserts,
         enableConstantEvaluation,
+        useProtobufTreeShaker,
         errorDetector);
   }
 
@@ -342,6 +363,7 @@
     Map<String, String> environmentDefines,
     bool enableAsserts,
     bool enableConstantEvaluation,
+    bool useProtobufTreeShaker,
     ErrorDetector errorDetector) async {
   if (errorDetector.hasCompilationErrors) return;
 
@@ -371,6 +393,18 @@
     no_dynamic_invocations_annotator.transformComponent(component);
   }
 
+  if (useProtobufTreeShaker) {
+    if (!useGlobalTypeFlowAnalysis) {
+      throw 'Protobuf tree shaker requires type flow analysis (--tfa)';
+    }
+
+    protobuf_tree_shaker.removeUnusedProtoReferences(
+        component, coreTypes, null);
+
+    globalTypeFlow.transformComponent(
+        compilerOptions.target, coreTypes, component);
+  }
+
   // TODO(35069): avoid recomputing CSA by reading it from the platform files.
   void ignoreAmbiguousSupertypes(cls, a, b) {}
   final hierarchy = new ClassHierarchy(component,
diff --git a/pkg/vm/lib/target/flutter_runner.dart b/pkg/vm/lib/target/flutter_runner.dart
index 3ffde3c..9266f3a 100644
--- a/pkg/vm/lib/target/flutter_runner.dart
+++ b/pkg/vm/lib/target/flutter_runner.dart
@@ -43,6 +43,5 @@
         'dart:fuchsia',
         'dart:vmservice_io',
         'dart:ui',
-        'dart:mozart.internal',
       ];
 }
diff --git a/pkg/vm/lib/transformations/ffi.dart b/pkg/vm/lib/transformations/ffi.dart
index ba4e06d..bcbf5fa 100644
--- a/pkg/vm/lib/transformations/ffi.dart
+++ b/pkg/vm/lib/transformations/ffi.dart
@@ -89,6 +89,7 @@
   final Library ffiLibrary;
   final Class nativeFunctionClass;
   final Class pointerClass;
+  final Class structClass;
   final Procedure castMethod;
   final Procedure loadMethod;
   final Procedure storeMethod;
@@ -110,6 +111,7 @@
         ffiLibrary = index.getLibrary('dart:ffi'),
         nativeFunctionClass = index.getClass('dart:ffi', 'NativeFunction'),
         pointerClass = index.getClass('dart:ffi', 'Pointer'),
+        structClass = index.getClass('dart:ffi', 'Struct'),
         castMethod = index.getMember('dart:ffi', 'Pointer', 'cast'),
         loadMethod = index.getMember('dart:ffi', 'Pointer', 'load'),
         storeMethod = index.getMember('dart:ffi', 'Pointer', 'store'),
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 32ff1f4..ad38a18 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -360,6 +360,8 @@
   }
 
   bool _hasAnnotation(Class node) {
+    // Pre constant 2018 update.
+    // TODO(dacoharkes): Remove pre constant 2018 after constants change landed.
     for (Expression e in node.annotations) {
       if (e is StaticGet) {
         if (e.target == structField) {
@@ -367,7 +369,12 @@
         }
       }
     }
-    return false;
+    Iterable<Class> postConstant2018 = node.annotations
+        .whereType<ConstantExpression>()
+        .map((expr) => expr.constant)
+        .whereType<InstanceConstant>()
+        .map((constant) => constant.classNode);
+    return postConstant2018.contains(structClass);
   }
 
   void _preventTreeShaking(Class node) {
@@ -386,11 +393,20 @@
   }
 
   Iterable<NativeType> _getAnnotations(Field node) {
-    return node.annotations
+    Iterable<NativeType> preConstant2018 = node.annotations
         .whereType<ConstructorInvocation>()
         .map((expr) => expr.target.parent)
         .map((klass) => _getFieldType(klass))
         .where((type) => type != null);
+    Iterable<NativeType> postConstant2018 = node.annotations
+        .whereType<ConstantExpression>()
+        .map((expr) => expr.constant)
+        .whereType<InstanceConstant>()
+        .map((constant) => constant.classNode)
+        .map((klass) => _getFieldType(klass))
+        .where((type) => type != null);
+    // TODO(dacoharkes): Remove preConstant2018 after constants change landed.
+    return postConstant2018.followedBy(preConstant2018);
   }
 }
 
diff --git a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
index 9034c55..1aa352e 100644
--- a/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
+++ b/pkg/vm/lib/transformations/protobuf_aware_treeshaker/transformer.dart
@@ -43,7 +43,7 @@
 void _treeshakeProtos(Target target, Component component, CoreTypes coreTypes,
     TransformationInfo info) {
   globalTypeFlow.transformComponent(target, coreTypes, component);
-  final collector = _removeUnusedProtoReferences(component, coreTypes, info);
+  final collector = removeUnusedProtoReferences(component, coreTypes, info);
   if (collector == null) {
     return;
   }
@@ -59,7 +59,7 @@
   component.metadata.clear();
 }
 
-InfoCollector _removeUnusedProtoReferences(
+InfoCollector removeUnusedProtoReferences(
     Component component, CoreTypes coreTypes, TransformationInfo info) {
   final protobufUri = Uri.parse('package:protobuf/protobuf.dart');
   final protobufLibs =
diff --git a/pkg/vm/lib/transformations/type_flow/types.dart b/pkg/vm/lib/transformations/type_flow/types.dart
index 9904fa7..9c52e34 100644
--- a/pkg/vm/lib/transformations/type_flow/types.dart
+++ b/pkg/vm/lib/transformations/type_flow/types.dart
@@ -118,6 +118,17 @@
       return new Type.nullableAny();
     } else if (dartType == const BottomType()) {
       return new Type.nullable(new Type.empty());
+    } else if (
+        // Recognize Null type and use a more precise representation which
+        // doesn't need type specialization.
+        // TODO(alexmarkov): figure out where exactly approximation happens if
+        // Null is represented as Nullable(Cone(Null)) instead of
+        // Nullable(Empty).
+        dartType is InterfaceType &&
+            dartType.classNode.name == 'Null' &&
+            dartType.classNode.enclosingLibrary.importUri.scheme == 'dart' &&
+            dartType.classNode.enclosingLibrary.importUri.path == 'core') {
+      return new Type.nullable(new Type.empty());
     }
     return new Type.nullable(new ConeType(dartType));
   }
diff --git a/pkg/vm/test/frontend_server_test.dart b/pkg/vm/test/frontend_server_test.dart
index 3ff0a6c..5310517 100644
--- a/pkg/vm/test/frontend_server_test.dart
+++ b/pkg/vm/test/frontend_server_test.dart
@@ -538,8 +538,8 @@
           mainFile
               .writeAsStringSync("import 'lib.dart';  main() => print(foo);\n");
           inputStreamController.add('recompile ${mainFile.path} abc\n'
-              '${mainFile.uri}\n'
-              'abc\n'
+                  '${mainFile.uri}\n'
+                  'abc\n'
               .codeUnits);
           count += 1;
         } else if (count == 1) {
@@ -597,8 +597,8 @@
           inputStreamController.add('accept\n'.codeUnits);
           mainFile.writeAsStringSync("main() => print('foo');\n");
           inputStreamController.add('recompile ${mainFile.path} abc\n'
-              '${mainFile.uri}\n'
-              'abc\n'
+                  '${mainFile.uri}\n'
+                  'abc\n'
               .codeUnits);
           count += 1;
         } else if (count == 1) {
@@ -687,8 +687,8 @@
 
           file.writeAsStringSync("import 'lib.dart'; main() => foo();\n");
           inputStreamController.add('recompile ${file.path} abc\n'
-              '${file.path}\n'
-              'abc\n'
+                  '${file.path}\n'
+                  'abc\n'
               .codeUnits);
 
           count += 1;
@@ -757,8 +757,8 @@
           var file2 = new File('${tempDir.path}/bar.dart')..createSync();
           file2.writeAsStringSync("main() {}\n");
           inputStreamController.add('recompile ${file2.path} abc\n'
-              '${file2.path}\n'
-              'abc\n'
+                  '${file2.path}\n'
+                  'abc\n'
               .codeUnits);
         } else {
           expect(count, 1);
@@ -853,8 +853,8 @@
             inputStreamController.add('reset\n'.codeUnits);
 
             inputStreamController.add('recompile ${fileB.path} abc\n'
-                '${fileB.path}\n'
-                'abc\n'
+                    '${fileB.path}\n'
+                    'abc\n'
                 .codeUnits);
             break;
           case 1:
@@ -925,8 +925,8 @@
             var file2 = new File('${tempDir.path}/bar.dart')..createSync();
             file2.writeAsStringSync("main() { baz(); }\n");
             inputStreamController.add('recompile ${file2.uri} abc\n'
-                '${file2.uri}\n'
-                'abc\n'
+                    '${file2.uri}\n'
+                    'abc\n'
                 .codeUnits);
             break;
           case 1:
@@ -938,8 +938,8 @@
             var file2 = new File('${tempDir.path}/bar.dart')..createSync();
             file2.writeAsStringSync("main() { }\n");
             inputStreamController.add('recompile ${file2.uri} abc\n'
-                '${file2.uri}\n'
-                'abc\n'
+                    '${file2.uri}\n'
+                    'abc\n'
                 .codeUnits);
             break;
           case 2:
@@ -1132,7 +1132,7 @@
             inputStreamController.add('accept\n'.codeUnits);
             inputStreamController.add('reset\n'.codeUnits);
             inputStreamController.add('recompile ${dart2js.path} x$count\n'
-                'x$count\n'
+                    'x$count\n'
                 .codeUnits);
           } else if (count == 1) {
             // Restart. Expect full kernel file.
@@ -1157,7 +1157,7 @@
             // Reload with no changes
             inputStreamController.add('accept\n'.codeUnits);
             inputStreamController.add('recompile ${dart2js.path} x$count\n'
-                'x$count\n'
+                    'x$count\n'
                 .codeUnits);
           } else if (count == 2) {
             // Partial file. Expect to be empty.
@@ -1174,8 +1174,8 @@
             // Reload with 1 change
             inputStreamController.add('accept\n'.codeUnits);
             inputStreamController.add('recompile ${dart2js.path} x$count\n'
-                '${dart2jsOtherFile.uri}\n'
-                'x$count\n'
+                    '${dart2jsOtherFile.uri}\n'
+                    'x$count\n'
                 .codeUnits);
           } else if (count == 3) {
             // Partial file. Expect to not be empty.
diff --git a/pkg/vm/test/incremental_compiler_test.dart b/pkg/vm/test/incremental_compiler_test.dart
index a280c93..2b714ec 100644
--- a/pkg/vm/test/incremental_compiler_test.dart
+++ b/pkg/vm/test/incremental_compiler_test.dart
@@ -408,6 +408,7 @@
       vm = await Process.start(Platform.resolvedExecutable, <String>[
         "--pause-isolates-on-exit",
         "--enable-vm-service:0",
+        "--disable-service-auth-codes",
         list.path
       ]);
 
@@ -469,6 +470,7 @@
         '--trace_reload_verbose',
         '--enable-vm-service=0', // Note: use 0 to avoid port collisions.
         '--pause_isolates_on_start',
+        '--disable-service-auth-codes',
         outputFile.path
       ];
       final vm = await Process.start(Platform.resolvedExecutable, vmArgs);
diff --git a/pkg/vm/testcases/bytecode/async.dart.expect b/pkg/vm/testcases/bytecode/async.dart.expect
index 3a89af2..cce2837 100644
--- a/pkg/vm/testcases/bytecode/async.dart.expect
+++ b/pkg/vm/testcases/bytecode/async.dart.expect
@@ -15,20 +15,20 @@
 Bytecode {
   Entry                3
   CheckStack           0
-  Allocate             CP#20
+  AllocateClosure      CP#0
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r2
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r2
   PushConstant         CP#0
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
@@ -55,27 +55,26 @@
   [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [18] = Reserved
   [19] = EndClosureFunctionScope
-  [20] = Class dart:core::_Closure
-  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [22] = Reserved
-  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [24] = Reserved
-  [25] = EmptyTypeArguments
-  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [27] = Reserved
-  [28] = InstanceField dart:core::_Closure::_function (field)
-  [29] = Reserved
-  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [31] = Reserved
-  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [33] = Reserved
-  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [35] = Reserved
-  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [37] = ICData dynamic target-name 'start', arg-desc CP#36
-  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [39] = Reserved
-  [40] = EndClosureFunctionScope
+  [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [21] = Reserved
+  [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [23] = Reserved
+  [24] = EmptyTypeArguments
+  [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [26] = Reserved
+  [27] = InstanceField dart:core::_Closure::_function (field)
+  [28] = Reserved
+  [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [30] = Reserved
+  [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [32] = Reserved
+  [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [34] = Reserved
+  [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [36] = ICData dynamic target-name 'start', arg-desc CP#35
+  [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [38] = Reserved
+  [39] = EndClosureFunctionScope
 }
 Closure #lib::asyncInFieldInitializer (field)::'<anonymous closure>' (dart:async::Future < dart:core::int > x) -> dart:async::Future < dart:core::Null >
 ClosureCode {
@@ -126,47 +125,47 @@
   PushNull
   StoreContextVar      0, 7
   Push                 r0
-  Allocate             CP#20
+  AllocateClosure      CP#10
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r2
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r2
   PushConstant         CP#10
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#30
+  DirectCall           1, CP#29
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#32
+  DirectCall           1, CP#31
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#34
+  DirectCall           1, CP#33
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#37
+  DynamicCall          2, CP#36
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#38
+  InterfaceCall        1, CP#37
   ReturnTOS
 
 }
@@ -294,41 +293,41 @@
   Push                 r0
   PushNull
   StoreContextVar      0, 3
-  Allocate             CP#14
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#15
+  StoreFieldTOS        CP#14
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#16
   Push                 r2
-  PushConstant         CP#19
-  StoreFieldTOS        CP#20
+  PushConstant         CP#18
+  StoreFieldTOS        CP#19
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#22
+  StoreFieldTOS        CP#21
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   PopLocal             r6
   Push                 r6
-  DirectCall           1, CP#24
+  DirectCall           1, CP#23
   PopLocal             r3
   Push                 r6
-  DirectCall           1, CP#26
+  DirectCall           1, CP#25
   PopLocal             r4
   Push                 r6
-  DirectCall           1, CP#28
+  DirectCall           1, CP#27
   PopLocal             r5
   Push                 r0
   LoadContextVar       0, 0
   Push                 r6
-  DynamicCall          2, CP#31
+  DynamicCall          2, CP#30
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  InterfaceCall        1, CP#32
+  InterfaceCall        1, CP#31
   ReturnTOS
 }
 ConstantPool {
@@ -346,26 +345,25 @@
   [11] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [12] = Reserved
   [13] = EndClosureFunctionScope
-  [14] = Class dart:core::_Closure
-  [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [16] = Reserved
-  [17] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [18] = Reserved
-  [19] = EmptyTypeArguments
-  [20] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [21] = Reserved
-  [22] = InstanceField dart:core::_Closure::_function (field)
-  [23] = Reserved
-  [24] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [25] = Reserved
-  [26] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [27] = Reserved
-  [28] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [29] = Reserved
-  [30] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [31] = ICData dynamic target-name 'start', arg-desc CP#30
-  [32] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [33] = Reserved
+  [14] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [15] = Reserved
+  [16] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [17] = Reserved
+  [18] = EmptyTypeArguments
+  [19] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [20] = Reserved
+  [21] = InstanceField dart:core::_Closure::_function (field)
+  [22] = Reserved
+  [23] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [24] = Reserved
+  [25] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [26] = Reserved
+  [27] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [28] = Reserved
+  [29] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [30] = ICData dynamic target-name 'start', arg-desc CP#29
+  [31] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [32] = Reserved
 }
 Closure #lib::foo::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureCode {
@@ -475,47 +473,47 @@
   PushNull
   StoreContextVar      0, 9
   Push                 r0
-  Allocate             CP#18
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#19
+  StoreFieldTOS        CP#18
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r2
-  PushConstant         CP#23
-  StoreFieldTOS        CP#24
+  PushConstant         CP#22
+  StoreFieldTOS        CP#23
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#26
+  StoreFieldTOS        CP#25
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#28
+  DirectCall           1, CP#27
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#30
+  DirectCall           1, CP#29
   StoreContextVar      0, 4
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#32
+  DirectCall           1, CP#31
   StoreContextVar      0, 5
   Push                 r0
   LoadContextVar       0, 2
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#35
+  DynamicCall          2, CP#34
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  InterfaceCall        1, CP#36
+  InterfaceCall        1, CP#35
   ReturnTOS
 }
 ConstantPool {
@@ -537,26 +535,25 @@
   [15] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [16] = Reserved
   [17] = EndClosureFunctionScope
-  [18] = Class dart:core::_Closure
-  [19] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [20] = Reserved
-  [21] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [22] = Reserved
-  [23] = EmptyTypeArguments
-  [24] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [25] = Reserved
-  [26] = InstanceField dart:core::_Closure::_function (field)
-  [27] = Reserved
-  [28] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [29] = Reserved
-  [30] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [31] = Reserved
-  [32] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [33] = Reserved
-  [34] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [35] = ICData dynamic target-name 'start', arg-desc CP#34
-  [36] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [37] = Reserved
+  [18] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [19] = Reserved
+  [20] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [21] = Reserved
+  [22] = EmptyTypeArguments
+  [23] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [24] = Reserved
+  [25] = InstanceField dart:core::_Closure::_function (field)
+  [26] = Reserved
+  [27] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [28] = Reserved
+  [29] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [30] = Reserved
+  [31] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [32] = Reserved
+  [33] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [34] = ICData dynamic target-name 'start', arg-desc CP#33
+  [35] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [36] = Reserved
 }
 Closure #lib::simpleAsyncAwait::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureCode {
@@ -733,47 +730,47 @@
   PushNull
   StoreContextVar      0, 9
   Push                 r0
-  Allocate             CP#26
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#27
+  StoreFieldTOS        CP#26
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#29
+  StoreFieldTOS        CP#28
   Push                 r2
-  PushConstant         CP#31
-  StoreFieldTOS        CP#32
+  PushConstant         CP#30
+  StoreFieldTOS        CP#31
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#34
+  StoreFieldTOS        CP#33
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 10
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#36
+  DirectCall           1, CP#35
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#38
+  DirectCall           1, CP#37
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 10
-  DirectCall           1, CP#40
+  DirectCall           1, CP#39
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 10
-  DynamicCall          2, CP#43
+  DynamicCall          2, CP#42
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#44
+  InterfaceCall        1, CP#43
   ReturnTOS
 }
 ConstantPool {
@@ -803,26 +800,25 @@
   [23] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [24] = Reserved
   [25] = EndClosureFunctionScope
-  [26] = Class dart:core::_Closure
-  [27] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [28] = Reserved
-  [29] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [30] = Reserved
-  [31] = EmptyTypeArguments
-  [32] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [33] = Reserved
-  [34] = InstanceField dart:core::_Closure::_function (field)
-  [35] = Reserved
-  [36] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [37] = Reserved
-  [38] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [39] = Reserved
-  [40] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [41] = Reserved
-  [42] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [43] = ICData dynamic target-name 'start', arg-desc CP#42
-  [44] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [45] = Reserved
+  [26] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [27] = Reserved
+  [28] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [29] = Reserved
+  [30] = EmptyTypeArguments
+  [31] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [32] = Reserved
+  [33] = InstanceField dart:core::_Closure::_function (field)
+  [34] = Reserved
+  [35] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [36] = Reserved
+  [37] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [38] = Reserved
+  [39] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [40] = Reserved
+  [41] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [42] = ICData dynamic target-name 'start', arg-desc CP#41
+  [43] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [44] = Reserved
 }
 Closure #lib::loops::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureCode {
@@ -1074,7 +1070,7 @@
 Bytecode {
   Entry                4
   CheckStack           0
-  AllocateContext      0, 16
+  AllocateContext      0, 18
   PopLocal             r0
   Push                 r0
   Push                 FP[-7]
@@ -1130,47 +1126,53 @@
   PushNull
   StoreContextVar      0, 14
   Push                 r0
-  Allocate             CP#24
+  PushNull
+  StoreContextVar      0, 15
+  Push                 r0
+  PushNull
+  StoreContextVar      0, 16
+  Push                 r0
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#25
+  StoreFieldTOS        CP#24
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#27
+  StoreFieldTOS        CP#26
   Push                 r2
-  PushConstant         CP#29
-  StoreFieldTOS        CP#30
+  PushConstant         CP#28
+  StoreFieldTOS        CP#29
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#32
+  StoreFieldTOS        CP#31
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
-  StoreContextVar      0, 15
+  StoreContextVar      0, 17
   Push                 r0
-  LoadContextVar       0, 15
-  DirectCall           1, CP#34
+  LoadContextVar       0, 17
+  DirectCall           1, CP#33
   PopLocal             r3
   Push                 r0
   Push                 r0
-  LoadContextVar       0, 15
-  DirectCall           1, CP#36
+  LoadContextVar       0, 17
+  DirectCall           1, CP#35
   StoreContextVar      0, 5
   Push                 r0
   Push                 r0
-  LoadContextVar       0, 15
-  DirectCall           1, CP#38
+  LoadContextVar       0, 17
+  DirectCall           1, CP#37
   StoreContextVar      0, 6
   Push                 r0
   LoadContextVar       0, 3
   Push                 r0
-  LoadContextVar       0, 15
-  DynamicCall          2, CP#41
+  LoadContextVar       0, 17
+  DynamicCall          2, CP#40
   Drop1
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        1, CP#42
+  InterfaceCall        1, CP#41
   ReturnTOS
 }
 ConstantPool {
@@ -1198,26 +1200,25 @@
   [21] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [22] = Reserved
   [23] = EndClosureFunctionScope
-  [24] = Class dart:core::_Closure
-  [25] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [26] = Reserved
-  [27] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [28] = Reserved
-  [29] = EmptyTypeArguments
-  [30] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [31] = Reserved
-  [32] = InstanceField dart:core::_Closure::_function (field)
-  [33] = Reserved
-  [34] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [35] = Reserved
-  [36] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [37] = Reserved
-  [38] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [39] = Reserved
-  [40] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [41] = ICData dynamic target-name 'start', arg-desc CP#40
-  [42] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [43] = Reserved
+  [24] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [25] = Reserved
+  [26] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [27] = Reserved
+  [28] = EmptyTypeArguments
+  [29] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [30] = Reserved
+  [31] = InstanceField dart:core::_Closure::_function (field)
+  [32] = Reserved
+  [33] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [34] = Reserved
+  [35] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [36] = Reserved
+  [37] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [38] = Reserved
+  [39] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [40] = ICData dynamic target-name 'start', arg-desc CP#39
+  [41] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [42] = Reserved
 }
 Closure #lib::tryCatchRethrow::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureCode {
@@ -1282,7 +1283,7 @@
   LoadContextVar       0, 6
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 15
+  LoadContextVar       0, 17
   DirectCall           4, CP#8
   PopLocal             r13
   PushNull
@@ -1339,7 +1340,7 @@
   LoadContextParent
   Push                 r4
   LoadContextVar       1, 0
-  StoreContextVar      0, 14
+  StoreContextVar      0, 15
   Push                 r4
   LoadContextParent
   PushInt              2
@@ -1359,7 +1360,7 @@
   LoadContextVar       0, 6
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 15
+  LoadContextVar       0, 17
   DirectCall           4, CP#8
   PopLocal             r13
   PushNull
@@ -1374,7 +1375,7 @@
   Push                 r4
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 14
+  LoadContextVar       0, 15
   Push                 r1
   InterfaceCall        2, CP#10
   StoreContextVar      1, 0
@@ -1413,7 +1414,7 @@
   LoadContextParent
   Push                 r4
   LoadContextVar       1, 0
-  StoreContextVar      0, 14
+  StoreContextVar      0, 16
   Push                 r4
   LoadContextParent
   PushInt              3
@@ -1433,7 +1434,7 @@
   LoadContextVar       0, 6
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 15
+  LoadContextVar       0, 17
   DirectCall           4, CP#8
   PopLocal             r12
   PushNull
@@ -1448,7 +1449,7 @@
   Push                 r4
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 14
+  LoadContextVar       0, 16
   Push                 r1
   InterfaceCall        2, CP#10
   StoreContextVar      1, 0
@@ -1475,7 +1476,7 @@
   LoadContextParent
   Push                 r4
   LoadContextVar       1, 0
-  StoreContextVar      0, 14
+  StoreContextVar      0, 16
   Push                 r4
   LoadContextParent
   PushInt              4
@@ -1495,7 +1496,7 @@
   LoadContextVar       0, 6
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 15
+  LoadContextVar       0, 17
   DirectCall           4, CP#8
   PopLocal             r12
   PushNull
@@ -1510,7 +1511,7 @@
   Push                 r4
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 14
+  LoadContextVar       0, 16
   Push                 r1
   InterfaceCall        2, CP#10
   StoreContextVar      1, 0
@@ -1537,7 +1538,7 @@
   LoadContextParent
   Push                 r4
   LoadContextVar       1, 0
-  StoreContextVar      0, 14
+  StoreContextVar      0, 16
   Push                 r4
   LoadContextParent
   PushInt              5
@@ -1557,7 +1558,7 @@
   LoadContextVar       0, 6
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 15
+  LoadContextVar       0, 17
   DirectCall           4, CP#8
   PopLocal             r12
   PushNull
@@ -1572,7 +1573,7 @@
   Push                 r4
   Push                 r4
   LoadContextParent
-  LoadContextVar       0, 14
+  LoadContextVar       0, 16
   Push                 r1
   InterfaceCall        2, CP#10
   StoreContextVar      1, 0
@@ -1656,20 +1657,20 @@
   Push                 r0
   PushInt              3
   StoreContextVar      0, 1
-  Allocate             CP#20
+  AllocateClosure      CP#0
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r3
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r3
   PushConstant         CP#0
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
@@ -1698,27 +1699,26 @@
   [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [18] = Reserved
   [19] = EndClosureFunctionScope
-  [20] = Class dart:core::_Closure
-  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [22] = Reserved
-  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [24] = Reserved
-  [25] = EmptyTypeArguments
-  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [27] = Reserved
-  [28] = InstanceField dart:core::_Closure::_function (field)
-  [29] = Reserved
-  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [31] = Reserved
-  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [33] = Reserved
-  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [35] = Reserved
-  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [37] = ICData dynamic target-name 'start', arg-desc CP#36
-  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [39] = Reserved
-  [40] = EndClosureFunctionScope
+  [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [21] = Reserved
+  [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [23] = Reserved
+  [24] = EmptyTypeArguments
+  [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [26] = Reserved
+  [27] = InstanceField dart:core::_Closure::_function (field)
+  [28] = Reserved
+  [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [30] = Reserved
+  [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [32] = Reserved
+  [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [34] = Reserved
+  [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [36] = ICData dynamic target-name 'start', arg-desc CP#35
+  [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [38] = Reserved
+  [39] = EndClosureFunctionScope
 }
 Closure #lib::closure::'nested' () -> dart:async::Future < dart:core::int >
 ClosureCode {
@@ -1766,47 +1766,47 @@
   PushNull
   StoreContextVar      1, 7
   Push                 r0
-  Allocate             CP#20
+  AllocateClosure      CP#7
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r2
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r2
   PushConstant         CP#7
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
   StoreContextVar      1, 8
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#30
+  DirectCall           1, CP#29
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#32
+  DirectCall           1, CP#31
   StoreContextVar      1, 2
   Push                 r0
   Push                 r0
   LoadContextVar       1, 8
-  DirectCall           1, CP#34
+  DirectCall           1, CP#33
   StoreContextVar      1, 3
   Push                 r0
   LoadContextVar       1, 0
   Push                 r0
   LoadContextVar       1, 8
-  DynamicCall          2, CP#37
+  DynamicCall          2, CP#36
   Drop1
   Push                 r0
   LoadContextVar       1, 0
-  InterfaceCall        1, CP#38
+  InterfaceCall        1, CP#37
   ReturnTOS
 
 }
@@ -2013,47 +2013,47 @@
   PushNull
   StoreContextVar      0, 7
   Push                 r0
-  Allocate             CP#20
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#21
+  StoreFieldTOS        CP#20
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#23
+  StoreFieldTOS        CP#22
   Push                 r2
-  PushConstant         CP#25
-  StoreFieldTOS        CP#26
+  PushConstant         CP#24
+  StoreFieldTOS        CP#25
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#28
+  StoreFieldTOS        CP#27
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#6
   StoreContextVar      0, 8
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#30
+  DirectCall           1, CP#29
   PopLocal             r3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#32
+  DirectCall           1, CP#31
   StoreContextVar      0, 3
   Push                 r0
   Push                 r0
   LoadContextVar       0, 8
-  DirectCall           1, CP#34
+  DirectCall           1, CP#33
   StoreContextVar      0, 4
   Push                 r0
   LoadContextVar       0, 1
   Push                 r0
   LoadContextVar       0, 8
-  DynamicCall          2, CP#37
+  DynamicCall          2, CP#36
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  InterfaceCall        1, CP#38
+  InterfaceCall        1, CP#37
   ReturnTOS
 }
 ConstantPool {
@@ -2077,26 +2077,25 @@
   [17] = InterfaceCall 'dart:async::Completer::completeError', ArgDesc num-args 3, num-type-args 0, names []
   [18] = Reserved
   [19] = EndClosureFunctionScope
-  [20] = Class dart:core::_Closure
-  [21] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [22] = Reserved
-  [23] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [24] = Reserved
-  [25] = EmptyTypeArguments
-  [26] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [27] = Reserved
-  [28] = InstanceField dart:core::_Closure::_function (field)
-  [29] = Reserved
-  [30] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [31] = Reserved
-  [32] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [33] = Reserved
-  [34] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
-  [35] = Reserved
-  [36] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [37] = ICData dynamic target-name 'start', arg-desc CP#36
-  [38] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
-  [39] = Reserved
+  [20] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [21] = Reserved
+  [22] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [23] = Reserved
+  [24] = EmptyTypeArguments
+  [25] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [26] = Reserved
+  [27] = InstanceField dart:core::_Closure::_function (field)
+  [28] = Reserved
+  [29] = DirectCall 'dart:async::_asyncStackTraceHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [30] = Reserved
+  [31] = DirectCall 'dart:async::_asyncThenWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [32] = Reserved
+  [33] = DirectCall 'dart:async::_asyncErrorWrapperHelper', ArgDesc num-args 1, num-type-args 0, names []
+  [34] = Reserved
+  [35] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [36] = ICData dynamic target-name 'start', arg-desc CP#35
+  [37] = InterfaceCall 'dart:async::Completer::get:future', ArgDesc num-args 1, num-type-args 0, names []
+  [38] = Reserved
 }
 Closure #lib::testAssert::':async_op' ([ dynamic :result, dynamic :exception, dynamic :stack_trace ]) -> dynamic
 ClosureCode {
@@ -2367,6 +2366,8 @@
     dynamic :exception0;
     dynamic :stack_trace0;
     dynamic :async_temporary_0;
+    dynamic :async_temporary_1;
+    dynamic :async_temporary_2;
     function :async_op([dynamic :result, dynamic :exception, dynamic :stack_trace]) → dynamic yielding 
       try {
         #L5:
@@ -2383,16 +2384,16 @@
                 :return_value = 42;
                 break #L5;
               }
-              :async_temporary_0 = x;
+              :async_temporary_1 = x;
               [yield] let dynamic #t6 = dart.async::_awaitHelper(b, :async_op_then, :async_op_error, :async_op) in null;
-              x = :async_temporary_0.{dart.core::num::+}(:result);
+              x = :async_temporary_1.{dart.core::num::+}(:result);
               rethrow;
             }
           finally {
             dart.core::print("fin");
-            :async_temporary_0 = x;
+            :async_temporary_2 = x;
             [yield] let dynamic #t7 = dart.async::_awaitHelper(c, :async_op_then, :async_op_error, :async_op) in null;
-            x = :async_temporary_0.{dart.core::num::+}(:result);
+            x = :async_temporary_2.{dart.core::num::+}(:result);
             :return_value = x;
             break #L5;
           }
diff --git a/pkg/vm/testcases/bytecode/closures.dart.expect b/pkg/vm/testcases/bytecode/closures.dart.expect
index 50124d6..c168ee6 100644
--- a/pkg/vm/testcases/bytecode/closures.dart.expect
+++ b/pkg/vm/testcases/bytecode/closures.dart.expect
@@ -24,27 +24,27 @@
   Push                 r0
   PushInt              5
   StoreContextVar      0, 0
-  Allocate             CP#7
+  AllocateClosure      CP#0
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#8
+  StoreFieldTOS        CP#7
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#9
   Push                 r3
-  PushConstant         CP#12
-  StoreFieldTOS        CP#13
+  PushConstant         CP#11
+  StoreFieldTOS        CP#12
   Push                 r3
   PushConstant         CP#0
-  StoreFieldTOS        CP#15
+  StoreFieldTOS        CP#14
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
   PushInt              3
-  DynamicCall          2, CP#18
+  DynamicCall          2, CP#17
   Drop1
   Push                 r0
   LoadContextVar       0, 0
@@ -58,18 +58,17 @@
   [4] = ObjectRef 'y'
   [5] = SubtypeTestCache
   [6] = EndClosureFunctionScope
-  [7] = Class dart:core::_Closure
-  [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [9] = Reserved
-  [10] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [11] = Reserved
-  [12] = EmptyTypeArguments
-  [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [14] = Reserved
-  [15] = InstanceField dart:core::_Closure::_function (field)
-  [16] = Reserved
-  [17] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [18] = ICData dynamic target-name 'call', arg-desc CP#17
+  [7] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [8] = Reserved
+  [9] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [10] = Reserved
+  [11] = EmptyTypeArguments
+  [12] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [13] = Reserved
+  [14] = InstanceField dart:core::_Closure::_function (field)
+  [15] = Reserved
+  [16] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [17] = ICData dynamic target-name 'call', arg-desc CP#16
 }
 Closure #lib::simpleClosure::'<anonymous closure>' (dart:core::int y) -> dart:core::Null
 ClosureCode {
@@ -246,11 +245,11 @@
 Bytecode {
   Entry                7
   CheckStack           0
-  Allocate             CP#14
+  AllocateClosure      CP#0
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#15
+  StoreFieldTOS        CP#14
   Push                 r3
   PushNull
   StoreFieldTOS        CP#6
@@ -259,33 +258,33 @@
   StoreFieldTOS        CP#3
   Push                 r3
   PushConstant         CP#0
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#16
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
   StoreLocal           r3
-  PushConstant         CP#19
+  PushConstant         CP#18
   StoreLocal           r6
-  DirectCall           2, CP#20
+  DirectCall           2, CP#19
   Drop1
-  Allocate             CP#14
+  Allocate             CP#21
   StoreLocal           r5
   Push                 r6
   StoreFieldTOS        CP#3
   Push                 r5
   Push                 r3
-  LoadFieldTOS         CP#15
-  StoreFieldTOS        CP#15
+  LoadFieldTOS         CP#14
+  StoreFieldTOS        CP#14
   Push                 r5
   Push                 r3
   LoadFieldTOS         CP#6
   StoreFieldTOS        CP#6
   Push                 r5
   Push                 r3
-  LoadFieldTOS         CP#17
-  StoreFieldTOS        CP#17
+  LoadFieldTOS         CP#16
+  StoreFieldTOS        CP#16
   Push                 r5
   Push                 r3
   LoadFieldTOS         CP#1
@@ -310,14 +309,14 @@
   [11] = ObjectRef 't'
   [12] = SubtypeTestCache
   [13] = EndClosureFunctionScope
-  [14] = Class dart:core::_Closure
-  [15] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [16] = Reserved
-  [17] = InstanceField dart:core::_Closure::_function (field)
-  [18] = Reserved
-  [19] = ObjectRef < dart:core::int >
-  [20] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names []
-  [21] = Reserved
+  [14] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [15] = Reserved
+  [16] = InstanceField dart:core::_Closure::_function (field)
+  [17] = Reserved
+  [18] = ObjectRef < dart:core::int >
+  [19] = DirectCall 'dart:_internal::_boundsCheckForPartialInstantiation', ArgDesc num-args 2, num-type-args 0, names []
+  [20] = Reserved
+  [21] = Class dart:core::_Closure
 }
 Closure #lib::testPartialInstantiation::'foo' <dart:core::Object T> (#lib::testPartialInstantiation::Closure/0::TypeParam/0 t) -> void
 ClosureCode {
@@ -672,12 +671,12 @@
   Push                 r1
   Push                 FP[-5]
   StoreContextVar      0, 0
-  Allocate             CP#30
+  AllocateClosure      CP#0
   StoreLocal           r4
   Push                 r4
   Push                 FP[-5]
   LoadTypeArgumentsField CP#14
-  StoreFieldTOS        CP#31
+  StoreFieldTOS        CP#30
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -686,18 +685,18 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#0
-  StoreFieldTOS        CP#33
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
-  PushConstant         CP#44
+  PushConstant         CP#43
   Push                 r3
-  DynamicCall          2, CP#45
+  DynamicCall          2, CP#44
   Drop1
-  PushConstant         CP#46
+  PushConstant         CP#45
   Push                 r3
-  DynamicCall          2, CP#47
+  DynamicCall          2, CP#46
   Drop1
   PushNull
   ReturnTOS
@@ -733,24 +732,23 @@
   [27] = DirectCall '#lib::callWithArgs', ArgDesc num-args 0, num-type-args 8, names []
   [28] = Reserved
   [29] = EndClosureFunctionScope
-  [30] = Class dart:core::_Closure
-  [31] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [32] = Reserved
-  [33] = InstanceField dart:core::_Closure::_function (field)
-  [34] = Reserved
-  [35] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [36] = ICData dynamic target-name 'call', arg-desc CP#35
-  [37] = EndClosureFunctionScope
-  [38] = ObjectRef < #lib::C7, #lib::C8 >
-  [39] = ObjectRef ArgDesc num-args 1, num-type-args 2, names []
-  [40] = ICData dynamic target-name 'call', arg-desc CP#39
-  [41] = ObjectRef < dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 > >
-  [42] = ICData dynamic target-name 'call', arg-desc CP#39
-  [43] = EndClosureFunctionScope
-  [44] = ObjectRef < #lib::C5, #lib::C6 >
-  [45] = ICData dynamic target-name 'call', arg-desc CP#39
-  [46] = ObjectRef < dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 > >
-  [47] = ICData dynamic target-name 'call', arg-desc CP#39
+  [30] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [31] = Reserved
+  [32] = InstanceField dart:core::_Closure::_function (field)
+  [33] = Reserved
+  [34] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [35] = ICData dynamic target-name 'call', arg-desc CP#34
+  [36] = EndClosureFunctionScope
+  [37] = ObjectRef < #lib::C7, #lib::C8 >
+  [38] = ObjectRef ArgDesc num-args 1, num-type-args 2, names []
+  [39] = ICData dynamic target-name 'call', arg-desc CP#38
+  [40] = ObjectRef < dart:core::List < #lib::C7 >, dart:core::List < #lib::C8 > >
+  [41] = ICData dynamic target-name 'call', arg-desc CP#38
+  [42] = EndClosureFunctionScope
+  [43] = ObjectRef < #lib::C5, #lib::C6 >
+  [44] = ICData dynamic target-name 'call', arg-desc CP#38
+  [45] = ObjectRef < dart:core::List < #lib::C5 >, dart:core::List < #lib::C6 > >
+  [46] = ICData dynamic target-name 'call', arg-desc CP#38
 }
 Closure #lib::A::foo::'nested1' <dart:core::Object T5, dart:core::Object T6> () -> void
 ClosureCode {
@@ -776,13 +774,13 @@
   PushInt              4
   DirectCall           4, CP#8
   PopLocal             r0
-  Allocate             CP#30
+  AllocateClosure      CP#10
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0, 0
   LoadTypeArgumentsField CP#14
-  StoreFieldTOS        CP#31
+  StoreFieldTOS        CP#30
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -791,18 +789,18 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#10
-  StoreFieldTOS        CP#33
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
-  PushConstant         CP#38
+  PushConstant         CP#37
   Push                 r3
-  DynamicCall          2, CP#40
+  DynamicCall          2, CP#39
   Drop1
-  PushConstant         CP#41
+  PushConstant         CP#40
   Push                 r3
-  DynamicCall          2, CP#42
+  DynamicCall          2, CP#41
   Drop1
   PushNull
   ReturnTOS
@@ -833,13 +831,13 @@
   PushInt              6
   DirectCall           4, CP#8
   PopLocal             r0
-  Allocate             CP#30
+  AllocateClosure      CP#11
   StoreLocal           r4
   Push                 r4
   Push                 r1
   LoadContextVar       0, 0
   LoadTypeArgumentsField CP#14
-  StoreFieldTOS        CP#31
+  StoreFieldTOS        CP#30
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#6
@@ -848,13 +846,13 @@
   StoreFieldTOS        CP#3
   Push                 r4
   PushConstant         CP#11
-  StoreFieldTOS        CP#33
+  StoreFieldTOS        CP#32
   Push                 r4
   Push                 r1
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#36
+  DynamicCall          1, CP#35
   Drop1
   PushNull
   ReturnTOS
@@ -1016,66 +1014,66 @@
   Push                 r0
   PushInt              3
   StoreContextVar      0, 2
-  Allocate             CP#10
+  AllocateClosure      CP#0
   StoreLocal           r4
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#12
   Push                 r4
-  PushConstant         CP#15
-  StoreFieldTOS        CP#16
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r4
   PushConstant         CP#0
-  StoreFieldTOS        CP#18
+  StoreFieldTOS        CP#17
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
   PushInt              10
-  DynamicCall          2, CP#26
+  DynamicCall          2, CP#25
   Drop1
   Push                 r3
   PushInt              11
-  DynamicCall          2, CP#27
+  DynamicCall          2, CP#26
   Drop1
   Push                 r2
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   Drop1
   Push                 r0
   LoadContextVar       0, 2
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   Drop1
   Push                 r0
   LoadContextVar       0, 1
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   Drop1
   Push                 r0
   PushInt              42
   StoreContextVar      0, 3
-  Allocate             CP#10
+  AllocateClosure      CP#27
   StoreLocal           r3
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#12
   Push                 r3
-  PushConstant         CP#15
-  StoreFieldTOS        CP#16
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r3
-  PushConstant         CP#28
-  StoreFieldTOS        CP#18
+  PushConstant         CP#27
+  StoreFieldTOS        CP#17
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  DynamicCall          1, CP#32
+  DynamicCall          1, CP#31
   Drop1
   PushNull
   ReturnTOS
@@ -1091,29 +1089,28 @@
   [7] = InterfaceCall '#lib::B::get:foo', ArgDesc num-args 1, num-type-args 0, names []
   [8] = Reserved
   [9] = EndClosureFunctionScope
-  [10] = Class dart:core::_Closure
-  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [12] = Reserved
-  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [14] = Reserved
-  [15] = EmptyTypeArguments
-  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [17] = Reserved
-  [18] = InstanceField dart:core::_Closure::_function (field)
-  [19] = Reserved
-  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [21] = ICData dynamic target-name 'call', arg-desc CP#20
-  [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
-  [23] = Reserved
-  [24] = EndClosureFunctionScope
-  [25] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
-  [26] = ICData dynamic target-name 'call', arg-desc CP#25
-  [27] = ICData dynamic target-name 'call', arg-desc CP#25
-  [28] = ClosureFunction 2
-  [29] = InterfaceCall '#lib::B::set:foo', ArgDesc num-args 2, num-type-args 0, names []
-  [30] = Reserved
-  [31] = EndClosureFunctionScope
-  [32] = ICData dynamic target-name 'call', arg-desc CP#20
+  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [11] = Reserved
+  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [13] = Reserved
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [16] = Reserved
+  [17] = InstanceField dart:core::_Closure::_function (field)
+  [18] = Reserved
+  [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [20] = ICData dynamic target-name 'call', arg-desc CP#19
+  [21] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [22] = Reserved
+  [23] = EndClosureFunctionScope
+  [24] = ObjectRef ArgDesc num-args 2, num-type-args 0, names []
+  [25] = ICData dynamic target-name 'call', arg-desc CP#24
+  [26] = ICData dynamic target-name 'call', arg-desc CP#24
+  [27] = ClosureFunction 2
+  [28] = InterfaceCall '#lib::B::set:foo', ArgDesc num-args 2, num-type-args 0, names []
+  [29] = Reserved
+  [30] = EndClosureFunctionScope
+  [31] = ICData dynamic target-name 'call', arg-desc CP#19
 }
 Closure #lib::B::topLevel::'<anonymous closure>' (dart:core::int y) -> dart:core::Null
 ClosureCode {
@@ -1154,30 +1151,30 @@
   Push                 r0
   PushInt              4
   StoreContextVar      1, 1
-  Allocate             CP#10
+  AllocateClosure      CP#6
   StoreLocal           r2
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#12
   Push                 r2
-  PushConstant         CP#15
-  StoreFieldTOS        CP#16
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r2
   PushConstant         CP#6
-  StoreFieldTOS        CP#18
+  StoreFieldTOS        CP#17
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#21
+  DynamicCall          1, CP#20
   Drop1
   Push                 r0
   LoadContextVar       1, 1
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   Drop1
 L1:
   PushNull
@@ -1225,7 +1222,7 @@
   LoadContextVar       0, 0
   Push                 r0
   LoadContextVar       0, 3
-  InterfaceCall        2, CP#29
+  InterfaceCall        2, CP#28
   Drop1
   PushNull
   ReturnTOS
@@ -1313,20 +1310,12 @@
   PushInt              0
   StoreContextVar      0, 0
   PushConstant         CP#0
-  StoreLocal           r3
-  Push                 r3
-  PushInt              0
-  CreateArrayTOS
-  StoreLocal           r3
-  DirectCall           2, CP#1
+  PushConstant         CP#1
+  DirectCall           2, CP#2
   PopLocal             r2
   PushConstant         CP#0
-  StoreLocal           r3
-  Push                 r3
-  PushInt              0
-  CreateArrayTOS
-  StoreLocal           r3
-  DirectCall           2, CP#1
+  PushConstant         CP#1
+  DirectCall           2, CP#2
   PopLocal             r4
   AllocateContext      1, 1
   StoreLocal           r1
@@ -1345,7 +1334,7 @@
   CompareIntLt
   JumpIfFalse          L1
   Push                 r2
-  Allocate             CP#7
+  AllocateClosure      CP#4
   StoreLocal           r3
   Push                 r3
   PushNull
@@ -1357,15 +1346,15 @@
   PushConstant         CP#12
   StoreFieldTOS        CP#13
   Push                 r3
-  PushConstant         CP#3
+  PushConstant         CP#4
   StoreFieldTOS        CP#15
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#4
+  StoreFieldTOS        CP#5
   InterfaceCall        2, CP#17
   Drop1
   Push                 r4
-  Allocate             CP#7
+  AllocateClosure      CP#19
   StoreLocal           r3
   Push                 r3
   PushNull
@@ -1381,7 +1370,7 @@
   StoreFieldTOS        CP#15
   Push                 r3
   Push                 r0
-  StoreFieldTOS        CP#4
+  StoreFieldTOS        CP#5
   InterfaceCall        2, CP#17
   Drop1
   Push                 r0
@@ -1409,13 +1398,13 @@
 }
 ConstantPool {
   [0] = ObjectRef < dart:core::Function >
-  [1] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
-  [2] = Reserved
-  [3] = ClosureFunction 0
-  [4] = InstanceField dart:core::_Closure::_context (field)
-  [5] = Reserved
-  [6] = EndClosureFunctionScope
-  [7] = Class dart:core::_Closure
+  [1] = ObjectRef const <dynamic> []
+  [2] = DirectCall 'dart:core::List::_fromLiteral (constructor)', ArgDesc num-args 2, num-type-args 0, names []
+  [3] = Reserved
+  [4] = ClosureFunction 0
+  [5] = InstanceField dart:core::_Closure::_context (field)
+  [6] = Reserved
+  [7] = EndClosureFunctionScope
   [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
   [9] = Reserved
   [10] = InstanceField dart:core::_Closure::_function_type_arguments (field)
@@ -1438,7 +1427,7 @@
   EntryFixed           1, 2
   CheckStack           0
   Push                 FP[-5]
-  LoadFieldTOS         CP#4
+  LoadFieldTOS         CP#5
   PopLocal             r0
   Push                 r0
   LoadContextVar       1, 0
@@ -1455,7 +1444,7 @@
   EntryFixed           2, 3
   CheckStack           0
   Push                 FP[-6]
-  LoadFieldTOS         CP#4
+  LoadFieldTOS         CP#5
   PopLocal             r0
   Push                 FP[-5]
   PushConstant         CP#20
@@ -1499,30 +1488,30 @@
   Push                 r2
   InterfaceCall        1, CP#4
   StoreContextVar      0, 0
-  Allocate             CP#10
+  AllocateClosure      CP#6
   StoreLocal           r4
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r4
   PushNull
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#12
   Push                 r4
-  PushConstant         CP#15
-  StoreFieldTOS        CP#16
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r4
   PushConstant         CP#6
-  StoreFieldTOS        CP#18
+  StoreFieldTOS        CP#17
   Push                 r4
   Push                 r0
   StoreFieldTOS        CP#7
   PopLocal             r3
   Push                 r3
-  DynamicCall          1, CP#21
+  DynamicCall          1, CP#20
   Drop1
   Push                 r0
   LoadContextVar       0, 0
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   Drop1
   Push                 r0
   LoadContextParent
@@ -1543,20 +1532,19 @@
   [7] = InstanceField dart:core::_Closure::_context (field)
   [8] = Reserved
   [9] = EndClosureFunctionScope
-  [10] = Class dart:core::_Closure
-  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [12] = Reserved
-  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [14] = Reserved
-  [15] = EmptyTypeArguments
-  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [17] = Reserved
-  [18] = InstanceField dart:core::_Closure::_function (field)
-  [19] = Reserved
-  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [21] = ICData dynamic target-name 'call', arg-desc CP#20
-  [22] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
-  [23] = Reserved
+  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [11] = Reserved
+  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [13] = Reserved
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [16] = Reserved
+  [17] = InstanceField dart:core::_Closure::_function (field)
+  [18] = Reserved
+  [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [20] = ICData dynamic target-name 'call', arg-desc CP#19
+  [21] = DirectCall 'dart:core::print', ArgDesc num-args 1, num-type-args 0, names []
+  [22] = Reserved
 }
 Closure #lib::C::testForInLoop::'<anonymous closure>' () -> dart:core::Null
 ClosureCode {
@@ -1650,21 +1638,21 @@
   PushConstant         CP#2
   AssertAssignable     0, CP#3
   Drop1
-  Allocate             CP#8
+  AllocateClosure      CP#4
   StoreLocal           r2
   Push                 r2
   Push                 FP[-6]
   LoadTypeArgumentsField CP#1
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r2
-  PushConstant         CP#13
-  StoreFieldTOS        CP#14
+  PushConstant         CP#12
+  StoreFieldTOS        CP#13
   Push                 r2
   PushConstant         CP#4
-  StoreFieldTOS        CP#16
+  StoreFieldTOS        CP#15
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#5
@@ -1680,16 +1668,15 @@
   [5] = InstanceField dart:core::_Closure::_context (field)
   [6] = Reserved
   [7] = EndClosureFunctionScope
-  [8] = Class dart:core::_Closure
-  [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [10] = Reserved
-  [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [12] = Reserved
-  [13] = EmptyTypeArguments
-  [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [15] = Reserved
-  [16] = InstanceField dart:core::_Closure::_function (field)
-  [17] = Reserved
+  [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [9] = Reserved
+  [10] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [11] = Reserved
+  [12] = EmptyTypeArguments
+  [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [14] = Reserved
+  [15] = InstanceField dart:core::_Closure::_function (field)
+  [16] = Reserved
 }
 Closure #lib::D::foo::'<anonymous closure>' () -> #lib::D::TypeParam/0
 ClosureCode {
@@ -1718,21 +1705,21 @@
   Push                 r0
   Push                 FP[-5]
   StoreContextVar      0, 0
-  Allocate             CP#5
+  AllocateClosure      CP#0
   StoreLocal           r2
   Push                 r2
   Push                 FP[-5]
-  LoadTypeArgumentsField CP#6
-  StoreFieldTOS        CP#7
+  LoadTypeArgumentsField CP#5
+  StoreFieldTOS        CP#6
   Push                 r2
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r2
-  PushConstant         CP#11
-  StoreFieldTOS        CP#12
+  PushConstant         CP#10
+  StoreFieldTOS        CP#11
   Push                 r2
   PushConstant         CP#0
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r2
   Push                 r0
   StoreFieldTOS        CP#1
@@ -1744,20 +1731,19 @@
   [2] = Reserved
   [3] = ClosureFunction 1
   [4] = EndClosureFunctionScope
-  [5] = Class dart:core::_Closure
-  [6] = TypeArgumentsField #lib::D
-  [7] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [8] = Reserved
-  [9] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [10] = Reserved
-  [11] = EmptyTypeArguments
-  [12] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [13] = Reserved
-  [14] = InstanceField dart:core::_Closure::_function (field)
-  [15] = Reserved
-  [16] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [17] = ICData dynamic target-name 'call', arg-desc CP#16
-  [18] = EndClosureFunctionScope
+  [5] = TypeArgumentsField #lib::D
+  [6] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [7] = Reserved
+  [8] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [9] = Reserved
+  [10] = EmptyTypeArguments
+  [11] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [12] = Reserved
+  [13] = InstanceField dart:core::_Closure::_function (field)
+  [14] = Reserved
+  [15] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [16] = ICData dynamic target-name 'call', arg-desc CP#15
+  [17] = EndClosureFunctionScope
 }
 Closure #lib::D::bar::'<anonymous closure>' () -> dart:core::Null
 ClosureCode {
@@ -1766,28 +1752,28 @@
   Push                 FP[-5]
   LoadFieldTOS         CP#1
   PopLocal             r0
-  Allocate             CP#5
+  AllocateClosure      CP#3
   StoreLocal           r3
   Push                 r3
   Push                 r0
   LoadContextVar       0, 0
-  LoadTypeArgumentsField CP#6
-  StoreFieldTOS        CP#7
+  LoadTypeArgumentsField CP#5
+  StoreFieldTOS        CP#6
   Push                 r3
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r3
-  PushConstant         CP#11
-  StoreFieldTOS        CP#12
+  PushConstant         CP#10
+  StoreFieldTOS        CP#11
   Push                 r3
   PushConstant         CP#3
-  StoreFieldTOS        CP#14
+  StoreFieldTOS        CP#13
   Push                 r3
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r2
   Push                 r2
-  DynamicCall          1, CP#17
+  DynamicCall          1, CP#16
   Drop1
   PushNull
   ReturnTOS
diff --git a/pkg/vm/testcases/bytecode/try_blocks.dart.expect b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
index 2cdcf6d..126eae9 100644
--- a/pkg/vm/testcases/bytecode/try_blocks.dart.expect
+++ b/pkg/vm/testcases/bytecode/try_blocks.dart.expect
@@ -222,26 +222,26 @@
   Push                 r0
   PushInt              2
   StoreContextVar      0, 1
-  Allocate             CP#8
+  AllocateClosure      CP#0
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r5
-  PushConstant         CP#13
-  StoreFieldTOS        CP#14
+  PushConstant         CP#12
+  StoreFieldTOS        CP#13
   Push                 r5
   PushConstant         CP#0
-  StoreFieldTOS        CP#16
+  StoreFieldTOS        CP#15
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
   PopLocal             r4
   Push                 r4
-  DynamicCall          1, CP#19
+  DynamicCall          1, CP#18
   Drop1
   Push                 r0
   LoadContextVar       0, 1
@@ -266,7 +266,7 @@
   StoreLocal           r5
   Push                 r5
   PushInt              0
-  PushConstant         CP#20
+  PushConstant         CP#19
   StoreIndexedTOS
   Push                 r5
   PushInt              1
@@ -274,30 +274,30 @@
   StoreIndexedTOS
   Push                 r5
   PushInt              2
-  PushConstant         CP#21
+  PushConstant         CP#20
   StoreIndexedTOS
   Push                 r5
   PushInt              3
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   DirectCall           1, CP#4
   Drop1
-  Allocate             CP#8
+  AllocateClosure      CP#23
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#9
+  StoreFieldTOS        CP#8
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r5
-  PushConstant         CP#13
-  StoreFieldTOS        CP#14
+  PushConstant         CP#12
+  StoreFieldTOS        CP#13
   Push                 r5
-  PushConstant         CP#24
-  StoreFieldTOS        CP#16
+  PushConstant         CP#23
+  StoreFieldTOS        CP#15
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
@@ -323,30 +323,29 @@
   [5] = Reserved
   [6] = Type dynamic
   [7] = EndClosureFunctionScope
-  [8] = Class dart:core::_Closure
-  [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [10] = Reserved
-  [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [12] = Reserved
-  [13] = EmptyTypeArguments
-  [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [15] = Reserved
-  [16] = InstanceField dart:core::_Closure::_function (field)
-  [17] = Reserved
-  [18] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [19] = ICData dynamic target-name 'call', arg-desc CP#18
-  [20] = ObjectRef 'caught '
-  [21] = ObjectRef ' '
-  [22] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
-  [23] = Reserved
-  [24] = ClosureFunction 1
-  [25] = ObjectRef 'danger bar'
-  [26] = Type dart:core::Error
-  [27] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
-  [28] = Reserved
-  [29] = ObjectRef 'error '
-  [30] = ObjectRef ', captured stack trace: '
-  [31] = EndClosureFunctionScope
+  [8] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [9] = Reserved
+  [10] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [11] = Reserved
+  [12] = EmptyTypeArguments
+  [13] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [14] = Reserved
+  [15] = InstanceField dart:core::_Closure::_function (field)
+  [16] = Reserved
+  [17] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [18] = ICData dynamic target-name 'call', arg-desc CP#17
+  [19] = ObjectRef 'caught '
+  [20] = ObjectRef ' '
+  [21] = DirectCall 'dart:core::_StringBase::_interpolate', ArgDesc num-args 1, num-type-args 0, names []
+  [22] = Reserved
+  [23] = ClosureFunction 1
+  [24] = ObjectRef 'danger bar'
+  [25] = Type dart:core::Error
+  [26] = InterfaceCall 'dart:core::Object::_simpleInstanceOf', ArgDesc num-args 2, num-type-args 0, names []
+  [27] = Reserved
+  [28] = ObjectRef 'error '
+  [29] = ObjectRef ', captured stack trace: '
+  [30] = EndClosureFunctionScope
 }
 Closure #lib::testTryCatch3::'foo' () -> void
 ClosureCode {
@@ -395,7 +394,7 @@
   Push                 r0
   PopLocal             r2
 Try #0 start:
-  PushConstant         CP#25
+  PushConstant         CP#24
   DirectCall           1, CP#4
   Drop1
   Jump                 L1
@@ -407,8 +406,8 @@
   MoveSpecial          exception, r2
   MoveSpecial          stackTrace, r3
   Push                 r2
-  PushConstant         CP#26
-  InterfaceCall        2, CP#27
+  PushConstant         CP#25
+  InterfaceCall        2, CP#26
   JumpIfFalse          L2
   Push                 r2
   PopLocal             r4
@@ -418,7 +417,7 @@
   StoreLocal           r5
   Push                 r5
   PushInt              0
-  PushConstant         CP#29
+  PushConstant         CP#28
   StoreIndexedTOS
   Push                 r5
   PushInt              1
@@ -426,14 +425,14 @@
   StoreIndexedTOS
   Push                 r5
   PushInt              2
-  PushConstant         CP#30
+  PushConstant         CP#29
   StoreIndexedTOS
   Push                 r5
   PushInt              3
   Push                 r0
   LoadContextVar       0, 2
   StoreIndexedTOS
-  DirectCall           1, CP#22
+  DirectCall           1, CP#21
   DirectCall           1, CP#4
   Drop1
   Jump                 L1
@@ -637,26 +636,26 @@
   PushConstant         CP#5
   DirectCall           1, CP#3
   Drop1
-  Allocate             CP#10
+  AllocateClosure      CP#6
   StoreLocal           r8
   Push                 r8
   PushNull
-  StoreFieldTOS        CP#11
+  StoreFieldTOS        CP#10
   Push                 r8
   PushNull
-  StoreFieldTOS        CP#13
+  StoreFieldTOS        CP#12
   Push                 r8
-  PushConstant         CP#15
-  StoreFieldTOS        CP#16
+  PushConstant         CP#14
+  StoreFieldTOS        CP#15
   Push                 r8
   PushConstant         CP#6
-  StoreFieldTOS        CP#18
+  StoreFieldTOS        CP#17
   Push                 r8
   Push                 r0
   StoreFieldTOS        CP#7
   PopLocal             r7
   Push                 r7
-  DynamicCall          1, CP#21
+  DynamicCall          1, CP#20
   Drop1
   Jump                 L4
 Try #1 end:
@@ -666,7 +665,7 @@
   PopLocal             r0
   MoveSpecial          exception, r5
   MoveSpecial          stackTrace, r6
-  PushConstant         CP#23
+  PushConstant         CP#22
   DirectCall           1, CP#3
   Drop1
   Push                 r5
@@ -675,7 +674,7 @@
 L4:
   Push                 r5
   PopLocal             r0
-  PushConstant         CP#23
+  PushConstant         CP#22
   DirectCall           1, CP#3
   Drop1
   Jump                 L5
@@ -686,7 +685,7 @@
   PopLocal             r0
   MoveSpecial          exception, r3
   MoveSpecial          stackTrace, r4
-  PushConstant         CP#25
+  PushConstant         CP#24
   DirectCall           1, CP#3
   Drop1
   Push                 r3
@@ -695,12 +694,12 @@
 L5:
   Push                 r3
   PopLocal             r0
-  PushConstant         CP#25
+  PushConstant         CP#24
   DirectCall           1, CP#3
   Drop1
   Jump                 L2
 L2:
-  PushConstant         CP#26
+  PushConstant         CP#25
   DirectCall           1, CP#3
   Drop1
   Jump                 L3
@@ -709,8 +708,8 @@
   ReturnTOS
 }
 ExceptionsTable {
-  try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#22]
-  try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#22]
+  try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#21]
+  try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#21]
 }
 ConstantPool {
   [0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
@@ -723,23 +722,22 @@
   [7] = InstanceField dart:core::_Closure::_context (field)
   [8] = Reserved
   [9] = EndClosureFunctionScope
-  [10] = Class dart:core::_Closure
-  [11] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [12] = Reserved
-  [13] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [14] = Reserved
-  [15] = EmptyTypeArguments
-  [16] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [17] = Reserved
-  [18] = InstanceField dart:core::_Closure::_function (field)
-  [19] = Reserved
-  [20] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [21] = ICData dynamic target-name 'call', arg-desc CP#20
-  [22] = Type dynamic
-  [23] = ObjectRef 'finally 1'
-  [24] = ObjectRef 'after try 1'
-  [25] = ObjectRef 'finally 2'
-  [26] = ObjectRef 'case 2'
+  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [11] = Reserved
+  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [13] = Reserved
+  [14] = EmptyTypeArguments
+  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [16] = Reserved
+  [17] = InstanceField dart:core::_Closure::_function (field)
+  [18] = Reserved
+  [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [20] = ICData dynamic target-name 'call', arg-desc CP#19
+  [21] = Type dynamic
+  [22] = ObjectRef 'finally 1'
+  [23] = ObjectRef 'after try 1'
+  [24] = ObjectRef 'finally 2'
+  [25] = ObjectRef 'case 2'
 }
 Closure #lib::testTryFinally2::'foo' () -> void
 ClosureCode {
@@ -780,20 +778,20 @@
   Push                 r0
   PopLocal             r3
 Try #0 start:
-  Allocate             CP#9
+  AllocateClosure      CP#0
   StoreLocal           r5
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#10
+  StoreFieldTOS        CP#9
   Push                 r5
   PushNull
-  StoreFieldTOS        CP#12
+  StoreFieldTOS        CP#11
   Push                 r5
-  PushConstant         CP#14
-  StoreFieldTOS        CP#15
+  PushConstant         CP#13
+  StoreFieldTOS        CP#14
   Push                 r5
   PushConstant         CP#0
-  StoreFieldTOS        CP#17
+  StoreFieldTOS        CP#16
   Push                 r5
   Push                 r0
   StoreFieldTOS        CP#1
@@ -811,7 +809,7 @@
   DirectCall           1, CP#3
   Drop1
   Push                 r2
-  DynamicCall          1, CP#20
+  DynamicCall          1, CP#19
   Drop1
   Push                 r3
   Push                 r4
@@ -824,7 +822,7 @@
   DirectCall           1, CP#3
   Drop1
   Push                 r2
-  DynamicCall          1, CP#21
+  DynamicCall          1, CP#20
   Drop1
   Push                 r0
   LoadContextParent
@@ -845,19 +843,18 @@
   [6] = Type dynamic
   [7] = ObjectRef 'try 2'
   [8] = EndClosureFunctionScope
-  [9] = Class dart:core::_Closure
-  [10] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
-  [11] = Reserved
-  [12] = InstanceField dart:core::_Closure::_function_type_arguments (field)
-  [13] = Reserved
-  [14] = EmptyTypeArguments
-  [15] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
-  [16] = Reserved
-  [17] = InstanceField dart:core::_Closure::_function (field)
-  [18] = Reserved
-  [19] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
-  [20] = ICData dynamic target-name 'call', arg-desc CP#19
-  [21] = ICData dynamic target-name 'call', arg-desc CP#19
+  [9] = InstanceField dart:core::_Closure::_instantiator_type_arguments (field)
+  [10] = Reserved
+  [11] = InstanceField dart:core::_Closure::_function_type_arguments (field)
+  [12] = Reserved
+  [13] = EmptyTypeArguments
+  [14] = InstanceField dart:core::_Closure::_delayed_type_arguments (field)
+  [15] = Reserved
+  [16] = InstanceField dart:core::_Closure::_function (field)
+  [17] = Reserved
+  [18] = ObjectRef ArgDesc num-args 1, num-type-args 0, names []
+  [19] = ICData dynamic target-name 'call', arg-desc CP#18
+  [20] = ICData dynamic target-name 'call', arg-desc CP#18
 }
 Closure #lib::testTryFinally3::'<anonymous closure>' () -> dart:core::int
 ClosureCode {
diff --git a/runtime/bin/BUILD.gn b/runtime/bin/BUILD.gn
index 55e9d2e..a13c951 100644
--- a/runtime/bin/BUILD.gn
+++ b/runtime/bin/BUILD.gn
@@ -138,6 +138,8 @@
     }
     deps = [ ":generate_abi_version_cc_file" ] + extra_deps
 
+    defines = [ "EXCLUDE_CFE_AND_KERNEL_PLATFORM" ]
+
     sources = [
       "address_sanitizer.cc",
       "builtin.cc",
@@ -846,37 +848,23 @@
   target_type = "static_library"
 }
 
-executable("process_test") {
-  sources = [
-    "process_test.cc",
+dart_executable("dartaotruntime") {
+  extra_configs = [ "..:dart_precompiled_runtime_config" ]
+  extra_deps = [ "..:libdart_precompiled_runtime" ]
+  extra_sources = [
+    "builtin.cc",
+    "snapshot_empty.cc",
+    "loader.cc",
+    "loader.h",
+    "gzip.cc",
+    "gzip.h",
+    "observatory_assets_empty.cc",
   ]
 }
 
-action("generate_snapshot_test_dat_file") {
-  snapshot_test_dat_file = "$root_gen_dir/snapshot_test.dat"
-  snapshot_test_in_dat_file = "../vm/snapshot_test_in.dat"
-  snapshot_test_dart_file = "../vm/snapshot_test.dart"
-  inputs = [
-    "../tools/create_string_literal.py",
-    snapshot_test_in_dat_file,
-    snapshot_test_dart_file,
-  ]
-
-  outputs = [
-    snapshot_test_dat_file,
-  ]
-
-  script = "../tools/create_string_literal.py"
-  args = [
-    "--output",
-    rebase_path(snapshot_test_dat_file),
-    "--input_cc",
-    rebase_path(snapshot_test_in_dat_file),
-    "--include",
-    "INTENTIONALLY_LEFT_BLANK",
-    "--var_name",
-    "INTENTIONALLY_LEFT_BLANK_TOO",
-    rebase_path(snapshot_test_dart_file),
+executable("process_test") {
+  sources = [
+    "process_test.cc",
   ]
 }
 
@@ -925,6 +913,10 @@
     "..:dart_os_config",
     "..:dart_maybe_product_config",
   ]
+
+  if (dart_target_arch != "ia32") {
+    configs += [ "..:dart_precompiler_config" ]
+  }
   if (is_fuchsia) {
     configs -= [ "//build/config:symbol_visibility_hidden" ]
   }
@@ -935,10 +927,9 @@
     ":dart_snapshot_cc",
     ":gen_kernel_bytecode_dill",
     ":generate_abi_version_cc_file",
-    ":generate_snapshot_test_dat_file",
     ":libdart_builtin",
     ":standalone_dart_io",
-    "..:libdart_jit",
+    "..:libdart_nosnapshot_with_precompiler",
     "//third_party/zlib",
   ]
   include_dirs = [
diff --git a/runtime/bin/builtin.cc b/runtime/bin/builtin.cc
index a10ee81..a18ca56 100644
--- a/runtime/bin/builtin.cc
+++ b/runtime/bin/builtin.cc
@@ -39,8 +39,9 @@
     Dart_Handle library = Dart_LookupLibrary(url);
     ASSERT(!Dart_IsError(library));
     // Setup the native resolver for built in library functions.
-    DART_CHECK_VALID(
-        Dart_SetNativeResolver(library, NativeLookup, NativeSymbol));
+    Dart_Handle result =
+        Dart_SetNativeResolver(library, NativeLookup, NativeSymbol);
+    ASSERT(!Dart_IsError(result));
   }
 }
 
diff --git a/runtime/bin/builtin_gen_snapshot.cc b/runtime/bin/builtin_gen_snapshot.cc
index 070e140..d4828a6 100644
--- a/runtime/bin/builtin_gen_snapshot.cc
+++ b/runtime/bin/builtin_gen_snapshot.cc
@@ -30,7 +30,9 @@
                                           bool* auto_setup_scope) {
   const char* function_name = NULL;
   Dart_Handle result = Dart_StringToCString(name, &function_name);
-  DART_CHECK_VALID(result);
+  if (Dart_IsError(result)) {
+    Dart_PropagateError(result);
+  }
   ASSERT(function_name != NULL);
   ASSERT(auto_setup_scope != NULL);
   *auto_setup_scope = true;
diff --git a/runtime/bin/builtin_natives.cc b/runtime/bin/builtin_natives.cc
index b91c95b..0c27be9 100644
--- a/runtime/bin/builtin_natives.cc
+++ b/runtime/bin/builtin_natives.cc
@@ -47,7 +47,9 @@
                                           bool* auto_setup_scope) {
   const char* function_name = NULL;
   Dart_Handle err = Dart_StringToCString(name, &function_name);
-  DART_CHECK_VALID(err);
+  if (Dart_IsError(err)) {
+    Dart_PropagateError(err);
+  }
   ASSERT(function_name != NULL);
   ASSERT(auto_setup_scope != NULL);
   *auto_setup_scope = true;
diff --git a/runtime/bin/dart_embedder_api_impl.cc b/runtime/bin/dart_embedder_api_impl.cc
index 4700774..492aab8 100644
--- a/runtime/bin/dart_embedder_api_impl.cc
+++ b/runtime/bin/dart_embedder_api_impl.cc
@@ -88,7 +88,8 @@
   Dart_EnterScope();
   // Load embedder specific bits and return.
   if (!bin::VmService::Setup(config.ip, config.port, config.dev_mode,
-                             /*trace_loading=*/false, config.deterministic)) {
+                             config.disable_auth_codes, /*trace_loading=*/false,
+                             config.deterministic)) {
     *error = strdup(bin::VmService::GetErrorMessage());
     return nullptr;
   }
diff --git a/runtime/bin/dfe.cc b/runtime/bin/dfe.cc
index 0ef24e7..edf14c4 100644
--- a/runtime/bin/dfe.cc
+++ b/runtime/bin/dfe.cc
@@ -11,6 +11,7 @@
 #include "bin/directory.h"
 #include "bin/error_exit.h"
 #include "bin/file.h"
+#include "bin/main_options.h"
 #include "bin/platform.h"
 #include "bin/utils.h"
 #include "include/dart_tools_api.h"
@@ -68,7 +69,13 @@
       frontend_filename_(NULL),
       application_kernel_buffer_(NULL),
       application_kernel_buffer_size_(0) {
-#if defined(DART_NO_SNAPSHOT) || defined(DART_PRECOMPILER)
+  // The run_vm_tests binary has the DART_PRECOMPILER set in order to allow unit
+  // tests to exercise JIT and AOT pipeline.
+  //
+  // Only on X64 do we have kernel-service.dart.snapshot available otherwise we
+  // need to fall back to the built-in one (if we have it).
+#if defined(EXCLUDE_CFE_AND_KERNEL_PLATFORM) || defined(DART_NO_SNAPSHOT) ||   \
+    (defined(DART_PRECOMPILER) && defined(TARGET_ARCH_X64))
   kernel_service_dill_ = NULL;
   kernel_service_dill_size_ = 0;
   platform_strong_dill_ = NULL;
@@ -93,7 +100,7 @@
 }
 
 void DFE::Init() {
-  Init(AbiVersion::GetCurrent());
+  Init(Options::kAbiVersionUnset);
 }
 
 void DFE::Init(int target_abi_version) {
@@ -122,7 +129,7 @@
   auto dir_prefix = std::unique_ptr<char, void (*)(void*)>(
       GetDirectoryPrefixFromExeName(), free);
 
-  if (target_abi_version != AbiVersion::GetCurrent()) {
+  if (target_abi_version != Options::kAbiVersionUnset) {
     kernel_service_dill_ = NULL;
     kernel_service_dill_size_ = 0;
     platform_strong_dill_ = NULL;
diff --git a/runtime/bin/entrypoints_verification_test_extension.cc b/runtime/bin/entrypoints_verification_test_extension.cc
index 5088e75..1f4eab6 100644
--- a/runtime/bin/entrypoints_verification_test_extension.cc
+++ b/runtime/bin/entrypoints_verification_test_extension.cc
@@ -8,7 +8,15 @@
 #include "./include/dart_api.h"
 #include "./include/dart_native_api.h"
 
-#define CHECK(H) DART_CHECK_VALID(H)
+#define CHECK(H)                                                               \
+  do {                                                                         \
+    Dart_Handle __handle__ = H;                                                \
+    if (Dart_IsError(__handle__)) {                                            \
+      const char* message = Dart_GetError(__handle__);                         \
+      fprintf(stderr, "Check \"" #H "\" failed: %s", message);                 \
+      abort();                                                                 \
+    }                                                                          \
+  } while (false)
 
 #define ASSERT(E)                                                              \
   if (!(E)) {                                                                  \
diff --git a/runtime/bin/io_natives.cc b/runtime/bin/io_natives.cc
index 94a0c35258..935f2ea 100644
--- a/runtime/bin/io_natives.cc
+++ b/runtime/bin/io_natives.cc
@@ -194,7 +194,7 @@
                                    bool* auto_setup_scope) {
   const char* function_name = NULL;
   Dart_Handle result = Dart_StringToCString(name, &function_name);
-  DART_CHECK_VALID(result);
+  ASSERT(!Dart_IsError(result));
   ASSERT(function_name != NULL);
   ASSERT(auto_setup_scope != NULL);
   *auto_setup_scope = true;
diff --git a/runtime/bin/main.cc b/runtime/bin/main.cc
index 9117f38..2d09c17 100644
--- a/runtime/bin/main.cc
+++ b/runtime/bin/main.cc
@@ -12,6 +12,7 @@
 #include "include/dart_embedder_api.h"
 #include "include/dart_tools_api.h"
 
+#include "bin/abi_version.h"
 #include "bin/builtin.h"
 #include "bin/console.h"
 #include "bin/crashpad.h"
@@ -508,10 +509,10 @@
   CHECK_RESULT(result);
 
   // Load embedder specific bits and return.
-  if (!VmService::Setup(Options::vm_service_server_ip(),
-                        Options::vm_service_server_port(),
-                        Options::vm_service_dev_mode(),
-                        Options::trace_loading(), Options::deterministic())) {
+  if (!VmService::Setup(
+          Options::vm_service_server_ip(), Options::vm_service_server_port(),
+          Options::vm_service_dev_mode(), Options::vm_service_auth_disabled(),
+          Options::trace_loading(), Options::deterministic())) {
     *error = strdup(VmService::GetErrorMessage());
     return NULL;
   }
@@ -605,7 +606,8 @@
   Dart_Isolate isolate = NULL;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  if (!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) {
+  if ((!isolate_run_app_snapshot && (isolate_snapshot_data == NULL)) ||
+      (Options::target_abi_version() != Options::kAbiVersionUnset)) {
     const uint8_t* platform_kernel_buffer = NULL;
     intptr_t platform_kernel_buffer_size = 0;
     dfe.LoadPlatform(&platform_kernel_buffer, &platform_kernel_buffer_size);
diff --git a/runtime/bin/main_options.cc b/runtime/bin/main_options.cc
index a0db7aa..42fa0b5 100644
--- a/runtime/bin/main_options.cc
+++ b/runtime/bin/main_options.cc
@@ -120,13 +120,14 @@
 // clang-format off
 void Options::PrintUsage() {
   Log::PrintErr(
-      "Usage: dart [<vm-flags>] <dart-script-file> [<dart-options>]\n"
+      "Usage: dart [<vm-flags>] <dart-script-file> [<script-arguments>]\n"
       "\n"
-      "Executes the Dart script passed as <dart-script-file>.\n"
+      "Executes the Dart script <dart-script-file> with "
+      "the given list of <script-arguments>.\n"
       "\n");
   if (!Options::verbose_option()) {
     Log::PrintErr(
-"Common options:\n"
+"Common VM flags:\n"
 "--enable-asserts\n"
 "  Enable assert statements.\n"
 "--help or -h\n"
@@ -325,7 +326,7 @@
   return true;
 }
 
-int Options::target_abi_version_ = AbiVersion::GetCurrent();
+int Options::target_abi_version_ = Options::kAbiVersionUnset;
 bool Options::ProcessAbiVersionOption(const char* arg,
                                       CommandLineOptions* vm_options) {
   const char* value = OptionProcessor::ProcessOption(arg, "--use_abi_version=");
diff --git a/runtime/bin/main_options.h b/runtime/bin/main_options.h
index e290696..8513fe3 100644
--- a/runtime/bin/main_options.h
+++ b/runtime/bin/main_options.h
@@ -38,6 +38,7 @@
   V(version, version_option)                                                   \
   V(compile_all, compile_all)                                                  \
   V(disable_service_origin_check, vm_service_dev_mode)                         \
+  V(disable_service_auth_codes, vm_service_auth_disabled)                      \
   V(deterministic, deterministic)                                              \
   V(trace_loading, trace_loading)                                              \
   V(short_socket_read, short_socket_read)                                      \
@@ -116,6 +117,7 @@
   static const char* vm_service_server_ip() { return vm_service_server_ip_; }
   static int vm_service_server_port() { return vm_service_server_port_; }
 
+  static constexpr int kAbiVersionUnset = -1;
   static int target_abi_version() { return target_abi_version_; }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
diff --git a/runtime/bin/run_vm_tests.cc b/runtime/bin/run_vm_tests.cc
index 4eb653e..aa36a87 100644
--- a/runtime/bin/run_vm_tests.cc
+++ b/runtime/bin/run_vm_tests.cc
@@ -156,6 +156,14 @@
       free(*error);
       *error = NULL;
     }
+    // If a test does not actually require the kernel isolate the main thead can
+    // start calling Dart::Cleanup() while the kernel isolate is booting up.
+    // This can cause the isolate to be killed early which will return `nullptr`
+    // here.
+    if (isolate == nullptr) {
+      delete isolate_data;
+      return NULL;
+    }
   }
   if (isolate == NULL) {
     delete isolate_data;
diff --git a/runtime/bin/vmservice/server.dart b/runtime/bin/vmservice/server.dart
index dcad9f8..447d334 100644
--- a/runtime/bin/vmservice/server.dart
+++ b/runtime/bin/vmservice/server.dart
@@ -147,6 +147,7 @@
   final String _ip;
   final int _port;
   final bool _originCheckDisabled;
+  final bool _authCodesDisabled;
   HttpServer _server;
   bool get running => _server != null;
 
@@ -157,11 +158,15 @@
     }
     var ip = _server.address.address;
     var port = _server.port;
-    var path = useAuthToken ? "$serviceAuthToken/" : "/";
+    var path = !_authCodesDisabled ? "$serviceAuthToken/" : "/";
     return new Uri(scheme: 'http', host: ip, port: port, path: path);
   }
 
-  Server(this._service, this._ip, this._port, this._originCheckDisabled);
+  // On Fuchsia, authentication codes are disabled by default. To enable, the authentication token
+  // would have to be written into the hub alongside the port number.
+  Server(this._service, this._ip, this._port, this._originCheckDisabled,
+      bool authCodesDisabled)
+      : _authCodesDisabled = (authCodesDisabled || Platform.isFuchsia);
 
   bool _isAllowedOrigin(String origin) {
     Uri uri;
@@ -214,7 +219,7 @@
   /// Checks the [requestUri] for the service auth token and returns the path.
   /// If the service auth token check fails, returns null.
   String _checkAuthTokenAndGetPath(Uri requestUri) {
-    if (!useAuthToken) {
+    if (_authCodesDisabled) {
       return requestUri.path == '/' ? ROOT_REDIRECT_PATH : requestUri.path;
     }
     final List<String> requestPathSegments = requestUri.pathSegments;
diff --git a/runtime/bin/vmservice/vmservice_io.dart b/runtime/bin/vmservice/vmservice_io.dart
index 64d602d..6d7c55f 100644
--- a/runtime/bin/vmservice/vmservice_io.dart
+++ b/runtime/bin/vmservice/vmservice_io.dart
@@ -23,6 +23,9 @@
 // Should the HTTP server auto start?
 @pragma("vm:entry-point")
 bool _autoStart;
+// Should the HTTP server require an auth code?
+@pragma("vm:entry-point")
+bool _authCodesDisabled;
 // Should the HTTP server run in devmode?
 @pragma("vm:entry-point")
 bool _originCheckDisabled;
@@ -45,7 +48,8 @@
   // Lazily create service.
   var service = new VMService();
   // Lazily create server.
-  server = new Server(service, _ip, _port, _originCheckDisabled);
+  server =
+      new Server(service, _ip, _port, _originCheckDisabled, _authCodesDisabled);
 }
 
 Future cleanupCallback() async {
diff --git a/runtime/bin/vmservice_impl.cc b/runtime/bin/vmservice_impl.cc
index 04a3e89..683d4b4 100644
--- a/runtime/bin/vmservice_impl.cc
+++ b/runtime/bin/vmservice_impl.cc
@@ -113,6 +113,7 @@
 bool VmService::Setup(const char* server_ip,
                       intptr_t server_port,
                       bool dev_mode_server,
+                      bool auth_codes_disabled,
                       bool trace_loading,
                       bool deterministic) {
   Dart_Isolate isolate = Dart_CurrentIsolate();
@@ -169,6 +170,11 @@
   SHUTDOWN_ON_ERROR(result);
   result = Dart_SetField(library, DartUtils::NewString("_originCheckDisabled"),
                          Dart_NewBoolean(dev_mode_server));
+  SHUTDOWN_ON_ERROR(result);
+
+  result = Dart_SetField(library, DartUtils::NewString("_authCodesDisabled"),
+                         Dart_NewBoolean(auth_codes_disabled));
+  SHUTDOWN_ON_ERROR(result);
 
 // Are we running on Windows?
 #if defined(HOST_OS_WINDOWS)
diff --git a/runtime/bin/vmservice_impl.h b/runtime/bin/vmservice_impl.h
index 0a40178..51e9bfc 100644
--- a/runtime/bin/vmservice_impl.h
+++ b/runtime/bin/vmservice_impl.h
@@ -17,6 +17,7 @@
   static bool Setup(const char* server_ip,
                     intptr_t server_port,
                     bool dev_mode_server,
+                    bool auth_codes_disabled,
                     bool trace_loading,
                     bool deterministic);
 
diff --git a/runtime/include/dart_api.h b/runtime/include/dart_api.h
index 51a1f80..be316ee 100644
--- a/runtime/include/dart_api.h
+++ b/runtime/include/dart_api.h
@@ -386,34 +386,10 @@
  *
  * \param An error handle (See Dart_IsError)
  *
- * \return On success, this function does not return.  On failure, an
- *   error handle is returned.
+ * \return On success, this function does not return.  On failure, the
+ * process is terminated.
  */
-DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle);
-/* TODO(turnidge): Should this really return an error handle? */
-/* Consider just terminating. */
-
-/* Internal routine used for reporting error handles. */
-DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
-                                         int line,
-                                         const char* handle_string,
-                                         const char* error);
-
-/* TODO(turnidge): Move DART_CHECK_VALID to some sort of dart_utils
- * header instead of this header. */
-/**
- * Aborts the process if 'handle' is an error handle.
- *
- * Provided for convenience.
- */
-#define DART_CHECK_VALID(handle)                                               \
-  {                                                                            \
-    Dart_Handle __handle = handle;                                             \
-    if (Dart_IsError((__handle))) {                                            \
-      _Dart_ReportErrorHandle(__FILE__, __LINE__, #handle,                     \
-                              Dart_GetError(__handle));                        \
-    }                                                                          \
-  }
+DART_EXPORT void Dart_PropagateError(Dart_Handle handle);
 
 /**
  * Converts an object to a string.
diff --git a/runtime/include/dart_embedder_api.h b/runtime/include/dart_embedder_api.h
index eda9059..9a91a83 100644
--- a/runtime/include/dart_embedder_api.h
+++ b/runtime/include/dart_embedder_api.h
@@ -60,6 +60,7 @@
   // TODO(vegorov) document these ones.
   bool dev_mode;
   bool deterministic;
+  bool disable_auth_codes;
 };
 
 // Create and initialize vm-service isolate. This method should be used
diff --git a/runtime/lib/convert_patch.dart b/runtime/lib/convert_patch.dart
index d2cf222..747e1e3 100644
--- a/runtime/lib/convert_patch.dart
+++ b/runtime/lib/convert_patch.dart
@@ -1857,8 +1857,7 @@
   final to = endIndex;
 
   // Special case for _Uint8ArrayView.
-  final cid = ClassID.getID(units);
-  if (identical(cid, ClassID.cidUint8ArrayView)) {
+  if (units is Uint8List) {
     if (from >= 0 && to >= 0 && to <= units.length) {
       for (int i = from; i < to; i++) {
         final unit = units[i];
diff --git a/runtime/lib/mirrors.cc b/runtime/lib/mirrors.cc
index d0e9f93..916649f 100644
--- a/runtime/lib/mirrors.cc
+++ b/runtime/lib/mirrors.cc
@@ -553,15 +553,22 @@
   const Library& lib = Library::Handle(zone, Library::MirrorsLibrary());
   const Class& cls = Class::Handle(
       zone, lib.LookupClassAllowPrivate(Symbols::_LocalMethodMirror()));
-  const Error& error = Error::Handle(zone, cls.EnsureIsFinalized(thread));
+  Error& error = Error::Handle(zone);
+  error ^= cls.EnsureIsFinalized(thread);
   ASSERT(error.IsNull());
 
-  Field& field = Field::Handle();
-  Smi& value = Smi::Handle();
+  Field& field = Field::Handle(zone);
+  Smi& value = Smi::Handle(zone);
+  String& fname = String::Handle(zone);
 
 #define CHECK_KIND_SHIFT(name)                                                 \
-  field = cls.LookupField(String::Handle(String::New(#name)));                 \
+  fname ^= String::New(#name);                                                 \
+  field = cls.LookupField(fname);                                              \
   ASSERT(!field.IsNull());                                                     \
+  if (field.IsUninitialized()) {                                               \
+    error ^= field.Initialize();                                               \
+    ASSERT(error.IsNull());                                                    \
+  }                                                                            \
   value ^= field.StaticValue();                                                \
   ASSERT(value.Value() == Mirrors::name);
   MIRRORS_KIND_SHIFT_LIST(CHECK_KIND_SHIFT)
diff --git a/runtime/lib/string_patch.dart b/runtime/lib/string_patch.dart
index e75284a..1099263 100644
--- a/runtime/lib/string_patch.dart
+++ b/runtime/lib/string_patch.dart
@@ -224,8 +224,7 @@
     var s = _OneByteString._allocate(len);
 
     // Special case for _Uint8ArrayView.
-    final cid = ClassID.getID(charCodes);
-    if (identical(cid, ClassID.cidUint8ArrayView)) {
+    if (charCodes is Uint8List) {
       if (start >= 0 && len >= 0) {
         for (int i = 0; i < len; i++) {
           s._setAt(i, charCodes[start + i]);
diff --git a/runtime/observatory/HACKING.md b/runtime/observatory/HACKING.md
index afcab5c..b645f9e 100644
--- a/runtime/observatory/HACKING.md
+++ b/runtime/observatory/HACKING.md
@@ -62,8 +62,8 @@
 submit your code.
 
 The main reviewers for Observatory related CLs are:
-  - turnidge
-  - johnmccutchan
+  - asiva
+  - bkonyi
   - rmacnak
 
 ## Write a new service test
diff --git a/runtime/observatory/lib/service_io.dart b/runtime/observatory/lib/service_io.dart
index 4565d9f..2ecbbf1 100644
--- a/runtime/observatory/lib/service_io.dart
+++ b/runtime/observatory/lib/service_io.dart
@@ -52,9 +52,7 @@
   }
 }
 
-/// The [WebSocketVM] communicates with a Dart VM over WebSocket. The Dart VM
-/// can be embedded in Chromium or standalone. In the case of Chromium, we
-/// make the service requests via the Chrome Remote Debugging Protocol.
+/// The [WebSocketVM] communicates with a Dart VM over WebSocket.
 class WebSocketVM extends CommonWebSocketVM {
   WebSocketVM(WebSocketVMTarget target) : super(target, new _IOWebSocket());
 }
diff --git a/runtime/observatory/lib/src/app/application.dart b/runtime/observatory/lib/src/app/application.dart
index 740c6ec..9b7f90c 100644
--- a/runtime/observatory/lib/src/app/application.dart
+++ b/runtime/observatory/lib/src/app/application.dart
@@ -277,11 +277,6 @@
     events.onConnectionClosed.listen(_addNotification);
   }
 
-  loadCrashDump(Map crashDump) {
-    _switchVM(new FakeVM(crashDump['result']));
-    app.locationManager.go(Uris.vm());
-  }
-
   void handleException(e, st) {
     if (e is ServerRpcException) {
       if (e.code == ServerRpcException.kFeatureDisabled) return;
diff --git a/runtime/observatory/lib/src/app/page.dart b/runtime/observatory/lib/src/app/page.dart
index 9563098..526e182 100644
--- a/runtime/observatory/lib/src/app/page.dart
+++ b/runtime/observatory/lib/src/app/page.dart
@@ -890,9 +890,7 @@
 
   void onInstall() {
     if (element == null) {
-      element = new VMConnectElement(
-          ObservatoryApplication.app.targets,
-          ObservatoryApplication.app.loadCrashDump,
+      element = new VMConnectElement(ObservatoryApplication.app.targets,
           ObservatoryApplication.app.notifications,
           queue: ObservatoryApplication.app.queue);
     }
diff --git a/runtime/observatory/lib/src/elements/vm_connect.dart b/runtime/observatory/lib/src/elements/vm_connect.dart
index d6036df..c8cac11 100644
--- a/runtime/observatory/lib/src/elements/vm_connect.dart
+++ b/runtime/observatory/lib/src/elements/vm_connect.dart
@@ -16,8 +16,6 @@
 import 'package:observatory/src/elements/view_footer.dart';
 import 'package:observatory/src/elements/vm_connect_target.dart';
 
-typedef void CrashDumpLoadCallback(Map dump);
-
 class VMConnectElement extends HtmlElement implements Renderable {
   static const tag =
       const Tag<VMConnectElement>('vm-connect', dependencies: const [
@@ -31,24 +29,21 @@
 
   Stream<RenderedEvent<VMConnectElement>> get onRendered => _r.onRendered;
 
-  CrashDumpLoadCallback _loadDump;
   M.NotificationRepository _notifications;
   M.TargetRepository _targets;
   StreamSubscription _targetsSubscription;
 
   String _address;
 
-  factory VMConnectElement(M.TargetRepository targets,
-      CrashDumpLoadCallback loadDump, M.NotificationRepository notifications,
+  factory VMConnectElement(
+      M.TargetRepository targets, M.NotificationRepository notifications,
       {String address: '', RenderingQueue queue}) {
     assert(address != null);
-    assert(loadDump != null);
     assert(notifications != null);
     assert(targets != null);
     VMConnectElement e = document.createElement(tag.name);
     e._r = new RenderingScheduler<VMConnectElement>(e, queue: queue);
     e._address = address;
-    e._loadDump = loadDump;
     e._notifications = notifications;
     e._targets = targets;
     return e;
@@ -124,19 +119,6 @@
                     ..text = 'Run Standalone with: \'--observe\'',
                 ],
               new DivElement()..classes = ['flex-item-20-percent'],
-              new DivElement()
-                ..classes = ['flex-item-40-percent']
-                ..children = <Element>[
-                  new HeadingElement.h2()..text = 'View crash dump',
-                  new BRElement(),
-                  _createCrushDumpLoader(),
-                  new BRElement(),
-                  new BRElement(),
-                  new PreElement()
-                    ..classes = ['well']
-                    ..text = 'Request a crash dump with:\n'
-                        '\'curl $host:$port/_getCrashDump > dump.json\'',
-                ]
             ],
         ],
       new ViewFooterElement(queue: _r.queue)
@@ -158,20 +140,6 @@
     return textbox;
   }
 
-  FileUploadInputElement _createCrushDumpLoader() {
-    FileUploadInputElement e = new FileUploadInputElement()
-      ..id = 'crashDumpFile';
-    e.onChange.listen((_) {
-      var reader = new FileReader();
-      reader.readAsText(e.files[0]);
-      reader.onLoad.listen((_) {
-        var crashDump = json.decode(reader.result);
-        _loadDump(crashDump);
-      });
-    });
-    return e;
-  }
-
   void _createAndConnect() {
     if (_address == null || _address.isEmpty) return;
     String normalizedNetworkAddress = _normalizeStandaloneAddress(_address);
diff --git a/runtime/observatory/lib/src/repositories/target.dart b/runtime/observatory/lib/src/repositories/target.dart
index 245542d..4fb1fb1 100644
--- a/runtime/observatory/lib/src/repositories/target.dart
+++ b/runtime/observatory/lib/src/repositories/target.dart
@@ -120,7 +120,7 @@
       scheme: 'ws',
       host: host ?? serverAddress.host,
       port: int.tryParse(port ?? '') ?? serverAddress.port,
-      path: '/ws',
+      path: serverAddress.path.isEmpty ? '/ws' : serverAddress.path + 'ws',
     );
     return wsAddress.toString();
   }
diff --git a/runtime/observatory/lib/src/service/object.dart b/runtime/observatory/lib/src/service/object.dart
index cc8f158..7e828a1 100644
--- a/runtime/observatory/lib/src/service/object.dart
+++ b/runtime/observatory/lib/src/service/object.dart
@@ -99,12 +99,6 @@
   String toString() => 'MalformedResponseRpcException(${message})';
 }
 
-class FakeVMRpcException extends RpcException {
-  FakeVMRpcException(String message) : super(message);
-
-  String toString() => 'FakeVMRpcException(${message})';
-}
-
 /// A [ServiceObject] represents a persistent object within the vm.
 abstract class ServiceObject implements M.ObjectRef {
   static int LexicalSortName(ServiceObject o1, ServiceObject o2) {
@@ -886,8 +880,6 @@
         await listenEventStream(kDebugStream, _dispatchEventToIsolate);
         await listenEventStream(_kGraphStream, _dispatchEventToIsolate);
         await listenEventStream(kServiceStream, _updateService);
-      } on FakeVMRpcException catch (_) {
-        // ignore FakeVMRpcExceptions here.
       } on NetworkRpcException catch (_) {
         // ignore network errors here.
       }
@@ -1011,78 +1003,6 @@
   }
 }
 
-class FakeVM extends VM {
-  String get displayName => name;
-
-  final Map _responses = {};
-  FakeVM(Map responses) {
-    if (responses == null) {
-      return;
-    }
-    responses.forEach((uri, response) {
-      // Encode as string.
-      _responses[_canonicalizeUri(Uri.parse(uri))] = response;
-    });
-  }
-
-  String _canonicalizeUri(Uri uri) {
-    // We use the uri as the key to the response map. Uri parameters can be
-    // serialized in any order, this function canonicalizes the uri parameters
-    // so they are serialized in sorted-by-parameter-name order.
-    var method = uri.path;
-    // Create a map sorted on insertion order.
-    var parameters = new Map();
-    // Sort keys.
-    var sortedKeys = uri.queryParameters.keys.toList();
-    sortedKeys.sort();
-    // Filter keys to remove any private options.
-    sortedKeys.removeWhere((k) => k.startsWith('_'));
-    // Insert parameters in sorted order.
-    for (var key in sortedKeys) {
-      parameters[key] = uri.queryParameters[key];
-    }
-    // Return canonical uri.
-    return new Uri(path: method, queryParameters: parameters).toString();
-  }
-
-  /// Force the VM to disconnect.
-  void disconnect() {
-    _onDisconnect.complete('Disconnected');
-  }
-
-  // Always connected.
-  Future _onConnect;
-  Future get onConnect {
-    if (_onConnect != null) {
-      return _onConnect;
-    }
-    _onConnect = new Future.value(this);
-    return _onConnect;
-  }
-
-  bool get isConnected => !isDisconnected;
-  // Only complete when requested.
-  Completer<String> _onDisconnect = new Completer<String>();
-  Future<String> get onDisconnect => _onDisconnect.future;
-  bool get isDisconnected => _onDisconnect.isCompleted;
-
-  Future<Map> invokeRpcRaw(String method, Map params) {
-    if (params.isEmpty) {
-      params = null;
-    }
-    var key = _canonicalizeUri(new Uri(path: method, queryParameters: params));
-    var response = _responses[key];
-    if (response == null) {
-      return new Future.error(new FakeVMRpcException(
-          "Unable to find key '${key}' in cached response set"));
-    }
-    return new Future.value(response);
-  }
-
-  @override
-  WebSocketVMTarget get target => throw new UnimplementedError();
-}
-
 /// Snapshot in time of tag counters.
 class TagProfileSnapshot {
   final double seconds;
diff --git a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
index 8727212..1f5d1b6 100644
--- a/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
+++ b/runtime/observatory/tests/observatory_ui/vm_connect/element_test.dart
@@ -10,8 +10,6 @@
 import 'package:observatory/src/elements/vm_connect.dart';
 import '../mocks.dart';
 
-void load(_) {}
-
 main() {
   VMConnectElement.tag.ensureRegistration();
 
@@ -21,14 +19,13 @@
   group('instantiation', () {
     test('default', () {
       final e = new VMConnectElement(
-          new TargetRepositoryMock(), load, new NotificationRepositoryMock());
+          new TargetRepositoryMock(), new NotificationRepositoryMock());
       expect(e, isNotNull, reason: 'element correctly created');
     });
   });
   test('is correctly listening', () async {
     final targets = new TargetRepositoryMock();
-    final e =
-        new VMConnectElement(targets, load, new NotificationRepositoryMock());
+    final e = new VMConnectElement(targets, new NotificationRepositoryMock());
     document.body.append(e);
     await e.onRendered.first;
     expect(targets.hasListeners, isTrue, reason: 'is listening');
@@ -42,8 +39,7 @@
         const TargetMock(name: 't-1'),
         const TargetMock(name: 't-2'),
       ]);
-      final e =
-          new VMConnectElement(targets, load, new NotificationRepositoryMock());
+      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
       document.body.append(e);
       await e.onRendered.first;
       expect(targets.listInvoked, isTrue, reason: 'should invoke list()');
@@ -57,8 +53,7 @@
     test('react to update event', () async {
       final list = <TargetMock>[const TargetMock(name: 't-1')];
       final targets = new TargetRepositoryMock(list: list);
-      final e =
-          new VMConnectElement(targets, load, new NotificationRepositoryMock());
+      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
       document.body.append(e);
       await e.onRendered.first;
       expect(e.querySelectorAll(tTag).length, equals(1));
@@ -80,8 +75,7 @@
           add: expectAsync1((String val) {
             expect(val, equals(address));
           }, count: 1, reason: 'should be invoked'));
-      final e = new VMConnectElement(
-          targets, load, new NotificationRepositoryMock(),
+      final e = new VMConnectElement(targets, new NotificationRepositoryMock(),
           address: address);
       document.body.append(e);
       await e.onRendered.first;
@@ -96,8 +90,7 @@
           setCurrent: expectAsync1((M.Target t) {
             expect(t, equals(list[0]));
           }, count: 1, reason: 'should be invoked'));
-      final e =
-          new VMConnectElement(targets, load, new NotificationRepositoryMock());
+      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
       document.body.append(e);
       await e.onRendered.first;
       (e.querySelector(tTag) as VMConnectTargetElement).connect();
@@ -111,8 +104,7 @@
           delete: expectAsync1((M.Target t) {
             expect(t, equals(list[0]));
           }, count: 1, reason: 'should be invoked'));
-      final e =
-          new VMConnectElement(targets, load, new NotificationRepositoryMock());
+      final e = new VMConnectElement(targets, new NotificationRepositoryMock());
       document.body.append(e);
       await e.onRendered.first;
       (e.querySelector(tTag) as VMConnectTargetElement).delete();
diff --git a/runtime/observatory/tests/service/crash_dump_test.dart b/runtime/observatory/tests/service/crash_dump_test.dart
deleted file mode 100644
index 2309c94..0000000
--- a/runtime/observatory/tests/service/crash_dump_test.dart
+++ /dev/null
@@ -1,36 +0,0 @@
-// 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 crash_dump_test;
-
-import 'dart:async';
-import 'dart:convert';
-import 'dart:io';
-import 'package:observatory/service_io.dart';
-
-import 'test_helper.dart';
-
-Future warmup() async {
-  print('hi');
-}
-
-var tests = <VMTest>[
-  (VM vm) async {
-    HttpClient client = new HttpClient();
-    print('Requesting uri ${serviceHttpAddress}/_getCrashDump');
-    var request =
-        await client.getUrl(Uri.parse('$serviceHttpAddress/_getCrashDump'));
-    var response = await request.close();
-    print('Received response');
-    Completer completer = new Completer<String>();
-    StringBuffer sb = new StringBuffer();
-    response.transform(utf8.decoder).listen((chunk) {
-      sb.write(chunk);
-    }, onDone: () => completer.complete(sb.toString()));
-    var responseString = await completer.future;
-    json.decode(responseString);
-  }
-];
-
-main(args) async => runVMTests(args, tests, testeeBefore: warmup);
diff --git a/runtime/observatory/tests/service/service_kernel.status b/runtime/observatory/tests/service/service_kernel.status
index 086e741a..7012181 100644
--- a/runtime/observatory/tests/service/service_kernel.status
+++ b/runtime/observatory/tests/service/service_kernel.status
@@ -50,6 +50,9 @@
 regress_34841_test: RuntimeError # http://dartbug.com/34841
 unused_changes_in_last_reload_test: RuntimeError
 
+[ $compiler == dartkb ]
+*: Skip # Debugging capabilities are not yet supported in bytecode modes.
+
 [ $compiler == dartkp ]
 *: SkipByDesign # Non-kernel also skips precompiled mode.
 
diff --git a/runtime/observatory/tests/service/test_helper.dart b/runtime/observatory/tests/service/test_helper.dart
index 3913854..05c37a1 100644
--- a/runtime/observatory/tests/service/test_helper.dart
+++ b/runtime/observatory/tests/service/test_helper.dart
@@ -132,6 +132,9 @@
     if (pause_on_exit) {
       fullArgs.add('--pause-isolates-on-exit');
     }
+    if (!useAuthToken) {
+      fullArgs.add('--disable-service-auth-codes');
+    }
     if (pause_on_unhandled_exceptions) {
       fullArgs.add('--pause-isolates-on-unhandled-exceptions');
     }
@@ -147,7 +150,7 @@
     fullArgs.addAll(args);
 
     return _spawnCommon(dartExecutable, fullArgs,
-        <String, String>{'DART_SERVICE_USE_AUTH': '$useAuthToken'});
+        <String, String>{});
   }
 
   Future<Process> _spawnSkyProcess(
diff --git a/runtime/runtime_args.gni b/runtime/runtime_args.gni
index d830208..cf9e71d 100644
--- a/runtime/runtime_args.gni
+++ b/runtime/runtime_args.gni
@@ -95,7 +95,7 @@
   # We create a kernel service app-jit snapshot only for when the target
   # architecture is x64 for other cases we will use the '.dill' file
   # which is already linked in the VM.
-  if (dart_target_arch == "x64" && !dart_platform_bytecode) {
+  if (dart_target_arch == "x64") {
     create_kernel_service_snapshot = true
   } else {
     create_kernel_service_snapshot = false
diff --git a/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart b/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart
index 6600482..d936339 100644
--- a/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart
+++ b/runtime/tests/vm/dart/appjit_bytecode_simple_test.dart
@@ -2,11 +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.
 
+// OtherResources=appjit_bytecode_simple_test_body.dart
+
 // Verify that app-jit snapshot contains dependencies between classes and CHA
 // optimized code.
 
 import 'dart:async';
+import 'dart:io' show Platform;
 
 import 'snapshot_test_helper.dart';
 
-Future<void> main() => runAppJitBytecodeTest();
+Future<void> main() => runAppJitBytecodeTest(
+    Platform.script.resolve('appjit_bytecode_simple_test_body.dart'));
diff --git a/runtime/tests/vm/dart/appjit_cha_deopt_test.dart b/runtime/tests/vm/dart/appjit_cha_deopt_test.dart
index fabc41b..104d431 100644
--- a/runtime/tests/vm/dart/appjit_cha_deopt_test.dart
+++ b/runtime/tests/vm/dart/appjit_cha_deopt_test.dart
@@ -2,13 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+// OtherResources=appjit_cha_deopt_test_body.dart
 // VMOptions=--optimization-counter-threshold=100
 
 // Verify that app-jit snapshot contains dependencies between classes and CHA
 // optimized code.
 
 import 'dart:async';
+import 'dart:io' show Platform;
 
 import 'snapshot_test_helper.dart';
 
-Future<void> main() => runAppJitTest();
+Future<void> main() =>
+    runAppJitTest(Platform.script.resolve('appjit_cha_deopt_test_body.dart'));
diff --git a/runtime/tests/vm/dart/appjit_load_static_licm_test.dart b/runtime/tests/vm/dart/appjit_load_static_licm_test.dart
index 9f51b70..804e30c 100644
--- a/runtime/tests/vm/dart/appjit_load_static_licm_test.dart
+++ b/runtime/tests/vm/dart/appjit_load_static_licm_test.dart
@@ -2,11 +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.
 
+// OtherResources=appjit_load_static_licm_test_body.dart
+
 // Verify that app-jit snapshot contains dependencies between classes and CHA
 // optimized code.
 
 import 'dart:async';
+import 'dart:io' show Platform;
 
 import 'snapshot_test_helper.dart';
 
-Future<void> main() => runAppJitTest();
+Future<void> main() => runAppJitTest(
+    Platform.script.resolve('appjit_load_static_licm_test_body.dart'));
diff --git a/runtime/tests/vm/dart/snapshot_test_helper.dart b/runtime/tests/vm/dart/snapshot_test_helper.dart
index 0a043af..5c63da1 100644
--- a/runtime/tests/vm/dart/snapshot_test_helper.dart
+++ b/runtime/tests/vm/dart/snapshot_test_helper.dart
@@ -151,12 +151,10 @@
   });
 }
 
-runAppJitTest() async {
+runAppJitTest(Uri testScriptUri) async {
   await withTempDir((String temp) async {
     final snapshotPath = p.join(temp, 'app.jit');
-    final testPath = Platform.script
-        .toFilePath()
-        .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart');
+    final testPath = testScriptUri.toFilePath();
 
     final trainingResult = await runDart('TRAINING RUN', [
       '--snapshot=$snapshotPath',
@@ -170,12 +168,10 @@
   });
 }
 
-Future<void> runAppJitBytecodeTest() async {
+Future<void> runAppJitBytecodeTest(Uri testScriptUri) async {
   await withTempDir((String temp) async {
     final snapshotPath = p.join(temp, 'app.jit');
-    final testPath = Platform.script
-        .toFilePath()
-        .replaceAll(new RegExp(r'_test.dart$'), '_test_body.dart');
+    final testPath = testScriptUri.toFilePath();
 
     final trainingResult = await runDart('TRAINING RUN', [
       '--enable_interpreter',
diff --git a/runtime/tests/vm/vm.status b/runtime/tests/vm/vm.status
index 6554bb2..b626857 100644
--- a/runtime/tests/vm/vm.status
+++ b/runtime/tests/vm/vm.status
@@ -267,7 +267,6 @@
 # Tests that use functionality not supported in Dart 2.
 [ ($compiler == dartk || $compiler == dartkb) || $compiler == dartkp ]
 cc/DartAPI_IsolateSetCheckedMode: SkipByDesign # Checked mode is not relevant for dart 2?
-cc/CompileFunctionOnHelperThread: SkipByDesign
 cc/CompileFunction: SkipByDesign
 cc/InvokeDynamic_CompileError: SkipByDesign
 cc/InvokeStatic_CompileError: SkipByDesign
@@ -299,3 +298,9 @@
 
 [ $compiler == dartkp ]
 dart/v8_snapshot_profile_writer_test: Pass, Slow # Can be slow due to re-invoking the precompiler.
+
+[ $compiler == dartkb ]
+cc/*: Skip # Bytecode modes are not properly hooked up in run_vm_tests.
+
+[ $mode == debug ]
+cc/IRTest_TypedDataAOT_FunctionalGetSet: Skip # run_vm_tests contains JIT/AOT but FLAG_precompiled_mode is not always correct. This causes this test to fail in debug mode, hitting an assertion. See http://dartbug.com/36521
diff --git a/runtime/tools/dartfuzz/dartfuzz.dart b/runtime/tools/dartfuzz/dartfuzz.dart
index 27cd715..9f79e8a 100644
--- a/runtime/tools/dartfuzz/dartfuzz.dart
+++ b/runtime/tools/dartfuzz/dartfuzz.dart
@@ -13,7 +13,7 @@
 // Version of DartFuzz. Increase this each time changes are made
 // to preserve the property that a given version of DartFuzz yields
 // the same fuzzed program for a deterministic random seed.
-const String version = '1.5';
+const String version = '1.7';
 
 // Restriction on statement and expression depths.
 const int stmtDepth = 2;
@@ -101,10 +101,10 @@
   void emitClasses() {
     assert(classFields.length == classMethods.length);
     for (int i = 0; i < classFields.length; i++) {
-      currentClass = i;
       emitLn('class X$i ${i == 0 ? "" : "extends X${i - 1}"} {');
       indent += 2;
       emitVarDecls('$fieldName${i}_', classFields[i]);
+      currentClass = i;
       emitMethods('$methodName${i}_', classMethods[i]);
       emitLn('void run() {');
       indent += 2;
@@ -156,7 +156,7 @@
     for (int i = 0; i < vars.length; i++) {
       DartType tp = vars[i];
       emitLn('${tp.name} $name$i = ', newline: false);
-      emitLiteral(tp);
+      emitLiteral(0, tp);
       emit(';', newline: true);
     }
     emit('', newline: true);
@@ -534,39 +534,96 @@
 
   void emitString() {
     emit("'");
-    int l = rand.nextInt(8);
-    for (int i = 0; i < l; i++) {
+    for (int i = 0, n = rand.nextInt(8); i < n; i++) {
       emitChar();
     }
     emit("'");
   }
 
-  void emitList(String open, String close) {
-    emit('$open ');
-    int l = 1 + rand.nextInt(4);
-    for (int i = 0; i < l; i++) {
-      emitInt();
-      if (i != (l - 1)) {
+  void emitElementExpr(int depth, DartType tp) {
+    if (currentMethod != null) {
+      emitExpr(depth, tp);
+    } else {
+      emitLiteral(depth, tp);
+    }
+  }
+
+  void emitElement(int depth, DartType tp) {
+    if (tp == DartType.INT_STRING_MAP) {
+      emitSmallPositiveInt();
+      emit(' : ');
+      emitElementExpr(depth, DartType.STRING);
+    } else {
+      emitElementExpr(depth, DartType.INT);
+    }
+  }
+
+  void emitCollectionElement(int depth, DartType tp) {
+    int r = depth <= exprDepth ? rand.nextInt(10) : 10;
+    switch (r + 3) {
+      // TODO(ajcbik): enable when on by default
+      // Favors elements over control-flow collections.
+      case 0:
+        emit('...'); // spread
+        emitCollection(depth + 1, tp);
+        break;
+      case 1:
+        emit('if (');
+        emitElementExpr(depth + 1, DartType.BOOL);
+        emit(') ');
+        emitCollectionElement(depth + 1, tp);
+        if (rand.nextBool()) {
+          emit(' else ');
+          emitCollectionElement(depth + 1, tp);
+        }
+        break;
+      case 2:
+        {
+          int i = localVars.length;
+          emit('for (int $localName$i ');
+          // For-loop (induction, list, set).
+          switch (rand.nextInt(3)) {
+            case 0:
+              emit('= 0; $localName$i < ');
+              emitSmallPositiveInt();
+              emit('; $localName$i++) ');
+              break;
+            case 1:
+              emit('in ');
+              emitCollection(depth + 1, DartType.INT_LIST);
+              emit(') ');
+              break;
+            default:
+              emit('in ');
+              emitCollection(depth + 1, DartType.INT_SET);
+              emit(') ');
+              break;
+          }
+          nest++;
+          localVars.add(DartType.INT);
+          emitCollectionElement(depth + 1, tp);
+          localVars.removeLast();
+          nest--;
+          break;
+        }
+      default:
+        emitElement(depth, tp);
+        break;
+    }
+  }
+
+  void emitCollection(int depth, DartType tp) {
+    emit(tp == DartType.INT_LIST ? '[ ' : '{ ');
+    for (int i = 0, n = 1 + rand.nextInt(8); i < n; i++) {
+      emitCollectionElement(depth, tp);
+      if (i != (n - 1)) {
         emit(', ');
       }
     }
-    emit(' $close');
+    emit(tp == DartType.INT_LIST ? ' ]' : ' }');
   }
 
-  void emitMap() {
-    emit('{ ');
-    int l = 1 + rand.nextInt(4);
-    for (int i = 0; i < l; i++) {
-      emit('$i : ');
-      emitString();
-      if (i != (l - 1)) {
-        emit(', ');
-      }
-    }
-    emit(' }');
-  }
-
-  void emitLiteral(DartType tp) {
+  void emitLiteral(int depth, DartType tp) {
     if (tp == DartType.BOOL) {
       emitBool();
     } else if (tp == DartType.INT) {
@@ -575,12 +632,10 @@
       emitDouble();
     } else if (tp == DartType.STRING) {
       emitString();
-    } else if (tp == DartType.INT_LIST) {
-      emitList('[', ']');
-    } else if (tp == DartType.INT_SET) {
-      emitList('{', '}');
-    } else if (tp == DartType.INT_STRING_MAP) {
-      emitMap();
+    } else if (tp == DartType.INT_LIST ||
+        tp == DartType.INT_SET ||
+        tp == DartType.INT_STRING_MAP) {
+      emitCollection(depth, tp);
     } else {
       assert(false);
     }
@@ -642,7 +697,7 @@
   void emitTerminal(int depth, DartType tp) {
     switch (rand.nextInt(2)) {
       case 0:
-        emitLiteral(tp);
+        emitLiteral(depth, tp);
         break;
       default:
         emitVar(depth, tp);
@@ -694,7 +749,7 @@
       emit('(');
       emitExpr(depth + 1, tp);
       emitBinaryOp(tp);
-      emitLiteral(tp);
+      emitLiteral(depth + 1, tp);
       emit(')');
       return;
     }
@@ -774,8 +829,9 @@
   void emitMethodCall(int depth, DartType tp) {
     // Only call backward to avoid infinite recursion.
     if (currentClass == null) {
-      // Outside a class: call backward in global methods.
-      if (pickedCall(depth, tp, methodName, globalMethods, currentMethod)) {
+      // Outside a class but inside a method: call backward in global methods.
+      if (currentMethod != null &&
+          pickedCall(depth, tp, methodName, globalMethods, currentMethod)) {
         return;
       }
     } else {
@@ -996,8 +1052,7 @@
 
   List<DartType> fillTypes1() {
     List<DartType> list = new List<DartType>();
-    int n = 1 + rand.nextInt(4);
-    for (int i = 0; i < n; i++) {
+    for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) {
       list.add(getType());
     }
     return list;
@@ -1005,8 +1060,7 @@
 
   List<List<DartType>> fillTypes2() {
     List<List<DartType>> list = new List<List<DartType>>();
-    int n = 1 + rand.nextInt(4);
-    for (int i = 0; i < n; i++) {
+    for (int i = 0, n = 1 + rand.nextInt(4); i < n; i++) {
       list.add(fillTypes1());
     }
     return list;
diff --git a/runtime/tools/dartfuzz/dartfuzz_api_table.dart b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
index de5df1c..170f19d 100644
--- a/runtime/tools/dartfuzz/dartfuzz_api_table.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_api_table.dart
@@ -50,12 +50,6 @@
     DartLib('FileSystemEntity.isFileSync', 'VS'),
     DartLib('FileSystemEntity.isDirectorySync', 'VS'),
     DartLib('FileSystemEntity.isWatchSupported', 'Vv'),
-    DartLib('Platform.isLinux', 'Vv'),
-    DartLib('Platform.isMacOS', 'Vv'),
-    DartLib('Platform.isWindows', 'Vv'),
-    DartLib('Platform.isAndroid', 'Vv'),
-    DartLib('Platform.isIOS', 'Vv'),
-    DartLib('Platform.isFuchsia', 'Vv'),
     DartLib('SecurityContext.alpnSupported', 'Vv'),
     DartLib('NetworkInterface.listSupported', 'Vv'),
   ];
@@ -176,7 +170,6 @@
     DartLib('FileSystemEvent.MOVE', 'Vv'),
     DartLib('FileSystemEvent.all', 'Vv'),
     DartLib('FileSystemEvent.ALL', 'Vv'),
-    DartLib('Platform.numberOfProcessors', 'Vv'),
     DartLib('exitCode', 'Vv'),
     DartLib('pid', 'Vv'),
     DartLib('ProcessInfo.currentRss', 'Vv'),
@@ -798,14 +791,6 @@
     DartLib('Uri.encodeFull', 'VS'),
     DartLib('Uri.decodeFull', 'VS'),
     DartLib('FileSystemEntity.parentOf', 'VS'),
-    DartLib('Platform.pathSeparator', 'Vv'),
-    DartLib('Platform.localeName', 'Vv'),
-    DartLib('Platform.operatingSystem', 'Vv'),
-    DartLib('Platform.operatingSystemVersion', 'Vv'),
-    DartLib('Platform.localHostname', 'Vv'),
-    DartLib('Platform.packageRoot', 'Vv'),
-    DartLib('Platform.packageConfig', 'Vv'),
-    DartLib('Platform.version', 'Vv'),
   ];
   static const listLibs = [
     DartLib('List.filled', 'VII'),
diff --git a/runtime/tools/dartfuzz/dartfuzz_test.dart b/runtime/tools/dartfuzz/dartfuzz_test.dart
index e90bbae..5bdaadc 100644
--- a/runtime/tools/dartfuzz/dartfuzz_test.dart
+++ b/runtime/tools/dartfuzz/dartfuzz_test.dart
@@ -69,7 +69,7 @@
     }
     // Every once in a while, stress test JIT.
     if (mode.startsWith('jit') && rand.nextInt(4) == 0) {
-      final r = rand.nextInt(6);
+      final r = rand.nextInt(7);
       if (r == 0) {
         prefix += '-NOFIELDGUARDS';
         extraFlags += ['--use_field_guards=false'];
@@ -89,7 +89,6 @@
         prefix += '-STACKTRACEEVERY';
         extraFlags += ['--stacktrace_every=100'];
       } else if (r == 6) {
-        // Crashes (https://github.com/dart-lang/sdk/issues/35196):
         prefix += '-OPTCOUNTER';
         extraFlags += ['--optimization_counter_threshold=1'];
       }
diff --git a/runtime/tools/dartfuzz/gen_api_table.dart b/runtime/tools/dartfuzz/gen_api_table.dart
index e02a310..768ba39 100755
--- a/runtime/tools/dartfuzz/gen_api_table.dart
+++ b/runtime/tools/dartfuzz/gen_api_table.dart
@@ -127,6 +127,10 @@
 }
 
 void visitClass(ClassElement classElement) {
+  // Platform operations cause too many divergences.
+  if (classElement.name == 'Platform') {
+    return;
+  }
   // Every class element contains elements for the members, viz. `methods` visits
   // methods, `fields` visits fields, `accessors` visits getters and setters, etc.
   // There are also accessors to get the superclass, mixins, interfaces, type
diff --git a/runtime/vm/BUILD.gn b/runtime/vm/BUILD.gn
index a82e940..680ab84 100644
--- a/runtime/vm/BUILD.gn
+++ b/runtime/vm/BUILD.gn
@@ -119,6 +119,14 @@
       "$root_out_dir/vm_outline" + output_postfix + ".dill",
     ]
     args = [ "dart:core" ]
+    is_product_flag = dart_runtime_mode == "release"
+    allow_causal_async_stacks = !is_product_flag
+    args += [
+      "-Ddart.vm.product=$is_product_flag",
+      "-Ddart.developer.causal_async_stacks=$allow_causal_async_stacks",
+      "-Ddart.isVM=true",
+    ]
+
     if (defined(invoker.exclude_source) && invoker.exclude_source) {
       args += [ "--exclude-source" ]
     }
diff --git a/runtime/vm/benchmark_test.cc b/runtime/vm/benchmark_test.cc
index c3e1db3..10ddc29 100644
--- a/runtime/vm/benchmark_test.cc
+++ b/runtime/vm/benchmark_test.cc
@@ -68,7 +68,7 @@
   EXPECT(worked);
 
   Dart_Handle result = bin::DartUtils::PrepareForScriptLoading(false, false);
-  DART_CHECK_VALID(result);
+  EXPECT_VALID(result);
 
   // Setup package root.
   char buffer[2048];
@@ -79,7 +79,7 @@
   Utils::SNPrint(buffer, 2048, packages_path, executable_path, path_separator,
                  path_separator);
   result = bin::DartUtils::SetupPackageRoot(buffer, NULL);
-  DART_CHECK_VALID(result);
+  EXPECT_VALID(result);
 }
 
 void Benchmark::RunAll(const char* executable) {
@@ -313,7 +313,7 @@
 
   Dart_Handle lib = TestCase::LoadTestScript(
       kScriptChars, reinterpret_cast<Dart_NativeEntryResolver>(bm_uda_lookup),
-      USER_TEST_URI, false);
+      RESOLVED_USER_TEST_URI, false);
   Dart_Handle result = Dart_FinalizeLoading(false);
   EXPECT_VALID(result);
 
diff --git a/runtime/vm/class_finalizer.cc b/runtime/vm/class_finalizer.cc
index f4d63f7..ce2bac2 100644
--- a/runtime/vm/class_finalizer.cc
+++ b/runtime/vm/class_finalizer.cc
@@ -1088,19 +1088,6 @@
     interface_class.AddDirectImplementor(cls,
                                          /* is_mixin = */ i == mixin_index);
   }
-
-  if (FLAG_use_cha_deopt) {
-    // Invalidate all CHA code which depends on knowing the implementors of any
-    // of the interfaces implemented by this new class.
-    ClassTable* class_table = thread->isolate()->class_table();
-    GrowableArray<intptr_t> cids;
-    InterfaceFinder finder(zone, class_table, &cids);
-    finder.FindAllInterfaces(cls);
-    for (intptr_t j = 0; j < cids.length(); ++j) {
-      interface_class = class_table->At(cids[j]);
-      interface_class.DisableCHAImplementorUsers();
-    }
-  }
 }
 
 void ClassFinalizer::FinalizeClass(const Class& cls) {
@@ -1169,6 +1156,22 @@
     RemoveCHAOptimizedCode(cls, cids);
   }
 
+  if (FLAG_use_cha_deopt) {
+    Zone* zone = thread->zone();
+    ClassTable* class_table = thread->isolate()->class_table();
+    auto& interface_class = Class::Handle(zone);
+
+    // We scan every interface this [cls] implements and invalidate all CHA code
+    // which depends on knowing the implementors of that interface.
+    GrowableArray<intptr_t> cids;
+    InterfaceFinder finder(zone, class_table, &cids);
+    finder.FindAllInterfaces(cls);
+    for (intptr_t j = 0; j < cids.length(); ++j) {
+      interface_class = class_table->At(cids[j]);
+      interface_class.DisableCHAImplementorUsers();
+    }
+  }
+
   if (cls.is_enum_class()) {
     AllocateEnumValues(cls);
   }
diff --git a/runtime/vm/class_table.cc b/runtime/vm/class_table.cc
index f3f5fd5..70ad37c 100644
--- a/runtime/vm/class_table.cc
+++ b/runtime/vm/class_table.cc
@@ -405,20 +405,6 @@
   obj->AddProperty("promotedBytes", promoted_size);
 }
 
-void ClassTable::UpdateAllocatedNew(intptr_t cid, intptr_t size) {
-  ClassHeapStats* stats = PreliminaryStatsAt(cid);
-  ASSERT(stats != NULL);
-  ASSERT(size != 0);
-  stats->recent.AddNew(size);
-}
-
-void ClassTable::UpdateAllocatedOld(intptr_t cid, intptr_t size) {
-  ClassHeapStats* stats = PreliminaryStatsAt(cid);
-  ASSERT(stats != NULL);
-  ASSERT(size != 0);
-  stats->recent.AddOld(size);
-}
-
 void ClassTable::UpdateAllocatedOldGC(intptr_t cid, intptr_t size) {
   ClassHeapStats* stats = PreliminaryStatsAt(cid);
   ASSERT(stats != NULL);
diff --git a/runtime/vm/class_table.h b/runtime/vm/class_table.h
index 6a49f54..fd2bdc1 100644
--- a/runtime/vm/class_table.h
+++ b/runtime/vm/class_table.h
@@ -261,8 +261,18 @@
 
 #ifndef PRODUCT
   // Called whenever a class is allocated in the runtime.
-  void UpdateAllocatedNew(intptr_t cid, intptr_t size);
-  void UpdateAllocatedOld(intptr_t cid, intptr_t size);
+  void UpdateAllocatedNew(intptr_t cid, intptr_t size) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    ASSERT(stats != NULL);
+    ASSERT(size != 0);
+    stats->recent.AddNew(size);
+  }
+  void UpdateAllocatedOld(intptr_t cid, intptr_t size) {
+    ClassHeapStats* stats = PreliminaryStatsAt(cid);
+    ASSERT(stats != NULL);
+    ASSERT(size != 0);
+    stats->recent.AddOld(size);
+  }
   void UpdateAllocatedOldGC(intptr_t cid, intptr_t size);
   void UpdateAllocatedExternalNew(intptr_t cid, intptr_t size);
   void UpdateAllocatedExternalOld(intptr_t cid, intptr_t size);
diff --git a/runtime/vm/compilation_trace.cc b/runtime/vm/compilation_trace.cc
index e5f91a0..48db21c 100644
--- a/runtime/vm/compilation_trace.cc
+++ b/runtime/vm/compilation_trace.cc
@@ -60,6 +60,13 @@
       function_(Function::Handle(zone_)),
       function2_(Function::Handle(zone_)),
       field_(Field::Handle(zone_)),
+      sites_(Array::Handle(zone_)),
+      site_(ICData::Handle(zone_)),
+      static_type_(AbstractType::Handle(zone_)),
+      receiver_cls_(Class::Handle(zone_)),
+      target_(Function::Handle(zone_)),
+      selector_(String::Handle(zone_)),
+      args_desc_(Array::Handle(zone_)),
       error_(Object::Handle(zone_)) {}
 
 static char* FindCharacter(char* str, char goal, char* limit) {
@@ -354,14 +361,75 @@
 }
 
 RawObject* CompilationTraceLoader::CompileFunction(const Function& function) {
-  if (function.is_abstract()) {
+  if (function.is_abstract() || function.HasCode()) {
     return Object::null();
   }
+
   // Prevent premature code collection due to major GC during startup.
   if (function.usage_counter() < Function::kGraceUsageCounter) {
     function.set_usage_counter(Function::kGraceUsageCounter);
   }
-  return Compiler::CompileFunction(thread_, function);
+
+  error_ = Compiler::CompileFunction(thread_, function);
+  if (error_.IsError()) {
+    return error_.raw();
+  }
+
+  SpeculateInstanceCallTargets(function);
+
+  return error_.raw();
+}
+
+// For instance calls, if the receiver's static type has one concrete
+// implementation, lookup the target for that implementation and add it
+// to the ICData's entries.
+// For some well-known interfaces, do the same for the most common concrete
+// implementation (e.g., int -> _Smi).
+void CompilationTraceLoader::SpeculateInstanceCallTargets(
+    const Function& function) {
+  sites_ = function.ic_data_array();
+  if (sites_.IsNull()) {
+    return;
+  }
+  for (intptr_t i = 1; i < sites_.Length(); i++) {
+    site_ ^= sites_.At(i);
+    if (site_.rebind_rule() != ICData::kInstance) {
+      continue;
+    }
+    if (site_.NumArgsTested() != 1) {
+      continue;
+    }
+
+    static_type_ = site_.receivers_static_type();
+    if (static_type_.IsNull()) {
+      continue;
+    } else if (static_type_.IsDoubleType()) {
+      receiver_cls_ = Isolate::Current()->class_table()->At(kDoubleCid);
+    } else if (static_type_.IsIntType()) {
+      receiver_cls_ = Isolate::Current()->class_table()->At(kSmiCid);
+    } else if (static_type_.IsStringType()) {
+      receiver_cls_ = Isolate::Current()->class_table()->At(kOneByteStringCid);
+    } else if (static_type_.IsDartFunctionType() ||
+               static_type_.IsDartClosureType()) {
+      receiver_cls_ = Isolate::Current()->class_table()->At(kClosureCid);
+    } else if (static_type_.HasTypeClass()) {
+      receiver_cls_ = static_type_.type_class();
+      if (receiver_cls_.is_implemented() || receiver_cls_.is_abstract()) {
+        continue;
+      }
+    } else {
+      continue;
+    }
+
+    selector_ = site_.target_name();
+    args_desc_ = site_.arguments_descriptor();
+    target_ = Resolver::ResolveDynamicForReceiverClass(
+        receiver_cls_, selector_, ArgumentsDescriptor(args_desc_));
+    if (!target_.IsNull() && !site_.HasReceiverClassId(receiver_cls_.id())) {
+      intptr_t count = 0;  // Don't pollute type feedback and coverage data.
+      site_.AddReceiverCheck(receiver_cls_.id(), target_, count);
+    }
+  }
 }
 
 TypeFeedbackSaver::TypeFeedbackSaver(WriteStream* stream)
diff --git a/runtime/vm/compilation_trace.h b/runtime/vm/compilation_trace.h
index 699f08c..e3a8fbd 100644
--- a/runtime/vm/compilation_trace.h
+++ b/runtime/vm/compilation_trace.h
@@ -42,6 +42,7 @@
                            const char* cls_cstr,
                            const char* func_cstr);
   RawObject* CompileFunction(const Function& function);
+  void SpeculateInstanceCallTargets(const Function& function);
 
   Thread* thread_;
   Zone* zone_;
@@ -54,6 +55,13 @@
   Function& function_;
   Function& function2_;
   Field& field_;
+  Array& sites_;
+  ICData& site_;
+  AbstractType& static_type_;
+  Class& receiver_cls_;
+  Function& target_;
+  String& selector_;
+  Array& args_desc_;
   Object& error_;
 };
 
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index b04473bf..07d879f 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -767,8 +767,6 @@
 // TODO(dartbug.com/30635) Evaluate how much this can be shared with
 // JitCallSpecializer.
 void AotCallSpecializer::VisitInstanceCall(InstanceCallInstr* instr) {
-  ASSERT(FLAG_precompiled_mode);
-
   // Type test is special as it always gets converted into inlined code.
   const Token::Kind op_kind = instr->token_kind();
   if (Token::IsTypeTestOperator(op_kind)) {
diff --git a/runtime/vm/compiler/assembler/assembler_arm.h b/runtime/vm/compiler/assembler/assembler_arm.h
index 2d224df..cef1ff6 100644
--- a/runtime/vm/compiler/assembler/assembler_arm.h
+++ b/runtime/vm/compiler/assembler/assembler_arm.h
@@ -15,7 +15,7 @@
 #include "platform/utils.h"
 #include "vm/code_entry_kind.h"
 #include "vm/compiler/runtime_api.h"
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/hash_map.h"
 #include "vm/simulator.h"
diff --git a/runtime/vm/compiler/assembler/assembler_arm64.h b/runtime/vm/compiler/assembler/assembler_arm64.h
index f542eea..de51436 100644
--- a/runtime/vm/compiler/assembler/assembler_arm64.h
+++ b/runtime/vm/compiler/assembler/assembler_arm64.h
@@ -14,7 +14,7 @@
 #include "platform/assert.h"
 #include "platform/utils.h"
 #include "vm/class_id.h"
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 #include "vm/hash_map.h"
 #include "vm/simulator.h"
 
diff --git a/runtime/vm/compiler/assembler/assembler_ia32.h b/runtime/vm/compiler/assembler/assembler_ia32.h
index e3e78c2..1ec4248 100644
--- a/runtime/vm/compiler/assembler/assembler_ia32.h
+++ b/runtime/vm/compiler/assembler/assembler_ia32.h
@@ -11,7 +11,7 @@
 
 #include "platform/assert.h"
 #include "platform/utils.h"
-#include "vm/constants_ia32.h"
+#include "vm/constants.h"
 #include "vm/constants_x86.h"
 #include "vm/pointer_tagging.h"
 
@@ -466,7 +466,7 @@
   F(sub, 0x2b, 0x29, 5)                                                        \
   F(sbb, 0x1b, 0x19, 3)                                                        \
   F(cmp, 0x3b, 0x39, 7)
-// clang-format on
+  // clang-format on
 
 #define DECLARE_ALU(op, opcode, opcode2, modrm_opcode)                         \
   void op##l(Register dst, Register src) { Alu(4, opcode, dst, src); }         \
diff --git a/runtime/vm/compiler/assembler/assembler_x64.h b/runtime/vm/compiler/assembler/assembler_x64.h
index 4e073d5..2df4c31 100644
--- a/runtime/vm/compiler/assembler/assembler_x64.h
+++ b/runtime/vm/compiler/assembler/assembler_x64.h
@@ -13,7 +13,7 @@
 
 #include "platform/assert.h"
 #include "platform/utils.h"
-#include "vm/constants_x64.h"
+#include "vm/constants.h"
 #include "vm/constants_x86.h"
 #include "vm/hash_map.h"
 #include "vm/pointer_tagging.h"
diff --git a/runtime/vm/compiler/backend/block_builder.h b/runtime/vm/compiler/backend/block_builder.h
new file mode 100644
index 0000000..0337556
--- /dev/null
+++ b/runtime/vm/compiler/backend/block_builder.h
@@ -0,0 +1,132 @@
+// 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.
+
+#ifndef RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
+#define RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
+
+#include "vm/compiler/backend/flow_graph.h"
+#include "vm/compiler/backend/il.h"
+
+namespace dart {
+namespace compiler {
+
+// Helper class for building basic blocks in SSA form.
+class BlockBuilder : public ValueObject {
+ public:
+  BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry)
+      : flow_graph_(flow_graph),
+        entry_(entry),
+        current_(entry),
+        dummy_env_(
+            new Environment(0, 0, flow_graph->parsed_function(), nullptr)) {}
+
+  Definition* AddToInitialDefinitions(Definition* def) {
+    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    auto normal_entry = flow_graph_->graph_entry()->normal_entry();
+    flow_graph_->AddToInitialDefinitions(normal_entry, def);
+    return def;
+  }
+
+  Definition* AddDefinition(Definition* def) {
+    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    AddInstruction(def);
+    return def;
+  }
+
+  Instruction* AddInstruction(Instruction* instr) {
+    if (instr->ComputeCanDeoptimize()) {
+      // All instructions that can deoptimize must have an environment attached
+      // to them.
+      instr->SetEnvironment(dummy_env_);
+    }
+    current_ = current_->AppendInstruction(instr);
+    return instr;
+  }
+
+  void AddReturn(Value* value) {
+    ReturnInstr* instr = new ReturnInstr(
+        TokenPos(), value, CompilerState::Current().GetNextDeoptId());
+    AddInstruction(instr);
+    entry_->set_last_instruction(instr);
+  }
+
+  Definition* AddParameter(intptr_t index, bool with_frame) {
+    return AddToInitialDefinitions(new ParameterInstr(
+        index, flow_graph_->graph_entry(), with_frame ? FPREG : SPREG));
+  }
+
+  TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
+
+  Definition* AddNullDefinition() {
+    return flow_graph_->GetConstant(Object::ZoneHandle());
+  }
+
+  Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
+    Definition* unboxed_value =
+        AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone));
+    if (is_checked) {
+      // The type of |value| has already been checked and it is safe to
+      // adjust reaching type. This is done manually because there is no type
+      // propagation when building intrinsics.
+      unboxed_value->AsUnbox()->value()->SetReachingType(
+          new CompileType(CompileType::FromCid(CidForRepresentation(rep))));
+    }
+    return unboxed_value;
+  }
+
+  Definition* AddUnboxInstr(Representation rep,
+                            Definition* boxed,
+                            bool is_checked) {
+    return AddUnboxInstr(rep, new Value(boxed), is_checked);
+  }
+
+  BranchInstr* AddBranch(ComparisonInstr* comp,
+                         TargetEntryInstr* true_successor,
+                         TargetEntryInstr* false_successor) {
+    auto branch =
+        new BranchInstr(comp, CompilerState::Current().GetNextDeoptId());
+    current_->AppendInstruction(branch);
+    current_ = nullptr;
+
+    *branch->true_successor_address() = true_successor;
+    *branch->false_successor_address() = false_successor;
+
+    return branch;
+  }
+
+  void AddPhi(PhiInstr* phi) {
+    phi->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
+    phi->mark_alive();
+    entry_->AsJoinEntry()->InsertPhi(phi);
+  }
+
+ private:
+  static intptr_t CidForRepresentation(Representation rep) {
+    switch (rep) {
+      case kUnboxedDouble:
+        return kDoubleCid;
+      case kUnboxedFloat32x4:
+        return kFloat32x4Cid;
+      case kUnboxedInt32x4:
+        return kInt32x4Cid;
+      case kUnboxedFloat64x2:
+        return kFloat64x2Cid;
+      case kUnboxedUint32:
+        return kDynamicCid;  // smi or mint.
+      default:
+        UNREACHABLE();
+        return kIllegalCid;
+    }
+  }
+
+  FlowGraph* flow_graph_;
+  BlockEntryInstr* entry_;
+  Instruction* current_;
+  Environment* dummy_env_;
+};
+
+}  // namespace compiler
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_BACKEND_BLOCK_BUILDER_H_
diff --git a/runtime/vm/compiler/backend/compile_type.h b/runtime/vm/compiler/backend/compile_type.h
index e659dbd..a6f4e93 100644
--- a/runtime/vm/compiler/backend/compile_type.h
+++ b/runtime/vm/compiler/backend/compile_type.h
@@ -13,6 +13,7 @@
 
 class AbstractType;
 class BufferFormatter;
+class Definition;
 
 // CompileType describes type of a value produced by a definition.
 //
@@ -41,6 +42,7 @@
         type_(other.type_) {}
 
   CompileType& operator=(const CompileType& other) {
+    // This intentionally does not change the owner of this type.
     is_nullable_ = other.is_nullable_;
     cid_ = other.cid_;
     type_ = other.type_;
@@ -89,7 +91,8 @@
       // unreachable values) as None.
       return None();
     }
-    return CompileType(kNonNullable, kIllegalCid, type_);
+
+    return CompileType(kNonNullable, cid_, type_);
   }
 
   static CompileType CreateNullable(bool is_nullable, intptr_t cid) {
@@ -209,14 +212,25 @@
   void PrintTo(BufferFormatter* f) const;
   const char* ToCString() const;
 
+  // CompileType object might be unowned or owned by a definition.
+  // Owned CompileType objects can change during type propagation when
+  // [RecomputeType] is called on the owner. We keep track of which
+  // definition owns [CompileType] to prevent situations where
+  // owned [CompileType] is cached as a reaching type in a [Value] which
+  // is no longer connected to the original owning definition.
+  // See [Value::SetReachingType].
+  void set_owner(Definition* owner) { owner_ = owner; }
+  Definition* owner() const { return owner_; }
+
  private:
   bool CanComputeIsInstanceOf(const AbstractType& type,
                               bool is_nullable,
                               bool* is_instance);
 
   bool is_nullable_;
-  intptr_t cid_;
+  classid_t cid_;
   const AbstractType* type_;
+  Definition* owner_ = nullptr;
 };
 
 }  // namespace dart
diff --git a/runtime/vm/compiler/backend/flow_graph.cc b/runtime/vm/compiler/backend/flow_graph.cc
index f8c33a1..e4e02d5 100644
--- a/runtime/vm/compiler/backend/flow_graph.cc
+++ b/runtime/vm/compiler/backend/flow_graph.cc
@@ -567,7 +567,7 @@
   InsertBefore(call, load_type_args, call->env(), FlowGraph::kValue);
 
   const AbstractType& type =
-      AbstractType::Handle(zone(), call->ic_data()->StaticReceiverType());
+      AbstractType::Handle(zone(), call->ic_data()->receivers_static_type());
   ASSERT(!type.IsNull());
   const TypeArguments& args = TypeArguments::Handle(zone(), type.arguments());
   Instruction* guard = new (zone()) CheckConditionInstr(
@@ -2136,7 +2136,7 @@
         // propagation information (e.g. it might no longer be a _Smi).
         for (Value::Iterator it(defn->input_use_list()); !it.Done();
              it.Advance()) {
-          it.Current()->SetReachingType(NULL);
+          it.Current()->SetReachingType(nullptr);
         }
 
         if (defn->IsBinarySmiOp()) {
diff --git a/runtime/vm/compiler/backend/flow_graph.h b/runtime/vm/compiler/backend/flow_graph.h
index 0012962..48f4ff0 100644
--- a/runtime/vm/compiler/backend/flow_graph.h
+++ b/runtime/vm/compiler/backend/flow_graph.h
@@ -412,6 +412,9 @@
   // Adds a 2-way phi.
   PhiInstr* AddPhi(JoinEntryInstr* join, Definition* d1, Definition* d2);
 
+  // SSA transformation methods and fields.
+  void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier);
+
  private:
   friend class FlowGraphCompiler;  // TODO(ajcbik): restructure
   friend class FlowGraphChecker;
@@ -421,9 +424,6 @@
   friend class DeadCodeElimination;
   friend class compiler::GraphIntrinsifier;
 
-  // SSA transformation methods and fields.
-  void ComputeDominators(GrowableArray<BitVector*>* dominance_frontier);
-
   void CompressPath(intptr_t start_index,
                     intptr_t current_index,
                     GrowableArray<intptr_t>* parent,
diff --git a/runtime/vm/compiler/backend/flow_graph_compiler.cc b/runtime/vm/compiler/backend/flow_graph_compiler.cc
index 990ae31..54f1e50 100644
--- a/runtime/vm/compiler/backend/flow_graph_compiler.cc
+++ b/runtime/vm/compiler/backend/flow_graph_compiler.cc
@@ -215,7 +215,7 @@
     }
   }
 
-  if (!is_optimizing()) {
+  if (!is_optimizing() && FLAG_reorder_basic_blocks) {
     // Initialize edge counter array.
     const intptr_t num_counters = flow_graph_.preorder().length();
     const Array& edge_counters =
@@ -320,12 +320,12 @@
 }
 
 intptr_t FlowGraphCompiler::UncheckedEntryOffset() const {
-  // On ARM64 we cannot use the position of the label bound in the
-  // FunctionEntryInstr, because `FunctionEntryInstr::EmitNativeCode` does not
-  // emit the monomorphic entry and frame entry (instead on ARM64 this is done
-  // in FlowGraphCompiler::CompileGraph()).
-  //
-  // See http://dartbug.com/34162
+// On ARM64 we cannot use the position of the label bound in the
+// FunctionEntryInstr, because `FunctionEntryInstr::EmitNativeCode` does not
+// emit the monomorphic entry and frame entry (instead on ARM64 this is done
+// in FlowGraphCompiler::CompileGraph()).
+//
+// See http://dartbug.com/34162
 #if defined(TARGET_ARCH_ARM64)
   return 0;
 #endif
@@ -344,7 +344,7 @@
     return target->Position();
   }
 
-  // Intrinsification happened.
+// Intrinsification happened.
 #ifdef DART_PRECOMPILER
   if (parsed_function().function().IsDynamicFunction()) {
     return Instructions::kMonomorphicEntryOffset;
@@ -1259,7 +1259,7 @@
   switch (ic_data.NumArgsTested()) {
     case 1:
 #if defined(TARGET_ARCH_X64)
-      if (ic_data.IsTrackingExactness()) {
+      if (ic_data.is_tracking_exactness()) {
         if (optimized) {
           return StubCode::OneArgOptimizedCheckInlineCacheWithExactnessCheck();
         } else {
@@ -1268,12 +1268,12 @@
       }
 #else
       // TODO(dartbug.com/34170) Port exactness tracking to other platforms.
-      ASSERT(!ic_data.IsTrackingExactness());
+      ASSERT(!ic_data.is_tracking_exactness());
 #endif
       return optimized ? StubCode::OneArgOptimizedCheckInlineCache()
                        : StubCode::OneArgCheckInlineCache();
     case 2:
-      ASSERT(!ic_data.IsTrackingExactness());
+      ASSERT(!ic_data.is_tracking_exactness());
       return optimized ? StubCode::TwoArgsOptimizedCheckInlineCache()
                        : StubCode::TwoArgsCheckInlineCache();
     default:
@@ -1759,7 +1759,7 @@
     ASSERT(res->TypeArgsLen() ==
            ArgumentsDescriptor(arguments_descriptor).TypeArgsLen());
     ASSERT(!res->is_static_call());
-    ASSERT(res->StaticReceiverType() == receiver_type.raw());
+    ASSERT(res->receivers_static_type() == receiver_type.raw());
     return res;
   }
   const ICData& ic_data = ICData::ZoneHandle(
@@ -1809,6 +1809,9 @@
     threshold = FLAG_reoptimization_counter_threshold;
   } else if (parsed_function_.function().IsIrregexpFunction()) {
     threshold = FLAG_regexp_optimization_counter_threshold;
+  } else if (FLAG_randomize_optimization_counter) {
+    threshold = Thread::Current()->GetRandomUInt64() %
+                FLAG_optimization_counter_threshold;
   } else {
     const intptr_t basic_blocks = flow_graph().preorder().length();
     ASSERT(basic_blocks > 0);
@@ -1818,6 +1821,21 @@
       threshold = FLAG_optimization_counter_threshold;
     }
   }
+
+  // Threshold = 0 doesn't make sense because we increment the counter before
+  // testing against the threshold. Perhaps we could interpret it to mean
+  // "generate optimized code immediately without unoptimized compilation
+  // first", but this isn't supported in our pipeline because there would be no
+  // code for the optimized code to deoptimize into.
+  if (threshold == 0) threshold = 1;
+
+  // See Compiler::CanOptimizeFunction. In short, we have to allow the
+  // unoptimized code to run at least once to prevent an infinite compilation
+  // loop.
+  if (threshold == 1 && parsed_function().function().HasBreakpoint()) {
+    threshold = 2;
+  }
+
   return threshold;
 }
 
diff --git a/runtime/vm/compiler/backend/il.cc b/runtime/vm/compiler/backend/il.cc
index 465be1e..6c2c344 100644
--- a/runtime/vm/compiler/backend/il.cc
+++ b/runtime/vm/compiler/backend/il.cc
@@ -479,15 +479,7 @@
 }
 #endif  // DEBUG
 
-Definition::Definition(intptr_t deopt_id)
-    : Instruction(deopt_id),
-      range_(NULL),
-      type_(NULL),
-      temp_index_(-1),
-      ssa_temp_index_(-1),
-      input_use_list_(NULL),
-      env_use_list_(NULL),
-      constant_value_(NULL) {}
+Definition::Definition(intptr_t deopt_id) : Instruction(deopt_id) {}
 
 // A value in the constant propagation lattice.
 //    - non-constant sentinel
@@ -4115,26 +4107,14 @@
     const Array& arguments_descriptor =
         Array::Handle(zone, GetArgumentsDescriptor());
 
-    AbstractType& static_receiver_type = AbstractType::Handle(zone);
-
-#if defined(TARGET_ARCH_X64)
-    // Enable static type exactness tracking for the callsite by setting
-    // static receiver type on the ICData.
-    if (checked_argument_count() == 1) {
-      if (static_receiver_type_ != nullptr &&
-          static_receiver_type_->HasTypeClass()) {
-        const Class& cls =
-            Class::Handle(zone, static_receiver_type_->type_class());
-        if (cls.IsGeneric() && !cls.IsFutureOrClass()) {
-          static_receiver_type = static_receiver_type_->raw();
-        }
-      }
+    AbstractType& receivers_static_type = AbstractType::Handle(zone);
+    if (receivers_static_type_ != nullptr) {
+      receivers_static_type = receivers_static_type_->raw();
     }
-#endif
 
     call_ic_data = compiler->GetOrAddInstanceCallICData(
         deopt_id(), function_name(), arguments_descriptor,
-        checked_argument_count(), static_receiver_type);
+        checked_argument_count(), receivers_static_type);
   } else {
     call_ic_data = &ICData::ZoneHandle(zone, ic_data()->raw());
   }
@@ -5063,13 +5043,15 @@
                                      intptr_t class_id,
                                      AlignmentType alignment,
                                      intptr_t deopt_id,
-                                     TokenPosition token_pos)
+                                     TokenPosition token_pos,
+                                     SpeculativeMode speculative_mode)
     : TemplateInstruction(deopt_id),
       emit_store_barrier_(emit_store_barrier),
       index_scale_(index_scale),
       class_id_(class_id),
       alignment_(StrengthenAlignment(class_id, alignment)),
-      token_pos_(token_pos) {
+      token_pos_(token_pos),
+      speculative_mode_(speculative_mode) {
   SetInputAt(kArrayPos, array);
   SetInputAt(kIndexPos, index);
   SetInputAt(kValuePos, value);
diff --git a/runtime/vm/compiler/backend/il.h b/runtime/vm/compiler/backend/il.h
index fa4b7be..3440130 100644
--- a/runtime/vm/compiler/backend/il.h
+++ b/runtime/vm/compiler/backend/il.h
@@ -30,6 +30,7 @@
 class BufferFormatter;
 class CallTargets;
 class CatchBlockEntryInstr;
+class CheckBoundBase;
 class ComparisonInstr;
 class Definition;
 class Environment;
@@ -117,7 +118,8 @@
 
   CompileType* Type();
 
-  void SetReachingType(CompileType* type) { reaching_type_ = type; }
+  CompileType* reaching_type() const { return reaching_type_; }
+  void SetReachingType(CompileType* type);
   void RefineReachingType(CompileType* type);
 
   void PrintTo(BufferFormatter* f) const;
@@ -758,6 +760,7 @@
   DECLARE_INSTRUCTION_TYPE_CHECK(Definition, Definition)
   DECLARE_INSTRUCTION_TYPE_CHECK(BlockEntryWithInitialDefs,
                                  BlockEntryWithInitialDefs)
+  DECLARE_INSTRUCTION_TYPE_CHECK(CheckBoundBase, CheckBoundBase)
   FOR_EACH_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
   FOR_EACH_ABSTRACT_INSTRUCTION(INSTRUCTION_TYPE_CHECK)
 
@@ -1839,7 +1842,9 @@
   // propagation during graph building.
   CompileType* Type() {
     if (type_ == NULL) {
-      type_ = new CompileType(ComputeType());
+      auto type = new CompileType(ComputeType());
+      type->set_owner(this);
+      set_type(type);
     }
     return type_;
   }
@@ -1865,8 +1870,10 @@
   PRINT_TO_SUPPORT
 
   bool UpdateType(CompileType new_type) {
-    if (type_ == NULL) {
-      type_ = new CompileType(new_type);
+    if (type_ == nullptr) {
+      auto type = new CompileType(new_type);
+      type->set_owner(this);
+      set_type(type);
       return true;
     }
 
@@ -1964,16 +1971,27 @@
   friend class RangeAnalysis;
   friend class Value;
 
-  Range* range_;
-  CompileType* type_;
+  Range* range_ = nullptr;
+
+  void set_type(CompileType* type) {
+    ASSERT(type->owner() == this);
+    type_ = type;
+  }
+
+#if !defined(PRODUCT) || defined(FORCE_INCLUDE_DISASSEMBLER)
+  const char* TypeAsCString() const {
+    return HasType() ? type_->ToCString() : "";
+  }
+#endif
 
  private:
-  intptr_t temp_index_;
-  intptr_t ssa_temp_index_;
-  Value* input_use_list_;
-  Value* env_use_list_;
+  intptr_t temp_index_ = -1;
+  intptr_t ssa_temp_index_ = -1;
+  Value* input_use_list_ = nullptr;
+  Value* env_use_list_ = nullptr;
 
-  Object* constant_value_;
+  Object* constant_value_ = nullptr;
+  CompileType* type_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(Definition);
 };
@@ -2111,6 +2129,12 @@
   DISALLOW_COPY_AND_ASSIGN(PhiInstr);
 };
 
+// This instruction represents an incomming parameter for a function entry,
+// or incomming value for OSR entry or incomming value for a catch entry.
+// When [base_reg] is set to FPREG [index] corresponds to environment
+// variable index (0 is the very first parameter, 1 is next and so on).
+// When [base_reg] is set to SPREG [index] corresponds to SP relative parameter
+// indices (0 is the very last parameter, 1 is next and so on).
 class ParameterInstr : public Definition {
  public:
   ParameterInstr(intptr_t index,
@@ -2220,7 +2244,9 @@
 // the frame.  This is asserted via `inliner.cc::CalleeGraphValidator`.
 class LoadIndexedUnsafeInstr : public TemplateDefinition<1, NoThrow> {
  public:
-  LoadIndexedUnsafeInstr(Value* index, intptr_t offset) : offset_(offset) {
+  LoadIndexedUnsafeInstr(Value* index, intptr_t offset, CompileType result_type)
+      : offset_(offset) {
+    UpdateType(result_type);
     SetInputAt(0, index);
   }
 
@@ -2775,6 +2801,8 @@
   virtual bool ComputeCanDeoptimize() const { return false; }
   virtual bool HasUnknownSideEffects() const { return false; }
 
+  PRINT_OPERANDS_TO_SUPPORT
+
  private:
   CompileType* constrained_type_;
   DISALLOW_COPY_AND_ASSIGN(RedefinitionInstr);
@@ -3299,9 +3327,9 @@
   intptr_t checked_argument_count() const { return checked_argument_count_; }
   const Function& interface_target() const { return interface_target_; }
 
-  void set_static_receiver_type(const AbstractType* receiver_type) {
-    ASSERT(receiver_type != nullptr && receiver_type->IsInstantiated());
-    static_receiver_type_ = receiver_type;
+  void set_receivers_static_type(const AbstractType* receiver_type) {
+    ASSERT(receiver_type != nullptr);
+    receivers_static_type_ = receiver_type;
   }
 
   bool has_unique_selector() const { return has_unique_selector_; }
@@ -3362,7 +3390,7 @@
   bool has_unique_selector_;
   Code::EntryKind entry_kind_ = Code::EntryKind::kNormal;
 
-  const AbstractType* static_receiver_type_ = nullptr;
+  const AbstractType* receivers_static_type_ = nullptr;
 
   DISALLOW_COPY_AND_ASSIGN(InstanceCallInstr);
 };
@@ -4695,7 +4723,8 @@
                     intptr_t class_id,
                     AlignmentType alignment,
                     intptr_t deopt_id,
-                    TokenPosition token_pos);
+                    TokenPosition token_pos,
+                    SpeculativeMode speculative_mode = kGuardInputs);
   DECLARE_INSTRUCTION(StoreIndexed)
 
   enum { kArrayPos = 0, kIndexPos = 1, kValuePos = 2 };
@@ -4719,6 +4748,8 @@
            (emit_store_barrier_ == kEmitStoreBarrier);
   }
 
+  virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
+
   virtual bool ComputeCanDeoptimize() const { return false; }
 
   virtual Representation RequiredInputRepresentation(intptr_t idx) const;
@@ -4745,6 +4776,7 @@
   const intptr_t class_id_;
   const AlignmentType alignment_;
   const TokenPosition token_pos_;
+  const SpeculativeMode speculative_mode_;
 
   DISALLOW_COPY_AND_ASSIGN(StoreIndexedInstr);
 };
@@ -6247,6 +6279,7 @@
   virtual bool ComputeCanDeoptimize() const { return false; }
 
   virtual CompileType ComputeType() const;
+  virtual bool RecomputeType();
 
   virtual bool HasUnknownSideEffects() const { return true; }
 
@@ -6994,8 +7027,10 @@
 
 class DoubleToFloatInstr : public TemplateDefinition<1, NoThrow, Pure> {
  public:
-  DoubleToFloatInstr(Value* value, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
+  DoubleToFloatInstr(Value* value,
+                     intptr_t deopt_id,
+                     SpeculativeMode speculative_mode = kGuardInputs)
+      : TemplateDefinition(deopt_id), speculative_mode_(speculative_mode) {
     SetInputAt(0, value);
   }
 
@@ -7020,6 +7055,8 @@
     return kUnboxedDouble;
   }
 
+  virtual SpeculativeMode speculative_mode() const { return speculative_mode_; }
+
   virtual intptr_t DeoptimizationTarget() const { return GetDeoptId(); }
 
   virtual bool AttributesEqual(Instruction* other) const { return true; }
@@ -7027,6 +7064,8 @@
   virtual Definition* Canonicalize(FlowGraph* flow_graph);
 
  private:
+  const SpeculativeMode speculative_mode_;
+
   DISALLOW_COPY_AND_ASSIGN(DoubleToFloatInstr);
 };
 
@@ -7380,17 +7419,12 @@
   DISALLOW_COPY_AND_ASSIGN(CheckClassIdInstr);
 };
 
-// Performs an array bounds check, where
-//   safe_index := CheckArrayBound(length, index)
-// returns the "safe" index when
-//   0 <= index < length
-// or otherwise deoptimizes (viz. speculative).
-class CheckArrayBoundInstr : public TemplateDefinition<2, NoThrow, Pure> {
+// Base class for speculative [CheckArrayBoundInstr] and
+// [GenericCheckBoundInstr]
+class CheckBoundBase : public TemplateDefinition<2, NoThrow, Pure> {
  public:
-  CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id),
-        generalized_(false),
-        licm_hoisted_(false) {
+  CheckBoundBase(Value* length, Value* index, intptr_t deopt_id)
+      : TemplateDefinition(deopt_id) {
     SetInputAt(kLengthPos, length);
     SetInputAt(kIndexPos, index);
   }
@@ -7398,6 +7432,28 @@
   Value* length() const { return inputs_[kLengthPos]; }
   Value* index() const { return inputs_[kIndexPos]; }
 
+  virtual bool IsCheckBoundBase() { return true; }
+  virtual CheckBoundBase* AsCheckBoundBase() { return this; }
+
+  // Give a name to the location/input indices.
+  enum { kLengthPos = 0, kIndexPos = 1 };
+
+ private:
+  DISALLOW_COPY_AND_ASSIGN(CheckBoundBase);
+};
+
+// Performs an array bounds check, where
+//   safe_index := CheckArrayBound(length, index)
+// returns the "safe" index when
+//   0 <= index < length
+// or otherwise deoptimizes (viz. speculative).
+class CheckArrayBoundInstr : public CheckBoundBase {
+ public:
+  CheckArrayBoundInstr(Value* length, Value* index, intptr_t deopt_id)
+      : CheckBoundBase(length, index, deopt_id),
+        generalized_(false),
+        licm_hoisted_(false) {}
+
   DECLARE_INSTRUCTION(CheckArrayBound)
 
   virtual CompileType ComputeType() const;
@@ -7420,9 +7476,6 @@
 
   void set_licm_hoisted(bool value) { licm_hoisted_ = value; }
 
-  // Give a name to the location/input indices.
-  enum { kLengthPos = 0, kIndexPos = 1 };
-
  private:
   bool generalized_;
   bool licm_hoisted_;
@@ -7431,20 +7484,14 @@
 };
 
 // Performs an array bounds check, where
-//   safe_index := CheckArrayBound(length, index)
+//   safe_index := GenericCheckBound(length, index)
 // returns the "safe" index when
 //   0 <= index < length
 // or otherwise throws an out-of-bounds exception (viz. non-speculative).
-class GenericCheckBoundInstr : public TemplateDefinition<2, Throws, Pure> {
+class GenericCheckBoundInstr : public CheckBoundBase {
  public:
   GenericCheckBoundInstr(Value* length, Value* index, intptr_t deopt_id)
-      : TemplateDefinition(deopt_id) {
-    SetInputAt(kLengthPos, length);
-    SetInputAt(kIndexPos, index);
-  }
-
-  Value* length() const { return inputs_[kLengthPos]; }
-  Value* index() const { return inputs_[kIndexPos]; }
+      : CheckBoundBase(length, index, deopt_id) {}
 
   virtual bool AttributesEqual(Instruction* other) const { return true; }
 
@@ -7459,9 +7506,6 @@
 
   bool IsRedundant(const RangeBoundary& length);
 
-  // Give a name to the location/input indices.
-  enum { kLengthPos = 0, kIndexPos = 1 };
-
  private:
   DISALLOW_COPY_AND_ASSIGN(GenericCheckBoundInstr);
 };
diff --git a/runtime/vm/compiler/backend/il_arm.cc b/runtime/vm/compiler/backend/il_arm.cc
index 942c9e8..dd332867 100644
--- a/runtime/vm/compiler/backend/il_arm.cc
+++ b/runtime/vm/compiler/backend/il_arm.cc
@@ -1856,10 +1856,7 @@
         __ strh(IP, field_nullability_operand);
       }
 
-      if (deopt == NULL) {
-        ASSERT(!compiler->is_optimizing());
-        __ b(&ok);
-      }
+      __ b(&ok);
     }
 
     if (deopt == NULL) {
@@ -1874,6 +1871,8 @@
       __ Push(value_reg);
       __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
       __ Drop(2);  // Drop the field and the value.
+    } else {
+      __ b(fail);
     }
   } else {
     ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_arm64.cc b/runtime/vm/compiler/backend/il_arm64.cc
index c5a2cf0..67e080b 100644
--- a/runtime/vm/compiler/backend/il_arm64.cc
+++ b/runtime/vm/compiler/backend/il_arm64.cc
@@ -1779,10 +1779,7 @@
         __ str(TMP, field_nullability_operand, kUnsignedHalfword);
       }
 
-      if (deopt == NULL) {
-        ASSERT(!compiler->is_optimizing());
-        __ b(&ok);
-      }
+      __ b(&ok);
     }
 
     if (deopt == NULL) {
@@ -1798,6 +1795,8 @@
       __ Push(value_reg);
       __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
       __ Drop(2);  // Drop the field and the value.
+    } else {
+      __ b(fail);
     }
   } else {
     ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_ia32.cc b/runtime/vm/compiler/backend/il_ia32.cc
index 71dedf6..19983a1 100644
--- a/runtime/vm/compiler/backend/il_ia32.cc
+++ b/runtime/vm/compiler/backend/il_ia32.cc
@@ -1682,10 +1682,7 @@
         __ movw(field_nullability_operand, Immediate(value_cid));
       }
 
-      if (deopt == NULL) {
-        ASSERT(!compiler->is_optimizing());
-        __ jmp(&ok);
-      }
+      __ jmp(&ok);
     }
 
     if (deopt == NULL) {
@@ -1700,6 +1697,8 @@
       __ pushl(value_reg);
       __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
       __ Drop(2);  // Drop the field and the value.
+    } else {
+      __ jmp(fail);
     }
   } else {
     ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/il_printer.cc b/runtime/vm/compiler/backend/il_printer.cc
index b735a6f..85d77dc 100644
--- a/runtime/vm/compiler/backend/il_printer.cc
+++ b/runtime/vm/compiler/backend/il_printer.cc
@@ -155,12 +155,15 @@
 
 void CompileType::PrintTo(BufferFormatter* f) const {
   const char* type_name = "?";
-  if ((cid_ != kIllegalCid) && (cid_ != kDynamicCid)) {
+  if (IsNone()) {
+    f->Print("T{}");
+    return;
+  } else if ((cid_ != kIllegalCid) && (cid_ != kDynamicCid)) {
     const Class& cls =
         Class::Handle(Isolate::Current()->class_table()->At(cid_));
     type_name = String::Handle(cls.ScrubbedName()).ToCString();
-  } else if (type_ != NULL && !type_->IsDynamicType()) {
-    type_name = TypeToUserVisibleName(*type_);
+  } else if (type_ != NULL) {
+    type_name = type_->IsDynamicType() ? "*" : TypeToUserVisibleName(*type_);
   } else if (!is_nullable()) {
     type_name = "!null";
   }
@@ -249,9 +252,9 @@
                               const ICData& ic_data,
                               intptr_t num_checks_to_print) {
   f->Print(" IC[");
-  if (ic_data.IsTrackingExactness()) {
+  if (ic_data.is_tracking_exactness()) {
     f->Print("(%s) ",
-             AbstractType::Handle(ic_data.StaticReceiverType()).ToCString());
+             AbstractType::Handle(ic_data.receivers_static_type()).ToCString());
   }
   f->Print("%" Pd ": ", ic_data.NumberOfChecks());
   Function& target = Function::Handle();
@@ -275,7 +278,7 @@
       f->Print("%s", String::Handle(cls.Name()).ToCString());
     }
     f->Print(" cnt:%" Pd " trgt:'%s'", count, target.ToQualifiedCString());
-    if (ic_data.IsTrackingExactness()) {
+    if (ic_data.is_tracking_exactness()) {
       f->Print(" %s", ic_data.GetExactnessAt(i).ToCString());
     }
   }
@@ -388,6 +391,13 @@
   }
 }
 
+void RedefinitionInstr::PrintOperandsTo(BufferFormatter* f) const {
+  Definition::PrintOperandsTo(f);
+  if (constrained_type_ != nullptr) {
+    f->Print(" ^ %s", constrained_type_->ToCString());
+  }
+}
+
 void Value::PrintTo(BufferFormatter* f) const {
   PrintUse(f, *definition());
 
@@ -972,9 +982,8 @@
     f->Print(" %s", RepresentationToCString(representation()));
   }
 
-  if (type_ != NULL) {
-    f->Print(" ");
-    type_->PrintTo(f);
+  if (HasType()) {
+    f->Print(" %s", TypeAsCString());
   }
 }
 
diff --git a/runtime/vm/compiler/backend/il_test_helper.cc b/runtime/vm/compiler/backend/il_test_helper.cc
new file mode 100644
index 0000000..4315c29
--- /dev/null
+++ b/runtime/vm/compiler/backend/il_test_helper.cc
@@ -0,0 +1,328 @@
+// 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.
+
+#include "vm/compiler/backend/il_test_helper.h"
+
+#include "vm/compiler/aot/aot_call_specializer.h"
+#include "vm/compiler/backend/block_scheduler.h"
+#include "vm/compiler/backend/flow_graph.h"
+#include "vm/compiler/backend/flow_graph_compiler.h"
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/inliner.h"
+#include "vm/compiler/call_specializer.h"
+#include "vm/compiler/compiler_pass.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/compiler/jit/jit_call_specializer.h"
+#include "vm/dart_api_impl.h"
+#include "vm/parser.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+RawLibrary* LoadTestScript(const char* script,
+                           Dart_NativeEntryResolver resolver,
+                           const char* lib_uri) {
+  Dart_Handle api_lib;
+  {
+    TransitionVMToNative transition(Thread::Current());
+    api_lib = TestCase::LoadTestScript(script, resolver, lib_uri);
+  }
+  auto& lib = Library::Handle();
+  lib ^= Api::UnwrapHandle(api_lib);
+  EXPECT(!lib.IsNull());
+  return lib.raw();
+}
+
+RawFunction* GetFunction(const Library& lib, const char* name) {
+  Thread* thread = Thread::Current();
+  const auto& func = Function::Handle(lib.LookupFunctionAllowPrivate(
+      String::Handle(Symbols::New(thread, name))));
+  EXPECT(!func.IsNull());
+  return func.raw();
+}
+
+void Invoke(const Library& lib, const char* name) {
+  Thread* thread = Thread::Current();
+  Dart_Handle api_lib = Api::NewHandle(thread, lib.raw());
+  TransitionVMToNative transition(thread);
+  Dart_Handle result =
+      Dart_Invoke(api_lib, NewString(name), /*argc=*/0, /*argv=*/nullptr);
+  EXPECT_VALID(result);
+}
+
+FlowGraph* TestPipeline::RunPasses(
+    std::initializer_list<CompilerPass::Id> passes) {
+  auto thread = Thread::Current();
+  auto zone = thread->zone();
+  const bool optimized = true;
+  const intptr_t osr_id = Compiler::kNoOSRDeoptId;
+
+  auto pipeline = CompilationPipeline::New(zone, function_);
+
+  parsed_function_ = new (zone)
+      ParsedFunction(thread, Function::ZoneHandle(zone, function_.raw()));
+  pipeline->ParseFunction(parsed_function_);
+
+  // Extract type feedback before the graph is built, as the graph
+  // builder uses it to attach it to nodes.
+  ic_data_array_ = new (zone) ZoneGrowableArray<const ICData*>();
+  if (mode_ == CompilerPass::kJIT) {
+    function_.RestoreICDataMap(ic_data_array_, /*clone_ic_data=*/false);
+  }
+
+  flow_graph_ = pipeline->BuildFlowGraph(zone, parsed_function_, ic_data_array_,
+                                         osr_id, optimized);
+
+  if (mode_ == CompilerPass::kAOT) {
+    flow_graph_->PopulateWithICData(function_);
+  }
+
+  BlockScheduler block_scheduler(flow_graph_);
+  const bool reorder_blocks =
+      FlowGraph::ShouldReorderBlocks(function_, optimized);
+  if (mode_ == CompilerPass::kJIT && reorder_blocks) {
+    block_scheduler.AssignEdgeWeights();
+  }
+
+  SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false);
+  pass_state_ = new CompilerPassState(thread, flow_graph_, &speculative_policy);
+  pass_state_->block_scheduler = &block_scheduler;
+  pass_state_->reorder_blocks = reorder_blocks;
+
+  if (optimized) {
+    pass_state_->inline_id_to_function.Add(&function_);
+    // We do not add the token position now because we don't know the
+    // position of the inlined call until later. A side effect of this
+    // is that the length of |inline_id_to_function| is always larger
+    // than the length of |inline_id_to_token_pos| by one.
+    // Top scope function has no caller (-1). We do this because we expect
+    // all token positions to be at an inlined call.
+    pass_state_->caller_inline_id.Add(-1);
+
+    JitCallSpecializer jit_call_specializer(flow_graph_, &speculative_policy);
+    AotCallSpecializer aot_call_specializer(/*precompiler=*/nullptr,
+                                            flow_graph_, &speculative_policy);
+    if (mode_ == CompilerPass::kAOT) {
+      pass_state_->call_specializer = &aot_call_specializer;
+    } else {
+      pass_state_->call_specializer = &jit_call_specializer;
+    }
+
+    if (passes.size() > 0) {
+      CompilerPass::RunPipelineWithPasses(pass_state_, passes);
+    } else {
+      CompilerPass::RunPipeline(mode_, pass_state_);
+    }
+  }
+
+  return flow_graph_;
+}
+
+void TestPipeline::CompileGraphAndAttachFunction() {
+  Zone* zone = thread_->zone();
+  const bool optimized = true;
+
+  SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false);
+
+#if defined(TARGET_ARCH_X64) || defined(TARGET_ARCH_IA32) ||                   \
+    defined(TARGET_ARCH_DBC)
+  const bool use_far_branches = false;
+#else
+  const bool use_far_branches = true;
+#endif
+
+  ASSERT(pass_state_->inline_id_to_function.length() ==
+         pass_state_->caller_inline_id.length());
+  ObjectPoolBuilder object_pool_builder;
+  Assembler assembler(&object_pool_builder, use_far_branches);
+  FlowGraphCompiler graph_compiler(
+      &assembler, flow_graph_, *parsed_function_, optimized,
+      &speculative_policy, pass_state_->inline_id_to_function,
+      pass_state_->inline_id_to_token_pos, pass_state_->caller_inline_id,
+      ic_data_array_);
+
+  graph_compiler.CompileGraph();
+
+  const auto& deopt_info_array =
+      Array::Handle(zone, graph_compiler.CreateDeoptInfo(&assembler));
+  const auto pool_attachment = Code::PoolAttachment::kAttachPool;
+  const auto& code = Code::Handle(Code::FinalizeCode(
+      &graph_compiler, &assembler, pool_attachment, optimized, nullptr));
+  code.set_is_optimized(optimized);
+  code.set_owner(function_);
+
+  graph_compiler.FinalizePcDescriptors(code);
+  code.set_deopt_info_array(deopt_info_array);
+
+  graph_compiler.FinalizeStackMaps(code);
+  graph_compiler.FinalizeVarDescriptors(code);
+  graph_compiler.FinalizeExceptionHandlers(code);
+  graph_compiler.FinalizeCatchEntryMovesMap(code);
+  graph_compiler.FinalizeStaticCallTargetsTable(code);
+  graph_compiler.FinalizeCodeSourceMap(code);
+
+  if (optimized) {
+    function_.InstallOptimizedCode(code);
+  } else {
+    function_.set_unoptimized_code(code);
+    function_.AttachCode(code);
+  }
+
+  // We expect there to be no deoptimizations.
+  if (mode_ == CompilerPass::kAOT) {
+    // TODO(kustermann): Enable this once we get rid of [CheckedSmiSlowPath]s.
+    // EXPECT(deopt_info_array.IsNull() || deopt_info_array.Length() == 0);
+  }
+}
+
+bool ILMatcher::TryMatch(std::initializer_list<MatchCode> match_codes) {
+  std::vector<MatchCode> qcodes = match_codes;
+
+  if (trace_) {
+    OS::PrintErr("ILMatcher: Matching the following graph\n");
+    FlowGraphPrinter::PrintGraph("ILMatcher", flow_graph_);
+    OS::PrintErr("ILMatcher: Starting match at %s:\n", cursor_->ToCString());
+  }
+
+  Instruction* cursor = cursor_;
+  for (size_t i = 0; i < qcodes.size(); ++i) {
+    Instruction** capture = qcodes[i].capture_;
+    if (trace_) {
+      OS::PrintErr("  matching %30s @ %s\n",
+                   MatchOpCodeToCString(qcodes[i].opcode()),
+                   cursor->ToCString());
+    }
+
+    auto next = MatchInternal(qcodes, i, cursor);
+    if (next == nullptr) {
+      if (trace_) {
+        OS::PrintErr("  -> Match failed\n");
+      }
+      cursor = next;
+      break;
+    }
+    if (capture != nullptr) {
+      *capture = cursor;
+    }
+    cursor = next;
+  }
+  if (cursor != nullptr) {
+    cursor_ = cursor;
+    return true;
+  }
+  return false;
+}
+
+Instruction* ILMatcher::MatchInternal(std::vector<MatchCode> match_codes,
+                                      size_t i,
+                                      Instruction* cursor) {
+  const MatchOpCode opcode = match_codes[i].opcode();
+  if (opcode == kMatchAndMoveBranchTrue) {
+    auto branch = cursor->AsBranch();
+    if (branch == nullptr) return nullptr;
+    return branch->true_successor();
+  }
+  if (opcode == kMatchAndMoveBranchFalse) {
+    auto branch = cursor->AsBranch();
+    if (branch == nullptr) return nullptr;
+    return branch->false_successor();
+  }
+  if (opcode == kMoveAny) {
+    return cursor->next();
+  }
+  if (opcode == kMoveParallelMoves) {
+    while (cursor != nullptr && cursor->IsParallelMove()) {
+      cursor = cursor->next();
+    }
+    return cursor;
+  }
+
+  if (opcode == kMoveGlob) {
+    ASSERT((i + 1) < match_codes.size());
+    while (true) {
+      if (cursor == nullptr) return nullptr;
+      if (MatchInternal(match_codes, i + 1, cursor) != nullptr) {
+        return cursor;
+      }
+      if (auto as_goto = cursor->AsGoto()) {
+        cursor = as_goto->successor();
+      } else {
+        cursor = cursor->next();
+      }
+    }
+  }
+
+  if (opcode == kMatchAndMoveGoto) {
+    if (auto goto_instr = cursor->AsGoto()) {
+      return goto_instr->successor();
+    }
+  }
+
+  switch (opcode) {
+#define EMIT_CASE(Instruction, _)                                              \
+  case kMatch##Instruction: {                                                  \
+    if (cursor->Is##Instruction()) {                                           \
+      return cursor;                                                           \
+    }                                                                          \
+    return nullptr;                                                            \
+  }                                                                            \
+  case kMatchAndMove##Instruction: {                                           \
+    if (cursor->Is##Instruction()) {                                           \
+      return cursor->next();                                                   \
+    }                                                                          \
+    return nullptr;                                                            \
+  }                                                                            \
+  case kMatchAndMoveOptional##Instruction: {                                   \
+    if (cursor->Is##Instruction()) {                                           \
+      return cursor->next();                                                   \
+    }                                                                          \
+    return cursor;                                                             \
+  }
+    FOR_EACH_INSTRUCTION(EMIT_CASE)
+#undef EMIT_CASE
+    default:
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return nullptr;
+}
+
+const char* ILMatcher::MatchOpCodeToCString(MatchOpCode opcode) {
+  if (opcode == kMatchAndMoveBranchTrue) {
+    return "kMatchAndMoveBranchTrue";
+  }
+  if (opcode == kMatchAndMoveBranchFalse) {
+    return "kMatchAndMoveBranchFalse";
+  }
+  if (opcode == kMoveAny) {
+    return "kMoveAny";
+  }
+  if (opcode == kMoveParallelMoves) {
+    return "kMoveParallelMoves";
+  }
+  if (opcode == kMoveGlob) {
+    return "kMoveGlob";
+  }
+
+  switch (opcode) {
+#define EMIT_CASE(Instruction, _)                                              \
+  case kMatch##Instruction:                                                    \
+    return "kMatch" #Instruction;                                              \
+  case kMatchAndMove##Instruction:                                             \
+    return "kMatchAndMove" #Instruction;                                       \
+  case kMatchAndMoveOptional##Instruction:                                     \
+    return "kMatchAndMoveOptional" #Instruction;
+    FOR_EACH_INSTRUCTION(EMIT_CASE)
+#undef EMIT_CASE
+    default:
+      UNREACHABLE();
+  }
+
+  UNREACHABLE();
+  return nullptr;
+}
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/backend/il_test_helper.h b/runtime/vm/compiler/backend/il_test_helper.h
new file mode 100644
index 0000000..84d7acf
--- /dev/null
+++ b/runtime/vm/compiler/backend/il_test_helper.h
@@ -0,0 +1,195 @@
+// 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.
+
+#ifndef RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
+#define RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
+
+#include <vector>
+
+#include "include/dart_api.h"
+
+#include "platform/allocation.h"
+#include "vm/compiler/backend/il.h"
+#include "vm/compiler/compiler_pass.h"
+#include "vm/compiler/compiler_state.h"
+#include "vm/unit_test.h"
+
+// The helpers in this file make it easier to write C++ unit tests which assert
+// that Dart code gets turned into certain IR.
+//
+// Here is an example on how to use it:
+//
+//     ISOLATE_UNIT_TEST_CASE(MyIRTest) {
+//       const char* script = R"(
+//           void foo() { ... }
+//           void main() { foo(); }
+//       )";
+//
+//       // Load the script and exercise the code once.
+//       const auto& lib = Library::Handle(LoadTestScript(script);
+//
+//       // Cause the code to be exercised once (to populate ICData).
+//       Invoke(lib, "main");
+//
+//       // Look up the function.
+//       const auto& function = Function::Handle(GetFunction(lib, "foo"));
+//
+//       // Run the JIT compilation pipeline with two passes.
+//       TestPipeline pipeline(function);
+//       FlowGraph* graph = pipeline.RunJITPasses("ComputeSSA,TypePropagation");
+//
+//       ...
+//     }
+//
+namespace dart {
+
+class FlowGraph;
+class Function;
+class Library;
+class RawFunction;
+class RawLibrary;
+
+RawLibrary* LoadTestScript(const char* script,
+                           Dart_NativeEntryResolver resolver = nullptr,
+                           const char* lib_uri = RESOLVED_USER_TEST_URI);
+
+RawFunction* GetFunction(const Library& lib, const char* name);
+
+void Invoke(const Library& lib, const char* name);
+
+class TestPipeline : public ValueObject {
+ public:
+  explicit TestPipeline(const Function& function,
+                        CompilerPass::PipelineMode mode)
+      : function_(function),
+        thread_(Thread::Current()),
+        compiler_state_(thread_),
+        mode_(mode) {}
+  ~TestPipeline() { delete pass_state_; }
+
+  // As a side-effect this will populate
+  //   - [ic_data_array_]
+  //   - [parsed_function_]
+  //   - [pass_state_]
+  //   - [flow_graph_]
+  FlowGraph* RunPasses(std::initializer_list<CompilerPass::Id> passes);
+
+  void CompileGraphAndAttachFunction();
+
+ private:
+  const Function& function_;
+  Thread* thread_;
+  CompilerState compiler_state_;
+  CompilerPass::PipelineMode mode_;
+  ZoneGrowableArray<const ICData*>* ic_data_array_ = nullptr;
+  ParsedFunction* parsed_function_ = nullptr;
+  CompilerPassState* pass_state_ = nullptr;
+  FlowGraph* flow_graph_ = nullptr;
+};
+
+// Match opcodes used for [ILMatcher], see below.
+enum MatchOpCode {
+// Emit a match and match-and-move code for every instruction.
+#define DEFINE_MATCH_OPCODES(Instruction, _)                                   \
+  kMatch##Instruction, kMatchAndMove##Instruction,                             \
+      kMatchAndMoveOptional##Instruction,
+  FOR_EACH_INSTRUCTION(DEFINE_MATCH_OPCODES)
+#undef DEFINE_MATCH_OPCODES
+
+  // Matches a branch and moves left.
+  kMatchAndMoveBranchTrue,
+
+  // Matches a branch and moves right.
+  kMatchAndMoveBranchFalse,
+
+  // Moves forward across any instruction.
+  kMoveAny,
+
+  // Moves over all parallel moves.
+  kMoveParallelMoves,
+
+  // Moves forward until the next match code matches.
+  kMoveGlob,
+};
+
+// Match codes used for [ILMatcher], see below.
+class MatchCode {
+ public:
+  MatchCode(MatchOpCode opcode)  // NOLINT
+      : opcode_(opcode), capture_(nullptr) {}
+
+  MatchCode(MatchOpCode opcode, Instruction** capture)
+      : opcode_(opcode), capture_(capture) {}
+
+#define DEFINE_TYPED_CONSTRUCTOR(Type, ignored)                                \
+  MatchCode(MatchOpCode opcode, Type##Instr** capture)                         \
+      : opcode_(opcode), capture_(reinterpret_cast<Instruction**>(capture)) {  \
+    RELEASE_ASSERT(opcode == kMatch##Type || opcode == kMatchAndMove##Type);   \
+  }
+  FOR_EACH_INSTRUCTION(DEFINE_TYPED_CONSTRUCTOR)
+#undef DEFINE_TYPED_CONSTRUCTOR
+
+  MatchOpCode opcode() { return opcode_; }
+
+ private:
+  friend class ILMatcher;
+
+  MatchOpCode opcode_;
+  Instruction** capture_;
+};
+
+// Used for matching a sequence of IL instructions including capturing support.
+//
+// Example:
+//
+//     TargetEntryInstr* entry = ....;
+//     BranchInstr* branch = nullptr;
+//
+//     ILMatcher matcher(flow_graph, entry);
+//     if (matcher.TryMatch({ kMoveGlob, {kMatchBranch, &branch}, })) {
+//       EXPECT(branch->operation_cid() == kMintCid);
+//       ...
+//     }
+//
+// This match will start at [entry], follow any number instructions (including
+// [GotoInstr]s until a [BranchInstr] is found).
+//
+// If the match was successful, this returns `true` and updates the current
+// value for the cursor.
+class ILMatcher : public ValueObject {
+ public:
+  ILMatcher(FlowGraph* flow_graph, Instruction* cursor, bool trace = true)
+      : flow_graph_(flow_graph),
+        cursor_(cursor),
+  // clang-format off
+#if !defined(PRODUCT)
+        trace_(trace) {}
+#else
+        trace_(false) {}
+#endif
+  // clang-format on
+
+  Instruction* value() { return cursor_; }
+
+  // From the current [value] according to match_codes.
+  //
+  // Returns `true` if the match was successful and cursor has been updated,
+  // otherwise returns `false`.
+  bool TryMatch(std::initializer_list<MatchCode> match_codes);
+
+ private:
+  Instruction* MatchInternal(std::vector<MatchCode> match_codes,
+                             size_t i,
+                             Instruction* cursor);
+
+  const char* MatchOpCodeToCString(MatchOpCode code);
+
+  FlowGraph* flow_graph_;
+  Instruction* cursor_;
+  bool trace_;
+};
+
+}  // namespace dart
+
+#endif  // RUNTIME_VM_COMPILER_BACKEND_IL_TEST_HELPER_H_
diff --git a/runtime/vm/compiler/backend/il_x64.cc b/runtime/vm/compiler/backend/il_x64.cc
index 16569e8..6947e3c 100644
--- a/runtime/vm/compiler/backend/il_x64.cc
+++ b/runtime/vm/compiler/backend/il_x64.cc
@@ -1768,10 +1768,7 @@
         __ movw(field_nullability_operand, Immediate(value_cid));
       }
 
-      if (deopt == NULL) {
-        ASSERT(!compiler->is_optimizing());
-        __ jmp(&ok);
-      }
+      __ jmp(&ok);
     }
 
     if (deopt == NULL) {
@@ -1786,6 +1783,8 @@
       __ pushq(value_reg);
       __ CallRuntime(kUpdateFieldCidRuntimeEntry, 2);
       __ Drop(2);  // Drop the field and the value.
+    } else {
+      __ jmp(fail);
     }
   } else {
     ASSERT(compiler->is_optimizing());
diff --git a/runtime/vm/compiler/backend/inliner.cc b/runtime/vm/compiler/backend/inliner.cc
index b53f252..8d34ae8 100644
--- a/runtime/vm/compiler/backend/inliner.cc
+++ b/runtime/vm/compiler/backend/inliner.cc
@@ -1069,15 +1069,14 @@
         if (FLAG_precompiled_mode) {
           callee_graph->PopulateWithICData(parsed_function->function());
         }
-#else
+#endif
+
         // If we inline a function which is intrinsified without a fall-through
         // to IR code, we will not have any ICData attached, so we do it
         // manually here.
-        if (function.is_intrinsic()) {
+        if (!FLAG_precompiled_mode && function.is_intrinsic()) {
           callee_graph->PopulateWithICData(parsed_function->function());
         }
-#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC) &&           \
-    // !defined(TARGET_ARCH_IA32)
 
         // The parameter stubs are a copy of the actual arguments providing
         // concrete information about the values, for example constant values,
@@ -2858,59 +2857,25 @@
 
 // Emits preparatory code for a typed getter/setter.
 // Handles three cases:
-//   (1) dynamic:  generates a conditional on the receiver cid
-//                 that handles external (load untagged) and
-//                 internal storage at runtime.
-//   (2) external: generates load untagged.
+//   (1) dynamic:  generates load untagged (internal or external)
+//   (2) external: generates load untagged
 //   (3) internal: no code required.
 static void PrepareInlineByteArrayBaseOp(FlowGraph* flow_graph,
                                          Instruction* call,
                                          Definition* receiver,
                                          intptr_t array_cid,
                                          Definition** array,
-                                         Instruction** cursor,
-                                         TargetEntryInstr** block_external,
-                                         TargetEntryInstr** block_internal) {
-  if (array_cid == kDynamicCid) {
-    // Dynamic case:   runtime resolution between external/internal typed data.
-    //                 cid = LoadCid
-    //                 if cid in [ kExternalTypedDataInt8ArrayCid,
-    //                             kExternalTypedDataFloat64x2ArrayCid ]
-    // block_external: LoadUntagged
-    //                 ..
-    //                 else
-    // block_internal: ..
-    //
-    // TODO(ajcbik): as suggested above, subtract + single unsigned test.
-    //
-    LoadClassIdInstr* load_cid =
-        new (Z) LoadClassIdInstr(new (Z) Value(receiver));
-    *cursor = flow_graph->AppendTo(*cursor, load_cid, NULL, FlowGraph::kValue);
-    ConstantInstr* cid_lo = flow_graph->GetConstant(
-        Smi::ZoneHandle(Smi::New(kExternalTypedDataInt8ArrayCid)));
-    RelationalOpInstr* le_lo = new (Z)
-        RelationalOpInstr(call->token_pos(), Token::kLTE, new (Z) Value(cid_lo),
-                          new (Z) Value(load_cid), kSmiCid, call->deopt_id());
-    ConstantInstr* cid_hi = flow_graph->GetConstant(
-        Smi::ZoneHandle(Smi::New(kExternalTypedDataFloat64x2ArrayCid)));
-    RelationalOpInstr* le_hi = new (Z) RelationalOpInstr(
-        call->token_pos(), Token::kLTE, new (Z) Value(load_cid),
-        new (Z) Value(cid_hi), kSmiCid, call->deopt_id());
-    *cursor = flow_graph->NewDiamond(*cursor, call,
-                                     FlowGraph::LogicalAnd(le_lo, le_hi),
-                                     block_external, block_internal);
-    LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
-        new (Z) Value(*array), ExternalTypedData::data_offset());
-    flow_graph->InsertAfter(*block_external, elements, NULL, FlowGraph::kValue);
-    *array = elements;  // return load untagged definition in array
-  } else if (RawObject::IsExternalTypedDataClassId(array_cid)) {
-    // External typed data: load untagged.
-    LoadUntaggedInstr* elements = new (Z) LoadUntaggedInstr(
-        new (Z) Value(*array), ExternalTypedData::data_offset());
+                                         Instruction** cursor) {
+  if (array_cid == kDynamicCid ||
+      RawObject::IsExternalTypedDataClassId(array_cid)) {
+    // Internal or External typed data: load untagged.
+    auto elements = new (Z) LoadUntaggedInstr(
+        new (Z) Value(*array), TypedDataBase::data_field_offset());
     *cursor = flow_graph->AppendTo(*cursor, elements, NULL, FlowGraph::kValue);
     *array = elements;
   } else {
     // Internal typed data: no action.
+    ASSERT(RawObject::IsTypedDataClassId(array_cid));
   }
 }
 
@@ -2968,33 +2933,11 @@
   // Generates a template for the load, either a dynamic conditional
   // that dispatches on external and internal storage, or a single
   // case that deals with either external or internal storage.
-  TargetEntryInstr* block_external = nullptr;
-  TargetEntryInstr* block_internal = nullptr;
   PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array,
-                               &cursor, &block_external, &block_internal);
+                               &cursor);
 
   // Fill out the generated template with loads.
-  if (array_cid == kDynamicCid) {
-    ASSERT(block_external != nullptr && block_internal != nullptr);
-    // Load from external in block_external and internal in block_internal
-    // (resolves (B)). The former loads from "array", which is the returned
-    // load untagged definition. The latter loads from the original "receiver".
-    LoadIndexedInstr* load1 = NewLoad(flow_graph, call, array, index, view_cid);
-    ASSERT(block_external->next() == array);
-    flow_graph->InsertAfter(
-        block_external->next(), load1,
-        call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
-        FlowGraph::kValue);
-    LoadIndexedInstr* load2 =
-        NewLoad(flow_graph, call, receiver, index, view_cid);
-    flow_graph->InsertAfter(
-        block_internal, load2,
-        call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
-        FlowGraph::kValue);
-    // Construct phi of external and internal load.
-    *last = flow_graph->AddPhi(cursor->AsJoinEntry(), load1, load2);
-  } else {
-    ASSERT(block_external == nullptr && block_internal == nullptr);
+  {
     // Load from either external or internal.
     LoadIndexedInstr* load = NewLoad(flow_graph, call, array, index, view_cid);
     flow_graph->AppendTo(
@@ -3184,31 +3127,11 @@
   // Generates a template for the store, either a dynamic conditional
   // that dispatches on external and internal storage, or a single
   // case that deals with either external or internal storage.
-  TargetEntryInstr* block_external = nullptr;
-  TargetEntryInstr* block_internal = nullptr;
   PrepareInlineByteArrayBaseOp(flow_graph, call, receiver, array_cid, &array,
-                               &cursor, &block_external, &block_internal);
+                               &cursor);
 
   // Fill out the generated template with stores.
-  if (array_cid == kDynamicCid) {
-    ASSERT(block_external != nullptr && block_internal != nullptr);
-    // Store to external in block_external and internal in block_internal
-    // (resolves (B)). The former stores to "array", which is the returned
-    // load untagged definition. The latter stores to the original "receiver".
-    ASSERT(block_external->next() == array);
-    flow_graph->InsertAfter(
-        block_external->next(),
-        NewStore(flow_graph, call, array, index, stored_value, view_cid),
-        call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
-        FlowGraph::kEffect);
-    flow_graph->InsertAfter(
-        block_internal,
-        NewStore(flow_graph, call, receiver, index, stored_value, view_cid),
-        call->deopt_id() != DeoptId::kNone ? call->env() : nullptr,
-        FlowGraph::kEffect);
-    *last = cursor;
-  } else {
-    ASSERT(block_external == nullptr && block_internal == nullptr);
+  {
     // Store on either external or internal.
     StoreIndexedInstr* store =
         NewStore(flow_graph, call, array, index, stored_value, view_cid);
diff --git a/runtime/vm/compiler/backend/linearscan.cc b/runtime/vm/compiler/backend/linearscan.cc
index d786d83..9c7d766 100644
--- a/runtime/vm/compiler/backend/linearscan.cc
+++ b/runtime/vm/compiler/backend/linearscan.cc
@@ -752,6 +752,9 @@
     if (param->base_reg() == FPREG) {
       slot_index =
           compiler::target::frame_layout.FrameSlotForVariableIndex(-slot_index);
+    } else {
+      ASSERT(param->base_reg() == SPREG);
+      slot_index += compiler::target::frame_layout.last_param_from_entry_sp;
     }
     range->set_assigned_location(
         Location::StackSlot(slot_index, param->base_reg()));
diff --git a/runtime/vm/compiler/backend/loops_test.cc b/runtime/vm/compiler/backend/loops_test.cc
index 1e9c8cd..4b208f8 100644
--- a/runtime/vm/compiler/backend/loops_test.cc
+++ b/runtime/vm/compiler/backend/loops_test.cc
@@ -9,6 +9,7 @@
 
 #include "vm/compiler/backend/loops.h"
 #include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/type_propagator.h"
 #include "vm/compiler/compiler_pass.h"
@@ -62,43 +63,18 @@
 
 // Helper method to build CFG and compute induction.
 static const char* ComputeInduction(Thread* thread, const char* script_chars) {
-  // Invoke the script.
-  Dart_Handle script = TestCase::LoadTestScript(script_chars, NULL);
-  Dart_Handle result = Dart_Invoke(script, NewString("main"), 0, NULL);
-  EXPECT_VALID(result);
+  // Load the script and exercise the code once.
+  const auto& root_library = Library::Handle(LoadTestScript(script_chars));
+  Invoke(root_library, "main");
 
-  // Find parsed function "foo".
-  TransitionNativeToVM transition(thread);
-  Zone* zone = thread->zone();
-  Library& lib =
-      Library::ZoneHandle(Library::RawCast(Api::UnwrapHandle(script)));
-  RawFunction* raw_func =
-      lib.LookupLocalFunction(String::Handle(Symbols::New(thread, "foo")));
-  ParsedFunction* parsed_function =
-      new (zone) ParsedFunction(thread, Function::ZoneHandle(zone, raw_func));
-  EXPECT(parsed_function != nullptr);
-
-  // Build flow graph.
-  CompilerState state(thread);
-  ZoneGrowableArray<const ICData*>* ic_data_array =
-      new (zone) ZoneGrowableArray<const ICData*>();
-  parsed_function->function().RestoreICDataMap(ic_data_array, true);
-  kernel::FlowGraphBuilder builder(parsed_function, ic_data_array, nullptr,
-                                   nullptr, true, DeoptId::kNone);
-  FlowGraph* flow_graph = builder.BuildGraph();
-  EXPECT(flow_graph != nullptr);
-
-  // Setup some pass data structures and perform minimum passes.
-  SpeculativeInliningPolicy speculative_policy(/*enable_blacklist*/ false);
-  CompilerPassState pass_state(thread, flow_graph, &speculative_policy);
-  JitCallSpecializer call_specializer(flow_graph, &speculative_policy);
-  pass_state.call_specializer = &call_specializer;
-  flow_graph->ComputeSSA(0, nullptr);
-  FlowGraphTypePropagator::Propagate(flow_graph);
-  call_specializer.ApplyICData();
-  flow_graph->SelectRepresentations();
-  FlowGraphTypePropagator::Propagate(flow_graph);
-  flow_graph->Canonicalize();
+  std::initializer_list<CompilerPass::Id> passes = {
+      CompilerPass::kComputeSSA,      CompilerPass::kTypePropagation,
+      CompilerPass::kApplyICData,     CompilerPass::kSelectRepresentations,
+      CompilerPass::kTypePropagation, CompilerPass::kCanonicalize,
+  };
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, CompilerPass::kJIT);
+  FlowGraph* flow_graph = pipeline.RunPasses(passes);
 
   // Build loop hierarchy and find induction.
   const LoopHierarchy& hierarchy = flow_graph->GetLoopHierarchy();
@@ -116,15 +92,17 @@
 // Induction tests.
 //
 
-TEST_CASE(BasicInductionUp) {
+ISOLATE_UNIT_TEST_CASE(BasicInductionUp) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0; i < 100; i++) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(0 + 1 * i) 100\n"  // phi
@@ -133,15 +111,17 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(BasicInductionDown) {
+ISOLATE_UNIT_TEST_CASE(BasicInductionDown) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 100; i > 0; i--) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 100; i > 0; i--) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(100 + -1 * i) 0\n"  // phi
@@ -150,15 +130,17 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(BasicInductionStepUp) {
+ISOLATE_UNIT_TEST_CASE(BasicInductionStepUp) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 10; i < 100; i += 2) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 10; i < 100; i += 2) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(10 + 2 * i)\n"  // phi
@@ -167,15 +149,17 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(BasicInductionStepDown) {
+ISOLATE_UNIT_TEST_CASE(BasicInductionStepDown) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 100; i >= 0; i -= 7) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 100; i >= 0; i -= 7) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(100 + -7 * i)\n"  // phi
@@ -184,19 +168,21 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(BasicInductionLoopNest) {
+ISOLATE_UNIT_TEST_CASE(BasicInductionLoopNest) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "    for (int j = 1; j < 100; j++) {\n"
-      "      for (int k = 2; k < 100; k++) {\n"
-      "      }\n"
-      "    }\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0; i < 100; i++) {
+          for (int j = 1; j < 100; j++) {
+            for (int k = 2; k < 100; k++) {
+            }
+          }
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [2\n"
       "  LIN(0 + 1 * i) 100\n"  // i
@@ -213,18 +199,20 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(ChainInduction) {
+ISOLATE_UNIT_TEST_CASE(ChainInduction) {
   const char* script_chars =
-      "foo() {\n"
-      "  int j = 1;\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "    j += 5;\n"
-      "    j += 7;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        int j = 1;
+        for (int i = 0; i < 100; i++) {
+          j += 5;
+          j += 7;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(1 + 12 * i)\n"     // phi (j)
@@ -236,21 +224,23 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(TwoWayInduction) {
+ISOLATE_UNIT_TEST_CASE(TwoWayInduction) {
   const char* script_chars =
-      "foo() {\n"
-      "  int j = 123;\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "     if (i == 10) {\n"
-      "       j += 3;\n"
-      "     } else {\n"
-      "       j += 3;\n"
-      "     }\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        int j = 123;
+        for (int i = 0; i < 100; i++) {
+           if (i == 10) {
+             j += 3;
+           } else {
+             j += 3;
+           }
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(123 + 3 * i)\n"    // phi (j)
@@ -263,19 +253,21 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(DerivedInduction) {
+ISOLATE_UNIT_TEST_CASE(DerivedInduction) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 1; i < 100; i++) {\n"
-      "    int a = i + 3;\n"
-      "    int b = i - 5;\n"
-      "    int c = i * 7;\n"
-      "    int d = - i;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 1; i < 100; i++) {
+          int a = i + 3;
+          int b = i - 5;
+          int c = i * 7;
+          int d = - i;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(1 + 1 * i) 100\n"  // phi
@@ -288,21 +280,23 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(WrapAroundAndDerived) {
+ISOLATE_UNIT_TEST_CASE(WrapAroundAndDerived) {
   const char* script_chars =
-      "foo() {\n"
-      "  int w = 99;\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "    int a = w + 3;\n"
-      "    int b = w - 5;\n"
-      "    int c = w * 7;\n"
-      "    int d = - w;\n"
-      "    w = i;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        int w = 99;
+        for (int i = 0; i < 100; i++) {
+          int a = w + 3;
+          int b = w - 5;
+          int c = w * 7;
+          int d = - w;
+          w = i;
+        }
+      }
+      main() {
+        foo();
+      }
+      )";
   const char* expected =
       "  [0\n"
       "  WRAP(99, LIN(0 + 1 * i))\n"    // phi (w)
@@ -316,23 +310,25 @@
   EXPECT_STREQ(ComputeInduction(thread, script_chars), expected);
 }
 
-TEST_CASE(PeriodicAndDerived) {
+ISOLATE_UNIT_TEST_CASE(PeriodicAndDerived) {
   const char* script_chars =
-      "foo() {\n"
-      "  int p1 = 3;\n"
-      "  int p2 = 5;\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "    int a = p1 + 3;\n"
-      "    int b = p1 - 5;\n"
-      "    int c = p1 * 7;\n"
-      "    int d = - p1;\n"
-      "    p1 = - p1;\n"
-      "    p2 = 100 - p2;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        int p1 = 3;
+        int p2 = 5;
+        for (int i = 0; i < 100; i++) {
+          int a = p1 + 3;
+          int b = p1 - 5;
+          int c = p1 * 7;
+          int d = - p1;
+          p1 = - p1;
+          p2 = 100 - p2;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  PERIOD(3, -3)\n"       // phi(p1)
@@ -353,15 +349,17 @@
 // Bound specific tests.
 //
 
-TEST_CASE(NonStrictConditionUp) {
+ISOLATE_UNIT_TEST_CASE(NonStrictConditionUp) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0; i <= 100; i++) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0; i <= 100; i++) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(0 + 1 * i) 101\n"  // phi
@@ -371,16 +369,18 @@
 }
 
 #ifndef TARGET_ARCH_DBC
-TEST_CASE(NonStrictConditionUpWrap) {
+ISOLATE_UNIT_TEST_CASE(NonStrictConditionUpWrap) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0x7ffffffffffffffe; i <= 0x7fffffffffffffff; i++) {\n"
-      "    if (i < 0) break;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0x7ffffffffffffffe; i <= 0x7fffffffffffffff; i++) {
+          if (i < 0) break;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(9223372036854775806 + 1 * i)\n"  // phi
@@ -394,15 +394,17 @@
 }
 #endif
 
-TEST_CASE(NonStrictConditionDown) {
+ISOLATE_UNIT_TEST_CASE(NonStrictConditionDown) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 100; i >= 0; i--) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 100; i >= 0; i--) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(100 + -1 * i) -1\n"  // phi
@@ -412,16 +414,18 @@
 }
 
 #ifndef TARGET_ARCH_DBC
-TEST_CASE(NonStrictConditionDownWrap) {
+ISOLATE_UNIT_TEST_CASE(NonStrictConditionDownWrap) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0x8000000000000001; i >= 0x8000000000000000; i--) {\n"
-      "    if (i > 0) break;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0x8000000000000001; i >= 0x8000000000000000; i--) {
+          if (i > 0) break;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(-9223372036854775807 + -1 * i)\n"  // phi
@@ -433,17 +437,20 @@
       "  ]\n";
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
+
 #endif
 
-TEST_CASE(NotEqualConditionUp) {
+ISOLATE_UNIT_TEST_CASE(NotEqualConditionUp) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 10; i != 20; i++) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 10; i != 20; i++) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(10 + 1 * i) 20\n"  // phi
@@ -452,15 +459,17 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(NotEqualConditionDown) {
+ISOLATE_UNIT_TEST_CASE(NotEqualConditionDown) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 20; i != 10; i--) {\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 20; i != 10; i--) {
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(20 + -1 * i) 10\n"  // phi
@@ -469,16 +478,18 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(SecondExitUp) {
+ISOLATE_UNIT_TEST_CASE(SecondExitUp) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 0; i < 100; i++) {\n"
-      "     if (i >= 50) break;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 0; i < 100; i++) {
+           if (i >= 50) break;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(0 + 1 * i) 100 50\n"  // phi
@@ -487,16 +498,18 @@
   EXPECT_STREQ(expected, ComputeInduction(thread, script_chars));
 }
 
-TEST_CASE(SecondExitDown) {
+ISOLATE_UNIT_TEST_CASE(SecondExitDown) {
   const char* script_chars =
-      "foo() {\n"
-      "  for (int i = 100; i > 0; i--) {\n"
-      "     if (i <= 10) break;\n"
-      "  }\n"
-      "}\n"
-      "main() {\n"
-      "  foo();\n"
-      "}\n";
+      R"(
+      foo() {
+        for (int i = 100; i > 0; i--) {
+           if (i <= 10) break;
+        }
+      }
+      main() {
+        foo();
+      }
+    )";
   const char* expected =
       "  [0\n"
       "  LIN(100 + -1 * i) 0 10\n"  // phi
diff --git a/runtime/vm/compiler/backend/range_analysis.cc b/runtime/vm/compiler/backend/range_analysis.cc
index e06cd75..c2bd37b 100644
--- a/runtime/vm/compiler/backend/range_analysis.cc
+++ b/runtime/vm/compiler/backend/range_analysis.cc
@@ -64,12 +64,8 @@
 
   for (intptr_t i = 0; i < graph_entry->SuccessorCount(); ++i) {
     auto successor = graph_entry->SuccessorAt(i);
-    if (successor->IsFunctionEntry() || successor->IsCatchBlockEntry()) {
-      auto function_entry = successor->AsFunctionEntry();
-      auto catch_entry = successor->AsCatchBlockEntry();
-      const auto& initial = function_entry != nullptr
-                                ? *function_entry->initial_definitions()
-                                : *catch_entry->initial_definitions();
+    if (auto entry = successor->AsBlockEntryWithInitialDefs()) {
+      const auto& initial = *entry->initial_definitions();
       for (intptr_t j = 0; j < initial.length(); ++j) {
         Definition* current = initial[j];
         if (IsIntegerDefinition(current)) {
@@ -215,31 +211,31 @@
 void RangeAnalysis::InsertConstraintsFor(Definition* defn) {
   for (Value* use = defn->input_use_list(); use != NULL;
        use = use->next_use()) {
-    if (use->instruction()->IsBranch()) {
+    if (auto branch = use->instruction()->AsBranch()) {
       if (ConstrainValueAfterBranch(use, defn)) {
-        Value* other_value = use->instruction()->InputAt(1 - use->use_index());
+        Value* other_value = branch->InputAt(1 - use->use_index());
         if (!IsIntegerDefinition(other_value->definition())) {
           ConstrainValueAfterBranch(other_value, other_value->definition());
         }
       }
-    } else if (use->instruction()->IsCheckArrayBound()) {
-      ConstrainValueAfterCheckArrayBound(use, defn);
+    } else if (auto check = use->instruction()->AsCheckBoundBase()) {
+      ConstrainValueAfterCheckBound(use, check, defn);
     }
   }
 }
 
-void RangeAnalysis::ConstrainValueAfterCheckArrayBound(Value* use,
-                                                       Definition* defn) {
-  CheckArrayBoundInstr* check = use->instruction()->AsCheckArrayBound();
-  intptr_t use_index = use->use_index();
+void RangeAnalysis::ConstrainValueAfterCheckBound(Value* use,
+                                                  CheckBoundBase* check,
+                                                  Definition* defn) {
+  const intptr_t use_index = use->use_index();
 
   Range* constraint_range = NULL;
-  if (use_index == CheckArrayBoundInstr::kIndexPos) {
+  if (use_index == CheckBoundBase::kIndexPos) {
     Definition* length = check->length()->definition();
     constraint_range = new (Z) Range(RangeBoundary::FromConstant(0),
                                      RangeBoundary::FromDefinition(length, -1));
   } else {
-    ASSERT(use_index == CheckArrayBoundInstr::kLengthPos);
+    ASSERT(use_index == CheckBoundBase::kLengthPos);
     Definition* index = check->index()->definition();
     constraint_range = new (Z)
         Range(RangeBoundary::FromDefinition(index, 1), RangeBoundary::MaxSmi());
diff --git a/runtime/vm/compiler/backend/range_analysis.h b/runtime/vm/compiler/backend/range_analysis.h
index 8a8ca4b..a16ea2b 100644
--- a/runtime/vm/compiler/backend/range_analysis.h
+++ b/runtime/vm/compiler/backend/range_analysis.h
@@ -566,7 +566,9 @@
                                        Instruction* after);
 
   bool ConstrainValueAfterBranch(Value* use, Definition* defn);
-  void ConstrainValueAfterCheckArrayBound(Value* use, Definition* defn);
+  void ConstrainValueAfterCheckBound(Value* use,
+                                     CheckBoundBase* check,
+                                     Definition* defn);
 
   // Infer ranges for integer (smi or mint) definitions.
   void InferRanges();
diff --git a/runtime/vm/compiler/backend/redundancy_elimination_test.cc b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
index dc9e015..21e63d8 100644
--- a/runtime/vm/compiler/backend/redundancy_elimination_test.cc
+++ b/runtime/vm/compiler/backend/redundancy_elimination_test.cc
@@ -4,6 +4,7 @@
 
 #include "vm/compiler/backend/redundancy_elimination.h"
 #include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
 #include "vm/compiler/backend/inliner.h"
 #include "vm/compiler/backend/loops.h"
 #include "vm/compiler/backend/type_propagator.h"
@@ -28,53 +29,6 @@
   return reinterpret_cast<Dart_NativeFunction>(&NoopNative);
 }
 
-// Helper method to build CFG and run some preliminary optimizations on it.
-// TODO(vegorov) we should consider moving this function into utils to share
-// between all compiler tests.
-static FlowGraph* BuildOptimizedGraph(Thread* thread,
-                                      const char* script_chars) {
-  // Invoke the script.
-  Dart_Handle script =
-      TestCase::LoadTestScript(script_chars, &NoopNativeLookup);
-  Dart_Handle result = Dart_Invoke(script, NewString("main"), 0, nullptr);
-  EXPECT_VALID(result);
-
-  // Find parsed function "foo".
-  TransitionNativeToVM transition(thread);
-  Zone* zone = thread->zone();
-  Library& lib =
-      Library::ZoneHandle(Library::RawCast(Api::UnwrapHandle(script)));
-  RawFunction* raw_func =
-      lib.LookupLocalFunction(String::Handle(Symbols::New(thread, "foo")));
-  ParsedFunction* parsed_function =
-      new (zone) ParsedFunction(thread, Function::ZoneHandle(zone, raw_func));
-  EXPECT(parsed_function != nullptr);
-
-  // Build flow graph.
-  CompilerState state(thread);
-  ZoneGrowableArray<const ICData*>* ic_data_array =
-      new (zone) ZoneGrowableArray<const ICData*>();
-  parsed_function->function().RestoreICDataMap(ic_data_array, true);
-  kernel::FlowGraphBuilder builder(parsed_function, ic_data_array, nullptr,
-                                   nullptr, true, DeoptId::kNone);
-  FlowGraph* flow_graph = builder.BuildGraph();
-  EXPECT(flow_graph != nullptr);
-
-  // Setup some pass data structures and perform minimum passes.
-  SpeculativeInliningPolicy speculative_policy(/*enable_blacklist=*/false);
-  CompilerPassState pass_state(thread, flow_graph, &speculative_policy);
-  JitCallSpecializer call_specializer(flow_graph, &speculative_policy);
-  pass_state.call_specializer = &call_specializer;
-  flow_graph->ComputeSSA(0, nullptr);
-  FlowGraphTypePropagator::Propagate(flow_graph);
-  call_specializer.ApplyICData();
-  flow_graph->SelectRepresentations();
-  FlowGraphTypePropagator::Propagate(flow_graph);
-  flow_graph->Canonicalize();
-
-  return flow_graph;
-}
-
 // Flatten all non-captured LocalVariables from the given scope and its children
 // and siblings into the given array based on their environment index.
 static void FlattenScopeIntoEnvironment(FlowGraph* graph,
@@ -106,13 +60,25 @@
     Thread* thread,
     const char* script_chars,
     std::initializer_list<const char*> synchronized) {
-  FlowGraph* graph = BuildOptimizedGraph(thread, script_chars);
+  // Load the script and exercise the code once.
+  const auto& root_library =
+      Library::Handle(LoadTestScript(script_chars, &NoopNativeLookup));
+  Invoke(root_library, "main");
+
+  // Build the flow graph.
+  std::initializer_list<CompilerPass::Id> passes = {
+      CompilerPass::kComputeSSA,      CompilerPass::kTypePropagation,
+      CompilerPass::kApplyICData,     CompilerPass::kSelectRepresentations,
+      CompilerPass::kTypePropagation, CompilerPass::kCanonicalize,
+  };
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, CompilerPass::kJIT);
+  FlowGraph* graph = pipeline.RunPasses(passes);
 
   // Finally run TryCatchAnalyzer on the graph (in AOT mode).
   OptimizeCatchEntryStates(graph, /*is_aot=*/true);
 
   EXPECT_EQ(1, graph->graph_entry()->catch_entries().length());
-
   auto scope = graph->parsed_function().node_sequence()->scope();
 
   GrowableArray<LocalVariable*> env;
@@ -146,7 +112,7 @@
 // Tests for TryCatchOptimizer.
 //
 
-TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple1) {
+ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple1) {
   const char* script_chars = R"(
       dynamic blackhole([dynamic val]) native 'BlackholeNative';
       foo(int p) {
@@ -165,7 +131,7 @@
   TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{});
 }
 
-TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple2) {
+ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Simple2) {
   const char* script_chars = R"(
       dynamic blackhole([dynamic val]) native 'BlackholeNative';
       foo(int p) {
@@ -185,7 +151,7 @@
   TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{"a"});
 }
 
-TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic1) {
+ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic1) {
   const char* script_chars = R"(
       dynamic blackhole([dynamic val]) native 'BlackholeNative';
       foo(int p) {
@@ -207,7 +173,7 @@
   TryCatchOptimizerTest(thread, script_chars, /*synchronized=*/{"a", "i"});
 }
 
-TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic2) {
+ISOLATE_UNIT_TEST_CASE(TryCatchOptimizer_DeadParameterElimination_Cyclic2) {
   const char* script_chars = R"(
       dynamic blackhole([dynamic val]) native 'BlackholeNative';
       foo(int p) {
diff --git a/runtime/vm/compiler/backend/type_propagator.cc b/runtime/vm/compiler/backend/type_propagator.cc
index e3f4f7d..0dec0c9 100644
--- a/runtime/vm/compiler/backend/type_propagator.cc
+++ b/runtime/vm/compiler/backend/type_propagator.cc
@@ -580,12 +580,14 @@
 
 CompileType* CompileType::ComputeRefinedType(CompileType* old_type,
                                              CompileType* new_type) {
+  ASSERT(new_type != nullptr);
+
   // In general, prefer the newly inferred type over old type.
   // It is possible that new and old types are unrelated or do not intersect
   // at all (for example, in case of unreachable code).
 
   // Discard None type as it is used to denote an unknown type.
-  if (old_type->IsNone()) {
+  if (old_type == nullptr || old_type->IsNone()) {
     return new_type;
   }
   if (new_type->IsNone()) {
@@ -826,13 +828,22 @@
   return reaching_type_;
 }
 
-void Value::RefineReachingType(CompileType* type) {
-  ASSERT(type != NULL);
-  if (reaching_type_ == NULL) {
-    reaching_type_ = type;
-  } else {
-    reaching_type_ = CompileType::ComputeRefinedType(reaching_type_, type);
+void Value::SetReachingType(CompileType* type) {
+  // If [type] is owned but not by the definition which flows into this use
+  // then we need to disconect the type from original owner by cloning it.
+  // This is done to prevent situations when [type] is updated by its owner
+  // but [owner] is no longer connected to this use through def-use chain
+  // and as a result type propagator does not recompute type of the current
+  // instruction.
+  if (type != nullptr && type->owner() != nullptr &&
+      type->owner() != definition()) {
+    type = new CompileType(*type);
   }
+  reaching_type_ = type;
+}
+
+void Value::RefineReachingType(CompileType* type) {
+  SetReachingType(CompileType::ComputeRefinedType(reaching_type_, type));
 }
 
 CompileType PhiInstr::ComputeType() const {
@@ -1447,6 +1458,10 @@
   return CompileType::Dynamic();
 }
 
+bool CheckedSmiOpInstr::RecomputeType() {
+  return UpdateType(ComputeType());
+}
+
 CompileType CheckedSmiComparisonInstr::ComputeType() const {
   if (Isolate::Current()->can_use_strong_mode_types()) {
     CompileType* type = call()->Type();
diff --git a/runtime/vm/compiler/backend/type_propagator_test.cc b/runtime/vm/compiler/backend/type_propagator_test.cc
new file mode 100644
index 0000000..ab6501bc
--- /dev/null
+++ b/runtime/vm/compiler/backend/type_propagator_test.cc
@@ -0,0 +1,519 @@
+// 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.
+
+#include <utility>
+
+#include "vm/compiler/backend/block_builder.h"
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/inliner.h"
+#include "vm/compiler/backend/loops.h"
+#include "vm/compiler/backend/redundancy_elimination.h"
+#include "vm/compiler/backend/type_propagator.h"
+#include "vm/compiler/compiler_pass.h"
+#include "vm/compiler/frontend/kernel_to_il.h"
+#include "vm/compiler/jit/compiler.h"
+#include "vm/compiler/jit/jit_call_specializer.h"
+#include "vm/log.h"
+#include "vm/object.h"
+#include "vm/parser.h"
+#include "vm/symbols.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#if !defined(PRODUCT)
+#define TOCSTRING(v) ((v)->ToCString())
+#else
+#define TOCSTRING(v) "<?>"
+#endif
+
+#define EXPECT_PROPERTY(entity, property)                                      \
+  do {                                                                         \
+    auto& it = *entity;                                                        \
+    if (!(property)) {                                                         \
+      dart::Expect(__FILE__, __LINE__)                                         \
+          .Fail("expected " #property " for " #entity " which is %s.\n",       \
+                TOCSTRING(entity));                                            \
+    }                                                                          \
+  } while (0)
+
+using compiler::BlockBuilder;
+
+FlowGraph* MakeDummyGraph(Thread* thread) {
+  const Function& func = Function::ZoneHandle(Function::New(
+      String::Handle(Symbols::New(thread, "dummy")),
+      RawFunction::kRegularFunction,
+      /*is_static=*/true,
+      /*is_const=*/false,
+      /*is_abstract=*/false,
+      /*is_external=*/false,
+      /*is_native=*/true,
+      Class::Handle(thread->isolate()->object_store()->object_class()),
+      TokenPosition::kNoSource));
+
+  Zone* zone = thread->zone();
+  ParsedFunction* parsed_function = new (zone) ParsedFunction(thread, func);
+
+  parsed_function->SetNodeSequence(new SequenceNode(
+      TokenPosition::kNoSource, new LocalScope(nullptr, 0, 0)));
+
+  auto graph_entry =
+      new GraphEntryInstr(*parsed_function, Compiler::kNoOSRDeoptId);
+
+  intptr_t block_id = 1;  // 0 is GraphEntry.
+  graph_entry->set_normal_entry(
+      new FunctionEntryInstr(graph_entry, block_id, kInvalidTryIndex,
+                             CompilerState::Current().GetNextDeoptId()));
+  return new FlowGraph(*parsed_function, graph_entry, block_id,
+                       PrologueInfo{-1, -1});
+}
+
+namespace {
+class FlowGraphBuilderHelper {
+ public:
+  explicit FlowGraphBuilderHelper(FlowGraph* flow_graph)
+      : state_(CompilerState::Current()),
+        flow_graph_(*flow_graph),
+        constant_dead_(flow_graph->GetConstant(Symbols::OptimizedOut())) {}
+
+  TargetEntryInstr* TargetEntry(intptr_t try_index = kInvalidTryIndex) const {
+    return new TargetEntryInstr(flow_graph_.allocate_block_id(), try_index,
+                                state_.GetNextDeoptId());
+  }
+
+  JoinEntryInstr* JoinEntry(intptr_t try_index = kInvalidTryIndex) const {
+    return new JoinEntryInstr(flow_graph_.allocate_block_id(), try_index,
+                              state_.GetNextDeoptId());
+  }
+
+  ConstantInstr* IntConstant(int64_t value) const {
+    return flow_graph_.GetConstant(
+        Integer::Handle(Integer::New(value, Heap::kOld)));
+  }
+
+  ConstantInstr* DoubleConstant(double value) {
+    return flow_graph_.GetConstant(
+        Double::Handle(Double::New(value, Heap::kOld)));
+  }
+
+  PhiInstr* Phi(JoinEntryInstr* join,
+                std::initializer_list<std::pair<BlockEntryInstr*, Definition*>>
+                    incomming) {
+    auto phi = new PhiInstr(join, incomming.size());
+    for (size_t i = 0; i < incomming.size(); i++) {
+      auto input = new Value(constant_dead_);
+      phi->SetInputAt(i, input);
+      input->definition()->AddInputUse(input);
+    }
+    for (auto pair : incomming) {
+      pending_phis_.Add({phi, pair.first, pair.second});
+    }
+    return phi;
+  }
+
+  void FinishGraph() {
+    flow_graph_.DiscoverBlocks();
+    GrowableArray<BitVector*> dominance_frontier;
+    flow_graph_.ComputeDominators(&dominance_frontier);
+
+    for (auto& pending : pending_phis_) {
+      auto join = pending.phi->block();
+      EXPECT(pending.phi->InputCount() == join->PredecessorCount());
+      auto pred_index = join->IndexOfPredecessor(pending.pred);
+      EXPECT(pred_index != -1);
+      pending.phi->InputAt(pred_index)->BindTo(pending.defn);
+    }
+  }
+
+ private:
+  CompilerState& state_;
+  FlowGraph& flow_graph_;
+  ConstantInstr* constant_dead_;
+
+  struct PendingPhiInput {
+    PhiInstr* phi;
+    BlockEntryInstr* pred;
+    Definition* defn;
+  };
+  GrowableArray<PendingPhiInput> pending_phis_;
+};
+}  // namespace
+
+ISOLATE_UNIT_TEST_CASE(TypePropagator_RedefinitionAfterStrictCompareWithNull) {
+  CompilerState S(thread);
+
+  FlowGraph* flow_graph = MakeDummyGraph(thread);
+  FlowGraphBuilderHelper H(flow_graph);
+
+  // Add a variable into the scope which would provide static type for the
+  // parameter.
+  LocalVariable* v0_var =
+      new LocalVariable(TokenPosition::kNoSource, TokenPosition::kNoSource,
+                        String::Handle(Symbols::New(thread, "v0")),
+                        AbstractType::ZoneHandle(Type::IntType()));
+  v0_var->set_type_check_mode(LocalVariable::kTypeCheckedByCaller);
+  flow_graph->parsed_function().node_sequence()->scope()->AddVariable(v0_var);
+
+  auto normal_entry = flow_graph->graph_entry()->normal_entry();
+
+  // We are going to build the following graph:
+  //
+  // B0[graph_entry]:
+  // B1[function_entry]:
+  //   v0 <- Parameter(0)
+  //   if v0 == null then B2 else B3
+  // B2:
+  //   Return(v0)
+  // B3:
+  //   Return(v0)
+
+  Definition* v0;
+  auto b2 = H.TargetEntry();
+  auto b3 = H.TargetEntry();
+
+  {
+    BlockBuilder builder(flow_graph, normal_entry);
+    v0 = builder.AddParameter(0, /*with_frame=*/true);
+    builder.AddBranch(
+        new StrictCompareInstr(
+            TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(v0),
+            new Value(flow_graph->GetConstant(Object::Handle())),
+            /*needs_number_check=*/false, S.GetNextDeoptId()),
+        b2, b3);
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b2);
+    builder.AddReturn(new Value(v0));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b3);
+    builder.AddReturn(new Value(v0));
+  }
+
+  H.FinishGraph();
+
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  // We expect that v0 is inferred to be nullable int because that is what
+  // static type of an associated variable tells us.
+  EXPECT(v0->Type()->IsNullableInt());
+
+  // In B2 v0 should not have any additional type information so reaching
+  // type should be still nullable int.
+  auto b2_value = b2->last_instruction()->AsReturn()->value();
+  EXPECT(b2_value->Type()->IsNullableInt());
+
+  // In B3 v0 is constrained by comparison with null - it should be non-nullable
+  // integer. There should be a Redefinition inserted to prevent LICM past
+  // the branch.
+  auto b3_value = b3->last_instruction()->AsReturn()->value();
+  EXPECT(b3_value->Type()->IsInt());
+  EXPECT(b3_value->definition()->IsRedefinition());
+  EXPECT(b3_value->definition()->GetBlock() == b3);
+}
+
+ISOLATE_UNIT_TEST_CASE(
+    TypePropagator_RedefinitionAfterStrictCompareWithLoadClassId) {
+  CompilerState S(thread);
+
+  FlowGraph* flow_graph = MakeDummyGraph(thread);
+  FlowGraphBuilderHelper H(flow_graph);
+
+  // We are going to build the following graph:
+  //
+  // B0[graph_entry]:
+  // B1[function_entry]:
+  //   v0 <- Parameter(0)
+  //   v1 <- LoadClassId(v0)
+  //   if v1 == kDoubleCid then B2 else B3
+  // B2:
+  //   Return(v0)
+  // B3:
+  //   Return(v0)
+
+  Definition* v0;
+  auto b1 = flow_graph->graph_entry()->normal_entry();
+  auto b2 = H.TargetEntry();
+  auto b3 = H.TargetEntry();
+
+  {
+    BlockBuilder builder(flow_graph, b1);
+    v0 = builder.AddParameter(0, /*with_frame=*/true);
+    auto load_cid = builder.AddDefinition(new LoadClassIdInstr(new Value(v0)));
+    builder.AddBranch(
+        new StrictCompareInstr(
+            TokenPosition::kNoSource, Token::kEQ_STRICT, new Value(load_cid),
+            new Value(H.IntConstant(kDoubleCid)),
+            /*needs_number_check=*/false, S.GetNextDeoptId()),
+        b2, b3);
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b2);
+    builder.AddReturn(new Value(v0));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b3);
+    builder.AddReturn(new Value(v0));
+  }
+
+  H.FinishGraph();
+
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  // There should be no information available about the incoming type of
+  // the parameter either on entry or in B3.
+  EXPECT_PROPERTY(v0->Type()->ToAbstractType(), it.IsDynamicType());
+  auto b3_value = b3->last_instruction()->AsReturn()->value();
+  EXPECT(b3_value->Type() == v0->Type());
+
+  // In B3 v0 is constrained by comparison of its cid with kDoubleCid - it
+  // should be non-nullable double. There should be a Redefinition inserted to
+  // prevent LICM past the branch.
+  auto b2_value = b2->last_instruction()->AsReturn()->value();
+  EXPECT_PROPERTY(b2_value->Type(), it.IsDouble());
+  EXPECT_PROPERTY(b2_value->definition(), it.IsRedefinition());
+  EXPECT_PROPERTY(b2_value->definition()->GetBlock(), &it == b2);
+}
+
+ISOLATE_UNIT_TEST_CASE(TypePropagator_Refinement) {
+  CompilerState S(thread);
+
+  const Class& object_class =
+      Class::Handle(thread->isolate()->object_store()->object_class());
+
+  const Function& target_func = Function::ZoneHandle(Function::New(
+      String::Handle(Symbols::New(thread, "dummy2")),
+      RawFunction::kRegularFunction,
+      /*is_static=*/true,
+      /*is_const=*/false,
+      /*is_abstract=*/false,
+      /*is_external=*/false,
+      /*is_native=*/true, object_class, TokenPosition::kNoSource));
+  target_func.set_result_type(AbstractType::Handle(Type::IntType()));
+
+  const Field& field = Field::ZoneHandle(
+      Field::New(String::Handle(Symbols::New(thread, "dummy")),
+                 /*is_static=*/true,
+                 /*is_final=*/false,
+                 /*is_const=*/false,
+                 /*is_reflectable=*/true, object_class, Object::dynamic_type(),
+                 TokenPosition::kNoSource, TokenPosition::kNoSource));
+
+  FlowGraph* flow_graph = MakeDummyGraph(thread);
+  FlowGraphBuilderHelper H(flow_graph);
+
+  // We are going to build the following graph:
+  //
+  // B0[graph_entry]
+  // B1[function_entry]:
+  //   v0 <- Parameter(0)
+  //   v1 <- Constant(0)
+  //   if v0 == 1 then B3 else B2
+  // B2:
+  //   v2 <- StaticCall(target_func)
+  //   goto B4
+  // B3:
+  //   goto B4
+  // B4:
+  //  v3 <- phi(v1, v2)
+  //  return v5
+
+  Definition* v0;
+  Definition* v2;
+  PhiInstr* v3;
+  auto b1 = flow_graph->graph_entry()->normal_entry();
+  auto b2 = H.TargetEntry();
+  auto b3 = H.TargetEntry();
+  auto b4 = H.JoinEntry();
+
+  {
+    BlockBuilder builder(flow_graph, b1);
+    v0 = builder.AddParameter(0, /*with_frame=*/true);
+    builder.AddBranch(new StrictCompareInstr(
+                          TokenPosition::kNoSource, Token::kEQ_STRICT,
+                          new Value(v0), new Value(H.IntConstant(1)),
+                          /*needs_number_check=*/false, S.GetNextDeoptId()),
+                      b2, b3);
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b2);
+    v2 = builder.AddDefinition(
+        new StaticCallInstr(TokenPosition::kNoSource, target_func,
+                            /*type_args_len=*/0,
+                            /*argument_names=*/Array::empty_array(),
+                            new PushArgumentsArray(0), S.GetNextDeoptId(),
+                            /*call_count=*/0, ICData::RebindRule::kStatic));
+    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b3);
+    builder.AddInstruction(new GotoInstr(b4, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b4);
+    v3 = H.Phi(b4, {{b2, v2}, {b3, H.IntConstant(0)}});
+    builder.AddPhi(v3);
+    builder.AddReturn(new Value(v3));
+  }
+
+  H.FinishGraph();
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  EXPECT_PROPERTY(v2->Type(), it.IsNullableInt());
+  EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());
+
+  auto v4 = new LoadStaticFieldInstr(new Value(flow_graph->GetConstant(field)),
+                                     TokenPosition::kNoSource);
+  flow_graph->InsertBefore(v2, v4, nullptr, FlowGraph::kValue);
+  v2->ReplaceUsesWith(v4);
+  v2->RemoveFromGraph();
+
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  EXPECT_PROPERTY(v3->Type(), it.IsNullableInt());
+}
+
+// This test verifies that mutable compile types are not incorrectly cached
+// as reaching types after inference.
+ISOLATE_UNIT_TEST_CASE(TypePropagator_Regress36156) {
+  CompilerState S(thread);
+
+  FlowGraph* flow_graph = MakeDummyGraph(thread);
+  FlowGraphBuilderHelper H(flow_graph);
+
+  // We are going to build the following graph:
+  //
+  // B0[graph_entry]
+  // B1[function_entry]:
+  //   v0 <- Parameter(0)
+  //   v1 <- Constant(42)
+  //   v2 <- Constant(24)
+  //   v4 <- Constant(1.0)
+  //   if v0 == 1 then B6 else B2
+  // B2:
+  //   if v0 == 2 then B3 else B4
+  // B3:
+  //   goto B5
+  // B4:
+  //   goto B5
+  // B5:
+  //   v3 <- phi(v1, v2)
+  //   goto B7
+  // B6:
+  //   goto B7
+  // B7:
+  //  v5 <- phi(v4, v3)
+  //  return v5
+
+  Definition* v0;
+  PhiInstr* v3;
+  PhiInstr* v5;
+  auto b1 = flow_graph->graph_entry()->normal_entry();
+  auto b2 = H.TargetEntry();
+  auto b3 = H.TargetEntry();
+  auto b4 = H.TargetEntry();
+  auto b5 = H.JoinEntry();
+  auto b6 = H.TargetEntry();
+  auto b7 = H.JoinEntry();
+
+  {
+    BlockBuilder builder(flow_graph, b1);
+    v0 = builder.AddParameter(0, /*with_frame=*/true);
+    builder.AddBranch(new StrictCompareInstr(
+                          TokenPosition::kNoSource, Token::kEQ_STRICT,
+                          new Value(v0), new Value(H.IntConstant(1)),
+                          /*needs_number_check=*/false, S.GetNextDeoptId()),
+                      b6, b2);
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b2);
+    builder.AddBranch(new StrictCompareInstr(
+                          TokenPosition::kNoSource, Token::kEQ_STRICT,
+                          new Value(v0), new Value(H.IntConstant(2)),
+                          /*needs_number_check=*/false, S.GetNextDeoptId()),
+                      b3, b4);
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b3);
+    builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b4);
+    builder.AddInstruction(new GotoInstr(b5, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b5);
+    v3 = H.Phi(b5, {{b3, H.IntConstant(42)}, {b4, H.IntConstant(24)}});
+    builder.AddPhi(v3);
+    builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b6);
+    builder.AddInstruction(new GotoInstr(b7, S.GetNextDeoptId()));
+  }
+
+  {
+    BlockBuilder builder(flow_graph, b7);
+    v5 = H.Phi(b7, {{b5, v3}, {b6, H.DoubleConstant(1.0)}});
+    builder.AddPhi(v5);
+    builder.AddInstruction(new ReturnInstr(TokenPosition::kNoSource,
+                                           new Value(v5), S.GetNextDeoptId()));
+  }
+
+  H.FinishGraph();
+
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  // We expect that v3 has an integer type, and v5 is either T{Object} or
+  // T{num}.
+  EXPECT_PROPERTY(v3->Type(), it.IsInt());
+  EXPECT_PROPERTY(v5->Type()->ToAbstractType(),
+                  it.IsObjectType() || it.IsNumberType());
+
+  // Now unbox v3 phi by inserting unboxing for both inputs and boxing
+  // for the result.
+  {
+    v3->set_representation(kUnboxedInt64);
+    for (intptr_t i = 0; i < v3->InputCount(); i++) {
+      auto input = v3->InputAt(i);
+      auto unbox =
+          new UnboxInt64Instr(input->CopyWithType(), S.GetNextDeoptId(),
+                              Instruction::kNotSpeculative);
+      flow_graph->InsertBefore(
+          v3->block()->PredecessorAt(i)->last_instruction(), unbox, nullptr,
+          FlowGraph::kValue);
+      input->BindTo(unbox);
+    }
+
+    auto box = new BoxInt64Instr(new Value(v3));
+    v3->ReplaceUsesWith(box);
+    flow_graph->InsertBefore(b4->last_instruction(), box, nullptr,
+                             FlowGraph::kValue);
+  }
+
+  // Run type propagation again.
+  FlowGraphTypePropagator::Propagate(flow_graph);
+
+  // If CompileType of v3 would be cached as a reaching type at its use in
+  // v5 then we will be incorrect type propagation results.
+  // We expect that v3 has an integer type, and v5 is either T{Object} or
+  // T{num}.
+  EXPECT_PROPERTY(v3->Type(), it.IsInt());
+  EXPECT_PROPERTY(v5->Type()->ToAbstractType(),
+                  it.IsObjectType() || it.IsNumberType());
+}
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/backend/typed_data_aot_test.cc b/runtime/vm/compiler/backend/typed_data_aot_test.cc
new file mode 100644
index 0000000..65156bf
--- /dev/null
+++ b/runtime/vm/compiler/backend/typed_data_aot_test.cc
@@ -0,0 +1,450 @@
+// 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.
+
+#include <vector>
+
+#include "vm/compiler/backend/il_printer.h"
+#include "vm/compiler/backend/il_test_helper.h"
+#include "vm/compiler/call_specializer.h"
+#include "vm/compiler/compiler_pass.h"
+#include "vm/object.h"
+#include "vm/unit_test.h"
+
+namespace dart {
+
+#if defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC)
+
+// This test asserts that we are inlining accesses to typed data interfaces
+// (e.g. Uint8List) if there are no instantiated 3rd party classes.
+ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_Inlining) {
+  const char* kScript =
+      R"(
+      import 'dart:typed_data';
+
+      void foo(Uint8List list, int from) {
+        if (from >= list.length) {
+          list[from];
+        }
+      }
+      )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+
+  CheckNullInstr* check_null = nullptr;
+  LoadFieldInstr* load_field = nullptr;
+  GenericCheckBoundInstr* bounds_check = nullptr;
+  Instruction* load_untagged = nullptr;
+  LoadIndexedInstr* load_indexed = nullptr;
+
+  ILMatcher cursor(flow_graph, entry);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      {kMatchAndMoveCheckNull, &check_null},
+      {kMatchAndMoveLoadField, &load_field},
+      kMoveGlob,
+      kMatchAndMoveBranchTrue,
+      kMoveGlob,
+      {kMatchAndMoveGenericCheckBound, &bounds_check},
+      {kMatchAndMoveLoadUntagged, &load_untagged},
+      kMoveParallelMoves,
+      {kMatchAndMoveLoadIndexed, &load_indexed},
+      kMoveGlob,
+      kMatchReturn,
+  }));
+
+  EXPECT(load_field->InputAt(0)->definition()->IsParameter());
+  EXPECT(bounds_check->InputAt(0)->definition() == load_field);
+  EXPECT(load_untagged->InputAt(0)->definition()->IsParameter());
+  EXPECT(load_indexed->InputAt(0)->definition() == load_untagged);
+}
+
+// This test asserts that we are not inlining accesses to typed data interfaces
+// (e.g. Uint8List) if there are instantiated 3rd party classes (e.g.
+// UnmodifiableUint8ListView).
+ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_NotInlining) {
+  const char* kScript =
+      R"(
+      import 'dart:typed_data';
+
+      createThirdPartyUint8List() => UnmodifiableUint8ListView(Uint8List(10));
+
+      void foo(Uint8List list, int from) {
+        if (from >= list.length) {
+          list[from];
+        }
+      }
+      )";
+
+  const auto& root_library = Library::Handle(LoadTestScript(kScript));
+
+  // Firstly we ensure a non internal/external/view Uint8List is allocated.
+  Invoke(root_library, "createThirdPartyUint8List");
+
+  // Now we ensure that we don't perform the inlining of the `list[from]`
+  // access.
+  const auto& function = Function::Handle(GetFunction(root_library, "foo"));
+  TestPipeline pipeline(function, CompilerPass::kAOT);
+  FlowGraph* flow_graph = pipeline.RunPasses({});
+
+  auto entry = flow_graph->graph_entry()->normal_entry();
+  EXPECT(entry != nullptr);
+
+  InstanceCallInstr* length_call = nullptr;
+  PushArgumentInstr* pusharg1 = nullptr;
+  PushArgumentInstr* pusharg2 = nullptr;
+  InstanceCallInstr* index_get_call = nullptr;
+
+  ILMatcher cursor(flow_graph, entry);
+  RELEASE_ASSERT(cursor.TryMatch({
+      kMoveGlob,
+      {kMatchAndMoveInstanceCall, &length_call},
+      kMoveGlob,
+      kMatchAndMoveBranchTrue,
+      kMoveGlob,
+      {kMatchAndMovePushArgument, &pusharg1},
+      {kMatchAndMovePushArgument, &pusharg2},
+      {kMatchAndMoveInstanceCall, &index_get_call},
+      kMoveGlob,
+      kMatchReturn,
+  }));
+
+  EXPECT(length_call->Selector() == Symbols::GetLength().raw());
+  EXPECT(pusharg1->InputAt(0)->definition()->IsParameter());
+  EXPECT(pusharg2->InputAt(0)->definition()->IsParameter());
+  EXPECT(index_get_call->Selector() == Symbols::IndexToken().raw());
+}
+
+// This test asserts that we are inlining get:length, [] and []= for all typed
+// data interfaces.  It also ensures that the asserted IR actually works by
+// exercising it.
+ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalGetSet) {
+  const char* kTemplate =
+      R"(
+      import 'dart:typed_data';
+
+      void reverse%s(%s list) {
+        final length = list.length;
+        final halfLength = length ~/ 2;
+        for (int i = 0; i < halfLength; ++i) {
+          final tmp = list[length-i-1];
+          list[length-i-1] = list[i];
+          list[i] = tmp;
+        }
+      }
+      )";
+
+  std::initializer_list<MatchCode> expected_il = {
+      // Before loop
+      kMoveGlob,
+      kMatchAndMoveCheckNull,
+      kMatchAndMoveLoadField,
+      kMoveGlob,
+      kMatchAndMoveBranchTrue,
+
+      // Loop
+      kMoveGlob,
+      // Load 1
+      kMatchAndMoveGenericCheckBound,
+      kMoveGlob,
+      kMatchAndMoveLoadUntagged,
+      kMoveParallelMoves,
+      kMatchAndMoveLoadIndexed,
+      kMoveGlob,
+      // Load 2
+      kMatchAndMoveGenericCheckBound,
+      kMoveGlob,
+      kMatchAndMoveLoadUntagged,
+      kMoveParallelMoves,
+      kMatchAndMoveLoadIndexed,
+      kMoveGlob,
+      // Store 1
+      kMatchAndMoveGenericCheckBound,
+      kMoveGlob,
+      kMoveParallelMoves,
+      kMatchAndMoveLoadUntagged,
+      kMoveParallelMoves,
+      kMatchAndMoveStoreIndexed,
+      kMoveGlob,
+      // Store 2
+      kMoveParallelMoves,
+      kMatchAndMoveLoadUntagged,
+      kMoveParallelMoves,
+      kMatchAndMoveStoreIndexed,
+      kMoveGlob,
+
+      // Exit the loop.
+      kMatchAndMoveBranchFalse,
+      kMoveGlob,
+      kMatchReturn,
+  };
+
+  char script_buffer[1024];
+  char uri_buffer[1024];
+  char function_name[1024];
+  auto& lib = Library::Handle();
+  auto& function = Function::Handle();
+  auto& view = TypedDataView::Handle();
+  auto& arguments = Array::Handle();
+  auto& result = Object::Handle();
+
+  auto run_reverse_list = [&](const char* name, const TypedDataBase& data) {
+    // Fill in the template with the [name].
+    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name);
+    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///reverse-%s.dart",
+                   name);
+    Utils::SNPrint(function_name, sizeof(function_name), "reverse%s", name);
+
+    // Create a new library, load the function and compile it using our AOT
+    // pipeline.
+    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
+    function = GetFunction(lib, function_name);
+    TestPipeline pipeline(function, CompilerPass::kAOT);
+    FlowGraph* flow_graph = pipeline.RunPasses({});
+    auto entry = flow_graph->graph_entry()->normal_entry();
+
+    // Ensure the IL matches what we expect.
+    ILMatcher cursor(flow_graph, entry);
+    EXPECT(cursor.TryMatch(expected_il));
+
+    // Compile the graph and attach the code.
+    pipeline.CompileGraphAndAttachFunction();
+
+    // Class ids are numbered from internal/view/external.
+    const classid_t view_cid = data.GetClassId() + 1;
+    ASSERT(RawObject::IsTypedDataViewClassId(view_cid));
+
+    // First and last element are not in the view, i.e.
+    //    view[0:view.length()-1] = data[1:data.length()-2]
+    const intptr_t length_in_bytes =
+        (data.LengthInBytes() - 2 * data.ElementSizeInBytes());
+    view = TypedDataView::New(view_cid, data, data.ElementSizeInBytes(),
+                              length_in_bytes / data.ElementSizeInBytes());
+    ASSERT(data.ElementType() == view.ElementType());
+
+    arguments = Array::New(1);
+    arguments.SetAt(0, view);
+    result = DartEntry::InvokeFunction(function, arguments);
+    EXPECT(result.IsNull());
+
+    // Ensure we didn't deoptimize to unoptimized code.
+    EXPECT(function.unoptimized_code() == Code::null());
+  };
+
+  const auto& uint8_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
+  const auto& uint8c_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
+  const auto& int16_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
+  const auto& uint16_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
+  const auto& int32_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
+  const auto& uint32_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
+  const auto& int64_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
+  const auto& uint64_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
+  const auto& float32_list =
+      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
+  const auto& float64_list =
+      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
+  const auto& int8_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
+  for (intptr_t i = 0; i < 16; ++i) {
+    int8_list.SetInt8(i, i);
+    uint8_list.SetUint8(i, i);
+    uint8c_list.SetUint8(i, i);
+    int16_list.SetInt16(2 * i, i);
+    uint16_list.SetUint16(2 * i, i);
+    int32_list.SetInt32(4 * i, i);
+    uint32_list.SetUint32(4 * i, i);
+    int64_list.SetInt64(8 * i, i);
+    uint64_list.SetUint64(8 * i, i);
+    float32_list.SetFloat32(4 * i, i + 0.5);
+    float64_list.SetFloat64(8 * i, i + 0.7);
+  }
+  run_reverse_list("Uint8List", int8_list);
+  run_reverse_list("Int8List", uint8_list);
+  run_reverse_list("Uint8ClampedList", uint8c_list);
+  run_reverse_list("Int16List", int16_list);
+  run_reverse_list("Uint16List", uint16_list);
+  run_reverse_list("Int32List", int32_list);
+  run_reverse_list("Uint32List", uint32_list);
+  run_reverse_list("Int64List", int64_list);
+  run_reverse_list("Uint64List", uint64_list);
+  run_reverse_list("Float32List", float32_list);
+  run_reverse_list("Float64List", float64_list);
+  for (intptr_t i = 0; i < 16; ++i) {
+    // Only the values in the view are reversed.
+    const bool in_view = i >= 1 && i < 15;
+
+    const int64_t expected_value = in_view ? (16 - i - 1) : i;
+    const uint64_t expected_uvalue = in_view ? (16 - i - 1) : i;
+    const float expected_fvalue = (in_view ? (16 - i - 1) : i) + 0.5;
+    const double expected_dvalue = (in_view ? (16 - i - 1) : i) + 0.7;
+
+    EXPECT(int8_list.GetInt8(i) == expected_value);
+    EXPECT(uint8_list.GetUint8(i) == expected_uvalue);
+    EXPECT(uint8c_list.GetUint8(i) == expected_uvalue);
+    EXPECT(int16_list.GetInt16(2 * i) == expected_value);
+    EXPECT(uint16_list.GetUint16(2 * i) == expected_uvalue);
+    EXPECT(int32_list.GetInt32(4 * i) == expected_value);
+    EXPECT(uint32_list.GetUint32(4 * i) == expected_uvalue);
+    EXPECT(int64_list.GetInt64(8 * i) == expected_value);
+    EXPECT(uint64_list.GetUint64(8 * i) == expected_uvalue);
+    EXPECT(float32_list.GetFloat32(4 * i) == expected_fvalue);
+    EXPECT(float64_list.GetFloat64(8 * i) == expected_dvalue);
+  }
+}
+
+// This test asserts that we get errors if receiver, index or value are null.
+ISOLATE_UNIT_TEST_CASE(IRTest_TypedDataAOT_FunctionalIndexError) {
+  const char* kTemplate =
+      R"(
+      import 'dart:typed_data';
+      void set%s(%s list, int index, %s value) {
+        list[index] = value;
+      }
+      )";
+
+  std::initializer_list<MatchCode> expected_il = {
+      // Receiver null check
+      kMoveGlob,
+      kMatchAndMoveCheckNull,
+
+      // Index null check
+      kMoveGlob,
+      kMatchAndMoveCheckNull,
+
+      // Value null check
+      kMoveGlob,
+      kMatchAndMoveCheckNull,
+
+      // LoadField length
+      kMoveGlob,
+      kMatchAndMoveLoadField,
+
+      // Bounds check
+      kMoveGlob,
+      kMatchAndMoveGenericCheckBound,
+
+      // Store value.
+      kMoveGlob,
+      kMatchAndMoveLoadUntagged,
+      kMoveParallelMoves,
+      kMatchAndMoveOptionalUnbox,
+      kMoveParallelMoves,
+      kMatchAndMoveStoreIndexed,
+
+      // Return
+      kMoveGlob,
+      kMatchReturn,
+  };
+
+  char script_buffer[1024];
+  char uri_buffer[1024];
+  char function_name[1024];
+  auto& lib = Library::Handle();
+  auto& function = Function::Handle();
+  auto& arguments = Array::Handle();
+  auto& result = Object::Handle();
+
+  const intptr_t kIndex = 1;
+  const intptr_t kLastStage = 3;
+
+  auto run_test = [&](const char* name, const char* type,
+                      const TypedDataBase& data, const Object& value,
+                      int stage) {
+    // Fill in the template with the [name].
+    Utils::SNPrint(script_buffer, sizeof(script_buffer), kTemplate, name, name,
+                   type);
+    Utils::SNPrint(uri_buffer, sizeof(uri_buffer), "file:///set-%s.dart", name);
+    Utils::SNPrint(function_name, sizeof(function_name), "set%s", name);
+
+    // Create a new library, load the function and compile it using our AOT
+    // pipeline.
+    lib = LoadTestScript(script_buffer, nullptr, uri_buffer);
+    function = GetFunction(lib, function_name);
+    TestPipeline pipeline(function, CompilerPass::kAOT);
+    FlowGraph* flow_graph = pipeline.RunPasses({});
+    auto entry = flow_graph->graph_entry()->normal_entry();
+
+    // Ensure the IL matches what we expect.
+    ILMatcher cursor(flow_graph, entry, /*trace=*/true);
+    EXPECT(cursor.TryMatch(expected_il));
+
+    // Compile the graph and attach the code.
+    pipeline.CompileGraphAndAttachFunction();
+
+    arguments = Array::New(3);
+    arguments.SetAt(0, stage == 0 ? Object::null_object() : data);
+    arguments.SetAt(
+        1, stage == 1 ? Object::null_object() : Smi::Handle(Smi::New(kIndex)));
+    arguments.SetAt(2, stage == 2 ? Object::null_object() : value);
+    result = DartEntry::InvokeFunction(function, arguments);
+
+    // Ensure we didn't deoptimize to unoptimized code.
+    EXPECT(function.unoptimized_code() == Code::null());
+
+    if (stage == kLastStage) {
+      // The last stage must be successful
+      EXPECT(result.IsNull());
+    } else {
+      // Ensure we get an error.
+      EXPECT(result.IsUnhandledException());
+      result = UnhandledException::Cast(result).exception();
+    }
+  };
+
+  const auto& uint8_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint8ArrayCid, 16));
+  const auto& uint8c_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint8ClampedArrayCid, 16));
+  const auto& int16_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt16ArrayCid, 16));
+  const auto& uint16_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint16ArrayCid, 16));
+  const auto& int32_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt32ArrayCid, 16));
+  const auto& uint32_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint32ArrayCid, 16));
+  const auto& int64_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt64ArrayCid, 16));
+  const auto& uint64_list =
+      TypedData::Handle(TypedData::New(kTypedDataUint64ArrayCid, 16));
+  const auto& float32_list =
+      TypedData::Handle(TypedData::New(kTypedDataFloat32ArrayCid, 16));
+  const auto& float64_list =
+      TypedData::Handle(TypedData::New(kTypedDataFloat64ArrayCid, 16));
+  const auto& int8_list =
+      TypedData::Handle(TypedData::New(kTypedDataInt8ArrayCid, 16));
+  const auto& int_value = Integer::Handle(Integer::New(42));
+  const auto& float_value = Double::Handle(Double::New(4.2));
+  for (intptr_t stage = 0; stage <= kLastStage; ++stage) {
+    run_test("Uint8List", "int", int8_list, int_value, stage);
+    run_test("Int8List", "int", uint8_list, int_value, stage);
+    run_test("Uint8ClampedList", "int", uint8c_list, int_value, stage);
+    run_test("Int16List", "int", int16_list, int_value, stage);
+    run_test("Uint16List", "int", uint16_list, int_value, stage);
+    run_test("Int32List", "int", int32_list, int_value, stage);
+    run_test("Uint32List", "int", uint32_list, int_value, stage);
+    run_test("Int64List", "int", int64_list, int_value, stage);
+    run_test("Uint64List", "int", uint64_list, int_value, stage);
+    run_test("Float32List", "double", float32_list, float_value, stage);
+    run_test("Float64List", "double", float64_list, float_value, stage);
+  }
+}
+
+#endif  // defined(DART_PRECOMPILER) && !defined(TARGET_ARCH_DBC)
+
+}  // namespace dart
diff --git a/runtime/vm/compiler/call_specializer.cc b/runtime/vm/compiler/call_specializer.cc
index d5a4c2d..c141850 100644
--- a/runtime/vm/compiler/call_specializer.cc
+++ b/runtime/vm/compiler/call_specializer.cc
@@ -17,6 +17,13 @@
 #define I (isolate())
 #define Z (zone())
 
+static void RefineUseTypes(Definition* instr) {
+  CompileType* new_type = instr->Type();
+  for (Value::Iterator it(instr->input_use_list()); !it.Done(); it.Advance()) {
+    it.Current()->RefineReachingType(new_type);
+  }
+}
+
 static bool ShouldInlineSimd() {
   return FlowGraphCompiler::SupportsUnboxedSimd128();
 }
@@ -921,7 +928,7 @@
   if (load->slot().nullable_cid() != kDynamicCid) {
     // Reset value types if we know concrete cid.
     for (Value::Iterator it(load->input_use_list()); !it.Done(); it.Advance()) {
-      it.Current()->SetReachingType(NULL);
+      it.Current()->SetReachingType(nullptr);
     }
   }
 }
@@ -1626,5 +1633,261 @@
   return true;  // May deoptimize since we have not identified all 'true' tests.
 }
 
+void TypedDataSpecializer::Optimize(FlowGraph* flow_graph) {
+  TypedDataSpecializer optimizer(flow_graph);
+  optimizer.VisitBlocks();
+}
+
+void TypedDataSpecializer::EnsureIsInitialized() {
+  if (initialized_) return;
+
+  initialized_ = true;
+
+  int_type_ = Type::IntType();
+  double_type_ = Type::Double();
+
+  const auto& typed_data = Library::Handle(
+      Z, Library::LookupLibrary(thread_, Symbols::DartTypedData()));
+
+  auto& td_class = Class::Handle(Z);
+  auto& direct_implementors = GrowableObjectArray::Handle(Z);
+
+#define INIT_HANDLE(iface, member_name, type, cid)                             \
+  td_class = typed_data.LookupClass(Symbols::iface());                         \
+  ASSERT(!td_class.IsNull());                                                  \
+  direct_implementors = td_class.direct_implementors();                        \
+  if (!HasThirdPartyImplementor(direct_implementors)) {                        \
+    member_name = td_class.RareType();                                         \
+  }
+
+  PUBLIC_TYPED_DATA_CLASS_LIST(INIT_HANDLE)
+#undef INIT_HANDLE
+}
+
+bool TypedDataSpecializer::HasThirdPartyImplementor(
+    const GrowableObjectArray& direct_implementors) {
+  // Check if there are non internal/external/view implementors.
+  for (intptr_t i = 0; i < direct_implementors.Length(); ++i) {
+    implementor_ ^= direct_implementors.At(i);
+
+    // We only consider [implementor_] a 3rd party implementor if it was
+    // finalized by the class finalizer, since only then can we have concrete
+    // instances of the [implementor_].
+    if (implementor_.is_finalized()) {
+      const classid_t cid = implementor_.id();
+      if (!RawObject::IsTypedDataClassId(cid) &&
+          !RawObject::IsTypedDataViewClassId(cid) &&
+          !RawObject::IsExternalTypedDataClassId(cid)) {
+        return true;
+      }
+    }
+  }
+  return false;
+}
+
+void TypedDataSpecializer::VisitInstanceCall(InstanceCallInstr* call) {
+  TryInlineCall(call);
+}
+
+void TypedDataSpecializer::VisitStaticCall(StaticCallInstr* call) {
+  TryInlineCall(call);
+}
+
+void TypedDataSpecializer::TryInlineCall(TemplateDartCall<0>* call) {
+  const bool is_length_getter = call->Selector() == Symbols::GetLength().raw();
+  const bool is_index_get = call->Selector() == Symbols::IndexToken().raw();
+  const bool is_index_set =
+      call->Selector() == Symbols::AssignIndexToken().raw();
+
+  if (is_length_getter || is_index_get || is_index_set) {
+    EnsureIsInitialized();
+
+    const intptr_t receiver_index = call->FirstArgIndex();
+
+    CompileType* receiver_type = call->ArgumentAt(receiver_index + 0)->Type();
+
+    CompileType* index_type = nullptr;
+    if (is_index_get || is_index_set) {
+      index_type = call->ArgumentAt(receiver_index + 1)->Type();
+    }
+
+    CompileType* value_type = nullptr;
+    if (is_index_set) {
+      value_type = call->ArgumentAt(receiver_index + 2)->Type();
+    }
+
+    auto& type_class = Class::Handle(zone_);
+#define TRY_INLINE(iface, member_name, type, cid)                              \
+  if (!member_name.IsNull()) {                                                 \
+    if (receiver_type->IsAssignableTo(member_name)) {                          \
+      if (is_length_getter) {                                                  \
+        type_class = member_name.type_class();                                 \
+        ReplaceWithLengthGetter(call);                                         \
+      } else if (is_index_get) {                                               \
+        if (!index_type->IsNullableInt()) return;                              \
+        type_class = member_name.type_class();                                 \
+        ReplaceWithIndexGet(call, cid);                                        \
+      } else {                                                                 \
+        if (!index_type->IsNullableInt()) return;                              \
+        if (!value_type->IsAssignableTo(type)) return;                         \
+        type_class = member_name.type_class();                                 \
+        ReplaceWithIndexSet(call, cid);                                        \
+      }                                                                        \
+      return;                                                                  \
+    }                                                                          \
+  }
+    PUBLIC_TYPED_DATA_CLASS_LIST(TRY_INLINE)
+#undef INIT_HANDLE
+  }
+}
+
+void TypedDataSpecializer::ReplaceWithLengthGetter(TemplateDartCall<0>* call) {
+  const intptr_t receiver_idx = call->FirstArgIndex();
+  auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition();
+
+  if (array->Type()->is_nullable()) {
+    AppendNullCheck(call, &array);
+  }
+  Definition* length = AppendLoadLength(call, array);
+  flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, length);
+  RefineUseTypes(length);
+}
+
+void TypedDataSpecializer::ReplaceWithIndexGet(TemplateDartCall<0>* call,
+                                               classid_t cid) {
+  const intptr_t receiver_idx = call->FirstArgIndex();
+  auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition();
+  auto index = call->PushArgumentAt(receiver_idx + 1)->value()->definition();
+
+  if (array->Type()->is_nullable()) {
+    AppendNullCheck(call, &array);
+  }
+  if (index->Type()->is_nullable()) {
+    AppendNullCheck(call, &index);
+  }
+  AppendBoundsCheck(call, array, &index);
+  Definition* value = AppendLoadIndexed(call, array, index, cid);
+  flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, value);
+  RefineUseTypes(value);
+}
+
+void TypedDataSpecializer::ReplaceWithIndexSet(TemplateDartCall<0>* call,
+                                               classid_t cid) {
+  const intptr_t receiver_idx = call->FirstArgIndex();
+  auto array = call->PushArgumentAt(receiver_idx + 0)->value()->definition();
+  auto index = call->PushArgumentAt(receiver_idx + 1)->value()->definition();
+  auto value = call->PushArgumentAt(receiver_idx + 2)->value()->definition();
+
+  if (array->Type()->is_nullable()) {
+    AppendNullCheck(call, &array);
+  }
+  if (index->Type()->is_nullable()) {
+    AppendNullCheck(call, &index);
+  }
+  if (value->Type()->is_nullable()) {
+    AppendNullCheck(call, &value);
+  }
+  AppendBoundsCheck(call, array, &index);
+  AppendStoreIndexed(call, array, index, value, cid);
+
+  RELEASE_ASSERT(!call->HasUses());
+  flow_graph_->ReplaceCurrentInstruction(current_iterator(), call, nullptr);
+}
+
+void TypedDataSpecializer::AppendNullCheck(TemplateDartCall<0>* call,
+                                           Definition** value) {
+  auto check =
+      new (Z) CheckNullInstr(new (Z) Value(*value), Symbols::OptimizedOut(),
+                             call->deopt_id(), call->token_pos());
+  flow_graph_->InsertBefore(call, check, call->env(), FlowGraph::kValue);
+
+  // Use data dependency as control dependency.
+  *value = check;
+}
+
+void TypedDataSpecializer::AppendBoundsCheck(TemplateDartCall<0>* call,
+                                             Definition* array,
+                                             Definition** index) {
+  auto length = new (Z) LoadFieldInstr(
+      new (Z) Value(array), Slot::TypedDataBase_length(), call->token_pos());
+  flow_graph_->InsertBefore(call, length, call->env(), FlowGraph::kValue);
+
+  auto check = new (Z) GenericCheckBoundInstr(
+      new (Z) Value(length), new (Z) Value(*index), DeoptId::kNone);
+  flow_graph_->InsertBefore(call, check, call->env(), FlowGraph::kValue);
+
+  // Use data dependency as control dependency.
+  *index = check;
+}
+
+Definition* TypedDataSpecializer::AppendLoadLength(TemplateDartCall<0>* call,
+                                                   Definition* array) {
+  auto length = new (Z) LoadFieldInstr(
+      new (Z) Value(array), Slot::TypedDataBase_length(), call->token_pos());
+  flow_graph_->InsertBefore(call, length, call->env(), FlowGraph::kValue);
+  return length;
+}
+
+Definition* TypedDataSpecializer::AppendLoadIndexed(TemplateDartCall<0>* call,
+                                                    Definition* array,
+                                                    Definition* index,
+                                                    classid_t cid) {
+  const intptr_t element_size = TypedDataBase::ElementSizeFor(cid);
+  const intptr_t index_scale = element_size;
+
+  auto data = new (Z) LoadUntaggedInstr(new (Z) Value(array),
+                                        TypedDataBase::data_field_offset());
+  flow_graph_->InsertBefore(call, data, call->env(), FlowGraph::kValue);
+
+  Definition* load = new (Z)
+      LoadIndexedInstr(new (Z) Value(data), new (Z) Value(index), index_scale,
+                       cid, kAlignedAccess, DeoptId::kNone, call->token_pos());
+  flow_graph_->InsertBefore(call, load, call->env(), FlowGraph::kValue);
+
+  if (cid == kTypedDataFloat32ArrayCid) {
+    load = new (Z) FloatToDoubleInstr(new (Z) Value(load), call->deopt_id());
+    flow_graph_->InsertBefore(call, load, call->env(), FlowGraph::kValue);
+  }
+
+  return load;
+}
+
+void TypedDataSpecializer::AppendStoreIndexed(TemplateDartCall<0>* call,
+                                              Definition* array,
+                                              Definition* index,
+                                              Definition* value,
+                                              classid_t cid) {
+  const intptr_t element_size = TypedDataBase::ElementSizeFor(cid);
+  const intptr_t index_scale = element_size;
+
+  const auto deopt_id = call->deopt_id();
+
+  if (cid == kTypedDataFloat32ArrayCid) {
+    value = new (Z) DoubleToFloatInstr(new (Z) Value(value), deopt_id,
+                                       Instruction::kNotSpeculative);
+    flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue);
+  } else if (cid == kTypedDataInt32ArrayCid) {
+    value = new (Z)
+        UnboxInt32Instr(UnboxInt32Instr::kTruncate, new (Z) Value(value),
+                        deopt_id, Instruction::kNotSpeculative);
+    flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue);
+  } else if (cid == kTypedDataUint32ArrayCid) {
+    value = new (Z) UnboxUint32Instr(new (Z) Value(value), deopt_id,
+                                     Instruction::kNotSpeculative);
+    ASSERT(value->AsUnboxInteger()->is_truncating());
+    flow_graph_->InsertBefore(call, value, call->env(), FlowGraph::kValue);
+  }
+
+  auto data = new (Z) LoadUntaggedInstr(new (Z) Value(array),
+                                        TypedDataBase::data_field_offset());
+  flow_graph_->InsertBefore(call, data, call->env(), FlowGraph::kValue);
+
+  auto store = new (Z) StoreIndexedInstr(
+      new (Z) Value(data), new (Z) Value(index), new (Z) Value(value),
+      kNoStoreBarrier, index_scale, cid, kAlignedAccess, DeoptId::kNone,
+      call->token_pos(), Instruction::kNotSpeculative);
+  flow_graph_->InsertBefore(call, store, call->env(), FlowGraph::kEffect);
+}
+
 }  // namespace dart
 #endif  // DART_PRECOMPILED_RUNTIME
diff --git a/runtime/vm/compiler/call_specializer.h b/runtime/vm/compiler/call_specializer.h
index cb9ca8c..e9a0a6d 100644
--- a/runtime/vm/compiler/call_specializer.h
+++ b/runtime/vm/compiler/call_specializer.h
@@ -178,6 +178,106 @@
   FlowGraph* flow_graph_;
 };
 
+#define PUBLIC_TYPED_DATA_CLASS_LIST(V)                                        \
+  V(Int8List, int8_list_type_, int_type_, kTypedDataInt8ArrayCid)              \
+  V(Uint8List, uint8_list_type_, int_type_, kTypedDataUint8ArrayCid)           \
+  V(Uint8ClampedList, uint8_clamped_type_, int_type_,                          \
+    kTypedDataUint8ClampedArrayCid)                                            \
+  V(Int16List, int16_list_type_, int_type_, kTypedDataInt16ArrayCid)           \
+  V(Uint16List, uint16_list_type_, int_type_, kTypedDataUint16ArrayCid)        \
+  V(Int32List, int32_list_type_, int_type_, kTypedDataInt32ArrayCid)           \
+  V(Uint32List, uint32_list_type_, int_type_, kTypedDataUint32ArrayCid)        \
+  V(Int64List, int64_list_type_, int_type_, kTypedDataInt64ArrayCid)           \
+  V(Uint64List, uint64_list_type_, int_type_, kTypedDataUint64ArrayCid)        \
+  V(Float32List, float32_list_type_, double_type_, kTypedDataFloat32ArrayCid)  \
+  V(Float64List, float64_list_type_, double_type_, kTypedDataFloat64ArrayCid)
+
+// Specializes instance/static calls with receiver type being a typed data
+// interface (if that interface is only implemented by internal/external/view
+// typed data classes).
+//
+// For example:
+//
+//    foo(Uint8List bytes) => bytes[0];
+//
+// Would be translated to something like this:
+//
+//    v0 <- Constant(0)
+//
+//    // Ensures the list is non-null.
+//    v1 <- ParameterInstr(0)
+//    v2 <- CheckNull(v1)
+//
+//    // Load the length & perform bounds checks
+//    v3 <- LoadField(v2, "TypedDataBase.length");
+//    v4 <- GenericCheckBounds(v3, v0);
+//
+//    // Directly access the byte, independent of whether `bytes` is
+//    // _Uint8List, _Uint8ArrayView or _ExternalUint8Array.
+//    v5 <- LoadUntagged(v1, "TypedDataBase.data");
+//    v5 <- LoadIndexed(v5, v4)
+//
+class TypedDataSpecializer : public FlowGraphVisitor {
+ public:
+  static void Optimize(FlowGraph* flow_graph);
+
+  virtual void VisitInstanceCall(InstanceCallInstr* instr);
+  virtual void VisitStaticCall(StaticCallInstr* instr);
+
+ private:
+  // clang-format off
+  explicit TypedDataSpecializer(FlowGraph* flow_graph)
+      : FlowGraphVisitor(flow_graph->reverse_postorder()),
+        thread_(Thread::Current()),
+        zone_(thread_->zone()),
+        flow_graph_(flow_graph),
+#define ALLOCATE_HANDLE(iface, member_name, type, cid)                         \
+        member_name(AbstractType::Handle(zone_)),
+        PUBLIC_TYPED_DATA_CLASS_LIST(ALLOCATE_HANDLE)
+#undef INIT_HANDLE
+        int_type_(AbstractType::Handle()),
+        double_type_(AbstractType::Handle()),
+        implementor_(Class::Handle()) {
+  }
+  // clang-format on
+
+  void EnsureIsInitialized();
+  bool HasThirdPartyImplementor(const GrowableObjectArray& direct_implementors);
+  void TryInlineCall(TemplateDartCall<0>* call);
+  void ReplaceWithLengthGetter(TemplateDartCall<0>* call);
+  void ReplaceWithIndexGet(TemplateDartCall<0>* call, classid_t cid);
+  void ReplaceWithIndexSet(TemplateDartCall<0>* call, classid_t cid);
+  void AppendNullCheck(TemplateDartCall<0>* call, Definition** array);
+  void AppendBoundsCheck(TemplateDartCall<0>* call,
+                         Definition* array,
+                         Definition** index);
+  Definition* AppendLoadLength(TemplateDartCall<0>* call, Definition* array);
+  Definition* AppendLoadIndexed(TemplateDartCall<0>* call,
+                                Definition* array,
+                                Definition* index,
+                                classid_t cid);
+  void AppendStoreIndexed(TemplateDartCall<0>* call,
+                          Definition* array,
+                          Definition* index,
+                          Definition* value,
+                          classid_t cid);
+
+  Zone* zone() const { return zone_; }
+
+  Thread* thread_;
+  Zone* zone_;
+  FlowGraph* flow_graph_;
+  bool initialized_ = false;
+
+#define DEF_HANDLE(iface, member_name, type, cid) AbstractType& member_name;
+  PUBLIC_TYPED_DATA_CLASS_LIST(DEF_HANDLE)
+#undef DEF_HANDLE
+
+  AbstractType& int_type_;
+  AbstractType& double_type_;
+  Class& implementor_;
+};
+
 }  // namespace dart
 
 #endif  // RUNTIME_VM_COMPILER_CALL_SPECIALIZER_H_
diff --git a/runtime/vm/compiler/compiler_pass.cc b/runtime/vm/compiler/compiler_pass.cc
index 9303066..3e08c06 100644
--- a/runtime/vm/compiler/compiler_pass.cc
+++ b/runtime/vm/compiler/compiler_pass.cc
@@ -241,6 +241,9 @@
     // unreachable code.
     INVOKE_PASS(ApplyICData);
   }
+  if (mode == kAOT) {
+    INVOKE_PASS(OptimizeTypedDataAccesses);
+  }
 #endif
   INVOKE_PASS(WidenSmiToInt32);
   INVOKE_PASS(SelectRepresentations);
@@ -270,6 +273,14 @@
   INVOKE_PASS(ReorderBlocks);
 }
 
+void CompilerPass::RunPipelineWithPasses(
+    CompilerPassState* state,
+    std::initializer_list<CompilerPass::Id> passes) {
+  for (auto pass_id : passes) {
+    passes_[pass_id]->Run(state);
+  }
+}
+
 COMPILER_PASS(ComputeSSA, {
   // Transform to SSA (virtual register 0 and no inlining arguments).
   flow_graph->ComputeSSA(0, NULL);
@@ -363,6 +374,9 @@
   ConstantPropagator::OptimizeBranches(flow_graph);
 });
 
+COMPILER_PASS(OptimizeTypedDataAccesses,
+              { TypedDataSpecializer::Optimize(flow_graph); });
+
 COMPILER_PASS(TryCatchOptimization, {
   OptimizeCatchEntryStates(flow_graph, /*is_aot=*/FLAG_precompiled_mode);
 });
diff --git a/runtime/vm/compiler/compiler_pass.h b/runtime/vm/compiler/compiler_pass.h
index 044ae6e..e5aa823 100644
--- a/runtime/vm/compiler/compiler_pass.h
+++ b/runtime/vm/compiler/compiler_pass.h
@@ -7,6 +7,8 @@
 
 #ifndef DART_PRECOMPILED_RUNTIME
 
+#include <initializer_list>
+
 #include "vm/growable_array.h"
 #include "vm/token_position.h"
 #include "vm/zone.h"
@@ -34,6 +36,7 @@
   V(LICM)                                                                      \
   V(OptimisticallySpecializeSmiPhis)                                           \
   V(OptimizeBranches)                                                          \
+  V(OptimizeTypedDataAccesses)                                                 \
   V(RangeAnalysis)                                                             \
   V(ReorderBlocks)                                                             \
   V(SelectRepresentations)                                                     \
@@ -141,6 +144,10 @@
 
   static void RunPipeline(PipelineMode mode, CompilerPassState* state);
 
+  static void RunPipelineWithPasses(
+      CompilerPassState* state,
+      std::initializer_list<CompilerPass::Id> passes);
+
  protected:
   // This function executes the pass. If it returns true then
   // we will run Canonicalize on the graph and execute the pass
diff --git a/runtime/vm/compiler/compiler_sources.gni b/runtime/vm/compiler/compiler_sources.gni
index ff5b6ed..f388295 100644
--- a/runtime/vm/compiler/compiler_sources.gni
+++ b/runtime/vm/compiler/compiler_sources.gni
@@ -37,6 +37,7 @@
   "assembler/disassembler_kbc.h",
   "assembler/disassembler_x86.cc",
   "assembler/object_pool_builder.h",
+  "backend/block_builder.h",
   "backend/block_scheduler.cc",
   "backend/block_scheduler.h",
   "backend/branch_optimizer.cc",
@@ -154,10 +155,14 @@
   "assembler/assembler_x64_test.cc",
   "assembler/disassembler_test.cc",
   "backend/il_test.cc",
+  "backend/il_test_helper.h",
+  "backend/il_test_helper.cc",
   "backend/locations_helpers_test.cc",
   "backend/loops_test.cc",
   "backend/range_analysis_test.cc",
   "backend/redundancy_elimination_test.cc",
   "backend/slot_test.cc",
+  "backend/type_propagator_test.cc",
+  "backend/typed_data_aot_test.cc",
   "cha_test.cc",
 ]
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index c6df1ea..0b6878c 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -7,6 +7,7 @@
 #include "vm/compiler/frontend/flow_graph_builder.h"  // For InlineExitCollector.
 #include "vm/compiler/jit/compiler.h"  // For Compiler::IsBackgroundCompilation().
 #include "vm/compiler/runtime_api.h"
+#include "vm/object_store.h"
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
 
@@ -406,10 +407,7 @@
 Fragment BaseFlowGraphBuilder::PushArgument() {
   PushArgumentInstr* argument = new (Z) PushArgumentInstr(Pop());
   Push(argument);
-
-  argument->set_temp_index(argument->temp_index() - 1);
   ++pending_argument_count_;
-
   return Fragment(argument);
 }
 
@@ -549,7 +547,7 @@
 LocalVariable* BaseFlowGraphBuilder::MakeTemporary() {
   char name[64];
   intptr_t index = stack_->definition()->temp_index();
-  Utils::SNPrint(name, 64, ":temp%" Pd, index);
+  Utils::SNPrint(name, 64, ":t%" Pd, index);
   const String& symbol_name =
       String::ZoneHandle(Z, Symbols::New(thread_, name));
   LocalVariable* variable =
@@ -557,8 +555,8 @@
                             symbol_name, Object::dynamic_type());
   // Set the index relative to the base of the expression stack including
   // outgoing arguments.
-  variable->set_index(VariableIndex(-parsed_function_->num_stack_locals() -
-                                    pending_argument_count_ - index));
+  variable->set_index(
+      VariableIndex(-parsed_function_->num_stack_locals() - index));
 
   // The value has uses as if it were a local variable.  Mark the definition
   // as used so that its temp index will not be cleared (causing it to never
@@ -688,8 +686,10 @@
   return Fragment(instr);
 }
 
-Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(intptr_t offset) {
-  LoadIndexedUnsafeInstr* instr = new (Z) LoadIndexedUnsafeInstr(Pop(), offset);
+Fragment BaseFlowGraphBuilder::LoadFpRelativeSlot(intptr_t offset,
+                                                  CompileType result_type) {
+  LoadIndexedUnsafeInstr* instr =
+      new (Z) LoadIndexedUnsafeInstr(Pop(), offset, result_type);
   Push(instr);
   return Fragment(instr);
 }
@@ -738,6 +738,18 @@
   return Fragment(allocate);
 }
 
+Fragment BaseFlowGraphBuilder::AllocateClosure(
+    TokenPosition position,
+    const Function& closure_function) {
+  const Class& cls = Class::ZoneHandle(Z, I->object_store()->closure_class());
+  ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0);
+  AllocateObjectInstr* allocate =
+      new (Z) AllocateObjectInstr(position, cls, arguments);
+  allocate->set_closure_function(closure_function);
+  Push(allocate);
+  return Fragment(allocate);
+}
+
 Fragment BaseFlowGraphBuilder::CreateArray() {
   Value* element_count = Pop();
   CreateArrayInstr* array =
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index 21fb118..5eb086b 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -212,7 +212,7 @@
   Fragment NullConstant();
   Fragment SmiRelationalOp(Token::Kind kind);
   Fragment SmiBinaryOp(Token::Kind op, bool is_truncating = false);
-  Fragment LoadFpRelativeSlot(intptr_t offset);
+  Fragment LoadFpRelativeSlot(intptr_t offset, CompileType result_type);
   Fragment StoreFpRelativeSlot(intptr_t offset);
   Fragment BranchIfTrue(TargetEntryInstr** then_entry,
                         TargetEntryInstr** otherwise_entry,
@@ -271,6 +271,8 @@
   Fragment AssertBool(TokenPosition position);
   Fragment BooleanNegate();
   Fragment AllocateContext(const GrowableArray<LocalVariable*>& scope);
+  Fragment AllocateClosure(TokenPosition position,
+                           const Function& closure_function);
   Fragment CreateArray();
   Fragment InstantiateType(const AbstractType& type);
   Fragment InstantiateTypeArguments(const TypeArguments& type_arguments);
@@ -280,6 +282,11 @@
   // enters the function through the unchecked entry.
   bool InliningUncheckedEntry() const { return inlining_unchecked_entry_; }
 
+  // Returns depth of expression stack.
+  intptr_t GetStackDepth() const {
+    return stack_ == nullptr ? 0 : stack_->definition()->temp_index() + 1;
+  }
+
  protected:
   intptr_t AllocateBlockId() { return ++last_used_block_id_; }
 
diff --git a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
index ca0eb36..03c8fc5 100644
--- a/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/bytecode_flow_graph_builder.cc
@@ -288,12 +288,12 @@
 
 intptr_t BytecodeFlowGraphBuilder::GetStackDepth() const {
   ASSERT(!is_generating_interpreter());
-  return B->stack_ == nullptr ? 0 : B->stack_->definition()->temp_index() + 1;
+  return B->GetStackDepth();
 }
 
 bool BytecodeFlowGraphBuilder::IsStackEmpty() const {
   ASSERT(!is_generating_interpreter());
-  return B->stack_ == nullptr;
+  return B->GetStackDepth() == 0;
 }
 
 ArgumentArray BytecodeFlowGraphBuilder::GetArguments(int count) {
@@ -327,12 +327,6 @@
     return;
   }
 
-  // Stack state propagation is supported for forward branches only.
-  // Bytecode generation guarantees that expression stack is empty between
-  // statements and backward jumps are only used to transfer control between
-  // statements (e.g. in loop and continue statements).
-  RELEASE_ASSERT(target_pc > pc_);
-
   Value* current_stack = B->stack_;
   Value* target_stack = stack_states_.Lookup(target_pc);
 
@@ -341,6 +335,8 @@
     // all incoming branches.
     RELEASE_ASSERT(target_stack == current_stack);
   } else {
+    // Stack state propagation is supported for forward branches only.
+    RELEASE_ASSERT(target_pc > pc_);
     stack_states_.Insert(target_pc, current_stack);
   }
 }
@@ -632,7 +628,8 @@
     store_type_args += B->LoadArgDescriptor();
     store_type_args += B->LoadNativeField(Slot::ArgumentsDescriptor_count());
     store_type_args += B->LoadFpRelativeSlot(
-        kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp));
+        kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp),
+        CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid));
     store_type_args +=
         B->StoreLocalRaw(TokenPosition::kNoSource, type_args_var);
     store_type_args += B->Drop();
@@ -666,11 +663,15 @@
   }
   const intptr_t loop_depth = DecodeOperandA().value();
   if (loop_depth == 0) {
+    ASSERT(IsStackEmpty());
     code_ += B->CheckStackOverflowInPrologue(position_);
   } else {
-    code_ += B->CheckStackOverflow(position_, loop_depth);
+    // Avoid OSR points inside block-expressions with pending stack slots.
+    // TODO(ajcbik): make sure OSR works for such cases too.
+    if (IsStackEmpty()) {
+      code_ += B->CheckStackOverflow(position_, loop_depth);
+    }
   }
-  ASSERT(IsStackEmpty());
 }
 
 void BytecodeFlowGraphBuilder::BuildPushConstant() {
@@ -787,7 +788,9 @@
     UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
   }
 
-  const String& name = String::Cast(ConstantAt(DecodeOperandD()).value());
+  const Function& interface_target =
+      Function::Cast(ConstantAt(DecodeOperandD()).value());
+  const String& name = String::ZoneHandle(Z, interface_target.name());
   ASSERT(name.IsSymbol());
 
   const Array& arg_desc_array =
@@ -811,12 +814,10 @@
 
   const ArgumentArray arguments = GetArguments(argc);
 
-  // TODO(alexmarkov): store interface_target in bytecode and pass it here.
-
   InstanceCallInstr* call = new (Z) InstanceCallInstr(
       position_, name, token_kind, arguments, arg_desc.TypeArgsLen(),
       Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), checked_argument_count,
-      *ic_data_array_, B->GetNextDeoptId());
+      *ic_data_array_, B->GetNextDeoptId(), interface_target);
 
   // TODO(alexmarkov): add type info - call->SetResultType()
 
@@ -842,12 +843,12 @@
 
   const ArgumentArray arguments = GetArguments(argc);
 
-  // TODO(alexmarkov): store interface_target in bytecode and pass it here.
+  const Function& interface_target = Function::null_function();
 
   InstanceCallInstr* call = new (Z) InstanceCallInstr(
       position_, name, token_kind, arguments, arg_desc.TypeArgsLen(),
       Array::ZoneHandle(Z, arg_desc.GetArgumentNames()), icdata.NumArgsTested(),
-      *ic_data_array_, icdata.deopt_id());
+      *ic_data_array_, icdata.deopt_id(), interface_target);
 
   ASSERT(call->ic_data() != nullptr);
   ASSERT(call->ic_data()->Original() == icdata.raw());
@@ -1631,6 +1632,15 @@
   BuildIntOp(Symbols::LessEqualOperator(), Token::kLTE, 2);
 }
 
+void BytecodeFlowGraphBuilder::BuildAllocateClosure() {
+  if (is_generating_interpreter()) {
+    UNIMPLEMENTED();  // TODO(alexmarkov): interpreter
+  }
+
+  const Function& target = Function::Cast(ConstantAt(DecodeOperandD()).value());
+  code_ += B->AllocateClosure(position_, target);
+}
+
 static bool IsICDataEntry(const ObjectPool& object_pool, intptr_t index) {
   if (object_pool.TypeAt(index) != ObjectPool::EntryType::kTaggedObject) {
     return false;
@@ -1824,7 +1834,10 @@
     if (join != nullptr) {
       Value* stack_state = stack_states_.Lookup(pc_);
       if (code_.is_open()) {
-        ASSERT((stack_state == nullptr) || (stack_state == B->stack_));
+        if (stack_state != B->stack_) {
+          ASSERT(stack_state == nullptr);
+          stack_states_.Insert(pc_, B->stack_);
+        }
         code_ += B->Goto(join);
       } else {
         ASSERT(IsStackEmpty());
diff --git a/runtime/vm/compiler/frontend/bytecode_reader.cc b/runtime/vm/compiler/frontend/bytecode_reader.cc
index 0834b09..6e53e13 100644
--- a/runtime/vm/compiler/frontend/bytecode_reader.cc
+++ b/runtime/vm/compiler/frontend/bytecode_reader.cc
@@ -474,32 +474,32 @@
   // be kept in sync with pkg/vm/lib/bytecode/constant_pool.dart.
   enum ConstantPoolTag {
     kInvalid,
-    kNull,    // TODO(alexmarkov): obsolete, remove
-    kString,  // TODO(alexmarkov): obsolete, remove
-    kInt,     // TODO(alexmarkov): obsolete, remove
-    kDouble,  // TODO(alexmarkov): obsolete, remove
-    kBool,    // TODO(alexmarkov): obsolete, remove
-    kArgDesc,
+    kUnused1,
+    kUnused2,
+    kUnused3,
+    kUnused4,
+    kUnused5,
+    kUnused6,
     kICData,
-    kStaticICData,
+    kUnused7,
     kStaticField,
     kInstanceField,
     kClass,
     kTypeArgumentsField,
-    kTearOff,  // TODO(alexmarkov): obsolete, remove
+    kUnused8,
     kType,
-    kTypeArguments,                       // TODO(alexmarkov): obsolete, remove
-    kList,                                // TODO(alexmarkov): obsolete, remove
-    kInstance,                            // TODO(alexmarkov): obsolete, remove
-    kTypeArgumentsForInstanceAllocation,  // TODO(alexmarkov): obsolete, remove
+    kUnused9,
+    kUnused10,
+    kUnused11,
+    kUnused12,
     kClosureFunction,
     kEndClosureFunctionScope,
     kNativeEntry,
     kSubtypeTestCache,
-    kPartialTearOffInstantiation,  // TODO(alexmarkov): obsolete, remove
+    kUnused13,
     kEmptyTypeArguments,
-    kSymbol,           // TODO(alexmarkov): obsolete, remove
-    kInterfaceCallV1,  // TODO(alexmarkov): obsolete, remove
+    kUnused14,
+    kUnused15,
     kObjectRef,
     kDirectCall,
     kInterfaceCall,
@@ -520,9 +520,6 @@
   Field& field = Field::Handle(Z);
   Class& cls = Class::Handle(Z);
   String& name = String::Handle(Z);
-  TypeArguments& type_args = TypeArguments::Handle(Z);
-  Class* symbol_class = nullptr;
-  Field* symbol_name_field = nullptr;
   const String* simpleInstanceOf = nullptr;
   const intptr_t obj_count = pool.Length();
   for (intptr_t i = 0; i < obj_count; ++i) {
@@ -530,50 +527,6 @@
     switch (tag) {
       case ConstantPoolTag::kInvalid:
         UNREACHABLE();
-      case ConstantPoolTag::kNull:
-        obj = Object::null();
-        break;
-      case ConstantPoolTag::kString:
-        obj = ReadString();
-        ASSERT(obj.IsString() && obj.IsCanonical());
-        break;
-      case ConstantPoolTag::kInt: {
-        uint32_t low_bits = helper_->ReadUInt32();
-        int64_t value = helper_->ReadUInt32();
-        value = (value << 32) | low_bits;
-        obj = Integer::New(value, Heap::kOld);
-        obj = H.Canonicalize(Integer::Cast(obj));
-      } break;
-      case ConstantPoolTag::kDouble: {
-        uint32_t low_bits = helper_->ReadUInt32();
-        uint64_t bits = helper_->ReadUInt32();
-        bits = (bits << 32) | low_bits;
-        double value = bit_cast<double, uint64_t>(bits);
-        obj = Double::New(value, Heap::kOld);
-        obj = H.Canonicalize(Double::Cast(obj));
-      } break;
-      case ConstantPoolTag::kBool:
-        if (helper_->ReadByte() == 1) {
-          obj = Bool::True().raw();
-        } else {
-          obj = Bool::False().raw();
-        }
-        break;
-      case ConstantPoolTag::kArgDesc: {
-        intptr_t num_arguments = helper_->ReadUInt();
-        intptr_t num_type_args = helper_->ReadUInt();
-        intptr_t num_arg_names = helper_->ReadListLength();
-        if (num_arg_names == 0) {
-          obj = ArgumentsDescriptor::New(num_type_args, num_arguments);
-        } else {
-          array = Array::New(num_arg_names);
-          for (intptr_t j = 0; j < num_arg_names; j++) {
-            name = ReadString();
-            array.SetAt(j, name);
-          }
-          obj = ArgumentsDescriptor::New(num_type_args, num_arguments, array);
-        }
-      } break;
       case ConstantPoolTag::kICData: {
         intptr_t flags = helper_->ReadByte();
         InvocationKind kind =
@@ -614,21 +567,6 @@
                         H.thread()->compiler_state().GetNextDeoptId(),
                         checked_argument_count, ICData::RebindRule::kInstance);
       } break;
-      case ConstantPoolTag::kStaticICData: {
-        elem = ReadObject();
-        ASSERT(elem.IsFunction());
-        name = Function::Cast(elem).name();
-        const int num_args_checked =
-            MethodRecognizer::NumArgsCheckedForStaticCall(Function::Cast(elem));
-        intptr_t arg_desc_index = helper_->ReadUInt();
-        ASSERT(arg_desc_index < i);
-        array ^= pool.ObjectAt(arg_desc_index);
-        obj = ICData::New(function, name,
-                          array,  // Arguments descriptor.
-                          H.thread()->compiler_state().GetNextDeoptId(),
-                          num_args_checked, ICData::RebindRule::kStatic);
-        ICData::Cast(obj).AddTarget(Function::Cast(elem));
-      } break;
       case ConstantPoolTag::kStaticField:
         obj = ReadObject();
         ASSERT(obj.IsField());
@@ -654,63 +592,10 @@
         cls ^= ReadObject();
         obj = Smi::New(cls.type_arguments_field_offset() / kWordSize);
         break;
-      case ConstantPoolTag::kTearOff:
-        obj = ReadObject();
-        ASSERT(obj.IsFunction());
-        obj = Function::Cast(obj).ImplicitClosureFunction();
-        ASSERT(obj.IsFunction());
-        obj = Function::Cast(obj).ImplicitStaticClosure();
-        ASSERT(obj.IsInstance());
-        obj = H.Canonicalize(Instance::Cast(obj));
-        break;
       case ConstantPoolTag::kType:
         obj = ReadObject();
         ASSERT(obj.IsAbstractType());
         break;
-      case ConstantPoolTag::kTypeArguments:
-        cls = Class::null();
-        obj = ReadTypeArguments(cls);
-        ASSERT(obj.IsNull() || obj.IsTypeArguments());
-        break;
-      case ConstantPoolTag::kList: {
-        obj = ReadObject();
-        ASSERT(obj.IsAbstractType());
-        const intptr_t length = helper_->ReadListLength();
-        array = Array::New(length, AbstractType::Cast(obj));
-        for (intptr_t j = 0; j < length; j++) {
-          intptr_t elem_index = helper_->ReadUInt();
-          ASSERT(elem_index < i);
-          elem = pool.ObjectAt(elem_index);
-          array.SetAt(j, elem);
-        }
-        array.MakeImmutable();
-        obj = H.Canonicalize(Array::Cast(array));
-        ASSERT(!obj.IsNull());
-      } break;
-      case ConstantPoolTag::kInstance: {
-        cls ^= ReadObject();
-        obj = Instance::New(cls, Heap::kOld);
-        intptr_t type_args_index = helper_->ReadUInt();
-        ASSERT(type_args_index < i);
-        type_args ^= pool.ObjectAt(type_args_index);
-        if (!type_args.IsNull()) {
-          Instance::Cast(obj).SetTypeArguments(type_args);
-        }
-        intptr_t num_fields = helper_->ReadUInt();
-        for (intptr_t j = 0; j < num_fields; j++) {
-          field ^= ReadObject();
-          intptr_t elem_index = helper_->ReadUInt();
-          ASSERT(elem_index < i);
-          elem = pool.ObjectAt(elem_index);
-          Instance::Cast(obj).SetField(field, elem);
-        }
-        obj = H.Canonicalize(Instance::Cast(obj));
-      } break;
-      case ConstantPoolTag::kTypeArgumentsForInstanceAllocation: {
-        cls ^= ReadObject();
-        obj = ReadTypeArguments(cls);
-        ASSERT(obj.IsNull() || obj.IsTypeArguments());
-      } break;
       case ConstantPoolTag::kClosureFunction: {
         intptr_t closure_index = helper_->ReadUInt();
         obj = closures_->At(closure_index);
@@ -731,61 +616,9 @@
       case ConstantPoolTag::kSubtypeTestCache: {
         obj = SubtypeTestCache::New();
       } break;
-      case ConstantPoolTag::kPartialTearOffInstantiation: {
-        intptr_t tearoff_index = helper_->ReadUInt();
-        ASSERT(tearoff_index < i);
-        const Closure& old_closure =
-            Closure::CheckedHandle(Z, pool.ObjectAt(tearoff_index));
-
-        intptr_t type_args_index = helper_->ReadUInt();
-        ASSERT(type_args_index < i);
-        type_args ^= pool.ObjectAt(type_args_index);
-
-        obj = Closure::New(
-            TypeArguments::Handle(Z, old_closure.instantiator_type_arguments()),
-            TypeArguments::Handle(Z, old_closure.function_type_arguments()),
-            type_args, Function::Handle(Z, old_closure.function()),
-            Context::Handle(Z, old_closure.context()), Heap::kOld);
-        obj = H.Canonicalize(Instance::Cast(obj));
-      } break;
       case ConstantPoolTag::kEmptyTypeArguments:
         obj = Object::empty_type_arguments().raw();
         break;
-      case ConstantPoolTag::kSymbol: {
-        name ^= ReadObject();
-        ASSERT(name.IsSymbol());
-        if (symbol_class == nullptr) {
-          elem = Library::InternalLibrary();
-          ASSERT(!elem.IsNull());
-          symbol_class = &Class::Handle(
-              Z, Library::Cast(elem).LookupClass(Symbols::Symbol()));
-          ASSERT(!symbol_class->IsNull());
-          symbol_name_field = &Field::Handle(
-              Z,
-              symbol_class->LookupInstanceFieldAllowPrivate(Symbols::_name()));
-          ASSERT(!symbol_name_field->IsNull());
-        }
-        obj = Instance::New(*symbol_class, Heap::kOld);
-        Instance::Cast(obj).SetField(*symbol_name_field, name);
-        obj = H.Canonicalize(Instance::Cast(obj));
-      } break;
-      case ConstantPoolTag::kInterfaceCallV1: {
-        helper_->ReadByte();  // TODO(regis): Remove, unneeded.
-        name ^= ReadObject();
-        ASSERT(name.IsSymbol());
-        intptr_t arg_desc_index = helper_->ReadUInt();
-        ASSERT(arg_desc_index < i);
-        array ^= pool.ObjectAt(arg_desc_index);
-        // InterfaceCall constant occupies 2 entries.
-        // The first entry is used for selector name.
-        pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
-                       ObjectPool::Patchability::kNotPatchable);
-        pool.SetObjectAt(i, name);
-        ++i;
-        ASSERT(i < obj_count);
-        // The second entry is used for arguments descriptor.
-        obj = array.raw();
-      } break;
       case ConstantPoolTag::kObjectRef:
         obj = ReadObject();
         break;
@@ -805,13 +638,11 @@
       case ConstantPoolTag::kInterfaceCall: {
         elem = ReadObject();
         ASSERT(elem.IsFunction());
-        name = Function::Cast(elem).name();
-        ASSERT(name.IsSymbol());
         // InterfaceCall constant occupies 2 entries.
-        // The first entry is used for selector name.
+        // The first entry is used for interface target.
         pool.SetTypeAt(i, ObjectPool::EntryType::kTaggedObject,
                        ObjectPool::Patchability::kNotPatchable);
-        pool.SetObjectAt(i, name);
+        pool.SetObjectAt(i, elem);
         ++i;
         ASSERT(i < obj_count);
         // The second entry is used for arguments descriptor.
@@ -1678,12 +1509,16 @@
       if (is_static) {
         field.SetStaticValue(value, true);
       } else {
-        // Note: optimizer relies on DoubleInitialized bit in its field-unboxing
-        // heuristics. See JitCallSpecializer::VisitStoreInstanceField for more
-        // details.
-        field.RecordStore(value);
-        if (value.IsDouble()) {
-          field.set_is_double_initialized(true);
+        // Null-initialized instance fields are tracked separately for each
+        // constructor (see handling of kHasNullableFieldsFlag).
+        if (!value.IsNull()) {
+          // Note: optimizer relies on DoubleInitialized bit in its
+          // field-unboxing heuristics.
+          // See JitCallSpecializer::VisitStoreInstanceField for more details.
+          field.RecordStore(value);
+          if (value.IsDouble()) {
+            field.set_is_double_initialized(true);
+          }
         }
       }
     }
diff --git a/runtime/vm/compiler/frontend/constant_evaluator.cc b/runtime/vm/compiler/frontend/constant_evaluator.cc
index 002b8f8f..2aba84f 100644
--- a/runtime/vm/compiler/frontend/constant_evaluator.cc
+++ b/runtime/vm/compiler/frontend/constant_evaluator.cc
@@ -97,6 +97,7 @@
       case kListConcatenation:
       case kSetConcatenation:
       case kMapConcatenation:
+      case kInstanceCreation:
         // These only occur inside unevaluated constants, so if we decide to
         // remove support for late evaluation of environment constants from
         // dill files in the VM, an implementation here will not be necessary.
@@ -1037,7 +1038,8 @@
   if (!IsBuildingFlowGraph()) return false;
 
   const Function& function = flow_graph_builder_->parsed_function_->function();
-  if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
+  if (function.kind() == RawFunction::kImplicitStaticFinalGetter &&
+      !I->CanOptimizeImmediately()) {
     // Don't cache constants in initializer expressions. They get
     // evaluated only once.
     return false;
@@ -1068,7 +1070,8 @@
   if (!IsBuildingFlowGraph()) return;
 
   const Function& function = flow_graph_builder_->parsed_function_->function();
-  if (function.kind() == RawFunction::kImplicitStaticFinalGetter) {
+  if (function.kind() == RawFunction::kImplicitStaticFinalGetter &&
+      !I->CanOptimizeImmediately()) {
     // Don't cache constants in initializer expressions. They get
     // evaluated only once.
     return;
diff --git a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
index 83a9d2a..6f326e7 100644
--- a/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
+++ b/runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc
@@ -1159,8 +1159,9 @@
     case kListConcatenation:
     case kSetConcatenation:
     case kMapConcatenation:
-      // Collection concatenation operations are removed by the constant
-      // evaluator.
+    case kInstanceCreation:
+      // Collection concatenation and instance creation operations are removed
+      // by the constant evaluator.
       UNREACHABLE();
       break;
     case kIsExpression:
@@ -1624,12 +1625,6 @@
   return flow_graph_builder_->AllocateObject(position, klass, argument_count);
 }
 
-Fragment StreamingFlowGraphBuilder::AllocateObject(
-    const Class& klass,
-    const Function& closure_function) {
-  return flow_graph_builder_->AllocateObject(klass, closure_function);
-}
-
 Fragment StreamingFlowGraphBuilder::AllocateContext(
     const GrowableArray<LocalVariable*>& context_variables) {
   return flow_graph_builder_->AllocateContext(context_variables);
@@ -4135,7 +4130,7 @@
 
     // Avoid OSR point inside block-expressions.
     // TODO(ajcbik): make sure OSR works inside BE too
-    if (block_expression_depth() == 0) loop += CheckStackOverflow(position);
+    if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position);
 
     if (condition.entry != nullptr) {
       loop <<= condition.entry;
@@ -4212,7 +4207,7 @@
 
     // Avoid OSR point inside block-expressions.
     // TODO(ajcbik): make sure OSR works inside BE too
-    if (block_expression_depth() == 0) loop += CheckStackOverflow(position);
+    if (B->GetStackDepth() == 0) loop += CheckStackOverflow(position);
 
     loop += condition;
   } else {
@@ -4955,11 +4950,8 @@
 
   function_node_helper.ReadUntilExcluding(FunctionNodeHelper::kEnd);
 
-  const Class& closure_class =
-      Class::ZoneHandle(Z, I->object_store()->closure_class());
-  ASSERT(!closure_class.IsNull());
   Fragment instructions =
-      flow_graph_builder_->AllocateObject(closure_class, function);
+      flow_graph_builder_->AllocateClosure(TokenPosition::kNoSource, function);
   LocalVariable* closure = MakeTemporary();
 
   // The function signature can have uninstantiated class type parameters.
diff --git a/runtime/vm/compiler/frontend/kernel_fingerprints.cc b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
index 1a88f1ba..be15d45 100644
--- a/runtime/vm/compiler/frontend/kernel_fingerprints.cc
+++ b/runtime/vm/compiler/frontend/kernel_fingerprints.cc
@@ -450,8 +450,9 @@
     case kListConcatenation:
     case kSetConcatenation:
     case kMapConcatenation:
-      // Collection concatenation operations are removed by the constant
-      // evaluator.
+    case kInstanceCreation:
+      // Collection concatenation and instance creation operations are removed
+      // by the constant evaluator.
       UNREACHABLE();
       break;
     case kIsExpression:
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index b7b19a9..713139f 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -224,16 +224,6 @@
   return Fragment(allocate);
 }
 
-Fragment FlowGraphBuilder::AllocateObject(const Class& klass,
-                                          const Function& closure_function) {
-  ArgumentArray arguments = new (Z) ZoneGrowableArray<PushArgumentInstr*>(Z, 0);
-  AllocateObjectInstr* allocate =
-      new (Z) AllocateObjectInstr(TokenPosition::kNoSource, klass, arguments);
-  allocate->set_closure_function(closure_function);
-  Push(allocate);
-  return Fragment(allocate);
-}
-
 Fragment FlowGraphBuilder::CatchBlockEntry(const Array& handler_types,
                                            intptr_t handler_index,
                                            bool needs_stacktrace,
@@ -367,7 +357,12 @@
   }
   if (call_site_attrs != nullptr && call_site_attrs->receiver_type != nullptr &&
       call_site_attrs->receiver_type->IsInstantiated()) {
-    call->set_static_receiver_type(call_site_attrs->receiver_type);
+    call->set_receivers_static_type(call_site_attrs->receiver_type);
+  } else if (!interface_target.IsNull()) {
+    const Class& owner = Class::Handle(Z, interface_target.Owner());
+    const AbstractType& type =
+        AbstractType::ZoneHandle(Z, owner.DeclarationType());
+    call->set_receivers_static_type(&type);
   }
   Push(call);
   return Fragment(call);
@@ -1068,9 +1063,7 @@
 Fragment FlowGraphBuilder::BuildImplicitClosureCreation(
     const Function& target) {
   Fragment fragment;
-  const Class& closure_class =
-      Class::ZoneHandle(Z, I->object_store()->closure_class());
-  fragment += AllocateObject(closure_class, target);
+  fragment += AllocateClosure(TokenPosition::kNoSource, target);
   LocalVariable* closure = MakeTemporary();
 
   // The function signature can have uninstantiated class type parameters.
@@ -1773,7 +1766,8 @@
     loop_body += LoadLocal(index);
     loop_body += SmiBinaryOp(Token::kSUB, /*truncate=*/true);
     loop_body += LoadFpRelativeSlot(
-        kWordSize * compiler::target::frame_layout.param_end_from_fp);
+        kWordSize * compiler::target::frame_layout.param_end_from_fp,
+        CompileType::Dynamic());
     loop_body += StoreIndexed(kArrayCid);
 
     // ++i
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.h b/runtime/vm/compiler/frontend/kernel_to_il.h
index 4355383..c7fb8da 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.h
+++ b/runtime/vm/compiler/frontend/kernel_to_il.h
@@ -125,7 +125,6 @@
   Fragment AllocateObject(TokenPosition position,
                           const Class& klass,
                           intptr_t argument_count);
-  Fragment AllocateObject(const Class& klass, const Function& closure_function);
   Fragment CatchBlockEntry(const Array& handler_types,
                            intptr_t handler_index,
                            bool needs_stacktrace,
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.cc b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
index 5fd9a77..971ac05 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.cc
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.cc
@@ -2237,8 +2237,9 @@
     case kListConcatenation:
     case kSetConcatenation:
     case kMapConcatenation:
-      // Collection concatenation operations are removed by the constant
-      // evaluator.
+    case kInstanceCreation:
+      // Collection concatenation and instance creation operations are removed
+      // by the constant evaluator.
       UNREACHABLE();
       break;
     case kIsExpression:
diff --git a/runtime/vm/compiler/frontend/prologue_builder.cc b/runtime/vm/compiler/frontend/prologue_builder.cc
index 3c5103c..deb29dc 100644
--- a/runtime/vm/compiler/frontend/prologue_builder.cc
+++ b/runtime/vm/compiler/frontend/prologue_builder.cc
@@ -21,6 +21,14 @@
 
 #define Z (zone_)
 
+// Returns static type of the parameter if it can be trusted (was type checked
+// by caller) and dynamic otherwise.
+static CompileType ParameterType(LocalVariable* param) {
+  return param->was_type_checked_by_caller()
+             ? CompileType::FromAbstractType(param->type())
+             : CompileType::Dynamic();
+}
+
 bool PrologueBuilder::PrologueSkippableOnUncheckedEntry(
     const Function& function) {
   return !function.HasOptionalParameters() &&
@@ -182,7 +190,8 @@
     copy_args_prologue += LoadLocal(optional_count_var);
     copy_args_prologue += LoadFpRelativeSlot(
         kWordSize * (compiler::target::frame_layout.param_end_from_fp +
-                     num_fixed_params - param));
+                     num_fixed_params - param),
+        ParameterType(ParameterVariable(param)));
     copy_args_prologue +=
         StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
     copy_args_prologue += Drop();
@@ -202,7 +211,8 @@
       good += LoadLocal(optional_count_var);
       good += LoadFpRelativeSlot(
           kWordSize * (compiler::target::frame_layout.param_end_from_fp +
-                       num_fixed_params - param));
+                       num_fixed_params - param),
+          ParameterType(ParameterVariable(param)));
       good += StoreLocalRaw(TokenPosition::kNoSource, ParameterVariable(param));
       good += Drop();
 
@@ -300,7 +310,8 @@
         }
         good += SmiBinaryOp(Token::kSUB, /* truncate= */ true);
         good += LoadFpRelativeSlot(
-            kWordSize * compiler::target::frame_layout.param_end_from_fp);
+            kWordSize * compiler::target::frame_layout.param_end_from_fp,
+            ParameterType(ParameterVariable(opt_param_position[i])));
 
         // Copy down.
         good += StoreLocalRaw(TokenPosition::kNoSource,
@@ -405,7 +416,8 @@
   store_type_args += LoadArgDescriptor();
   store_type_args += LoadNativeField(Slot::ArgumentsDescriptor_count());
   store_type_args += LoadFpRelativeSlot(
-      kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp));
+      kWordSize * (1 + compiler::target::frame_layout.param_end_from_fp),
+      CompileType::CreateNullable(/*is_nullable=*/true, kTypeArgumentsCid));
   store_type_args += StoreLocal(TokenPosition::kNoSource, type_args_var);
   store_type_args += Drop();
 
diff --git a/runtime/vm/compiler/frontend/scope_builder.cc b/runtime/vm/compiler/frontend/scope_builder.cc
index e23bf10..ea837d5 100644
--- a/runtime/vm/compiler/frontend/scope_builder.cc
+++ b/runtime/vm/compiler/frontend/scope_builder.cc
@@ -765,8 +765,9 @@
     case kListConcatenation:
     case kSetConcatenation:
     case kMapConcatenation:
-      // Collection concatenation operations are removed by the constant
-      // evaluator.
+    case kInstanceCreation:
+      // Collection concatenation and instance creation operations are removed
+      // by the constant evaluator.
       UNREACHABLE();
       break;
     case kIsExpression:
diff --git a/runtime/vm/compiler/graph_intrinsifier.cc b/runtime/vm/compiler/graph_intrinsifier.cc
index 1b2f8e8..85b9e11 100644
--- a/runtime/vm/compiler/graph_intrinsifier.cc
+++ b/runtime/vm/compiler/graph_intrinsifier.cc
@@ -7,6 +7,7 @@
 #if !defined(DART_PRECOMPILED_RUNTIME) && !defined(TARGET_ARCH_DBC)
 
 #include "vm/compiler/graph_intrinsifier.h"
+#include "vm/compiler/backend/block_builder.h"
 #include "vm/compiler/backend/flow_graph.h"
 #include "vm/compiler/backend/flow_graph_compiler.h"
 #include "vm/compiler/backend/il.h"
@@ -115,24 +116,6 @@
   return true;
 }
 
-static intptr_t CidForRepresentation(Representation rep) {
-  switch (rep) {
-    case kUnboxedDouble:
-      return kDoubleCid;
-    case kUnboxedFloat32x4:
-      return kFloat32x4Cid;
-    case kUnboxedInt32x4:
-      return kInt32x4Cid;
-    case kUnboxedFloat64x2:
-      return kFloat64x2Cid;
-    case kUnboxedUint32:
-      return kDynamicCid;  // smi or mint.
-    default:
-      UNREACHABLE();
-      return kIllegalCid;
-  }
-}
-
 static Representation RepresentationForCid(intptr_t cid) {
   switch (cid) {
     case kDoubleCid:
@@ -154,100 +137,6 @@
 // IR instructions which would jump to a deoptimization sequence on failure
 // instead branch to the intrinsic slow path.
 //
-class BlockBuilder : public ValueObject {
- public:
-  BlockBuilder(FlowGraph* flow_graph, BlockEntryInstr* entry)
-      : flow_graph_(flow_graph),
-        entry_(entry),
-        current_(entry),
-        fall_through_env_(new Environment(0,
-                                          0,
-                                          flow_graph->parsed_function(),
-                                          NULL)) {}
-
-  Definition* AddToInitialDefinitions(Definition* def) {
-    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
-    auto normal_entry = flow_graph_->graph_entry()->normal_entry();
-    flow_graph_->AddToInitialDefinitions(normal_entry, def);
-    return def;
-  }
-
-  Definition* AddDefinition(Definition* def) {
-    def->set_ssa_temp_index(flow_graph_->alloc_ssa_temp_index());
-    AddInstruction(def);
-    return def;
-  }
-
-  Instruction* AddInstruction(Instruction* instr) {
-    if (instr->ComputeCanDeoptimize()) {
-      // Since we use the presence of an environment to determine if an
-      // instructions can deoptimize, we need an empty environment for
-      // instructions that "deoptimize" to the intrinsic fall-through code.
-      instr->SetEnvironment(fall_through_env_);
-    }
-    current_ = current_->AppendInstruction(instr);
-    return instr;
-  }
-
-  void AddIntrinsicReturn(Value* value) {
-    ReturnInstr* instr = new ReturnInstr(
-        TokenPos(), value, CompilerState::Current().GetNextDeoptId());
-    AddInstruction(instr);
-    entry_->set_last_instruction(instr);
-  }
-
-  Definition* AddParameter(intptr_t index) {
-    intptr_t adjustment = GraphIntrinsifier::ParameterSlotFromSp();
-    return AddToInitialDefinitions(new ParameterInstr(
-        adjustment + index, flow_graph_->graph_entry(), SPREG));
-  }
-
-  TokenPosition TokenPos() { return flow_graph_->function().token_pos(); }
-
-  Definition* AddNullDefinition() {
-    return AddDefinition(new ConstantInstr(Object::ZoneHandle(Object::null())));
-  }
-
-  Definition* AddUnboxInstr(Representation rep, Value* value, bool is_checked) {
-    Definition* unboxed_value =
-        AddDefinition(UnboxInstr::Create(rep, value, DeoptId::kNone));
-    if (is_checked) {
-      // The type of |value| has already been checked and it is safe to
-      // adjust reaching type. This is done manually because there is no type
-      // propagation when building intrinsics.
-      unboxed_value->AsUnbox()->value()->SetReachingType(
-          new CompileType(CompileType::FromCid(CidForRepresentation(rep))));
-    }
-    return unboxed_value;
-  }
-
-  Definition* AddUnboxInstr(Representation rep,
-                            Definition* boxed,
-                            bool is_checked) {
-    return AddUnboxInstr(rep, new Value(boxed), is_checked);
-  }
-
-  Definition* InvokeMathCFunction(MethodRecognizer::Kind recognized_kind,
-                                  ZoneGrowableArray<Value*>* args) {
-    return InvokeMathCFunctionHelper(recognized_kind, args);
-  }
-
- private:
-  Definition* InvokeMathCFunctionHelper(MethodRecognizer::Kind recognized_kind,
-                                        ZoneGrowableArray<Value*>* args) {
-    InvokeMathCFunctionInstr* invoke_math_c_function =
-        new InvokeMathCFunctionInstr(args, DeoptId::kNone, recognized_kind,
-                                     TokenPos());
-    AddDefinition(invoke_math_c_function);
-    return invoke_math_c_function;
-  }
-
-  FlowGraph* flow_graph_;
-  BlockEntryInstr* entry_;
-  Instruction* current_;
-  Environment* fall_through_env_;
-};
-
 static Definition* PrepareIndexedOp(FlowGraph* flow_graph,
                                     BlockBuilder* builder,
                                     Definition* array,
@@ -269,8 +158,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* index = builder.AddParameter(1);
-  Definition* array = builder.AddParameter(2);
+  Definition* index = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* array = builder.AddParameter(1, /*with_frame=*/false);
 
   index = PrepareIndexedOp(flow_graph, &builder, array, index,
                            Slot::GetLengthFieldForArrayCid(array_cid));
@@ -336,7 +225,7 @@
       UNREACHABLE();
       break;
   }
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -346,9 +235,9 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
+  Definition* value = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* index = builder.AddParameter(1, /*with_frame=*/false);
+  Definition* array = builder.AddParameter(2, /*with_frame=*/false);
 
   index = PrepareIndexedOp(flow_graph, &builder, array, index,
                            Slot::GetLengthFieldForArrayCid(array_cid));
@@ -434,7 +323,7 @@
       array_cid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
   // Return null.
   Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
+  builder.AddReturn(new Value(null_def));
   return true;
 }
 
@@ -549,8 +438,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* index = builder.AddParameter(1);
-  Definition* str = builder.AddParameter(2);
+  Definition* index = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* str = builder.AddParameter(1, /*with_frame=*/false);
 
   index =
       PrepareIndexedOp(flow_graph, &builder, str, index, Slot::String_length());
@@ -567,7 +456,7 @@
   Definition* result = builder.AddDefinition(new LoadIndexedInstr(
       new Value(str), new Value(index), Instance::ElementSizeFor(cid), cid,
       kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -599,8 +488,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* right = builder.AddParameter(1);
-  Definition* left = builder.AddParameter(2);
+  Definition* right = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* left = builder.AddParameter(1, /*with_frame=*/false);
 
   Cids* value_check = Cids::CreateMonomorphic(zone, cid);
   // Check argument. Receiver (left) is known to be a Float32x4.
@@ -617,7 +506,7 @@
       new Value(right_simd), DeoptId::kNone));
   Definition* result =
       builder.AddDefinition(BoxInstr::Create(rep, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -643,7 +532,7 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* receiver = builder.AddParameter(1);
+  Definition* receiver = builder.AddParameter(0, /*with_frame=*/false);
 
   Definition* unboxed_receiver =
       builder.AddUnboxInstr(kUnboxedFloat32x4, new Value(receiver),
@@ -654,7 +543,7 @@
 
   Definition* result = builder.AddDefinition(
       BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -683,11 +572,11 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* array = builder.AddParameter(1);
+  Definition* array = builder.AddParameter(0, /*with_frame=*/false);
 
   Definition* length = builder.AddDefinition(
       new LoadFieldInstr(new Value(array), field, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(length));
+  builder.AddReturn(new Value(length));
   return true;
 }
 
@@ -724,13 +613,13 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* array = builder.AddParameter(1);
+  Definition* array = builder.AddParameter(0, /*with_frame=*/false);
 
   Definition* backing_store = builder.AddDefinition(new LoadFieldInstr(
       new Value(array), Slot::GrowableObjectArray_data(), builder.TokenPos()));
   Definition* capacity = builder.AddDefinition(new LoadFieldInstr(
       new Value(backing_store), Slot::Array_length(), builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(capacity));
+  builder.AddReturn(new Value(capacity));
   return true;
 }
 
@@ -739,8 +628,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* index = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
+  Definition* index = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false);
 
   index = PrepareIndexedOp(flow_graph, &builder, growable_array, index,
                            Slot::GrowableObjectArray_length());
@@ -752,7 +641,7 @@
       new Value(backing_store), new Value(index),
       Instance::ElementSizeFor(kArrayCid),  // index scale
       kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -770,9 +659,9 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
+  Definition* value = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* index = builder.AddParameter(1, /*with_frame=*/false);
+  Definition* array = builder.AddParameter(2, /*with_frame=*/false);
 
   index = PrepareIndexedOp(flow_graph, &builder, array, index,
                            Slot::Array_length());
@@ -783,7 +672,7 @@
       kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
   // Return null.
   Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
+  builder.AddReturn(new Value(null_def));
   return true;
 }
 
@@ -801,9 +690,9 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* value = builder.AddParameter(1);
-  Definition* index = builder.AddParameter(2);
-  Definition* array = builder.AddParameter(3);
+  Definition* value = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* index = builder.AddParameter(1, /*with_frame=*/false);
+  Definition* array = builder.AddParameter(2, /*with_frame=*/false);
 
   index = PrepareIndexedOp(flow_graph, &builder, array, index,
                            Slot::GrowableObjectArray_length());
@@ -818,7 +707,7 @@
       kArrayCid, kAlignedAccess, DeoptId::kNone, builder.TokenPos()));
   // Return null.
   Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
+  builder.AddReturn(new Value(null_def));
   return true;
 }
 
@@ -827,8 +716,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* data = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
+  Definition* data = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false);
   Zone* zone = flow_graph->zone();
 
   Cids* value_check = Cids::CreateMonomorphic(zone, kArrayCid);
@@ -840,7 +729,7 @@
       new Value(data), kEmitStoreBarrier, builder.TokenPos()));
   // Return null.
   Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
+  builder.AddReturn(new Value(null_def));
   return true;
 }
 
@@ -849,8 +738,8 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* length = builder.AddParameter(1);
-  Definition* growable_array = builder.AddParameter(2);
+  Definition* length = builder.AddParameter(0, /*with_frame=*/false);
+  Definition* growable_array = builder.AddParameter(1, /*with_frame=*/false);
 
   builder.AddInstruction(
       new CheckSmiInstr(new Value(length), DeoptId::kNone, builder.TokenPos()));
@@ -858,7 +747,7 @@
       Slot::GrowableObjectArray_length(), new Value(growable_array),
       new Value(length), kNoStoreBarrier, builder.TokenPos()));
   Definition* null_def = builder.AddNullDefinition();
-  builder.AddIntrinsicReturn(new Value(null_def));
+  builder.AddReturn(new Value(null_def));
   return true;
 }
 
@@ -870,7 +759,7 @@
   auto normal_entry = graph_entry->normal_entry();
   BlockBuilder builder(flow_graph, normal_entry);
 
-  Definition* receiver = builder.AddParameter(1);
+  Definition* receiver = builder.AddParameter(0, /*with_frame=*/false);
   Definition* unboxed_value =
       builder.AddUnboxInstr(kUnboxedDouble, new Value(receiver),
                             /* is_checked = */ true);
@@ -878,7 +767,7 @@
       Token::kNEGATE, new Value(unboxed_value), DeoptId::kNone));
   Definition* result = builder.AddDefinition(
       BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
-  builder.AddIntrinsicReturn(new Value(result));
+  builder.AddReturn(new Value(result));
   return true;
 }
 
@@ -892,19 +781,21 @@
       new ZoneGrowableArray<Value*>(num_parameters);
 
   for (intptr_t i = 0; i < num_parameters; i++) {
-    const intptr_t parameter_index = (num_parameters - i);
-    Definition* value = builder->AddParameter(parameter_index);
+    const intptr_t parameter_index = (num_parameters - i - 1);
+    Definition* value =
+        builder->AddParameter(parameter_index, /*with_frame=*/false);
     Definition* unboxed_value =
         builder->AddUnboxInstr(kUnboxedDouble, value, /* is_checked = */ false);
     args->Add(new Value(unboxed_value));
   }
 
-  Definition* unboxed_result = builder->InvokeMathCFunction(kind, args);
-
+  Definition* unboxed_result =
+      builder->AddDefinition(new InvokeMathCFunctionInstr(
+          args, DeoptId::kNone, kind, builder->TokenPos()));
   Definition* result = builder->AddDefinition(
       BoxInstr::Create(kUnboxedDouble, new Value(unboxed_result)));
 
-  builder->AddIntrinsicReturn(new Value(result));
+  builder->AddReturn(new Value(result));
 
   return true;
 }
diff --git a/runtime/vm/compiler/jit/compiler.cc b/runtime/vm/compiler/jit/compiler.cc
index b7afea4..412e6b0 100644
--- a/runtime/vm/compiler/jit/compiler.cc
+++ b/runtime/vm/compiler/jit/compiler.cc
@@ -271,6 +271,14 @@
     // so do not optimize the function. Bump usage counter down to avoid
     // repeatedly entering the runtime for an optimization attempt.
     function.SetUsageCounter(0);
+
+    // If the optimization counter = 1, the unoptimized code will come back here
+    // immediately, causing an infinite compilation loop. The compiler raises
+    // the threshold for functions with breakpoints, so we drop the unoptimized
+    // to force it to be recompiled.
+    if (thread->isolate()->CanOptimizeImmediately()) {
+      function.ClearCode();
+    }
     return false;
   }
 #endif
@@ -361,7 +369,7 @@
   RawCode* FinalizeCompilation(Assembler* assembler,
                                FlowGraphCompiler* graph_compiler,
                                FlowGraph* flow_graph);
-  void CheckIfBackgroundCompilerIsBeingStopped();
+  void CheckIfBackgroundCompilerIsBeingStopped(bool optimizing_compiler);
 
   ParsedFunction* parsed_function_;
   const bool optimized_;
@@ -556,12 +564,22 @@
   return code.raw();
 }
 
-void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped() {
+void CompileParsedFunctionHelper::CheckIfBackgroundCompilerIsBeingStopped(
+    bool optimizing_compiler) {
   ASSERT(Compiler::IsBackgroundCompilation());
-  if (!isolate()->background_compiler()->is_running()) {
-    // The background compiler is being stopped.
-    Compiler::AbortBackgroundCompilation(
-        DeoptId::kNone, "Background compilation is being stopped");
+  if (optimizing_compiler) {
+    if (!isolate()->optimizing_background_compiler()->is_running()) {
+      // The background compiler is being stopped.
+      Compiler::AbortBackgroundCompilation(
+          DeoptId::kNone, "Optimizing Background compilation is being stopped");
+    }
+  } else {
+    if (FLAG_enable_interpreter &&
+        !isolate()->background_compiler()->is_running()) {
+      // The background compiler is being stopped.
+      Compiler::AbortBackgroundCompilation(
+          DeoptId::kNone, "Background compilation is being stopped");
+    }
   }
 }
 
@@ -708,12 +726,12 @@
           // changes code page access permissions (makes them temporary not
           // executable).
           {
-            CheckIfBackgroundCompilerIsBeingStopped();
+            CheckIfBackgroundCompilerIsBeingStopped(optimized());
             SafepointOperationScope safepoint_scope(thread());
             // Do not Garbage collect during this stage and instead allow the
             // heap to grow.
             NoHeapGrowthControlScope no_growth_control;
-            CheckIfBackgroundCompilerIsBeingStopped();
+            CheckIfBackgroundCompilerIsBeingStopped(optimized());
             *result =
                 FinalizeCompilation(&assembler, &graph_compiler, flow_graph);
           }
@@ -757,18 +775,18 @@
         if (FLAG_trace_bailout) {
           THR_Print("%s\n", error.ToErrorCString());
         }
+        if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() &&
+            (LanguageError::Cast(error).kind() == Report::kBailout)) {
+          // If is is not a background compilation, discard the error if it was
+          // not a real error, but just a bailout. If we're it a background
+          // compilation this will be dealt with in the caller.
+        } else {
+          // Otherwise, continue propagating unless we will try again.
+          thread()->set_sticky_error(error);
+        }
         done = true;
       }
 
-      if (!Compiler::IsBackgroundCompilation() && error.IsLanguageError() &&
-          (LanguageError::Cast(error).kind() == Report::kBailout)) {
-        // If is is not a background compilation, discard the error if it was
-        // not a real error, but just a bailout. If we're it a background
-        // compilation this will be dealt with in the caller.
-      } else {
-        // Otherwise, continue propagating.
-        thread()->set_sticky_error(error);
-      }
     }
   }
   return result->raw();
@@ -1474,7 +1492,7 @@
   }
 }
 
-void BackgroundCompiler::CompileOptimized(const Function& function) {
+void BackgroundCompiler::Compile(const Function& function) {
   ASSERT(Thread::Current()->IsMutatorThread());
   // TODO(srdjan): Checking different strategy for collecting garbage
   // accumulated by background compiler.
@@ -1516,18 +1534,6 @@
   ASSERT(thread->IsMutatorThread());
   ASSERT(!thread->IsAtSafepoint());
 
-  // Finalize NoSuchMethodError, _Mint; occasionally needed in optimized
-  // compilation.
-  Class& cls = Class::Handle(
-      thread->zone(), Library::LookupCoreClass(Symbols::NoSuchMethodError()));
-  ASSERT(!cls.IsNull());
-  Error& error = Error::Handle(thread->zone(), cls.EnsureIsFinalized(thread));
-  ASSERT(error.IsNull());
-  cls = Library::LookupCoreClass(Symbols::_Mint());
-  ASSERT(!cls.IsNull());
-  error = cls.EnsureIsFinalized(thread);
-  ASSERT(error.IsNull());
-
   MonitorLocker ml(done_monitor_);
   if (running_ || !done_) return;
   running_ = true;
@@ -1653,7 +1659,7 @@
   UNREACHABLE();
 }
 
-void BackgroundCompiler::CompileOptimized(const Function& function) {
+void BackgroundCompiler::Compile(const Function& function) {
   UNREACHABLE();
 }
 
diff --git a/runtime/vm/compiler/jit/compiler.h b/runtime/vm/compiler/jit/compiler.h
index eef93a8..c7e6412 100644
--- a/runtime/vm/compiler/jit/compiler.h
+++ b/runtime/vm/compiler/jit/compiler.h
@@ -157,46 +157,57 @@
 
   static void Start(Isolate* isolate) {
     ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
+    if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) {
       isolate->background_compiler()->Start();
     }
+    if (isolate->optimizing_background_compiler() != NULL) {
+      isolate->optimizing_background_compiler()->Start();
+    }
   }
   static void Stop(Isolate* isolate) {
     ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
+    if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) {
       isolate->background_compiler()->Stop();
     }
+    if (isolate->optimizing_background_compiler() != NULL) {
+      isolate->optimizing_background_compiler()->Stop();
+    }
   }
   static void Enable(Isolate* isolate) {
     ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
+    if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) {
       isolate->background_compiler()->Enable();
     }
+    if (isolate->optimizing_background_compiler() != NULL) {
+      isolate->optimizing_background_compiler()->Enable();
+    }
   }
   static void Disable(Isolate* isolate) {
     ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
+    if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) {
       isolate->background_compiler()->Disable();
     }
-  }
-  static bool IsDisabled(Isolate* isolate) {
-    ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
-      return isolate->background_compiler()->IsDisabled();
+    if (isolate->optimizing_background_compiler() != NULL) {
+      isolate->optimizing_background_compiler()->Disable();
     }
-    return false;
   }
-  static bool IsRunning(Isolate* isolate) {
+  static bool IsDisabled(Isolate* isolate, bool optimizing_compiler) {
     ASSERT(Thread::Current()->IsMutatorThread());
-    if (isolate->background_compiler() != NULL) {
-      return isolate->background_compiler()->IsRunning();
+    if (optimizing_compiler) {
+      if (isolate->optimizing_background_compiler() != NULL) {
+        return isolate->optimizing_background_compiler()->IsDisabled();
+      }
+    } else {
+      if (FLAG_enable_interpreter && isolate->background_compiler() != NULL) {
+        return isolate->background_compiler()->IsDisabled();
+      }
     }
     return false;
   }
 
-  // Call to optimize a function in the background, enters the function in the
-  // compilation queue.
-  void CompileOptimized(const Function& function);
+  // Call to compile (unoptimized or optimized) a function in the background,
+  // enters the function in the compilation queue.
+  void Compile(const Function& function);
 
   void VisitPointers(ObjectPointerVisitor* visitor);
 
diff --git a/runtime/vm/compiler/runtime_api.cc b/runtime/vm/compiler/runtime_api.cc
index 9020925..ae05577 100644
--- a/runtime/vm/compiler/runtime_api.cc
+++ b/runtime/vm/compiler/runtime_api.cc
@@ -348,8 +348,8 @@
   return dart::ICData::entries_offset();
 }
 
-word ICData::static_receiver_type_offset() {
-  return dart::ICData::static_receiver_type_offset();
+word ICData::receivers_static_type_offset() {
+  return dart::ICData::receivers_static_type_offset();
 }
 
 word ICData::state_bits_offset() {
diff --git a/runtime/vm/compiler/runtime_api.h b/runtime/vm/compiler/runtime_api.h
index 1036a98..825bbb1 100644
--- a/runtime/vm/compiler/runtime_api.h
+++ b/runtime/vm/compiler/runtime_api.h
@@ -411,7 +411,7 @@
   static word owner_offset();
   static word arguments_descriptor_offset();
   static word entries_offset();
-  static word static_receiver_type_offset();
+  static word receivers_static_type_offset();
   static word state_bits_offset();
 
   static word CodeIndexFor(word num_args);
diff --git a/runtime/vm/compiler/stub_code_compiler_arm.cc b/runtime/vm/compiler/stub_code_compiler_arm.cc
index d8f41bd..ce9321b 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm.cc
@@ -14,7 +14,7 @@
 #include "vm/code_entry_kind.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 #include "vm/instructions.h"
 #include "vm/static_type_exactness_state.h"
 #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_arm64.cc b/runtime/vm/compiler/stub_code_compiler_arm64.cc
index 6ff109c..6b0d490 100644
--- a/runtime/vm/compiler/stub_code_compiler_arm64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_arm64.cc
@@ -14,7 +14,7 @@
 #include "vm/code_entry_kind.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 #include "vm/instructions.h"
 #include "vm/static_type_exactness_state.h"
 #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_ia32.cc b/runtime/vm/compiler/stub_code_compiler_ia32.cc
index 5b366b3..86f75d6 100644
--- a/runtime/vm/compiler/stub_code_compiler_ia32.cc
+++ b/runtime/vm/compiler/stub_code_compiler_ia32.cc
@@ -14,7 +14,7 @@
 #include "vm/code_entry_kind.h"
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/backend/locations.h"
-#include "vm/constants_ia32.h"
+#include "vm/constants.h"
 #include "vm/instructions.h"
 #include "vm/static_type_exactness_state.h"
 #include "vm/tags.h"
diff --git a/runtime/vm/compiler/stub_code_compiler_x64.cc b/runtime/vm/compiler/stub_code_compiler_x64.cc
index ccc30b5..2c5dd0a 100644
--- a/runtime/vm/compiler/stub_code_compiler_x64.cc
+++ b/runtime/vm/compiler/stub_code_compiler_x64.cc
@@ -13,7 +13,7 @@
 #include "vm/class_id.h"
 #include "vm/code_entry_kind.h"
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_x64.h"
+#include "vm/constants.h"
 #include "vm/instructions.h"
 #include "vm/static_type_exactness_state.h"
 #include "vm/tags.h"
@@ -2017,10 +2017,10 @@
     __ j(EQUAL, &call_target_function_through_unchecked_entry);
 
     // Check trivial exactness.
-    // Note: RawICData::static_receiver_type_ is guaranteed to be not null
+    // Note: RawICData::receivers_static_type_ is guaranteed to be not null
     // because we only emit calls to this stub when it is not null.
     __ movq(RCX,
-            FieldAddress(RBX, target::ICData::static_receiver_type_offset()));
+            FieldAddress(RBX, target::ICData::receivers_static_type_offset()));
     __ movq(RCX, FieldAddress(RCX, target::Type::arguments_offset()));
     // RAX contains an offset to type arguments in words as a smi,
     // hence TIMES_4. RDX is guaranteed to be non-smi because it is expected to
diff --git a/runtime/vm/compiler_test.cc b/runtime/vm/compiler_test.cc
index 02a4ed1..d10c8c4 100644
--- a/runtime/vm/compiler_test.cc
+++ b/runtime/vm/compiler_test.cc
@@ -37,12 +37,13 @@
       "    // A.foo();\n"
       "  }\n"
       "}\n";
-  String& url = String::Handle(String::New("dart-test:CompileFunction"));
-  String& source = String::Handle(String::New(kScriptChars));
-  Script& script =
-      Script::Handle(Script::New(url, source, RawScript::kScriptTag));
-  Library& lib = Library::Handle(Library::CoreLibrary());
-  EXPECT(CompilerTest::TestCompileScript(lib, script));
+  Dart_Handle library;
+  {
+    TransitionVMToNative transition(thread);
+    library = TestCase::LoadTestScript(kScriptChars, NULL);
+  }
+  const Library& lib =
+      Library::Handle(Library::RawCast(Api::UnwrapHandle(library)));
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls =
       Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
@@ -68,19 +69,19 @@
                function_source.ToCString());
 }
 
-ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) {
+ISOLATE_UNIT_TEST_CASE(OptimizeCompileFunctionOnHelperThread) {
   // Create a simple function and compile it without optimization.
   const char* kScriptChars =
       "class A {\n"
       "  static foo() { return 42; }\n"
       "}\n";
-  String& url =
-      String::Handle(String::New("dart-test:CompileFunctionOnHelperThread"));
-  String& source = String::Handle(String::New(kScriptChars));
-  Script& script =
-      Script::Handle(Script::New(url, source, RawScript::kScriptTag));
-  Library& lib = Library::Handle(Library::CoreLibrary());
-  EXPECT(CompilerTest::TestCompileScript(lib, script));
+  Dart_Handle library;
+  {
+    TransitionVMToNative transition(thread);
+    library = TestCase::LoadTestScript(kScriptChars, NULL);
+  }
+  const Library& lib =
+      Library::Handle(Library::RawCast(Api::UnwrapHandle(library)));
   EXPECT(ClassFinalizer::ProcessPendingClasses());
   Class& cls =
       Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
@@ -98,7 +99,7 @@
 #endif
   Isolate* isolate = thread->isolate();
   BackgroundCompiler::Start(isolate);
-  isolate->background_compiler()->CompileOptimized(func);
+  isolate->optimizing_background_compiler()->Compile(func);
   Monitor* m = new Monitor();
   {
     MonitorLocker ml(m);
@@ -110,6 +111,50 @@
   BackgroundCompiler::Stop(isolate);
 }
 
+ISOLATE_UNIT_TEST_CASE(CompileFunctionOnHelperThread) {
+  // Create a simple function and compile it without optimization.
+  const char* kScriptChars =
+      "class A {\n"
+      "  static foo() { return 42; }\n"
+      "}\n";
+  Dart_Handle library;
+  {
+    TransitionVMToNative transition(thread);
+    library = TestCase::LoadTestScript(kScriptChars, NULL);
+  }
+  const Library& lib =
+      Library::Handle(Library::RawCast(Api::UnwrapHandle(library)));
+  EXPECT(ClassFinalizer::ProcessPendingClasses());
+  Class& cls =
+      Class::Handle(lib.LookupClass(String::Handle(Symbols::New(thread, "A"))));
+  EXPECT(!cls.IsNull());
+  String& function_foo_name = String::Handle(String::New("foo"));
+  Function& func =
+      Function::Handle(cls.LookupStaticFunction(function_foo_name));
+  EXPECT(!func.HasCode());
+  if (!FLAG_enable_interpreter) {
+    CompilerTest::TestCompileFunction(func);
+    EXPECT(func.HasCode());
+    return;
+  }
+#if !defined(PRODUCT)
+  // Constant in product mode.
+  FLAG_background_compilation = true;
+#endif
+  Isolate* isolate = thread->isolate();
+  BackgroundCompiler::Start(isolate);
+  isolate->background_compiler()->Compile(func);
+  Monitor* m = new Monitor();
+  {
+    MonitorLocker ml(m);
+    while (!func.HasCode()) {
+      ml.WaitWithSafepointCheck(thread, 1);
+    }
+  }
+  delete m;
+  BackgroundCompiler::Stop(isolate);
+}
+
 ISOLATE_UNIT_TEST_CASE(RegenerateAllocStubs) {
   const char* kScriptChars =
       "class A {\n"
diff --git a/runtime/vm/constants.h b/runtime/vm/constants.h
index c6412d2..90137d3 100644
--- a/runtime/vm/constants.h
+++ b/runtime/vm/constants.h
@@ -19,4 +19,50 @@
 #error Unknown architecture.
 #endif
 
+#if defined(HOST_ARCH_IA32)
+#include "vm/constants_ia32.h"
+#elif defined(HOST_ARCH_X64)
+#include "vm/constants_x64.h"
+#elif defined(HOST_ARCH_ARM)
+#include "vm/constants_arm.h"
+#elif defined(HOST_ARCH_ARM64)
+#include "vm/constants_arm64.h"
+#else
+#error Unknown host architecture.
+#endif
+
+namespace dart {
+
+#if defined(TARGET_ARCH_IA32)
+using namespace arch_ia32;  // NOLINT
+#elif defined(TARGET_ARCH_X64)
+using namespace arch_x64;  // NOLINT
+#elif defined(TARGET_ARCH_ARM)
+using namespace arch_arm;  // NOLINT
+#elif defined(TARGET_ARCH_ARM64)
+using namespace arch_arm64;  // NOLINT
+#elif defined(TARGET_ARCH_DBC)
+// DBC is defined in namespace dart already.
+#else
+#error Unknown architecture.
+#endif
+
+namespace host {
+
+#if defined(HOST_ARCH_IA32)
+using namespace arch_ia32;  // NOLINT
+#elif defined(HOST_ARCH_X64)
+using namespace arch_x64;  // NOLINT
+#elif defined(HOST_ARCH_ARM)
+using namespace arch_arm;  // NOLINT
+#elif defined(HOST_ARCH_ARM64)
+using namespace arch_arm64;  // NOLINT
+#else
+#error Unknown host architecture.
+#endif
+
+}  // namespace host
+
+}  // namespace dart
+
 #endif  // RUNTIME_VM_CONSTANTS_H_
diff --git a/runtime/vm/constants_arm.h b/runtime/vm/constants_arm.h
index 4e272c5..fe2ffcc 100644
--- a/runtime/vm/constants_arm.h
+++ b/runtime/vm/constants_arm.h
@@ -5,10 +5,14 @@
 #ifndef RUNTIME_VM_CONSTANTS_ARM_H_
 #define RUNTIME_VM_CONSTANTS_ARM_H_
 
+#ifndef RUNTIME_VM_CONSTANTS_H_
+#error Do not include constants_arm.h directly; use constants.h instead.
+#endif
+
 #include "platform/assert.h"
 #include "platform/globals.h"
 
-namespace dart {
+namespace arch_arm {
 
 // We support both VFPv3-D16 and VFPv3-D32 profiles, but currently only one at
 // a time.
@@ -609,14 +613,14 @@
   inline float ImmFloatField() const {
     uint32_t imm32 = (Bit(19) << 31) | (((1 << 5) - Bit(18)) << 25) |
                      (Bits(16, 2) << 23) | (Bits(0, 4) << 19);
-    return bit_cast<float, uint32_t>(imm32);
+    return ::dart::bit_cast<float, uint32_t>(imm32);
   }
 
   // Field used in VFP double immediate move instruction
   inline double ImmDoubleField() const {
     uint64_t imm64 = (Bit(19) * (1LL << 63)) | (((1LL << 8) - Bit(18)) << 54) |
                      (Bits(16, 2) * (1LL << 52)) | (Bits(0, 4) * (1LL << 48));
-    return bit_cast<double, uint64_t>(imm64);
+    return ::dart::bit_cast<double, uint64_t>(imm64);
   }
 
   inline Register DivRdField() const {
@@ -757,13 +761,13 @@
   // reference to an instruction is to convert a pointer. There is no way
   // to allocate or create instances of class Instr.
   // Use the At(pc) function to create references to Instr.
-  static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+  static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); }
 
  private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
 };
 
-}  // namespace dart
+}  // namespace arch_arm
 
 #endif  // RUNTIME_VM_CONSTANTS_ARM_H_
diff --git a/runtime/vm/constants_arm64.cc b/runtime/vm/constants_arm64.cc
index 0714ae3..9938d7c 100644
--- a/runtime/vm/constants_arm64.cc
+++ b/runtime/vm/constants_arm64.cc
@@ -2,11 +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.
 
-#if defined(TARGET_ARCH_ARM64)
-
+#define RUNTIME_VM_CONSTANTS_H_  // To work around include guard.
 #include "vm/constants_arm64.h"
 
-namespace dart {
+namespace arch_arm64 {
 
 const Register CallingConventions::ArgumentRegisters[] = {
     R0, R1, R2, R3, R4, R5, R6, R7,
@@ -16,6 +15,4 @@
     V0, V1, V2, V3, V4, V5, V6, V7,
 };
 
-}  // namespace dart
-
-#endif
+}  // namespace arch_arm64
diff --git a/runtime/vm/constants_arm64.h b/runtime/vm/constants_arm64.h
index fa592e1..8dfabc8 100644
--- a/runtime/vm/constants_arm64.h
+++ b/runtime/vm/constants_arm64.h
@@ -5,9 +5,13 @@
 #ifndef RUNTIME_VM_CONSTANTS_ARM64_H_
 #define RUNTIME_VM_CONSTANTS_ARM64_H_
 
+#ifndef RUNTIME_VM_CONSTANTS_H_
+#error Do not include constants_arm64.h directly; use constants.h instead.
+#endif
+
 #include "platform/assert.h"
 
-namespace dart {
+namespace arch_arm64 {
 
 enum Register {
   R0 = 0,
@@ -107,7 +111,7 @@
 // Register aliases.
 const Register TMP = R16;  // Used as scratch register by assembler.
 const Register TMP2 = R17;
-const Register PP = R27;   // Caches object pool pointer in generated code.
+const Register PP = R27;  // Caches object pool pointer in generated code.
 const Register CODE_REG = R24;
 const Register FPREG = FP;          // Frame pointer register.
 const Register SPREG = R15;         // Stack pointer register.
@@ -397,10 +401,7 @@
   SystemFixed = CompareBranchFixed | B31 | B30 | B24,
   HINT = SystemFixed | B17 | B16 | B13 | B4 | B3 | B2 | B1 | B0,
   CLREX = SystemFixed | B17 | B16 | B13 | B12 | B11 | B10 | B9 | B8 | B6 | B4 |
-          B3 |
-          B2 |
-          B1 |
-          B0,
+          B3 | B2 | B1 | B0,
 };
 
 // C3.2.5
@@ -1186,13 +1187,13 @@
   // reference to an instruction is to convert a pointer. There is no way
   // to allocate or create instances of class Instr.
   // Use the At(pc) function to create references to Instr.
-  static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+  static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); }
 
  private:
   DISALLOW_ALLOCATION();
   DISALLOW_IMPLICIT_CONSTRUCTORS(Instr);
 };
 
-}  // namespace dart
+}  // namespace arch_arm64
 
 #endif  // RUNTIME_VM_CONSTANTS_ARM64_H_
diff --git a/runtime/vm/constants_ia32.cc b/runtime/vm/constants_ia32.cc
index 62c3f6a..a12af82 100644
--- a/runtime/vm/constants_ia32.cc
+++ b/runtime/vm/constants_ia32.cc
@@ -2,11 +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.
 
-#if defined(TARGET_ARCH_IA32)
-
+#define RUNTIME_VM_CONSTANTS_H_  // To work around include guard.
 #include "vm/constants_ia32.h"
 
-namespace dart {
+namespace arch_ia32 {
 
 // Although 'kArgumentRegisters' and 'kFpuArgumentRegisters' are both 0, we have
 // to give these arrays at least one element to appease MSVC.
@@ -16,6 +15,4 @@
 const FpuRegister CallingConventions::FpuArgumentRegisters[] = {
     static_cast<FpuRegister>(0)};
 
-}  // namespace dart
-
-#endif
+}  // namespace arch_ia32
diff --git a/runtime/vm/constants_ia32.h b/runtime/vm/constants_ia32.h
index 24e3783..16eeb4e 100644
--- a/runtime/vm/constants_ia32.h
+++ b/runtime/vm/constants_ia32.h
@@ -5,9 +5,13 @@
 #ifndef RUNTIME_VM_CONSTANTS_IA32_H_
 #define RUNTIME_VM_CONSTANTS_IA32_H_
 
+#ifndef RUNTIME_VM_CONSTANTS_H_
+#error Do not include constants_ia32.h directly; use constants.h instead.
+#endif
+
 #include "platform/assert.h"
 
-namespace dart {
+namespace arch_ia32 {
 
 enum Register {
   EAX = 0,
@@ -88,7 +92,7 @@
   TIMES_4 = 2,
   TIMES_8 = 3,
   TIMES_16 = 4,
-  TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
+  TIMES_HALF_WORD_SIZE = ::dart::kWordSizeLog2 - 1
 };
 
 class Instr {
@@ -107,7 +111,7 @@
   // reference to an instruction is to convert a pointer. There is no way
   // to allocate or create instances of class Instr.
   // Use the At(pc) function to create references to Instr.
-  static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+  static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); }
 
  private:
   DISALLOW_ALLOCATION();
@@ -142,6 +146,6 @@
   static constexpr Register kSecondNonArgumentRegister = ECX;
 };
 
-}  // namespace dart
+}  // namespace arch_ia32
 
 #endif  // RUNTIME_VM_CONSTANTS_IA32_H_
diff --git a/runtime/vm/constants_kbc.h b/runtime/vm/constants_kbc.h
index 7128a46..d3b0f35 100644
--- a/runtime/vm/constants_kbc.h
+++ b/runtime/vm/constants_kbc.h
@@ -389,6 +389,10 @@
 //    Receiver and argument should have static type int.
 //    Check SP[-1] and SP[0] for null; push SP[-1] <op> SP[0] ? true : false.
 //
+//  - AllocateClosure D
+//
+//    Allocate closure object for closure function ConstantPool[D].
+//
 // BYTECODE LIST FORMAT
 //
 // KernelBytecode list below is specified using the following format:
@@ -485,6 +489,7 @@
   V(CompareIntGe,                          0, ___, ___, ___)                   \
   V(CompareIntLe,                          0, ___, ___, ___)                   \
   V(DirectCall,                          A_D, num, num, ___)                   \
+  V(AllocateClosure,                       D, lit, ___, ___)                   \
 
   // These bytecodes are only generated within the VM. Reassinging their
   // opcodes is not a breaking change.
@@ -505,11 +510,11 @@
   // Magic value of bytecode files.
   static const intptr_t kMagicValue = 0x44424332;  // 'DBC2'
   // Minimum bytecode format version supported by VM.
-  static const intptr_t kMinSupportedBytecodeFormatVersion = 1;
+  static const intptr_t kMinSupportedBytecodeFormatVersion = 2;
   // Maximum bytecode format version supported by VM.
   // The range of supported versions should include version produced by bytecode
   // generator (currentBytecodeFormatVersion in pkg/vm/lib/bytecode/dbc.dart).
-  static const intptr_t kMaxSupportedBytecodeFormatVersion = 3;
+  static const intptr_t kMaxSupportedBytecodeFormatVersion = 4;
 
   enum Opcode {
 #define DECLARE_BYTECODE(name, encoding, op1, op2, op3) k##name,
diff --git a/runtime/vm/constants_x64.cc b/runtime/vm/constants_x64.cc
index 3f38d9d..8d80a33 100644
--- a/runtime/vm/constants_x64.cc
+++ b/runtime/vm/constants_x64.cc
@@ -2,11 +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.
 
-#if defined(TARGET_ARCH_X64)
-
+#define RUNTIME_VM_CONSTANTS_H_  // To work around include guard.
 #include "vm/constants_x64.h"
 
-namespace dart {
+namespace arch_x64 {
 
 #if defined(_WIN64)
 const Register CallingConventions::ArgumentRegisters[] = {
@@ -26,6 +25,4 @@
     XmmRegister::XMM4, XmmRegister::XMM5, XmmRegister::XMM6, XmmRegister::XMM7};
 #endif
 
-}  // namespace dart
-
-#endif
+}  // namespace arch_x64
diff --git a/runtime/vm/constants_x64.h b/runtime/vm/constants_x64.h
index 3e8d0070..3d37645 100644
--- a/runtime/vm/constants_x64.h
+++ b/runtime/vm/constants_x64.h
@@ -5,10 +5,14 @@
 #ifndef RUNTIME_VM_CONSTANTS_X64_H_
 #define RUNTIME_VM_CONSTANTS_X64_H_
 
+#ifndef RUNTIME_VM_CONSTANTS_H_
+#error Do not include constants_x64.h directly; use constants.h instead.
+#endif
+
 #include "platform/assert.h"
 #include "platform/globals.h"
 
-namespace dart {
+namespace arch_x64 {
 
 enum Register {
   RAX = 0,
@@ -140,7 +144,7 @@
   TIMES_4 = 2,
   TIMES_8 = 3,
   TIMES_16 = 4,
-  TIMES_HALF_WORD_SIZE = kWordSizeLog2 - 1
+  TIMES_HALF_WORD_SIZE = ::dart::kWordSizeLog2 - 1
 };
 
 #define R(reg) (1 << (reg))
@@ -166,7 +170,7 @@
   // same time? (Windows no, rest yes)
   static const bool kArgumentIntRegXorFpuReg = true;
 
-  static const intptr_t kShadowSpaceBytes = 4 * kWordSize;
+  static const intptr_t kShadowSpaceBytes = 4 * ::dart::kWordSize;
 
   static const intptr_t kVolatileCpuRegisters =
       R(RAX) | R(RCX) | R(RDX) | R(R8) | R(R9) | R(R10) | R(R11);
@@ -268,7 +272,7 @@
   // reference to an instruction is to convert a pointer. There is no way
   // to allocate or create instances of class Instr.
   // Use the At(pc) function to create references to Instr.
-  static Instr* At(uword pc) { return reinterpret_cast<Instr*>(pc); }
+  static Instr* At(::dart::uword pc) { return reinterpret_cast<Instr*>(pc); }
 
  private:
   DISALLOW_ALLOCATION();
@@ -280,6 +284,6 @@
 // becomes important to us.
 const int MAX_NOP_SIZE = 8;
 
-}  // namespace dart
+}  // namespace arch_x64
 
 #endif  // RUNTIME_VM_CONSTANTS_X64_H_
diff --git a/runtime/vm/cpu_ia32.cc b/runtime/vm/cpu_ia32.cc
index 08cfc5e..82ab263 100644
--- a/runtime/vm/cpu_ia32.cc
+++ b/runtime/vm/cpu_ia32.cc
@@ -9,7 +9,7 @@
 #include "vm/cpu_ia32.h"
 
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_ia32.h"
+#include "vm/constants.h"
 #include "vm/cpuinfo.h"
 #include "vm/heap/heap.h"
 #include "vm/isolate.h"
diff --git a/runtime/vm/cpu_x64.cc b/runtime/vm/cpu_x64.cc
index 553e9cd..a4a17f1 100644
--- a/runtime/vm/cpu_x64.cc
+++ b/runtime/vm/cpu_x64.cc
@@ -9,7 +9,7 @@
 #include "vm/cpu_x64.h"
 
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_x64.h"
+#include "vm/constants.h"
 #include "vm/cpuinfo.h"
 #include "vm/heap/heap.h"
 #include "vm/isolate.h"
diff --git a/runtime/vm/dart.cc b/runtime/vm/dart.cc
index d1354ca..ffb115e 100644
--- a/runtime/vm/dart.cc
+++ b/runtime/vm/dart.cc
@@ -759,6 +759,10 @@
     buffer.AddString(FLAG_causal_async_stacks ? " causal_async_stacks"
                                               : " no-causal_async_stacks");
 
+    buffer.AddString((FLAG_enable_interpreter || FLAG_use_bytecode_compiler)
+                         ? " bytecode"
+                         : " no-bytecode");
+
 // Generated code must match the host architecture and ABI.
 #if defined(TARGET_ARCH_ARM)
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
diff --git a/runtime/vm/dart_api_impl.cc b/runtime/vm/dart_api_impl.cc
index 683a636..b1f2ce4 100644
--- a/runtime/vm/dart_api_impl.cc
+++ b/runtime/vm/dart_api_impl.cc
@@ -806,12 +806,13 @@
   return Api::NewHandle(T, UnhandledException::New(obj, stacktrace));
 }
 
-DART_EXPORT Dart_Handle Dart_PropagateError(Dart_Handle handle) {
+DART_EXPORT void Dart_PropagateError(Dart_Handle handle) {
   Thread* thread = Thread::Current();
+  CHECK_ISOLATE(thread->isolate());
   TransitionNativeToVM transition(thread);
   const Object& obj = Object::Handle(thread->zone(), Api::UnwrapHandle(handle));
   if (!obj.IsError()) {
-    return Api::NewError(
+    FATAL1(
         "%s expects argument 'handle' to be an error handle.  "
         "Did you forget to check Dart_IsError first?",
         CURRENT_FUNC);
@@ -819,7 +820,8 @@
   if (thread->top_exit_frame_info() == 0) {
     // There are no dart frames on the stack so it would be illegal to
     // propagate an error here.
-    return Api::NewError("No Dart frames on stack, cannot propagate error.");
+    FATAL1("No Dart frames on stack, cannot propagate error: %s",
+           Error::Cast(obj).ToErrorCString());
   }
   // Unwind all the API scopes till the exit frame before propagating.
   const Error* error;
@@ -837,16 +839,6 @@
   }
   Exceptions::PropagateError(*error);
   UNREACHABLE();
-  return Api::NewError("Cannot reach here.  Internal error.");
-}
-
-DART_EXPORT void _Dart_ReportErrorHandle(const char* file,
-                                         int line,
-                                         const char* handle,
-                                         const char* message) {
-  fprintf(stderr, "%s:%d: error handle: '%s':\n    '%s'\n", file, line, handle,
-          message);
-  OS::Abort();
 }
 
 DART_EXPORT Dart_Handle Dart_ToString(Dart_Handle object) {
@@ -1045,7 +1037,7 @@
 #if !defined(PRODUCT)
 #define VM_METRIC_API(type, variable, name, unit)                              \
   DART_EXPORT int64_t Dart_VM##variable##Metric() {                            \
-    return vm_metric_##variable##_.value();                                    \
+    return vm_metric_##variable.value();                                       \
   }
 VM_METRIC_LIST(VM_METRIC_API);
 #undef VM_METRIC_API
diff --git a/runtime/vm/dart_api_impl_test.cc b/runtime/vm/dart_api_impl_test.cc
index b4ad32a..406901a 100644
--- a/runtime/vm/dart_api_impl_test.cc
+++ b/runtime/vm/dart_api_impl_test.cc
@@ -571,8 +571,7 @@
     EXPECT_VALID(result);  // We do not expect to reach here.
     UNREACHABLE();
   } else {
-    result = Dart_PropagateError(result);
-    EXPECT_VALID(result);  // We do not expect to reach here.
+    Dart_PropagateError(result);
     UNREACHABLE();
   }
 }
@@ -5375,7 +5374,7 @@
   Dart_Handle instance;
   // Create a test library and Load up a test script in it.
   // The test library must have a dart: url so it can import dart:_internal.
-  Dart_Handle lib = TestCase::LoadCoreTestScript(kScriptChars, NULL);
+  Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
   Dart_Handle type = Dart_GetType(lib, NewString("TestClass"), 0, NULL);
   EXPECT_VALID(type);
 
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index 52064e7..3759e0f 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1407,34 +1407,28 @@
       ContextLevel());
 }
 
-void ActivationFrame::PrintToJSONObject(JSONObject* jsobj, bool full) {
+void ActivationFrame::PrintToJSONObject(JSONObject* jsobj) {
   if (kind_ == kRegular) {
-    PrintToJSONObjectRegular(jsobj, full);
+    PrintToJSONObjectRegular(jsobj);
   } else if (kind_ == kAsyncCausal) {
-    PrintToJSONObjectAsyncCausal(jsobj, full);
+    PrintToJSONObjectAsyncCausal(jsobj);
   } else if (kind_ == kAsyncSuspensionMarker) {
-    PrintToJSONObjectAsyncSuspensionMarker(jsobj, full);
+    PrintToJSONObjectAsyncSuspensionMarker(jsobj);
   } else if (kind_ == kAsyncActivation) {
-    PrintToJSONObjectAsyncActivation(jsobj, full);
+    PrintToJSONObjectAsyncActivation(jsobj);
   } else {
     UNIMPLEMENTED();
   }
 }
 
-void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj, bool full) {
+void ActivationFrame::PrintToJSONObjectRegular(JSONObject* jsobj) {
   const Script& script = Script::Handle(SourceScript());
   jsobj->AddProperty("type", "Frame");
   jsobj->AddProperty("kind", KindToCString(kind_));
   const TokenPosition pos = TokenPos().SourcePosition();
   jsobj->AddLocation(script, pos);
-  jsobj->AddProperty("function", function(), !full);
+  jsobj->AddProperty("function", function());
   jsobj->AddProperty("code", code());
-  if (full) {
-    // TODO(cutch): The old "full" script usage no longer fits
-    // in the world where we pass the script as part of the
-    // location.
-    jsobj->AddProperty("script", script, !full);
-  }
   {
     JSONArray jsvars(jsobj, "vars");
     const int num_vars = NumLocalVariables();
@@ -1455,7 +1449,7 @@
         jsvar.AddProperty("type", "BoundVariable");
         var_name = String::ScrubName(var_name);
         jsvar.AddProperty("name", var_name.ToCString());
-        jsvar.AddProperty("value", var_value, !full);
+        jsvar.AddProperty("value", var_value);
         // Where was the variable declared?
         jsvar.AddProperty("declarationTokenPos", declaration_token_pos);
         // When the variable becomes visible to the scope.
@@ -1467,45 +1461,31 @@
   }
 }
 
-void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj,
-                                                   bool full) {
+void ActivationFrame::PrintToJSONObjectAsyncCausal(JSONObject* jsobj) {
   jsobj->AddProperty("type", "Frame");
   jsobj->AddProperty("kind", KindToCString(kind_));
   const Script& script = Script::Handle(SourceScript());
   const TokenPosition pos = TokenPos().SourcePosition();
   jsobj->AddLocation(script, pos);
-  jsobj->AddProperty("function", function(), !full);
+  jsobj->AddProperty("function", function());
   jsobj->AddProperty("code", code());
-  if (full) {
-    // TODO(cutch): The old "full" script usage no longer fits
-    // in the world where we pass the script as part of the
-    // location.
-    jsobj->AddProperty("script", script, !full);
-  }
 }
 
-void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj,
-                                                             bool full) {
+void ActivationFrame::PrintToJSONObjectAsyncSuspensionMarker(
+    JSONObject* jsobj) {
   jsobj->AddProperty("type", "Frame");
   jsobj->AddProperty("kind", KindToCString(kind_));
   jsobj->AddProperty("marker", "AsynchronousSuspension");
 }
 
-void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj,
-                                                       bool full) {
+void ActivationFrame::PrintToJSONObjectAsyncActivation(JSONObject* jsobj) {
   jsobj->AddProperty("type", "Frame");
   jsobj->AddProperty("kind", KindToCString(kind_));
   const Script& script = Script::Handle(SourceScript());
   const TokenPosition pos = TokenPos().SourcePosition();
   jsobj->AddLocation(script, pos);
-  jsobj->AddProperty("function", function(), !full);
+  jsobj->AddProperty("function", function());
   jsobj->AddProperty("code", code());
-  if (full) {
-    // TODO(cutch): The old "full" script usage no longer fits
-    // in the world where we pass the script as part of the
-    // location.
-    jsobj->AddProperty("script", script, !full);
-  }
 }
 
 static bool IsFunctionVisible(const Function& function) {
diff --git a/runtime/vm/debugger.h b/runtime/vm/debugger.h
index 011dcca..d15fbb9 100644
--- a/runtime/vm/debugger.h
+++ b/runtime/vm/debugger.h
@@ -338,10 +338,7 @@
                                         const Array& type_definitions,
                                         const TypeArguments& type_arguments);
 
-  // Print the activation frame into |jsobj|. if |full| is false, script
-  // and local variable objects are only references. if |full| is true,
-  // the complete script, function, and, local variable objects are included.
-  void PrintToJSONObject(JSONObject* jsobj, bool full = false);
+  void PrintToJSONObject(JSONObject* jsobj);
 
   RawObject* GetAsyncAwaiter();
   RawObject* GetCausalStack();
@@ -349,10 +346,10 @@
   bool HandlesException(const Instance& exc_obj);
 
  private:
-  void PrintToJSONObjectRegular(JSONObject* jsobj, bool full);
-  void PrintToJSONObjectAsyncCausal(JSONObject* jsobj, bool full);
-  void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj, bool full);
-  void PrintToJSONObjectAsyncActivation(JSONObject* jsobj, bool full);
+  void PrintToJSONObjectRegular(JSONObject* jsobj);
+  void PrintToJSONObjectAsyncCausal(JSONObject* jsobj);
+  void PrintToJSONObjectAsyncSuspensionMarker(JSONObject* jsobj);
+  void PrintToJSONObjectAsyncActivation(JSONObject* jsobj);
   void PrintContextMismatchError(intptr_t ctx_slot,
                                  intptr_t frame_ctx_level,
                                  intptr_t var_ctx_level);
diff --git a/runtime/vm/flag_list.h b/runtime/vm/flag_list.h
index edd0226..d7b662d 100644
--- a/runtime/vm/flag_list.h
+++ b/runtime/vm/flag_list.h
@@ -57,8 +57,6 @@
     "Debugger support async functions.")                                       \
   P(background_compilation, bool, USING_MULTICORE,                             \
     "Run optimizing compilation in background")                                \
-  R(background_compilation_stop_alot, false, bool, false,                      \
-    "Stress test system: stop background compiler often.")                     \
   P(causal_async_stacks, bool, !USING_PRODUCT, "Improved async stacks")        \
   P(collect_code, bool, true, "Attempt to GC infrequently used code.")         \
   P(collect_dynamic_function_names, bool, true,                                \
@@ -127,6 +125,9 @@
     "Initial size of new gen semi space in MB")                                \
   P(optimization_counter_threshold, int, 30000,                                \
     "Function's usage-counter value before it is optimized, -1 means never")   \
+  R(randomize_optimization_counter, false, bool, false,                        \
+    "Randomize optimization counter thresholds on a per-function basis (for "  \
+    "testing).")                                                               \
   P(optimization_level, int, 2,                                                \
     "Optimization level: 1 (favor size), 2 (default), 3 (favor speed)")        \
   P(old_gen_heap_size, int, kDefaultMaxOldGenHeapSize,                         \
diff --git a/runtime/vm/frame_layout.h b/runtime/vm/frame_layout.h
index 53ddcc7..3242353 100644
--- a/runtime/vm/frame_layout.h
+++ b/runtime/vm/frame_layout.h
@@ -23,9 +23,13 @@
   // The offset (in words) from FP to the last fixed object.
   int last_fixed_object_from_fp;
 
-  // The offset (in words) from FP to the first local.
+  // The offset (in words) from FP to the slot past the last parameter.
   int param_end_from_fp;
 
+  // The offset (in words) from SP on entry (before frame is setup) to
+  // the last parameter.
+  int last_param_from_entry_sp;
+
   // The offset (in words) from FP to the first local.
   int first_local_from_fp;
 
diff --git a/runtime/vm/instructions_arm.cc b/runtime/vm/instructions_arm.cc
index 785f8fb..c8e8af9 100644
--- a/runtime/vm/instructions_arm.cc
+++ b/runtime/vm/instructions_arm.cc
@@ -9,7 +9,7 @@
 #include "vm/instructions_arm.h"
 
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
 #include "vm/reverse_pc_lookup_cache.h"
diff --git a/runtime/vm/instructions_arm.h b/runtime/vm/instructions_arm.h
index 37b7cef..d3e1cdb 100644
--- a/runtime/vm/instructions_arm.h
+++ b/runtime/vm/instructions_arm.h
@@ -12,7 +12,7 @@
 
 #include "vm/allocation.h"
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 #include "vm/native_function.h"
 
 namespace dart {
diff --git a/runtime/vm/instructions_arm64.cc b/runtime/vm/instructions_arm64.cc
index ea9a118..d34d7a7 100644
--- a/runtime/vm/instructions_arm64.cc
+++ b/runtime/vm/instructions_arm64.cc
@@ -9,7 +9,7 @@
 #include "vm/instructions_arm64.h"
 
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
 #include "vm/reverse_pc_lookup_cache.h"
diff --git a/runtime/vm/instructions_arm64.h b/runtime/vm/instructions_arm64.h
index c78cee3..8550643 100644
--- a/runtime/vm/instructions_arm64.h
+++ b/runtime/vm/instructions_arm64.h
@@ -12,7 +12,7 @@
 
 #include "vm/allocation.h"
 #include "vm/compiler/assembler/assembler.h"
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 #include "vm/native_function.h"
 
 namespace dart {
diff --git a/runtime/vm/instructions_x64.cc b/runtime/vm/instructions_x64.cc
index 70ed255..7c0e336 100644
--- a/runtime/vm/instructions_x64.cc
+++ b/runtime/vm/instructions_x64.cc
@@ -9,7 +9,7 @@
 #include "vm/instructions.h"
 #include "vm/instructions_x64.h"
 
-#include "vm/constants_x64.h"
+#include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/object.h"
 
diff --git a/runtime/vm/interpreter.cc b/runtime/vm/interpreter.cc
index 746e199..c36b640 100644
--- a/runtime/vm/interpreter.cc
+++ b/runtime/vm/interpreter.cc
@@ -209,6 +209,11 @@
     // Everything matches.
     return false;
   }
+
+  DART_FORCE_INLINE static bool IsFinalized(RawClass* cls) {
+    return Class::ClassFinalizedBits::decode(cls->ptr()->state_bits_) ==
+           RawClass::kFinalized;
+  }
 };
 
 DART_FORCE_INLINE static uint32_t* SavedCallerPC(RawObject** FP) {
@@ -222,6 +227,21 @@
   return function;
 }
 
+DART_FORCE_INLINE static RawObject* InitializeHeader(uword addr,
+                                                     intptr_t class_id,
+                                                     intptr_t instance_size) {
+  uint32_t tags = 0;
+  tags = RawObject::ClassIdTag::update(class_id, tags);
+  tags = RawObject::SizeTag::update(instance_size, tags);
+  tags = RawObject::OldBit::update(false, tags);
+  tags = RawObject::OldAndNotMarkedBit::update(false, tags);
+  tags = RawObject::OldAndNotRememberedBit::update(false, tags);
+  tags = RawObject::NewBit::update(true, tags);
+  // Also writes zero in the hash_ field.
+  *reinterpret_cast<uword*>(addr + Object::tags_offset()) = tags;
+  return RawObject::FromAddr(addr);
+}
+
 void LookupCache::Clear() {
   for (intptr_t i = 0; i < kNumEntries; i++) {
     entries_[i].receiver_cid = kIllegalCid;
@@ -432,17 +452,32 @@
   frame[1] = Bytecode::null();
   frame[2] = reinterpret_cast<RawObject*>(pc);
   frame[3] = reinterpret_cast<RawObject*>(base);
-  fp_ = frame + kKBCDartFrameFixedSize;
-  thread->set_top_exit_frame_info(reinterpret_cast<uword>(fp_));
+
+  RawObject** exit_fp = frame + kKBCDartFrameFixedSize;
+  thread->set_top_exit_frame_info(reinterpret_cast<uword>(exit_fp));
+  fp_ = exit_fp;
+
 #if defined(DEBUG)
   if (IsTracingExecution()) {
     THR_Print("%" Pu64 " ", icount_);
     THR_Print("Exiting interpreter 0x%" Px " at fp_ 0x%" Px "\n",
-              reinterpret_cast<uword>(this), reinterpret_cast<uword>(fp_));
+              reinterpret_cast<uword>(this), reinterpret_cast<uword>(exit_fp));
   }
 #endif
 }
 
+void Interpreter::Unexit(Thread* thread) {
+#if !defined(PRODUCT)
+  // For the profiler.
+  RawObject** exit_fp =
+      reinterpret_cast<RawObject**>(thread->top_exit_frame_info());
+  ASSERT(exit_fp != 0);
+  pc_ = SavedCallerPC(exit_fp);
+  fp_ = SavedCallerFP(exit_fp);
+#endif
+  thread->set_top_exit_frame_info(0);
+}
+
 // Calling into runtime may trigger garbage collection and relocate objects,
 // so all RawObject* pointers become outdated and should not be used across
 // runtime calls.
@@ -458,7 +493,7 @@
     thread->set_vm_tag(reinterpret_cast<uword>(drt));
     drt(args);
     thread->set_vm_tag(VMTag::kDartInterpretedTagId);
-    thread->set_top_exit_frame_info(0);
+    interpreter->Unexit(thread);
     return true;
   } else {
     return false;
@@ -475,7 +510,7 @@
     thread->set_vm_tag(reinterpret_cast<uword>(function));
     wrapper(args, function);
     thread->set_vm_tag(VMTag::kDartInterpretedTagId);
-    thread->set_top_exit_frame_info(0);
+    interpreter->Unexit(thread);
     return true;
   } else {
     return false;
@@ -522,9 +557,9 @@
 #else
       result = entrypoint(code, argdesc_, call_base, thread);
 #endif
-      thread->set_top_exit_frame_info(0);
       ASSERT(thread->vm_tag() == VMTag::kDartInterpretedTagId);
       ASSERT(thread->execution_state() == Thread::kThreadInGenerated);
+      Unexit(thread);
     } else {
       return false;
     }
@@ -553,10 +588,10 @@
     if (RawObject::IsErrorClassId(result_cid)) {
       // Unwind to entry frame.
       fp_ = *FP;
-      pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_));
+      pc_ = SavedCallerPC(fp_);
       while (!IsEntryFrameMarker(pc_)) {
         fp_ = SavedCallerFP(fp_);
-        pc_ = reinterpret_cast<uword>(SavedCallerPC(fp_));
+        pc_ = SavedCallerPC(fp_);
       }
       // Pop entry frame.
       fp_ = SavedCallerFP(fp_);
@@ -810,9 +845,9 @@
   callee_fp[kKBCSavedCallerFpSlotFromFp] = reinterpret_cast<RawObject*>(*FP);
   pp_ = bytecode->ptr()->object_pool_;
   *pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
-  pc_ = reinterpret_cast<uword>(*pc);  // For the profiler.
+  NOT_IN_PRODUCT(pc_ = *pc);  // For the profiler.
   *FP = callee_fp;
-  fp_ = callee_fp;  // For the profiler.
+  NOT_IN_PRODUCT(fp_ = callee_fp);  // For the profiler.
   *SP = *FP - 1;
   return true;
 }
@@ -886,7 +921,10 @@
     Exit(thread, *FP, top + 5, *pc);
     NativeArguments native_args(thread, 3, /* argv */ top + 1,
                                 /* result */ top + 4);
-    DRT_InterpretedInterfaceCallMissHandler(native_args);
+    if (!InvokeRuntime(thread, this, DRT_InterpretedInterfaceCallMissHandler,
+                       native_args)) {
+      return false;
+    }
 
     target = static_cast<RawFunction*>(top[4]);
     target_name = static_cast<RawString*>(top[2]);
@@ -1091,9 +1129,9 @@
 
 #define HANDLE_EXCEPTION                                                       \
   do {                                                                         \
-    FP = reinterpret_cast<RawObject**>(fp_);                                   \
-    pc = reinterpret_cast<uint32_t*>(pc_);                                     \
-    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {                     \
+    FP = fp_;                                                                  \
+    pc = pc_;                                                                  \
+    if (IsEntryFrameMarker(pc)) {                                              \
       pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
       argdesc_ =                                                               \
           reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);   \
@@ -1119,9 +1157,9 @@
 
 #define HANDLE_EXCEPTION                                                       \
   do {                                                                         \
-    FP = reinterpret_cast<RawObject**>(fp_);                                   \
-    pc = reinterpret_cast<uint32_t*>(pc_);                                     \
-    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {                     \
+    FP = fp_;                                                                  \
+    pc = pc_;                                                                  \
+    if (IsEntryFrameMarker(pc)) {                                              \
       pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]); \
       argdesc_ =                                                               \
           reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);   \
@@ -1140,7 +1178,6 @@
 #define HANDLE_RETURN                                                          \
   do {                                                                         \
     pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;          \
-    fp_ = FP; /* For the profiler. */                                          \
   } while (0)
 
 // Runtime call helpers: handle invocation and potential exception after return.
@@ -1178,7 +1215,7 @@
 #define BOX_INT64_RESULT(result)                                               \
   if (LIKELY(Smi::IsValid(result))) {                                          \
     SP[0] = Smi::New(static_cast<intptr_t>(result));                           \
-  } else if (!AllocateInt64Box(thread, result, pc, FP, SP)) {                  \
+  } else if (!AllocateMint(thread, result, pc, FP, SP)) {                      \
     HANDLE_EXCEPTION;                                                          \
   }                                                                            \
   ASSERT(Integer::GetInt64Value(RAW_CAST(Integer, SP[0])) == result);
@@ -1274,26 +1311,22 @@
               arguments.raw_ptr()->data(), thread);
 }
 
-// Allocate _Mint box for the given int64_t value and puts it into SP[0].
+// Allocate a _Mint for the given int64_t value and puts it into SP[0].
 // Returns false on exception.
-DART_NOINLINE bool Interpreter::AllocateInt64Box(Thread* thread,
-                                                 int64_t value,
-                                                 uint32_t* pc,
-                                                 RawObject** FP,
-                                                 RawObject** SP) {
+DART_NOINLINE bool Interpreter::AllocateMint(Thread* thread,
+                                             int64_t value,
+                                             uint32_t* pc,
+                                             RawObject** FP,
+                                             RawObject** SP) {
   ASSERT(!Smi::IsValid(value));
   const intptr_t instance_size = Mint::InstanceSize();
-  const uword start =
-      thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
-  if (LIKELY(start != 0)) {
-    uword tags = 0;
-    tags = RawObject::ClassIdTag::update(kMintCid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    // Also writes zero in the hash_ field.
-    *reinterpret_cast<uword*>(start + Mint::tags_offset()) = tags;
-    *reinterpret_cast<int64_t*>(start + Mint::value_offset()) = value;
-    SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
+  const uword start = thread->top();
+  if (LIKELY((start + instance_size) < thread->end())) {
+    thread->set_top(start + instance_size);
+    RawMint* result =
+        Mint::RawCast(InitializeHeader(start, kMintCid, instance_size));
+    result->ptr()->value_ = value;
+    SP[0] = result;
     return true;
   } else {
     SP[0] = 0;  // Space for the result.
@@ -1309,110 +1342,132 @@
   }
 }
 
-// Allocate _Double box for the given double value and puts it into SP[0].
+// Allocate a _Double for the given double value and put it into SP[0].
 // Returns false on exception.
-DART_NOINLINE bool Interpreter::AllocateDoubleBox(Thread* thread,
-                                                  double value,
+DART_NOINLINE bool Interpreter::AllocateDouble(Thread* thread,
+                                               double value,
+                                               uint32_t* pc,
+                                               RawObject** FP,
+                                               RawObject** SP) {
+  const intptr_t instance_size = Double::InstanceSize();
+  const uword start = thread->top();
+  if (LIKELY((start + instance_size) < thread->end())) {
+    thread->set_top(start + instance_size);
+    RawDouble* result =
+        Double::RawCast(InitializeHeader(start, kDoubleCid, instance_size));
+    result->ptr()->value_ = value;
+    SP[0] = result;
+    return true;
+  } else {
+    SP[0] = 0;  // Space for the result.
+    SP[1] = thread->isolate()->object_store()->double_class();
+    SP[2] = Object::null();  // Type arguments.
+    Exit(thread, FP, SP + 3, pc);
+    NativeArguments args(thread, 2, SP + 1, SP);
+    if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
+      return false;
+    }
+    Double::RawCast(SP[0])->ptr()->value_ = value;
+    return true;
+  }
+}
+
+// Allocate a _Float32x4 for the given simd value and put it into SP[0].
+// Returns false on exception.
+DART_NOINLINE bool Interpreter::AllocateFloat32x4(Thread* thread,
+                                                  simd128_value_t value,
                                                   uint32_t* pc,
                                                   RawObject** FP,
                                                   RawObject** SP) {
-  const intptr_t instance_size = Double::InstanceSize();
-  const uword start =
-      thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
-  if (LIKELY(start != 0)) {
-    uword tags = 0;
-    tags = RawObject::ClassIdTag::update(kDoubleCid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    // Also writes zero in the hash_ field.
-    *reinterpret_cast<uword*>(start + Double::tags_offset()) = tags;
-    *reinterpret_cast<double*>(start + Double::value_offset()) = value;
-    SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
-    return true;
-  } else {
-    SP[0] = 0;  // Space for the result.
-    SP[1] = thread->isolate()->object_store()->double_class();  // Class object.
-    SP[2] = Object::null();  // Type arguments.
-    Exit(thread, FP, SP + 3, pc);
-    NativeArguments args(thread, 2, SP + 1, SP);
-    if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
-      return false;
-    }
-    reinterpret_cast<RawDouble*>(SP[0])->ptr()->value_ = value;
-    return true;
-  }
-}
-
-// Allocate _Float32x4 box for the given simd value and puts it into SP[0].
-// Returns false on exception.
-DART_NOINLINE bool Interpreter::AllocateFloat32x4Box(Thread* thread,
-                                                     simd128_value_t value,
-                                                     uint32_t* pc,
-                                                     RawObject** FP,
-                                                     RawObject** SP) {
   const intptr_t instance_size = Float32x4::InstanceSize();
-  const uword start =
-      thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
-  if (LIKELY(start != 0)) {
-    uword tags = 0;
-    tags = RawObject::ClassIdTag::update(kFloat32x4Cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    // Also writes zero in the hash_ field.
-    *reinterpret_cast<uword*>(start + Float32x4::tags_offset()) = tags;
-    SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
-    value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_);
+  const uword start = thread->top();
+  if (LIKELY((start + instance_size) < thread->end())) {
+    thread->set_top(start + instance_size);
+    RawFloat32x4* result = Float32x4::RawCast(
+        InitializeHeader(start, kFloat32x4Cid, instance_size));
+    value.writeTo(result->ptr()->value_);
+    SP[0] = result;
     return true;
   } else {
     SP[0] = 0;  // Space for the result.
-    SP[1] =
-        thread->isolate()->object_store()->float32x4_class();  // Class object.
+    SP[1] = thread->isolate()->object_store()->float32x4_class();
     SP[2] = Object::null();  // Type arguments.
     Exit(thread, FP, SP + 3, pc);
     NativeArguments args(thread, 2, SP + 1, SP);
     if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
       return false;
     }
-    value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_);
+    value.writeTo(Float32x4::RawCast(SP[0])->ptr()->value_);
     return true;
   }
 }
 
-// Allocate _Float64x2 box for the given simd value and puts it into SP[0].
+// Allocate _Float64x2 box for the given simd value and put it into SP[0].
 // Returns false on exception.
-DART_NOINLINE bool Interpreter::AllocateFloat64x2Box(Thread* thread,
-                                                     simd128_value_t value,
-                                                     uint32_t* pc,
-                                                     RawObject** FP,
-                                                     RawObject** SP) {
+DART_NOINLINE bool Interpreter::AllocateFloat64x2(Thread* thread,
+                                                  simd128_value_t value,
+                                                  uint32_t* pc,
+                                                  RawObject** FP,
+                                                  RawObject** SP) {
   const intptr_t instance_size = Float64x2::InstanceSize();
-  const uword start =
-      thread->heap()->new_space()->TryAllocateInTLAB(thread, instance_size);
-  if (LIKELY(start != 0)) {
-    uword tags = 0;
-    tags = RawObject::ClassIdTag::update(kFloat64x2Cid, tags);
-    tags = RawObject::SizeTag::update(instance_size, tags);
-    tags = RawObject::NewBit::update(true, tags);
-    // Also writes zero in the hash_ field.
-    *reinterpret_cast<uword*>(start + Float64x2::tags_offset()) = tags;
-    SP[0] = reinterpret_cast<RawObject*>(start + kHeapObjectTag);
-    value.writeTo(reinterpret_cast<RawFloat64x2*>(SP[0])->ptr()->value_);
+  const uword start = thread->top();
+  if (LIKELY((start + instance_size) < thread->end())) {
+    thread->set_top(start + instance_size);
+    RawFloat64x2* result = Float64x2::RawCast(
+        InitializeHeader(start, kFloat64x2Cid, instance_size));
+    value.writeTo(result->ptr()->value_);
+    SP[0] = result;
     return true;
   } else {
     SP[0] = 0;  // Space for the result.
-    SP[1] =
-        thread->isolate()->object_store()->float64x2_class();  // Class object.
+    SP[1] = thread->isolate()->object_store()->float64x2_class();
     SP[2] = Object::null();  // Type arguments.
     Exit(thread, FP, SP + 3, pc);
     NativeArguments args(thread, 2, SP + 1, SP);
     if (!InvokeRuntime(thread, this, DRT_AllocateObject, args)) {
       return false;
     }
-    value.writeTo(reinterpret_cast<RawFloat32x4*>(SP[0])->ptr()->value_);
+    value.writeTo(Float64x2::RawCast(SP[0])->ptr()->value_);
     return true;
   }
 }
 
+// Allocate a _List with the given type arguments and length and put it into
+// SP[0]. Returns false on exception.
+bool Interpreter::AllocateArray(Thread* thread,
+                                RawTypeArguments* type_args,
+                                RawObject* length_object,
+                                uint32_t* pc,
+                                RawObject** FP,
+                                RawObject** SP) {
+  if (LIKELY(!length_object->IsHeapObject())) {
+    const intptr_t length = Smi::Value(Smi::RawCast(length_object));
+    if (LIKELY((0 <= length) && (length <= Array::kMaxElements))) {
+      const intptr_t instance_size = Array::InstanceSize(length);
+      const uword start = thread->top();
+      if (LIKELY((start + instance_size) < thread->end())) {
+        thread->set_top(start + instance_size);
+        RawArray* result =
+            Array::RawCast(InitializeHeader(start, kArrayCid, instance_size));
+        result->ptr()->type_arguments_ = type_args;
+        result->ptr()->length_ = Smi::New(length);
+        for (intptr_t i = 0; i < length; i++) {
+          result->ptr()->data()[i] = Object::null();
+        }
+        SP[0] = result;
+        return true;
+      }
+    }
+  }
+
+  SP[0] = 0;  // Space for the result;
+  SP[1] = length_object;
+  SP[2] = type_args;
+  Exit(thread, FP, SP + 3, pc);
+  NativeArguments args(thread, 2, SP + 1, SP);
+  return InvokeRuntime(thread, this, DRT_AllocateArray, args);
+}
+
 RawObject* Interpreter::Call(RawFunction* function,
                              RawArray* argdesc,
                              intptr_t argc,
@@ -1494,8 +1549,8 @@
   // Ready to start executing bytecode. Load entry point and corresponding
   // object pool.
   pc = reinterpret_cast<uint32_t*>(bytecode->ptr()->instructions_);
-  pc_ = reinterpret_cast<uword>(pc);  // For the profiler.
-  fp_ = FP;                           // For the profiler.
+  NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
+  NOT_IN_PRODUCT(fp_ = FP);  // For the profiler.
   pp_ = bytecode->ptr()->object_pool_;
 
   // Save current VM tag and mark thread as executing Dart code. For the
@@ -1988,7 +2043,8 @@
       RawObject** call_top = SP + 1;
 
       InterpreterHelpers::IncrementUsageCounter(FrameFunction(FP));
-      RawString* target_name = static_cast<RawString*>(LOAD_CONSTANT(kidx));
+      RawString* target_name =
+          static_cast<RawFunction*>(LOAD_CONSTANT(kidx))->ptr()->name_;
       argdesc_ = static_cast<RawArray*>(LOAD_CONSTANT(kidx + 1));
       if (!InterfaceCall(thread, target_name, call_base, call_top, &pc, &FP,
                          &SP)) {
@@ -2092,12 +2148,12 @@
         //                                            : new _GrowableList<E>(0);
         // }
         if (InterpreterHelpers::ArgDescPosCount(argdesc_) == 2) {
-          SP[1] = SP[0];   // length
-          SP[2] = SP[-1];  // type
-          Exit(thread, FP, SP + 3, pc);
-          NativeArguments native_args(thread, 2, SP + 1, SP - 1);
-          INVOKE_RUNTIME(DRT_AllocateArray, native_args);
-          SP -= 1;  // Result is in SP - 1.
+          RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+          RawObject* length = SP[0];
+          SP--;
+          if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
+            HANDLE_EXCEPTION;
+          }
         } else {
           ASSERT(InterpreterHelpers::ArgDescPosCount(argdesc_) == 1);
           // SP[-1] is type.
@@ -2115,12 +2171,12 @@
         }
       } break;
       case MethodRecognizer::kObjectArrayAllocate: {
-        SP[1] = SP[0];   // length
-        SP[2] = SP[-1];  // type
-        Exit(thread, FP, SP + 3, pc);
-        NativeArguments native_args(thread, 2, SP + 1, SP - 1);
-        INVOKE_RUNTIME(DRT_AllocateArray, native_args);
-        SP -= 1;  // Result is in SP - 1.
+        RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+        RawObject* length = SP[0];
+        SP--;
+        if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
+          HANDLE_EXCEPTION;
+        }
       } break;
       case MethodRecognizer::kLinkedHashMap_getIndex: {
         RawInstance* instance = reinterpret_cast<RawInstance*>(SP[0]);
@@ -2224,20 +2280,23 @@
     result = *SP;
     // Restore caller PC.
     pc = SavedCallerPC(FP);
-    pc_ = reinterpret_cast<uword>(pc);  // For the profiler.
 
     // Check if it is a fake PC marking the entry frame.
-    if (IsEntryFrameMarker(reinterpret_cast<uword>(pc))) {
+    if (IsEntryFrameMarker(pc)) {
       // Pop entry frame.
-      fp_ = SavedCallerFP(FP);
+      RawObject** entry_fp = SavedCallerFP(FP);
       // Restore exit frame info saved in entry frame.
-      pp_ = reinterpret_cast<RawObjectPool*>(fp_[kKBCSavedPpSlotFromEntryFp]);
-      argdesc_ =
-          reinterpret_cast<RawArray*>(fp_[kKBCSavedArgDescSlotFromEntryFp]);
-      uword exit_fp = reinterpret_cast<uword>(fp_[kKBCExitLinkSlotFromEntryFp]);
+      pp_ = reinterpret_cast<RawObjectPool*>(
+          entry_fp[kKBCSavedPpSlotFromEntryFp]);
+      argdesc_ = reinterpret_cast<RawArray*>(
+          entry_fp[kKBCSavedArgDescSlotFromEntryFp]);
+      uword exit_fp =
+          reinterpret_cast<uword>(entry_fp[kKBCExitLinkSlotFromEntryFp]);
       thread->set_top_exit_frame_info(exit_fp);
       thread->set_top_resource(top_resource);
       thread->set_vm_tag(vm_tag);
+      fp_ = entry_fp;
+      NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
 #if defined(DEBUG)
       if (IsTracingExecution()) {
         THR_Print("%" Pu64 " ", icount_);
@@ -2262,7 +2321,8 @@
     // Restore SP, FP and PP. Push result and dispatch.
     SP = FrameArguments(FP, argc);
     FP = SavedCallerFP(FP);
-    fp_ = FP;  // For the profiler.
+    NOT_IN_PRODUCT(fp_ = FP);  // For the profiler.
+    NOT_IN_PRODUCT(pc_ = pc);  // For the profiler.
     pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
     *SP = result;
     DISPATCH();
@@ -2315,7 +2375,7 @@
       double raw_value = Double::RawCast(value)->ptr()->value_;
       ASSERT(*(reinterpret_cast<RawDouble**>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
-      if (!AllocateDoubleBox(thread, raw_value, pc, FP, SP)) {
+      if (!AllocateDouble(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
       RawDouble* box = Double::RawCast(SP[0]);
@@ -2328,7 +2388,7 @@
       raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
       ASSERT(*(reinterpret_cast<RawFloat32x4**>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
-      if (!AllocateFloat32x4Box(thread, raw_value, pc, FP, SP)) {
+      if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
       RawFloat32x4* box = Float32x4::RawCast(SP[0]);
@@ -2341,7 +2401,7 @@
       raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
       ASSERT(*(reinterpret_cast<RawFloat64x2**>(instance->ptr()) +
                offset_in_words) == null_value);  // Initializing store.
-      if (!AllocateFloat64x2Box(thread, raw_value, pc, FP, SP)) {
+      if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
       RawFloat64x2* box = Float64x2::RawCast(SP[0]);
@@ -2436,17 +2496,32 @@
     DISPATCH();
   }
 
-  // TODO(vegorov) allocation bytecodes can benefit from the new-space
-  // allocation fast-path that does not transition into the runtime system.
   {
     BYTECODE(AllocateContext, A_D);
     const uint16_t num_context_variables = rD;
     {
-      *++SP = 0;
-      SP[1] = Smi::New(num_context_variables);
-      Exit(thread, FP, SP + 2, pc);
-      NativeArguments args(thread, 1, SP + 1, SP);
-      INVOKE_RUNTIME(DRT_AllocateContext, args);
+      const intptr_t instance_size =
+          Context::InstanceSize(num_context_variables);
+      ASSERT(Utils::IsAligned(instance_size, kObjectAlignment));
+      const uword start = thread->top();
+      if (LIKELY((start + instance_size) < thread->end())) {
+        thread->set_top(start + instance_size);
+        RawContext* result = Context::RawCast(
+            InitializeHeader(start, kContextCid, instance_size));
+        result->ptr()->num_variables_ = num_context_variables;
+        result->ptr()->parent_ = static_cast<RawContext*>(null_value);
+        for (intptr_t offset = sizeof(RawContext); offset < instance_size;
+             offset += kWordSize) {
+          *reinterpret_cast<RawObject**>(start + offset) = null_value;
+        }
+        *++SP = result;
+      } else {
+        *++SP = 0;
+        SP[1] = Smi::New(num_context_variables);
+        Exit(thread, FP, SP + 2, pc);
+        NativeArguments args(thread, 1, SP + 1, SP);
+        INVOKE_RUNTIME(DRT_AllocateContext, args);
+      }
     }
     DISPATCH();
   }
@@ -2464,9 +2539,27 @@
 
   {
     BYTECODE(Allocate, A_D);
-    SP[1] = 0;                  // Space for the result.
-    SP[2] = LOAD_CONSTANT(rD);  // Class object.
-    SP[3] = null_value;         // Type arguments.
+    RawClass* cls = Class::RawCast(LOAD_CONSTANT(rD));
+    if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
+      const intptr_t class_id = cls->ptr()->id_;
+      const intptr_t instance_size = cls->ptr()->instance_size_in_words_
+                                     << kWordSizeLog2;
+      const uword start = thread->top();
+      if (LIKELY((start + instance_size) < thread->end())) {
+        thread->set_top(start + instance_size);
+        RawObject* result = InitializeHeader(start, class_id, instance_size);
+        for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+             offset += kWordSize) {
+          *reinterpret_cast<RawObject**>(start + offset) = null_value;
+        }
+        *++SP = result;
+        DISPATCH();
+      }
+    }
+
+    SP[1] = 0;           // Space for the result.
+    SP[2] = cls;         // Class object.
+    SP[3] = null_value;  // Type arguments.
     Exit(thread, FP, SP + 4, pc);
     NativeArguments args(thread, 2, SP + 2, SP + 1);
     INVOKE_RUNTIME(DRT_AllocateObject, args);
@@ -2476,8 +2569,30 @@
 
   {
     BYTECODE(AllocateT, 0);
-    SP[1] = SP[-0];  // Class object.
-    SP[2] = SP[-1];  // Type arguments
+    RawClass* cls = Class::RawCast(SP[0]);
+    RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+    if (LIKELY(InterpreterHelpers::IsFinalized(cls))) {
+      const intptr_t class_id = cls->ptr()->id_;
+      const intptr_t instance_size = cls->ptr()->instance_size_in_words_
+                                     << kWordSizeLog2;
+      const uword start = thread->top();
+      if (LIKELY((start + instance_size) < thread->end())) {
+        thread->set_top(start + instance_size);
+        RawObject* result = InitializeHeader(start, class_id, instance_size);
+        for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+             offset += kWordSize) {
+          *reinterpret_cast<RawObject**>(start + offset) = null_value;
+        }
+        const intptr_t type_args_offset =
+            cls->ptr()->type_arguments_field_offset_in_words_ << kWordSizeLog2;
+        *reinterpret_cast<RawObject**>(start + type_args_offset) = type_args;
+        *--SP = result;
+        DISPATCH();
+      }
+    }
+
+    SP[1] = cls;
+    SP[2] = type_args;
     Exit(thread, FP, SP + 3, pc);
     NativeArguments args(thread, 2, SP + 1, SP - 1);
     INVOKE_RUNTIME(DRT_AllocateObject, args);
@@ -2487,12 +2602,12 @@
 
   {
     BYTECODE(CreateArrayTOS, 0);
-    SP[1] = SP[-0];  // Length.
-    SP[2] = SP[-1];  // Type.
-    Exit(thread, FP, SP + 3, pc);
-    NativeArguments args(thread, 2, SP + 1, SP - 1);
-    INVOKE_RUNTIME(DRT_AllocateArray, args);
-    SP -= 1;
+    RawTypeArguments* type_args = TypeArguments::RawCast(SP[-1]);
+    RawObject* length = SP[0];
+    SP--;
+    if (!AllocateArray(thread, type_args, length, pc, FP, SP)) {
+      HANDLE_EXCEPTION;
+    }
     DISPATCH();
   }
 
@@ -2856,6 +2971,32 @@
   }
 
   {
+    BYTECODE(AllocateClosure, A_D);
+    const intptr_t instance_size = Closure::InstanceSize();
+    const uword start = thread->top();
+    if (LIKELY((start + instance_size) < thread->end())) {
+      thread->set_top(start + instance_size);
+      RawClosure* result =
+          Closure::RawCast(InitializeHeader(start, kClosureCid, instance_size));
+      for (intptr_t offset = sizeof(RawInstance); offset < instance_size;
+           offset += kWordSize) {
+        *reinterpret_cast<RawObject**>(start + offset) = null_value;
+      }
+      SP[1] = result;
+      ++SP;
+    } else {
+      SP[1] = 0;  // Space for the result.
+      SP[2] = thread->isolate()->object_store()->closure_class();
+      SP[3] = null_value;  // Type arguments.
+      Exit(thread, FP, SP + 4, pc);
+      NativeArguments args(thread, 2, SP + 2, SP + 1);
+      INVOKE_RUNTIME(DRT_AllocateObject, args);
+      ++SP;
+    }
+    DISPATCH();
+  }
+
+  {
     BYTECODE(Trap, 0);
     UNIMPLEMENTED();
     DISPATCH();
@@ -2863,9 +3004,22 @@
 
   {
     BYTECODE(VMInternal_ImplicitGetter, 0);
+
+    RawFunction* function = FrameFunction(FP);
+    int32_t counter = ++(function->ptr()->usage_counter_);
+    if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
+                 counter >= FLAG_compilation_counter_threshold &&
+                 !Function::HasCode(function))) {
+      SP[1] = 0;  // Unused code result.
+      SP[2] = function;
+      Exit(thread, FP, SP + 3, pc);
+      NativeArguments native_args(thread, 1, SP + 2, SP + 1);
+      INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args);
+      function = FrameFunction(FP);
+    }
+
     // Field object is cached in function's data_.
-    RawField* field =
-        reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
+    RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
     intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
 
     const intptr_t kArgc = 1;
@@ -2882,22 +3036,22 @@
     classid_t guarded_cid = field->ptr()->guarded_cid_;
     if (unboxing && (guarded_cid == kDoubleCid)) {
       double raw_value = Double::RawCast(value)->ptr()->value_;
-      // AllocateDoubleBox places result at SP[0]
-      if (!AllocateDoubleBox(thread, raw_value, pc, FP, SP)) {
+      // AllocateDouble places result at SP[0]
+      if (!AllocateDouble(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
     } else if (unboxing && (guarded_cid == kFloat32x4Cid)) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float32x4::RawCast(value)->ptr()->value_);
-      // AllocateFloat32x4Box places result at SP[0]
-      if (!AllocateFloat32x4Box(thread, raw_value, pc, FP, SP)) {
+      // AllocateFloat32x4 places result at SP[0]
+      if (!AllocateFloat32x4(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
     } else if (unboxing && (guarded_cid == kFloat64x2Cid)) {
       simd128_value_t raw_value;
       raw_value.readFrom(Float64x2::RawCast(value)->ptr()->value_);
-      // AllocateFloat64x2Box places result at SP[0]
-      if (!AllocateFloat64x2Box(thread, raw_value, pc, FP, SP)) {
+      // AllocateFloat64x2 places result at SP[0]
+      if (!AllocateFloat64x2(thread, raw_value, pc, FP, SP)) {
         HANDLE_EXCEPTION;
       }
     }
@@ -2907,9 +3061,22 @@
 
   {
     BYTECODE(VMInternal_ImplicitSetter, 0);
+
+    RawFunction* function = FrameFunction(FP);
+    int32_t counter = ++(function->ptr()->usage_counter_);
+    if (UNLIKELY(FLAG_compilation_counter_threshold >= 0 &&
+                 counter >= FLAG_compilation_counter_threshold &&
+                 !Function::HasCode(function))) {
+      SP[1] = 0;  // Unused code result.
+      SP[2] = function;
+      Exit(thread, FP, SP + 3, pc);
+      NativeArguments native_args(thread, 1, SP + 2, SP + 1);
+      INVOKE_RUNTIME(DRT_OptimizeInvokedFunction, native_args);
+      function = FrameFunction(FP);
+    }
+
     // Field object is cached in function's data_.
-    RawField* field =
-        reinterpret_cast<RawField*>(FrameFunction(FP)->ptr()->data_);
+    RawField* field = reinterpret_cast<RawField*>(function->ptr()->data_);
     intptr_t offset_in_words = Smi::Value(field->ptr()->value_.offset_);
     const intptr_t kArgc = 2;
     RawInstance* instance =
@@ -3039,8 +3206,7 @@
     // Restore caller context as we are going to throw NoSuchMethod.
     pc = SavedCallerPC(FP);
 
-    const bool has_dart_caller =
-        !IsEntryFrameMarker(reinterpret_cast<uword>(pc));
+    const bool has_dart_caller = !IsEntryFrameMarker(pc);
     const intptr_t argc = has_dart_caller ? KernelBytecode::DecodeArgc(pc[-1])
                                           : (reinterpret_cast<uword>(pc) >> 2);
     const intptr_t type_args_len =
@@ -3050,7 +3216,7 @@
     SP = FrameArguments(FP, 0);
     RawObject** args = SP - argc;
     FP = SavedCallerFP(FP);
-    fp_ = FP;  // For the profiler.
+    NOT_IN_PRODUCT(fp_ = FP);  // For the profiler.
     if (has_dart_caller) {
       pp_ = InterpreterHelpers::FrameBytecode(FP)->ptr()->object_pool_;
     }
@@ -3159,9 +3325,9 @@
     thread->set_active_stacktrace(Object::null_object());
     special_[KernelBytecode::kExceptionSpecialIndex] = raw_exception;
     special_[KernelBytecode::kStackTraceSpecialIndex] = raw_stacktrace;
-    pc_ = thread->resume_pc();
+    pc_ = reinterpret_cast<uint32_t*>(thread->resume_pc());
   } else {
-    pc_ = pc;
+    pc_ = reinterpret_cast<uint32_t*>(pc);
   }
 
   // Set the tag.
diff --git a/runtime/vm/interpreter.h b/runtime/vm/interpreter.h
index effc48a..165a6d7 100644
--- a/runtime/vm/interpreter.h
+++ b/runtime/vm/interpreter.h
@@ -26,6 +26,7 @@
 class RawFunction;
 class RawString;
 class RawSubtypeTestCache;
+class RawTypeArguments;
 class ObjectPointerVisitor;
 
 class LookupCache : public ValueObject {
@@ -93,7 +94,9 @@
   }
 
   // Identify an entry frame by looking at its pc marker value.
-  static bool IsEntryFrameMarker(uword pc) { return (pc & 2) != 0; }
+  static bool IsEntryFrameMarker(uint32_t* pc) {
+    return (reinterpret_cast<uword>(pc) & 2) != 0;
+  }
 
   RawObject* Call(const Function& function,
                   const Array& arguments_descriptor,
@@ -110,7 +113,9 @@
 
   uword get_sp() const { return reinterpret_cast<uword>(fp_); }  // Yes, fp_.
   uword get_fp() const { return reinterpret_cast<uword>(fp_); }
-  uword get_pc() const { return pc_; }
+  uword get_pc() const { return reinterpret_cast<uword>(pc_); }
+
+  void Unexit(Thread* thread);
 
   void VisitObjectPointers(ObjectPointerVisitor* visitor);
   void MajorGC() { lookup_cache_.Clear(); }
@@ -121,8 +126,8 @@
   uword overflow_stack_limit_;
   uword stack_limit_;
 
-  RawObject** fp_;
-  uword pc_;
+  RawObject** volatile fp_;
+  uint32_t* volatile pc_;
   DEBUG_ONLY(uint64_t icount_;)
 
   InterpreterSetjmpBuffer* last_setjmp_buffer_;
@@ -205,26 +210,32 @@
                         RawObject** args,
                         RawSubtypeTestCache* cache);
 
-  bool AllocateInt64Box(Thread* thread,
-                        int64_t value,
-                        uint32_t* pc,
-                        RawObject** FP,
-                        RawObject** SP);
-  bool AllocateDoubleBox(Thread* thread,
-                         double value,
+  bool AllocateMint(Thread* thread,
+                    int64_t value,
+                    uint32_t* pc,
+                    RawObject** FP,
+                    RawObject** SP);
+  bool AllocateDouble(Thread* thread,
+                      double value,
+                      uint32_t* pc,
+                      RawObject** FP,
+                      RawObject** SP);
+  bool AllocateFloat32x4(Thread* thread,
+                         simd128_value_t value,
                          uint32_t* pc,
                          RawObject** FP,
                          RawObject** SP);
-  bool AllocateFloat32x4Box(Thread* thread,
-                            simd128_value_t value,
-                            uint32_t* pc,
-                            RawObject** FP,
-                            RawObject** SP);
-  bool AllocateFloat64x2Box(Thread* thread,
-                            simd128_value_t value,
-                            uint32_t* pc,
-                            RawObject** FP,
-                            RawObject** SP);
+  bool AllocateFloat64x2(Thread* thread,
+                         simd128_value_t value,
+                         uint32_t* pc,
+                         RawObject** FP,
+                         RawObject** SP);
+  bool AllocateArray(Thread* thread,
+                     RawTypeArguments* type_args,
+                     RawObject* length,
+                     uint32_t* pc,
+                     RawObject** FP,
+                     RawObject** SP);
 
 #if defined(DEBUG)
   // Returns true if tracing of executed instructions is enabled.
diff --git a/runtime/vm/isolate.cc b/runtime/vm/isolate.cc
index b99c204..49caa27 100644
--- a/runtime/vm/isolate.cc
+++ b/runtime/vm/isolate.cc
@@ -866,6 +866,7 @@
       heap_(NULL),
       isolate_flags_(0),
       background_compiler_(NULL),
+      optimizing_background_compiler_(NULL),
 #if !defined(PRODUCT)
       debugger_(NULL),
       last_resume_timestamp_(OS::GetCurrentTimeMillis()),
@@ -951,7 +952,11 @@
         "         See dartbug.com/30524 for more information.\n");
   }
 
-  NOT_IN_PRECOMPILED(background_compiler_ = new BackgroundCompiler(this));
+  if (FLAG_enable_interpreter) {
+    NOT_IN_PRECOMPILED(background_compiler_ = new BackgroundCompiler(this));
+  }
+  NOT_IN_PRECOMPILED(optimizing_background_compiler_ =
+                         new BackgroundCompiler(this));
 }
 
 #undef REUSABLE_HANDLE_SCOPE_INIT
@@ -966,8 +971,13 @@
   delete reverse_pc_lookup_cache_;
   reverse_pc_lookup_cache_ = nullptr;
 
-  delete background_compiler_;
-  background_compiler_ = NULL;
+  if (FLAG_enable_interpreter) {
+    delete background_compiler_;
+    background_compiler_ = NULL;
+  }
+
+  delete optimizing_background_compiler_;
+  optimizing_background_compiler_ = NULL;
 
 #if !defined(PRODUCT)
   delete debugger_;
@@ -1862,8 +1872,12 @@
 void Isolate::Shutdown() {
   ASSERT(this == Isolate::Current());
   BackgroundCompiler::Stop(this);
-  delete background_compiler_;
-  background_compiler_ = NULL;
+  if (FLAG_enable_interpreter) {
+    delete background_compiler_;
+    background_compiler_ = NULL;
+  }
+  delete optimizing_background_compiler_;
+  optimizing_background_compiler_ = NULL;
 
 #if defined(DEBUG)
   if (heap_ != NULL && FLAG_verify_on_transition) {
@@ -1986,6 +2000,9 @@
   if (background_compiler() != NULL) {
     background_compiler()->VisitPointers(visitor);
   }
+  if (optimizing_background_compiler() != NULL) {
+    optimizing_background_compiler()->VisitPointers(visitor);
+  }
 
 #if !defined(PRODUCT)
   // Visit objects in the debugger.
diff --git a/runtime/vm/isolate.h b/runtime/vm/isolate.h
index c4dd373..584eeae 100644
--- a/runtime/vm/isolate.h
+++ b/runtime/vm/isolate.h
@@ -479,6 +479,10 @@
     return background_compiler_;
   }
 
+  BackgroundCompiler* optimizing_background_compiler() const {
+    return optimizing_background_compiler_;
+  }
+
 #if !defined(PRODUCT)
   void UpdateLastAllocationProfileAccumulatorResetTimestamp() {
     last_allocationprofile_accumulator_reset_timestamp_ =
@@ -697,6 +701,13 @@
     return FLAG_use_strong_mode_types && !unsafe_trust_strong_mode_types();
   }
 
+  // Whether it's possible for unoptimized code to optimize immediately on entry
+  // (can happen with random or very low optimization counter thresholds)
+  bool CanOptimizeImmediately() const {
+    return FLAG_optimization_counter_threshold < 2 ||
+           FLAG_randomize_optimization_counter;
+  }
+
   bool should_load_vmservice() const {
     return ShouldLoadVmServiceBit::decode(isolate_flags_);
   }
@@ -909,9 +920,12 @@
 
   uint32_t isolate_flags_;
 
-  // Background compilation.
+  // Unoptimized background compilation.
   BackgroundCompiler* background_compiler_;
 
+  // Optimized background compilation.
+  BackgroundCompiler* optimizing_background_compiler_;
+
 // Fields that aren't needed in a product build go here with boolean flags at
 // the top.
 #if !defined(PRODUCT)
diff --git a/runtime/vm/isolate_reload.cc b/runtime/vm/isolate_reload.cc
index 381a50b..76e8e9d 100644
--- a/runtime/vm/isolate_reload.cc
+++ b/runtime/vm/isolate_reload.cc
@@ -1890,151 +1890,34 @@
   // new ones.
 }
 
-class MarkFunctionsForRecompilation : public ObjectVisitor {
+class InvalidationCollector : public ObjectVisitor {
  public:
-  MarkFunctionsForRecompilation(Isolate* isolate,
-                                IsolateReloadContext* reload_context,
-                                Zone* zone)
-      : ObjectVisitor(),
-        handle_(Object::Handle(zone)),
-        owning_class_(Class::Handle(zone)),
-        owning_lib_(Library::Handle(zone)),
-        code_(Code::Handle(zone)),
-        bytecode_(Bytecode::Handle(zone)),
-        reload_context_(reload_context),
-        zone_(zone) {}
+  InvalidationCollector(Zone* zone,
+                        GrowableArray<const Function*>* functions,
+                        GrowableArray<const KernelProgramInfo*>* kernel_infos)
+      : zone_(zone), functions_(functions), kernel_infos_(kernel_infos) {}
+  virtual ~InvalidationCollector() {}
 
   virtual void VisitObject(RawObject* obj) {
     if (obj->IsPseudoObject()) {
-      // Cannot even be wrapped in handles.
-      return;
+      return;  // Cannot be wrapped in handles.
     }
-    handle_ = obj;
-    if (handle_.IsFunction()) {
-      const Function& func = Function::Cast(handle_);
-      if (func.IsSignatureFunction()) {
-        return;
-      }
-
-      // Switch to unoptimized code or the lazy compilation stub.
-      func.SwitchToLazyCompiledUnoptimizedCode();
-
-      // Grab the current code.
-      code_ = func.CurrentCode();
-      ASSERT(!code_.IsNull());
-      bytecode_ = func.bytecode();
-      const bool clear_code = IsFromDirtyLibrary(func);
-      const bool stub_code = code_.IsStubCode();
-
-      // Zero edge counters.
-      func.ZeroEdgeCounters();
-
-      if (!stub_code || !bytecode_.IsNull()) {
-        if (clear_code) {
-          VTIR_Print("Marking %s for recompilation, clearing code\n",
-                     func.ToCString());
-          ClearAllCode(func);
-        } else {
-          if (!stub_code) {
-            PreserveUnoptimizedCode();
-          }
-          if (!bytecode_.IsNull()) {
-            PreserveBytecode();
-          }
-        }
-      }
-
-      // Clear counters.
-      func.set_usage_counter(0);
-      func.set_deoptimization_counter(0);
-      func.set_optimized_instruction_count(0);
-      func.set_optimized_call_site_count(0);
+    const Object& handle = Object::Handle(zone_, obj);
+    if (handle.IsFunction()) {
+      functions_->Add(&Function::Cast(handle));
+    } else if (handle.IsKernelProgramInfo()) {
+      kernel_infos_->Add(&KernelProgramInfo::Cast(handle));
     }
   }
 
  private:
-  void ClearAllCode(const Function& func) {
-    // Null out the ICData array and code.
-    func.ClearICDataArray();
-    func.ClearCode();
-    func.SetWasCompiled(false);
-  }
-
-  void PreserveUnoptimizedCode() {
-    ASSERT(!code_.IsNull());
-    // We are preserving the unoptimized code, fill all ICData arrays with
-    // the sentinel values so that we have no stale type feedback.
-    code_.ResetICDatas(zone_);
-  }
-
-  void PreserveBytecode() {
-    ASSERT(!bytecode_.IsNull());
-    // We are preserving the bytecode, fill all ICData arrays with
-    // the sentinel values so that we have no stale type feedback.
-    bytecode_.ResetICDatas(zone_);
-  }
-
-  bool IsFromDirtyLibrary(const Function& func) {
-    owning_class_ = func.Owner();
-    owning_lib_ = owning_class_.library();
-    return reload_context_->IsDirty(owning_lib_);
-  }
-
-  Object& handle_;
-  Class& owning_class_;
-  Library& owning_lib_;
-  Code& code_;
-  Bytecode& bytecode_;
-  IsolateReloadContext* reload_context_;
-  Zone* zone_;
+  Zone* const zone_;
+  GrowableArray<const Function*>* const functions_;
+  GrowableArray<const KernelProgramInfo*>* const kernel_infos_;
 };
 
 typedef UnorderedHashMap<SmiTraits> IntHashMap;
 
-class InvalidateKernelInfoCaches : public ObjectVisitor {
- public:
-  explicit InvalidateKernelInfoCaches(Zone* zone)
-      : ObjectVisitor(),
-        handle_(Object::Handle(zone)),
-        data_(Array::Handle(zone)),
-        key_(Object::Handle(zone)),
-        value_(Smi::Handle(zone)) {}
-
-  virtual void VisitObject(RawObject* obj) {
-    if (obj->IsPseudoObject()) {
-      // Cannot even be wrapped in handles.
-      return;
-    }
-    handle_ = obj;
-    if (!handle_.IsKernelProgramInfo()) {
-      return;
-    }
-    const KernelProgramInfo& info = KernelProgramInfo::Cast(handle_);
-    // Clear the libraries cache.
-    {
-      data_ ^= info.libraries_cache();
-      ASSERT(!data_.IsNull());
-      IntHashMap table(&key_, &value_, &data_);
-      table.Clear();
-      info.set_libraries_cache(table.Release());
-    }
-    // Clear the classes cache.
-    {
-      data_ ^= info.classes_cache();
-      ASSERT(!data_.IsNull());
-      IntHashMap table(&key_, &value_, &data_);
-      table.Clear();
-      info.set_classes_cache(table.Release());
-    }
-  }
-
- private:
-  Object& handle_;
-  Array& data_;
-  Object& key_;
-  Smi& value_;
-};
-
 void IsolateReloadContext::RunInvalidationVisitors() {
   TIMELINE_SCOPE(MarkAllFunctionsForRecompilation);
   TIR_Print("---- RUNNING INVALIDATION HEAP VISITORS\n");
@@ -2042,15 +1925,92 @@
   StackZone stack_zone(thread);
   Zone* zone = stack_zone.GetZone();
 
-  HeapIterationScope iteration(thread);
-  GrowableArray<ObjectVisitor*> arr(zone, 2);
-  ExtensibleObjectVisitor visitor(&arr);
-  MarkFunctionsForRecompilation function_visitor(isolate_, this, zone);
-  InvalidateKernelInfoCaches kernel_info_visitor(zone);
+  GrowableArray<const Function*> functions(4 * KB);
+  GrowableArray<const KernelProgramInfo*> kernel_infos(KB);
 
-  visitor.Add(&function_visitor);
-  visitor.Add(&kernel_info_visitor);
-  iteration.IterateObjects(&visitor);
+  {
+    HeapIterationScope iteration(thread);
+    InvalidationCollector visitor(zone, &functions, &kernel_infos);
+    iteration.IterateObjects(&visitor);
+  }
+
+  Array& data = Array::Handle(zone);
+  Object& key = Object::Handle(zone);
+  Smi& value = Smi::Handle(zone);
+  for (intptr_t i = 0; i < kernel_infos.length(); i++) {
+    const KernelProgramInfo& info = *kernel_infos[i];
+    // Clear the libraries cache.
+    {
+      data ^= info.libraries_cache();
+      ASSERT(!data.IsNull());
+      IntHashMap table(&key, &value, &data);
+      table.Clear();
+      info.set_libraries_cache(table.Release());
+    }
+    // Clear the classes cache.
+    {
+      data ^= info.classes_cache();
+      ASSERT(!data.IsNull());
+      IntHashMap table(&key, &value, &data);
+      table.Clear();
+      info.set_classes_cache(table.Release());
+    }
+  }
+
+  Class& owning_class = Class::Handle(zone);
+  Library& owning_lib = Library::Handle(zone);
+  Code& code = Code::Handle(zone);
+  Bytecode& bytecode = Bytecode::Handle(zone);
+  for (intptr_t i = 0; i < functions.length(); i++) {
+    const Function& func = *functions[i];
+    if (func.IsSignatureFunction()) {
+      continue;
+    }
+
+    // Switch to unoptimized code or the lazy compilation stub.
+    func.SwitchToLazyCompiledUnoptimizedCode();
+
+    // Grab the current code.
+    code = func.CurrentCode();
+    ASSERT(!code.IsNull());
+    bytecode = func.bytecode();
+
+    owning_class = func.Owner();
+    owning_lib = owning_class.library();
+    const bool clear_code = IsDirty(owning_lib);
+    const bool stub_code = code.IsStubCode();
+
+    // Zero edge counters.
+    func.ZeroEdgeCounters();
+
+    if (!stub_code || !bytecode.IsNull()) {
+      if (clear_code) {
+        VTIR_Print("Marking %s for recompilation, clearing code\n",
+                   func.ToCString());
+        // Null out the ICData array and code.
+        func.ClearICDataArray();
+        func.ClearCode();
+        func.SetWasCompiled(false);
+      } else {
+        if (!stub_code) {
+          // We are preserving the unoptimized code, fill all ICData arrays with
+          // the sentinel values so that we have no stale type feedback.
+          code.ResetICDatas(zone);
+        }
+        if (!bytecode.IsNull()) {
+          // We are preserving the bytecode, fill all ICData arrays with
+          // the sentinel values so that we have no stale type feedback.
+          bytecode.ResetICDatas(zone);
+        }
+      }
+    }
+
+    // Clear counters.
+    func.set_usage_counter(0);
+    func.set_deoptimization_counter(0);
+    func.set_optimized_instruction_count(0);
+    func.set_optimized_call_site_count(0);
+  }
 }
 
 void IsolateReloadContext::InvalidateWorld() {
diff --git a/runtime/vm/isolate_test.cc b/runtime/vm/isolate_test.cc
index a9d3a85..b019598c 100644
--- a/runtime/vm/isolate_test.cc
+++ b/runtime/vm/isolate_test.cc
@@ -43,30 +43,30 @@
   // Necessary because asynchronous errors use "print" to print their
   // stack trace.
   Dart_Handle url = NewString("dart:_internal");
-  DART_CHECK_VALID(url);
+  EXPECT_VALID(url);
   Dart_Handle internal_lib = Dart_LookupLibrary(url);
-  DART_CHECK_VALID(internal_lib);
+  EXPECT_VALID(internal_lib);
   Dart_Handle print = Dart_GetField(test_lib, NewString("_nullPrintClosure"));
   Dart_Handle result =
       Dart_SetField(internal_lib, NewString("_printClosure"), print);
 
-  DART_CHECK_VALID(result);
+  EXPECT_VALID(result);
 
   // Setup the 'scheduleImmediate' closure.
   url = NewString("dart:isolate");
-  DART_CHECK_VALID(url);
+  EXPECT_VALID(url);
   Dart_Handle isolate_lib = Dart_LookupLibrary(url);
-  DART_CHECK_VALID(isolate_lib);
+  EXPECT_VALID(isolate_lib);
   Dart_Handle schedule_immediate_closure = Dart_Invoke(
       isolate_lib, NewString("_getIsolateScheduleImmediateClosure"), 0, NULL);
   Dart_Handle args[1];
   args[0] = schedule_immediate_closure;
   url = NewString("dart:async");
-  DART_CHECK_VALID(url);
+  EXPECT_VALID(url);
   Dart_Handle async_lib = Dart_LookupLibrary(url);
-  DART_CHECK_VALID(async_lib);
-  DART_CHECK_VALID(Dart_Invoke(
-      async_lib, NewString("_setScheduleImmediateClosure"), 1, args));
+  EXPECT_VALID(async_lib);
+  EXPECT_VALID(Dart_Invoke(async_lib, NewString("_setScheduleImmediateClosure"),
+                           1, args));
 
   result = Dart_Invoke(test_lib, NewString("testMain"), 0, NULL);
   EXPECT_VALID(result);
diff --git a/runtime/vm/kernel_binary.h b/runtime/vm/kernel_binary.h
index ab22ff4..96c4986 100644
--- a/runtime/vm/kernel_binary.h
+++ b/runtime/vm/kernel_binary.h
@@ -20,7 +20,7 @@
 
 // Both version numbers are inclusive.
 static const uint32_t kMinSupportedKernelFormatVersion = 18;
-static const uint32_t kMaxSupportedKernelFormatVersion = 22;
+static const uint32_t kMaxSupportedKernelFormatVersion = 23;
 
 // Keep in sync with package:kernel/lib/binary/tag.dart
 #define KERNEL_TAG_LIST(V)                                                     \
@@ -65,6 +65,7 @@
   V(ListConcatenation, 111)                                                    \
   V(SetConcatenation, 112)                                                     \
   V(MapConcatenation, 113)                                                     \
+  V(InstanceCreation, 114)                                                     \
   V(IsExpression, 37)                                                          \
   V(AsExpression, 38)                                                          \
   V(StringLiteral, 39)                                                         \
diff --git a/runtime/vm/malloc_hooks_arm.cc b/runtime/vm/malloc_hooks_arm.cc
index 7e857e5..e344434 100644
--- a/runtime/vm/malloc_hooks_arm.cc
+++ b/runtime/vm/malloc_hooks_arm.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 4;
 
 }  // namespace dart
 
diff --git a/runtime/vm/malloc_hooks_arm64.cc b/runtime/vm/malloc_hooks_arm64.cc
index e50ea0b..d063748 100644
--- a/runtime/vm/malloc_hooks_arm64.cc
+++ b/runtime/vm/malloc_hooks_arm64.cc
@@ -10,7 +10,7 @@
 
 namespace dart {
 
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 4;
 
 }  // namespace dart
 
diff --git a/runtime/vm/malloc_hooks_ia32.cc b/runtime/vm/malloc_hooks_ia32.cc
index 2b7a371..b056456 100644
--- a/runtime/vm/malloc_hooks_ia32.cc
+++ b/runtime/vm/malloc_hooks_ia32.cc
@@ -11,9 +11,9 @@
 namespace dart {
 
 #if defined(DEBUG)
-const intptr_t kSkipCount = 6;
-#elif !(defined(PRODUCT) || defined(DEBUG))
 const intptr_t kSkipCount = 5;
+#elif !(defined(PRODUCT) || defined(DEBUG))
+const intptr_t kSkipCount = 4;
 #endif
 
 }  // namespace dart
diff --git a/runtime/vm/malloc_hooks_x64.cc b/runtime/vm/malloc_hooks_x64.cc
index 2ec564b..25e2283 100644
--- a/runtime/vm/malloc_hooks_x64.cc
+++ b/runtime/vm/malloc_hooks_x64.cc
@@ -11,9 +11,9 @@
 namespace dart {
 
 #if defined(DEBUG)
-const intptr_t kSkipCount = 6;
-#elif !(defined(PRODUCT) || defined(DEBUG))
 const intptr_t kSkipCount = 5;
+#elif !(defined(PRODUCT) || defined(DEBUG))
+const intptr_t kSkipCount = 4;
 #endif
 
 }  // namespace dart
diff --git a/runtime/vm/metrics.cc b/runtime/vm/metrics.cc
index 99bc372..c20cfc7 100644
--- a/runtime/vm/metrics.cc
+++ b/runtime/vm/metrics.cc
@@ -303,9 +303,14 @@
   return Service::MaxRSS();
 }
 
+#define VM_METRIC_VARIABLE(type, variable, name, unit)                         \
+  type vm_metric_##variable;
+VM_METRIC_LIST(VM_METRIC_VARIABLE);
+#undef VM_METRIC_VARIABLE
+
 void Metric::Init() {
 #define VM_METRIC_INIT(type, variable, name, unit)                             \
-  vm_metric_##variable##_.InitInstance(name, NULL, Metric::unit);
+  vm_metric_##variable.InitInstance(name, NULL, Metric::unit);
   VM_METRIC_LIST(VM_METRIC_INIT);
 #undef VM_METRIC_INIT
 }
@@ -323,7 +328,7 @@
     OS::PrintErr("\n");
   }
 #define VM_METRIC_CLEANUP(type, variable, name, unit)                          \
-  vm_metric_##variable##_.CleanupInstance();
+  vm_metric_##variable.CleanupInstance();
   VM_METRIC_LIST(VM_METRIC_CLEANUP);
 #undef VM_METRIC_CLEANUP
 }
diff --git a/runtime/vm/metrics.h b/runtime/vm/metrics.h
index 75f0781..b54fc12 100644
--- a/runtime/vm/metrics.h
+++ b/runtime/vm/metrics.h
@@ -182,7 +182,7 @@
 
 #if !defined(PRODUCT)
 #define VM_METRIC_VARIABLE(type, variable, name, unit)                         \
-  static type vm_metric_##variable##_;
+  extern type vm_metric_##variable;
 VM_METRIC_LIST(VM_METRIC_VARIABLE);
 #undef VM_METRIC_VARIABLE
 #endif  // !defined(PRODUCT)
diff --git a/runtime/vm/object.cc b/runtime/vm/object.cc
index ac67816..0397d9c 100644
--- a/runtime/vm/object.cc
+++ b/runtime/vm/object.cc
@@ -2588,6 +2588,10 @@
 }
 
 void Class::set_type_parameters(const TypeArguments& value) const {
+  ASSERT((num_own_type_arguments() == kUnknownNumTypeArguments) ||
+         is_prefinalized());
+  ASSERT((num_type_arguments() == kUnknownNumTypeArguments) ||
+         is_prefinalized());
   StorePointer(&raw_ptr()->type_parameters_, value.raw());
 }
 
@@ -13146,14 +13150,24 @@
 }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-void ICData::SetStaticReceiverType(const AbstractType& type) const {
-  StorePointer(&raw_ptr()->static_receiver_type_, type.raw());
+void ICData::SetReceiversStaticType(const AbstractType& type) const {
+  StorePointer(&raw_ptr()->receivers_static_type_, type.raw());
+
+#if defined(TARGET_ARCH_X64)
+  if (!type.IsNull() && type.HasTypeClass() && (NumArgsTested() == 1) &&
+      type.IsInstantiated()) {
+    const Class& cls = Class::Handle(type.type_class());
+    if (cls.IsGeneric() && !cls.IsFutureOrClass()) {
+      set_tracking_exactness(true);
+    }
+  }
+#endif  // defined(TARGET_ARCH_X64)
 }
 #endif
 
 void ICData::ResetSwitchable(Zone* zone) const {
   ASSERT(NumArgsTested() == 1);
-  ASSERT(!IsTrackingExactness());
+  ASSERT(!is_tracking_exactness());
   set_entries(Array::Handle(zone, CachedEmptyICDataArray(1, false)));
 }
 
@@ -13298,7 +13312,7 @@
 }
 
 intptr_t ICData::TestEntryLength() const {
-  return TestEntryLengthFor(NumArgsTested(), IsTrackingExactness());
+  return TestEntryLengthFor(NumArgsTested(), is_tracking_exactness());
 }
 
 intptr_t ICData::Length() const {
@@ -13535,7 +13549,7 @@
 void ICData::AddCheck(const GrowableArray<intptr_t>& class_ids,
                       const Function& target,
                       intptr_t count) const {
-  ASSERT(!IsTrackingExactness());
+  ASSERT(!is_tracking_exactness());
   ASSERT(!target.IsNull());
   ASSERT((target.name() == target_name()) || ValidateInterceptor(target));
   DEBUG_ASSERT(!HasCheck(class_ids));
@@ -13648,7 +13662,7 @@
   if (Isolate::Current()->compilation_allowed()) {
     data.SetAt(data_pos + 1, target);
     data.SetAt(data_pos + 2, Smi::Handle(Smi::New(count)));
-    if (IsTrackingExactness()) {
+    if (is_tracking_exactness()) {
       data.SetAt(data_pos + 3, Smi::Handle(Smi::New(exactness.Encode())));
     }
   } else {
@@ -13666,7 +13680,7 @@
 }
 
 StaticTypeExactnessState ICData::GetExactnessAt(intptr_t index) const {
-  if (!IsTrackingExactness()) {
+  if (!is_tracking_exactness()) {
     return StaticTypeExactnessState::NotTracking();
   }
   const Array& data = Array::Handle(entries());
@@ -14086,7 +14100,7 @@
                                  intptr_t deopt_id,
                                  intptr_t num_args_tested,
                                  RebindRule rebind_rule,
-                                 const AbstractType& static_receiver_type) {
+                                 const AbstractType& receivers_static_type) {
   ASSERT(!owner.IsNull());
   ASSERT(!target_name.IsNull());
   ASSERT(!arguments_descriptor.IsNull());
@@ -14107,7 +14121,7 @@
   result.set_state_bits(0);
   result.set_rebind_rule(rebind_rule);
   result.SetNumArgsTested(num_args_tested);
-  NOT_IN_PRECOMPILED(result.SetStaticReceiverType(static_receiver_type));
+  NOT_IN_PRECOMPILED(result.SetReceiversStaticType(receivers_static_type));
   return result.raw();
 }
 
@@ -14136,15 +14150,15 @@
                        intptr_t deopt_id,
                        intptr_t num_args_tested,
                        RebindRule rebind_rule,
-                       const AbstractType& static_receiver_type) {
+                       const AbstractType& receivers_static_type) {
   Zone* zone = Thread::Current()->zone();
   const ICData& result = ICData::Handle(
       zone,
       NewDescriptor(zone, owner, target_name, arguments_descriptor, deopt_id,
-                    num_args_tested, rebind_rule, static_receiver_type));
+                    num_args_tested, rebind_rule, receivers_static_type));
   result.set_entries(Array::Handle(
       zone,
-      CachedEmptyICDataArray(num_args_tested, result.IsTrackingExactness())));
+      CachedEmptyICDataArray(num_args_tested, result.is_tracking_exactness())));
   return result.raw();
 }
 
@@ -14154,7 +14168,7 @@
       Function::Handle(from.Owner()), String::Handle(from.target_name()),
       Array::Handle(from.arguments_descriptor()), from.deopt_id(),
       num_args_tested, from.rebind_rule(),
-      AbstractType::Handle(from.StaticReceiverType())));
+      AbstractType::Handle(from.receivers_static_type())));
   // Copy deoptimization reasons.
   result.SetDeoptReasons(from.DeoptReasons());
   return result.raw();
@@ -14162,12 +14176,13 @@
 
 RawICData* ICData::Clone(const ICData& from) {
   Zone* zone = Thread::Current()->zone();
-  const ICData& result = ICData::Handle(ICData::NewDescriptor(
-      zone, Function::Handle(zone, from.Owner()),
-      String::Handle(zone, from.target_name()),
-      Array::Handle(zone, from.arguments_descriptor()), from.deopt_id(),
-      from.NumArgsTested(), from.rebind_rule(),
-      AbstractType::Handle(from.StaticReceiverType())));
+  const ICData& result = ICData::Handle(
+      zone, ICData::NewDescriptor(
+                zone, Function::Handle(zone, from.Owner()),
+                String::Handle(zone, from.target_name()),
+                Array::Handle(zone, from.arguments_descriptor()),
+                from.deopt_id(), from.NumArgsTested(), from.rebind_rule(),
+                AbstractType::Handle(zone, from.receivers_static_type())));
   // Clone entry array.
   const Array& from_array = Array::Handle(zone, from.entries());
   const intptr_t len = from_array.Length();
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index dbdbe2c..a3a1aca 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -1441,6 +1441,7 @@
   friend class Instance;
   friend class Object;
   friend class Type;
+  friend class InterpreterHelpers;
   friend class Intrinsifier;
   friend class ClassFunctionVisitor;
 };
@@ -1588,15 +1589,20 @@
   bool IsImmutable() const;
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  RawAbstractType* StaticReceiverType() const {
-    return raw_ptr()->static_receiver_type_;
+  RawAbstractType* receivers_static_type() const {
+    return raw_ptr()->receivers_static_type_;
   }
-  void SetStaticReceiverType(const AbstractType& type) const;
-  bool IsTrackingExactness() const {
-    return StaticReceiverType() != Object::null();
+  void SetReceiversStaticType(const AbstractType& type) const;
+  bool is_tracking_exactness() const {
+    return TrackingExactnessBit::decode(raw_ptr()->state_bits_);
+  }
+  void set_tracking_exactness(bool value) const {
+    StoreNonPointer(
+        &raw_ptr()->state_bits_,
+        TrackingExactnessBit::update(value, raw_ptr()->state_bits_));
   }
 #else
-  bool IsTrackingExactness() const { return false; }
+  bool is_tracking_exactness() const { return false; }
 #endif
 
   void Reset(Zone* zone) const;
@@ -1702,8 +1708,8 @@
   static intptr_t owner_offset() { return OFFSET_OF(RawICData, owner_); }
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
-  static intptr_t static_receiver_type_offset() {
-    return OFFSET_OF(RawICData, static_receiver_type_);
+  static intptr_t receivers_static_type_offset() {
+    return OFFSET_OF(RawICData, receivers_static_type_);
   }
 #endif
 
@@ -1882,7 +1888,9 @@
   enum {
     kNumArgsTestedPos = 0,
     kNumArgsTestedSize = 2,
-    kDeoptReasonPos = kNumArgsTestedPos + kNumArgsTestedSize,
+    kTrackingExactnessPos = kNumArgsTestedPos + kNumArgsTestedSize,
+    kTrackingExactnessSize = 1,
+    kDeoptReasonPos = kTrackingExactnessPos + kTrackingExactnessSize,
     kDeoptReasonSize = kLastRecordedDeoptReason + 1,
     kRebindRulePos = kDeoptReasonPos + kDeoptReasonSize,
     kRebindRuleSize = 3
@@ -1894,6 +1902,10 @@
                                             uint32_t,
                                             kNumArgsTestedPos,
                                             kNumArgsTestedSize> {};
+  class TrackingExactnessBit : public BitField<uint32_t,
+                                               bool,
+                                               kTrackingExactnessPos,
+                                               kTrackingExactnessSize> {};
   class DeoptReasonBits : public BitField<uint32_t,
                                           uint32_t,
                                           ICData::kDeoptReasonPos,
@@ -3409,7 +3421,7 @@
   // Returns false if any value read from this field is guaranteed to be
   // not null.
   // Internally we is_nullable_ field contains either kNullCid (nullable) or
-  // any other value (non-nullable) instead of boolean. This is done to simplify
+  // kInvalidCid (non-nullable) instead of boolean. This is done to simplify
   // guarding sequence in the generated code.
   bool is_nullable() const { return raw_ptr()->is_nullable_ == kNullCid; }
   void set_is_nullable(bool val) const {
diff --git a/runtime/vm/object_reload.cc b/runtime/vm/object_reload.cc
index ffd3cb9..31eb620 100644
--- a/runtime/vm/object_reload.cc
+++ b/runtime/vm/object_reload.cc
@@ -45,7 +45,9 @@
   ASSERT(saved_ic_datalength > 0);
   const Array& edge_counters_array =
       Array::Handle(Array::RawCast(saved_ic_data.At(0)));
-  ASSERT(!edge_counters_array.IsNull());
+  if (edge_counters_array.IsNull()) {
+    return;
+  }
   // Fill edge counters array with zeros.
   const Smi& zero = Smi::Handle(Smi::New(0));
   for (intptr_t i = 0; i < edge_counters_array.Length(); i++) {
@@ -703,7 +705,7 @@
   RebindRule rule = rebind_rule();
   if (rule == kInstance) {
     const intptr_t num_args = NumArgsTested();
-    const bool tracking_exactness = IsTrackingExactness();
+    const bool tracking_exactness = is_tracking_exactness();
     const intptr_t len = Length();
     // We need at least one non-sentinel entry to require a check
     // for the smi fast path case.
diff --git a/runtime/vm/profiler.cc b/runtime/vm/profiler.cc
index adde4dd..7eed0f3 100644
--- a/runtime/vm/profiler.cc
+++ b/runtime/vm/profiler.cc
@@ -417,6 +417,7 @@
 
 static void DumpStackFrame(intptr_t frame_index,
                            uword pc,
+                           uword fp,
                            bool try_symbolize_dart_frames) {
   Thread* thread = Thread::Current();
   if ((thread != NULL) && !thread->IsAtSafepoint() &&
@@ -430,7 +431,8 @@
         code = Code::LookupCode(pc);  // In current isolate.
       }
       if (!code.IsNull()) {
-        OS::PrintErr("  [0x%" Pp "] %s\n", pc, code.QualifiedName());
+        OS::PrintErr("  pc 0x%" Pp " fp 0x%" Pp " %s\n", pc, fp,
+                     code.QualifiedName());
         return;
       }
     }
@@ -438,12 +440,24 @@
 
   uintptr_t start = 0;
   char* native_symbol_name = NativeSymbolResolver::LookupSymbolName(pc, &start);
-  if (native_symbol_name == NULL) {
-    OS::PrintErr("  [0x%" Pp "] Unknown symbol\n", pc);
-  } else {
-    OS::PrintErr("  [0x%" Pp "] %s\n", pc, native_symbol_name);
+  if (native_symbol_name != NULL) {
+    OS::PrintErr("  pc 0x%" Pp " fp 0x%" Pp " %s\n", pc, fp,
+                 native_symbol_name);
     NativeSymbolResolver::FreeSymbolName(native_symbol_name);
+    return;
   }
+
+  char* dso_name;
+  uword dso_base;
+  if (NativeSymbolResolver::LookupSharedObject(pc, &dso_base, &dso_name)) {
+    uword dso_offset = pc - dso_base;
+    OS::PrintErr("  pc 0x%" Pp " fp 0x%" Pp " %s+0x%" Px "\n", pc, fp, dso_name,
+                 dso_offset);
+    NativeSymbolResolver::FreeSymbolName(dso_name);
+    return;
+  }
+
+  OS::PrintErr("  pc 0x%" Pp " fp 0x%" Pp " Unknown symbol\n", pc, fp);
 }
 
 class ProfilerStackWalker : public ValueObject {
@@ -469,14 +483,14 @@
     }
   }
 
-  bool Append(uword pc) {
+  bool Append(uword pc, uword fp) {
     if (frames_skipped_ < skip_count_) {
       frames_skipped_++;
       return true;
     }
 
     if (sample_ == NULL) {
-      DumpStackFrame(frame_index_, pc, try_symbolize_dart_frames_);
+      DumpStackFrame(frame_index_, pc, fp, try_symbolize_dart_frames_);
       frame_index_++;
       total_frames_++;
       return true;
@@ -632,7 +646,7 @@
                                                    in_interpreted_frame));
       }
 
-      if (!Append(reinterpret_cast<uword>(pc_))) {
+      if (!Append(reinterpret_cast<uword>(pc_), reinterpret_cast<uword>(fp_))) {
         break;  // Sample is full.
       }
 
@@ -725,7 +739,7 @@
   void walk() {
     const uword kMaxStep = VirtualMemory::PageSize();
 
-    Append(original_pc_);
+    Append(original_pc_, original_fp_);
 
     uword* pc = reinterpret_cast<uword*>(original_pc_);
     uword* fp = reinterpret_cast<uword*>(original_fp_);
@@ -747,10 +761,6 @@
     }
 
     while (true) {
-      if (!Append(reinterpret_cast<uword>(pc))) {
-        return;
-      }
-
       pc = CallerPC(fp);
       previous_fp = fp;
       fp = CallerFP(fp);
@@ -794,6 +804,10 @@
 
       // Move the lower bound up.
       lower_bound_ = reinterpret_cast<uword>(fp);
+
+      if (!Append(reinterpret_cast<uword>(pc), reinterpret_cast<uword>(fp))) {
+        return;
+      }
     }
   }
 
diff --git a/runtime/vm/profiler.h b/runtime/vm/profiler.h
index 2f68dbf..d5122fc7d 100644
--- a/runtime/vm/profiler.h
+++ b/runtime/vm/profiler.h
@@ -80,8 +80,8 @@
   // SampleThread is called from inside the signal handler and hence it is very
   // critical that the implementation of SampleThread does not do any of the
   // following:
-  //   * Accessing TLS -- Because on Windows the callback will be running in a
-  //                      different thread.
+  //   * Accessing TLS -- Because on Windows and Fuchsia the callback will be
+  //                      running in a different thread.
   //   * Allocating memory -- Because this takes locks which may already be
   //                          held, resulting in a dead lock.
   //   * Taking a lock -- See above.
diff --git a/runtime/vm/raw_object.h b/runtime/vm/raw_object.h
index a6989f9..5f77d72 100644
--- a/runtime/vm/raw_object.h
+++ b/runtime/vm/raw_object.h
@@ -1066,7 +1066,7 @@
   TokenPosition end_token_pos_;
   classid_t guarded_cid_;
   classid_t is_nullable_;  // kNullCid if field can contain null value and
-                           // any other value otherwise.
+                           // kInvalidCid otherwise.
 
 #if !defined(DART_PRECOMPILED_RUNTIME)
   typedef BitField<uint32_t, bool, 0, 1> IsDeclaredInBytecode;
@@ -1701,10 +1701,8 @@
   RawArray* entries_;          // Contains class-ids, target and count.
   RawString* target_name_;     // Name of target function.
   RawArray* args_descriptor_;  // Arguments descriptor.
-  // Static type of the receiver. If it is set then we are performing
-  // exactness profiling for the receiver type. See StaticTypeExactnessState
-  // class for more information.
-  NOT_IN_PRECOMPILED(RawAbstractType* static_receiver_type_);
+  // Static type of the receiver, if instance call and available.
+  NOT_IN_PRECOMPILED(RawAbstractType* receivers_static_type_);
   RawObject* owner_;  // Parent/calling function or original IC of cloned IC.
   VISIT_TO(RawObject*, owner_);
   RawObject** to_snapshot(Snapshot::Kind kind) {
diff --git a/runtime/vm/runtime_entry.cc b/runtime/vm/runtime_entry.cc
index d4c12b1..bcc8277 100644
--- a/runtime/vm/runtime_entry.cc
+++ b/runtime/vm/runtime_entry.cc
@@ -1142,14 +1142,14 @@
     return target_function.raw();
   }
   if (args.length() == 1) {
-    if (ic_data.IsTrackingExactness()) {
+    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(
                                    Type::Cast(AbstractType::Handle(
-                                       ic_data.StaticReceiverType())),
+                                       ic_data.receivers_static_type())),
                                    receiver);
       ic_data.AddReceiverCheck(
           receiver.GetClassId(), target_function,
@@ -2144,6 +2144,9 @@
   if ((!optimizing_compilation) ||
       Compiler::CanOptimizeFunction(thread, function)) {
     if (FLAG_background_compilation) {
+      if (FLAG_enable_inlining_annotations) {
+        FATAL("Cannot enable inlining annotations and background compilation");
+      }
       Field& field = Field::Handle(zone, isolate->GetDeoptimizingBoxedField());
       while (!field.IsNull()) {
         if (FLAG_trace_optimization || FLAG_trace_field_guards) {
@@ -2154,25 +2157,21 @@
         // Get next field.
         field = isolate->GetDeoptimizingBoxedField();
       }
-    }
-    // TODO(srdjan): Fix background compilation of regular expressions.
-    if (FLAG_background_compilation) {
-      if (FLAG_enable_inlining_annotations) {
-        FATAL("Cannot enable inlining annotations and background compilation");
-      }
-      if (!BackgroundCompiler::IsDisabled(isolate) &&
+      if (!BackgroundCompiler::IsDisabled(isolate, optimizing_compilation) &&
           function.is_background_optimizable()) {
-        if (FLAG_background_compilation_stop_alot) {
-          BackgroundCompiler::Stop(isolate);
-        }
-        // Reduce the chance of triggering optimization while the function is
-        // being optimized in the background. INT_MIN should ensure that it
-        // takes long time to trigger optimization.
+        // Ensure background compiler is running, if not start it.
+        BackgroundCompiler::Start(isolate);
+        // Reduce the chance of triggering a compilation while the function is
+        // being compiled in the background. INT_MIN should ensure that it
+        // takes long time to trigger a compilation.
         // Note that the background compilation queue rejects duplicate entries.
         function.SetUsageCounter(INT_MIN);
-        BackgroundCompiler::Start(isolate);
-        isolate->background_compiler()->CompileOptimized(function);
-
+        if (optimizing_compilation) {
+          isolate->optimizing_background_compiler()->Compile(function);
+        } else {
+          ASSERT(FLAG_enable_interpreter);
+          isolate->background_compiler()->Compile(function);
+        }
         // Continue in the same code.
         arguments.SetReturn(function);
         return;
diff --git a/runtime/vm/service.cc b/runtime/vm/service.cc
index accf3f0..2aeb4a3 100644
--- a/runtime/vm/service.cc
+++ b/runtime/vm/service.cc
@@ -1488,7 +1488,8 @@
 }
 
 static const MethodParameter* get_stack_params[] = {
-    RUNNABLE_ISOLATE_PARAMETER, new BoolParameter("_full", false), NULL,
+    RUNNABLE_ISOLATE_PARAMETER,
+    NULL,
 };
 
 static bool GetStack(Thread* thread, JSONStream* js) {
@@ -1503,7 +1504,6 @@
   DebuggerStackTrace* awaiter_stack = isolate->debugger()->AwaiterStackTrace();
   // Do we want the complete script object and complete local variable objects?
   // This is true for dump requests.
-  const bool full = BoolParameter::Parse(js->LookupParam("_full"), false);
   JSONObject jsobj(js);
   jsobj.AddProperty("type", "Stack");
   {
@@ -1513,7 +1513,7 @@
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = stack->FrameAt(i);
       JSONObject jsobj(&jsarr);
-      frame->PrintToJSONObject(&jsobj, full);
+      frame->PrintToJSONObject(&jsobj);
       jsobj.AddProperty("index", i);
     }
   }
@@ -1524,7 +1524,7 @@
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = async_causal_stack->FrameAt(i);
       JSONObject jsobj(&jsarr);
-      frame->PrintToJSONObject(&jsobj, full);
+      frame->PrintToJSONObject(&jsobj);
       jsobj.AddProperty("index", i);
     }
   }
@@ -1535,7 +1535,7 @@
     for (intptr_t i = 0; i < num_frames; i++) {
       ActivationFrame* frame = awaiter_stack->FrameAt(i);
       JSONObject jsobj(&jsarr);
-      frame->PrintToJSONObject(&jsobj, full);
+      frame->PrintToJSONObject(&jsobj);
       jsobj.AddProperty("index", i);
     }
   }
@@ -1590,20 +1590,6 @@
   return HandleCommonEcho(&jsobj, js);
 }
 
-static bool DumpIdZone(Thread* thread, JSONStream* js) {
-  // TODO(johnmccutchan): Respect _idZone parameter passed to RPC. For now,
-  // always send the ObjectIdRing.
-  //
-  ObjectIdRing* ring = thread->isolate()->object_id_ring();
-  ASSERT(ring != NULL);
-  // When printing the ObjectIdRing, force object id reuse policy.
-  RingServiceIdZone reuse_zone;
-  reuse_zone.Init(ring, ObjectIdRing::kReuseId);
-  js->set_id_zone(&reuse_zone);
-  ring->PrintJSON(js);
-  return true;
-}
-
 static bool Echo(Thread* thread, JSONStream* js) {
   JSONObject jsobj(js);
   return HandleCommonEcho(&jsobj, js);
@@ -4841,7 +4827,6 @@
 
 // clang-format off
 static const ServiceMethodDescriptor service_methods_[] = {
-  { "_dumpIdZone", DumpIdZone, NULL },
   { "_echo", Echo,
     NULL },
   { "_respondWithMalformedJson", RespondWithMalformedJson,
diff --git a/runtime/vm/service/service.md b/runtime/vm/service/service.md
index 0040087..e3c2fd1 100644
--- a/runtime/vm/service/service.md
+++ b/runtime/vm/service/service.md
@@ -1308,7 +1308,7 @@
   // The isolate has encountered a Dart language error in the program.
   LanguageError,
 
-  // The isolate has encounted an internal error. These errors should be
+  // The isolate has encountered an internal error. These errors should be
   // reported as bugs.
   InternalError,
 
diff --git a/runtime/vm/service/service_dev.md b/runtime/vm/service/service_dev.md
index a440425..dbfa952 100644
--- a/runtime/vm/service/service_dev.md
+++ b/runtime/vm/service/service_dev.md
@@ -1308,7 +1308,7 @@
   // The isolate has encountered a Dart language error in the program.
   LanguageError,
 
-  // The isolate has encounted an internal error. These errors should be
+  // The isolate has encountered an internal error. These errors should be
   // reported as bugs.
   InternalError,
 
diff --git a/runtime/vm/simulator_arm.cc b/runtime/vm/simulator_arm.cc
index ec829b9..2cd0745 100644
--- a/runtime/vm/simulator_arm.cc
+++ b/runtime/vm/simulator_arm.cc
@@ -15,7 +15,7 @@
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 #include "vm/cpu.h"
 #include "vm/native_arguments.h"
 #include "vm/os_thread.h"
diff --git a/runtime/vm/simulator_arm.h b/runtime/vm/simulator_arm.h
index 406f7ce..8f269b2 100644
--- a/runtime/vm/simulator_arm.h
+++ b/runtime/vm/simulator_arm.h
@@ -16,7 +16,7 @@
 #error Do not include simulator_arm.h directly; use simulator.h.
 #endif
 
-#include "vm/constants_arm.h"
+#include "vm/constants.h"
 
 namespace dart {
 
diff --git a/runtime/vm/simulator_arm64.cc b/runtime/vm/simulator_arm64.cc
index 0d9f446..c835793 100644
--- a/runtime/vm/simulator_arm64.cc
+++ b/runtime/vm/simulator_arm64.cc
@@ -15,7 +15,7 @@
 
 #include "vm/compiler/assembler/assembler.h"
 #include "vm/compiler/assembler/disassembler.h"
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 #include "vm/native_arguments.h"
 #include "vm/os_thread.h"
 #include "vm/stack_frame.h"
diff --git a/runtime/vm/simulator_arm64.h b/runtime/vm/simulator_arm64.h
index 43ae2ea..8a48451 100644
--- a/runtime/vm/simulator_arm64.h
+++ b/runtime/vm/simulator_arm64.h
@@ -16,7 +16,7 @@
 #error Do not include simulator_arm64.h directly; use simulator.h.
 #endif
 
-#include "vm/constants_arm64.h"
+#include "vm/constants.h"
 
 namespace dart {
 
diff --git a/runtime/vm/snapshot_test.cc b/runtime/vm/snapshot_test.cc
index 2ca95a0..04f4e6a 100644
--- a/runtime/vm/snapshot_test.cc
+++ b/runtime/vm/snapshot_test.cc
@@ -804,72 +804,6 @@
   free(isolate_snapshot_data_buffer);
 }
 
-VM_UNIT_TEST_CASE(FullSnapshot1) {
-  // This buffer has to be static for this to compile with Visual Studio.
-  // If it is not static compilation of this file with Visual Studio takes
-  // more than 30 minutes!
-  static const char kFullSnapshotScriptChars[] = {
-#include "snapshot_test.dat"
-  };
-  const char* kScriptChars = kFullSnapshotScriptChars;
-
-  uint8_t* isolate_snapshot_data_buffer;
-
-  // Start an Isolate, load a script and create a full snapshot.
-  Timer timer1(true, "Snapshot_test");
-  timer1.Start();
-  {
-    TestIsolateScope __test_isolate__;
-
-    Thread* thread = Thread::Current();
-    StackZone zone(thread);
-    HandleScope scope(thread);
-
-    // Create a test library and Load up a test script in it.
-    Dart_Handle lib = TestCase::LoadTestScript(kScriptChars, NULL);
-    EXPECT_VALID(Api::CheckAndFinalizePendingClasses(thread));
-    timer1.Stop();
-    OS::PrintErr("Without Snapshot: %" Pd64 "us\n", timer1.TotalElapsedTime());
-
-    // Write snapshot with object content.
-    {
-      TransitionNativeToVM transition(thread);
-      FullSnapshotWriter writer(
-          Snapshot::kFull, NULL, &isolate_snapshot_data_buffer,
-          &malloc_allocator, NULL, /*image_writer*/ nullptr);
-      writer.WriteFullSnapshot();
-    }
-
-    // Invoke a function which returns an object.
-    Dart_Handle cls = Dart_GetClass(lib, NewString("FieldsTest"));
-    Dart_Handle result = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
-    EXPECT_VALID(result);
-  }
-
-  // Now Create another isolate using the snapshot and execute a method
-  // from the script.
-  Timer timer2(true, "Snapshot_test");
-  timer2.Start();
-  TestCase::CreateTestIsolateFromSnapshot(isolate_snapshot_data_buffer);
-  {
-    Dart_EnterScope();  // Start a Dart API scope for invoking API functions.
-    timer2.Stop();
-    OS::PrintErr("From Snapshot: %" Pd64 "us\n", timer2.TotalElapsedTime());
-
-    // Invoke a function which returns an object.
-    Dart_Handle cls = Dart_GetClass(TestCase::lib(), NewString("FieldsTest"));
-    Dart_Handle result = Dart_Invoke(cls, NewString("testMain"), 0, NULL);
-    if (Dart_IsError(result)) {
-      // Print the error.  It is probably an unhandled exception.
-      fprintf(stderr, "%s\n", Dart_GetError(result));
-    }
-    EXPECT_VALID(result);
-    Dart_ExitScope();
-  }
-  Dart_ShutdownIsolate();
-  free(isolate_snapshot_data_buffer);
-}
-
 // Helper function to call a top level Dart function and serialize the result.
 static Message* GetSerialized(Dart_Handle lib, const char* dart_function) {
   Dart_Handle result;
diff --git a/runtime/vm/snapshot_test.dart b/runtime/vm/snapshot_test.dart
deleted file mode 100644
index a8e037d..0000000
--- a/runtime/vm/snapshot_test.dart
+++ /dev/null
@@ -1,1552 +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.
-
-import 'dart:isolate';
-import 'dart:async';
-
-class Expect {
-  static void equals(x, y) {
-    if (x != y) throw new ArgumentError('not equal');
-  }
-}
-
-class Fields {
-  Fields(int i, int j)
-      : fld1 = i,
-        fld2 = j,
-        fld5 = true {}
-  int fld1;
-  final int fld2;
-  static int fld3;
-  static const int fld4 = 10;
-  bool fld5;
-}
-
-class FieldsTest {
-  static Fields testMain() {
-    Fields obj = new Fields(10, 20);
-    Expect.equals(10, obj.fld1);
-    Expect.equals(20, obj.fld2);
-    Expect.equals(10, Fields.fld4);
-    Expect.equals(true, obj.fld5);
-    return obj;
-  }
-}
-// Benchpress: A collection of micro-benchmarks.
-// Ported from internal v8 benchmark suite.
-
-class Error {
-  static void error(String msg) {
-    throw msg;
-  }
-}
-
-// F i b o n a c c i
-class Fibonacci {
-  static int fib(int n) {
-    if (n <= 1) return 1;
-    return fib(n - 1) + fib(n - 2);
-  }
-}
-
-class FibBenchmark extends BenchmarkBase {
-  const FibBenchmark() : super("Fibonacci");
-
-  void warmup() {
-    Fibonacci.fib(10);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    var result = Fibonacci.fib(20);
-    if (result != 10946)
-      Error.error("Wrong result: $result. Should be: 10946.");
-  }
-
-  static void main() {
-    new FibBenchmark().report();
-  }
-}
-
-// L o o p
-class Loop {
-  static int loop(int outerIterations) {
-    int sum = 0;
-    for (int i = 0; i < outerIterations; i++) {
-      for (int j = 0; j < 100; j++) {
-        sum++;
-      }
-    }
-    return sum;
-  }
-}
-
-class LoopBenchmark extends BenchmarkBase {
-  const LoopBenchmark() : super("Loop");
-
-  void warmup() {
-    Loop.loop(10);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    var result = Loop.loop(200);
-    if (result != 20000) Error.error("Wrong result: $result. Should be: 20000");
-  }
-
-  static void main() {
-    new LoopBenchmark().report();
-  }
-}
-
-// T o w e r s
-class TowersDisk {
-  final int size;
-  TowersDisk next;
-
-  TowersDisk(size)
-      : this.size = size,
-        next = null {}
-}
-
-class Towers {
-  List<TowersDisk> piles;
-  int movesDone;
-  Towers(int disks)
-      : piles = new List<TowersDisk>(3),
-        movesDone = 0 {
-    build(0, disks);
-  }
-
-  void build(int pile, int disks) {
-    for (var i = disks - 1; i >= 0; i--) {
-      push(pile, new TowersDisk(i));
-    }
-  }
-
-  void push(int pile, TowersDisk disk) {
-    TowersDisk top = piles[pile];
-    if ((top != null) && (disk.size >= top.size))
-      Error.error("Cannot put a big disk on a smaller disk.");
-    disk.next = top;
-    piles[pile] = disk;
-  }
-
-  TowersDisk pop(int pile) {
-    var top = piles[pile];
-    if (top == null)
-      Error.error("Attempting to remove a disk from an empty pile.");
-    piles[pile] = top.next;
-    top.next = null;
-    return top;
-  }
-
-  void moveTop(int from, int to) {
-    push(to, pop(from));
-    movesDone++;
-  }
-
-  void move(int from, int to, int disks) {
-    if (disks == 1) {
-      moveTop(from, to);
-    } else {
-      int other = 3 - from - to;
-      move(from, other, disks - 1);
-      moveTop(from, to);
-      move(other, to, disks - 1);
-    }
-  }
-}
-
-class TowersBenchmark extends BenchmarkBase {
-  const TowersBenchmark() : super("Towers");
-
-  void warmup() {
-    new Towers(6).move(0, 1, 6);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    var towers = new Towers(13);
-    towers.move(0, 1, 13);
-    if (towers.movesDone != 8191) {
-      var moves = towers.movesDone;
-      Error.error("Error in result: $moves should be: 8191");
-    }
-  }
-
-  static void main() {
-    new TowersBenchmark().report();
-  }
-}
-
-// S i e v e
-class SieveBenchmark extends BenchmarkBase {
-  const SieveBenchmark() : super("Sieve");
-
-  static int sieve(int size) {
-    int primeCount = 0;
-    List<bool> flags = new List<bool>(size + 1);
-    for (int i = 1; i < size; i++) flags[i] = true;
-    for (int i = 2; i < size; i++) {
-      if (flags[i]) {
-        primeCount++;
-        for (int k = i + 1; k <= size; k += i) flags[k - 1] = false;
-      }
-    }
-    return primeCount;
-  }
-
-  void warmup() {
-    sieve(100);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    int result = sieve(1000);
-    if (result != 168) Error.error("Wrong result: $result should be: 168");
-  }
-
-  static void main() {
-    new SieveBenchmark().report();
-  }
-}
-
-// P e r m u t e
-// The original benchmark uses one-based indexing. Even though arrays in JS and
-// lists in dart are zero-based, we stay with one-based indexing
-// (wasting one element).
-class Permute {
-  int permuteCount;
-  Permute() {}
-
-  void swap(int n, int k, List<int> list) {
-    int tmp = list[n];
-    list[n] = list[k];
-    list[k] = tmp;
-  }
-
-  void doPermute(int n, List<int> list) {
-    permuteCount++;
-    if (n != 1) {
-      doPermute(n - 1, list);
-      for (int k = n - 1; k >= 1; k--) {
-        swap(n, k, list);
-        doPermute(n - 1, list);
-        swap(n, k, list);
-      }
-    }
-  }
-
-  int permute(int size) {
-    permuteCount = 0;
-    List<int> list = new List<int>(size);
-    for (int i = 1; i < size; i++) list[i] = i - 1;
-    doPermute(size - 1, list);
-    return permuteCount;
-  }
-}
-
-class PermuteBenchmark extends BenchmarkBase {
-  const PermuteBenchmark() : super("Permute");
-
-  void warmup() {
-    new Permute().permute(4);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    int result = new Permute().permute(8);
-    if (result != 8660) Error.error("Wrong result: $result should be: 8660");
-  }
-
-  static void main() {
-    new PermuteBenchmark().report();
-  }
-}
-
-// Q u e e n s
-// The original benchmark uses one-based indexing. Even though arrays in JS and
-// lists in dart are zero-based, we stay with one-based indexing
-// (wasting one element).
-class Queens {
-  static bool tryQueens(
-      int i, List<bool> a, List<bool> b, List<bool> c, List<int> x) {
-    int j = 0;
-    bool q = false;
-    while ((!q) && (j != 8)) {
-      j++;
-      q = false;
-      if (b[j] && a[i + j] && c[i - j + 7]) {
-        x[i] = j;
-        b[j] = false;
-        a[i + j] = false;
-        c[i - j + 7] = false;
-        if (i < 8) {
-          q = tryQueens(i + 1, a, b, c, x);
-          if (!q) {
-            b[j] = true;
-            a[i + j] = true;
-            c[i - j + 7] = true;
-          }
-        } else {
-          q = true;
-        }
-      }
-    }
-    return q;
-  }
-
-  static void queens() {
-    List<bool> a = new List<bool>(9);
-    List<bool> b = new List<bool>(17);
-    List<bool> c = new List<bool>(15);
-    List<int> x = new List<int>(9);
-    b[1] = false;
-    for (int i = -7; i <= 16; i++) {
-      if ((i >= 1) && (i <= 8)) a[i] = true;
-      if (i >= 2) b[i] = true;
-      if (i <= 7) c[i + 7] = true;
-    }
-
-    if (!tryQueens(1, b, a, c, x)) Error.error("Error in queens");
-  }
-}
-
-class QueensBenchmark extends BenchmarkBase {
-  const QueensBenchmark() : super("Queens");
-
-  void warmup() {
-    Queens.queens();
-  }
-
-  void exercise() {
-    Queens.queens();
-  }
-
-  static void main() {
-    new QueensBenchmark().report();
-  }
-}
-
-// R e c u r s e
-class Recurse {
-  static int recurse(int n) {
-    if (n <= 0) return 1;
-    recurse(n - 1);
-    return recurse(n - 1);
-  }
-}
-
-class RecurseBenchmark extends BenchmarkBase {
-  const RecurseBenchmark() : super("Recurse");
-
-  void warmup() {
-    Recurse.recurse(7);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    Recurse.recurse(13);
-  }
-
-  static void main() {
-    new RecurseBenchmark().report();
-  }
-}
-
-// S u m
-class SumBenchmark extends BenchmarkBase {
-  const SumBenchmark() : super("Sum");
-
-  static int sum(int start, int end) {
-    var sum = 0;
-    for (var i = start; i <= end; i++) sum += i;
-    return sum;
-  }
-
-  void warmup() {
-    sum(1, 1000);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    int result = sum(1, 10000);
-    if (result != 50005000)
-      Error.error("Wrong result: $result should be 50005000");
-  }
-
-  static void main() {
-    new SumBenchmark().report();
-  }
-}
-
-// H e l p e r   f u n c t i o n s   f o r   s o r t s
-class Random {
-  static const int INITIAL_SEED = 74755;
-  int seed;
-  Random() : seed = INITIAL_SEED {}
-
-  int random() {
-    seed = ((seed * 1309) + 13849) % 65536;
-    return seed;
-  }
-}
-
-//
-class SortData {
-  List<int> list;
-  int min;
-  int max;
-
-  SortData(int length) {
-    Random r = new Random();
-    list = new List<int>(length);
-    for (int i = 0; i < length; i++) list[i] = r.random();
-
-    int min, max;
-    min = max = list[0];
-    for (int i = 0; i < length; i++) {
-      int e = list[i];
-      if (e > max) max = e;
-      if (e < min) min = e;
-    }
-
-    this.min = min;
-    this.max = max;
-  }
-
-  void check() {
-    List<int> a = list;
-    int len = a.length;
-    if ((a[0] != min) || a[len - 1] != max) Error.error("List is not sorted");
-    for (var i = 1; i < len; i++) {
-      if (a[i - 1] > a[i]) Error.error("List is not sorted");
-    }
-  }
-}
-
-// B u b b l e S o r t
-class BubbleSort {
-  static void sort(List<int> a) {
-    int len = a.length;
-    for (int i = len - 2; i >= 0; i--) {
-      for (int j = 0; j <= i; j++) {
-        int c = a[j];
-        int n = a[j + 1];
-        if (c > n) {
-          a[j] = n;
-          a[j + 1] = c;
-        }
-      }
-    }
-  }
-}
-
-class BubbleSortBenchmark extends BenchmarkBase {
-  const BubbleSortBenchmark() : super("BubbleSort");
-
-  void warmup() {
-    SortData data = new SortData(30);
-    BubbleSort.sort(data.list);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    SortData data = new SortData(130);
-    BubbleSort.sort(data.list);
-    data.check();
-  }
-
-  static void main() {
-    new BubbleSortBenchmark().report();
-  }
-}
-
-// Q u i c k S o r t
-class QuickSort {
-  static void sort(List<int> a, int low, int high) {
-    int pivot = a[(low + high) >> 1];
-    int i = low;
-    int j = high;
-    while (i <= j) {
-      while (a[i] < pivot) i++;
-      while (pivot < a[j]) j--;
-      if (i <= j) {
-        int tmp = a[i];
-        a[i] = a[j];
-        a[j] = tmp;
-        i++;
-        j--;
-      }
-    }
-
-    if (low < j) sort(a, low, j);
-    if (i < high) sort(a, i, high);
-  }
-}
-
-class QuickSortBenchmark extends BenchmarkBase {
-  const QuickSortBenchmark() : super("QuickSort");
-
-  void warmup() {
-    SortData data = new SortData(100);
-    QuickSort.sort(data.list, 0, data.list.length - 1);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    SortData data = new SortData(800);
-    QuickSort.sort(data.list, 0, data.list.length - 1);
-    data.check();
-  }
-
-  static void main() {
-    new QuickSortBenchmark().report();
-  }
-}
-
-// T r e e S o r t
-class TreeNodePress {
-  int value;
-  TreeNodePress left;
-  TreeNodePress right;
-
-  TreeNodePress(int n) : value = n {}
-
-  void insert(int n) {
-    if (n < value) {
-      if (left == null)
-        left = new TreeNodePress(n);
-      else
-        left.insert(n);
-    } else {
-      if (right == null)
-        right = new TreeNodePress(n);
-      else
-        right.insert(n);
-    }
-  }
-
-  void check() {
-    TreeNodePress left = this.left;
-    TreeNodePress right = this.right;
-    int value = this.value;
-
-    return ((left == null) || ((left.value < value) && left.check())) &&
-        ((right == null) || ((right.value >= value) && right.check()));
-  }
-}
-
-class TreeSort {
-  static void sort(List<int> a) {
-    int len = a.length;
-    TreeNodePress tree = new TreeNodePress(a[0]);
-    for (var i = 1; i < len; i++) tree.insert(a[i]);
-    if (!tree.check()) Error.error("Invalid result, tree not sorted");
-  }
-}
-
-class TreeSortBenchmark extends BenchmarkBase {
-  const TreeSortBenchmark() : super("TreeSort");
-
-  void warmup() {
-    TreeSort.sort(new SortData(100).list);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    TreeSort.sort(new SortData(1000).list);
-  }
-}
-
-// T a k
-class TakBenchmark extends BenchmarkBase {
-  const TakBenchmark() : super("Tak");
-
-  static void tak(int x, int y, int z) {
-    if (y >= x) return z;
-    return tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y));
-  }
-
-  void warmup() {
-    tak(9, 6, 3);
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    tak(18, 12, 6);
-  }
-
-  static void main() {
-    new TakBenchmark().report();
-  }
-}
-
-// T a k l
-class ListElement {
-  final int length;
-  final ListElement next;
-
-  const ListElement(int length, ListElement next)
-      : this.length = length,
-        this.next = next;
-
-  static ListElement makeList(int length) {
-    if (length == 0) return null;
-    return new ListElement(length, makeList(length - 1));
-  }
-
-  static bool isShorter(ListElement x, ListElement y) {
-    ListElement xTail = x;
-    ListElement yTail = y;
-    while (yTail != null) {
-      if (xTail == null) return true;
-      xTail = xTail.next;
-      yTail = yTail.next;
-    }
-    return false;
-  }
-}
-
-class Takl {
-  static ListElement takl(ListElement x, ListElement y, ListElement z) {
-    if (ListElement.isShorter(y, x)) {
-      return takl(takl(x.next, y, z), takl(y.next, z, x), takl(z.next, x, y));
-    } else {
-      return z;
-    }
-  }
-}
-
-class TaklBenchmark extends BenchmarkBase {
-  const TaklBenchmark() : super("Takl");
-
-  void warmup() {
-    Takl.takl(ListElement.makeList(8), ListElement.makeList(4),
-        ListElement.makeList(3));
-  }
-
-  void exercise() {
-    // This value has been copied from benchpress.js, so that we can compare
-    // performance.
-    ListElement result = Takl.takl(ListElement.makeList(15),
-        ListElement.makeList(10), ListElement.makeList(6));
-    if (result.length != 10) {
-      int len = result.length;
-      Error.error("Wrong result: $len should be: 10");
-    }
-  }
-
-  static void main() {
-    new TaklBenchmark().report();
-  }
-}
-
-// M a i n
-
-class BenchPress {
-  static void mainWithArgs(List<String> args) {
-    List<BenchmarkBase> benchmarks = [
-      new BubbleSortBenchmark(),
-      new FibBenchmark(),
-      new LoopBenchmark(),
-      new PermuteBenchmark(),
-      new QueensBenchmark(),
-      new QuickSortBenchmark(),
-      new RecurseBenchmark(),
-      new SieveBenchmark(),
-      new SumBenchmark(),
-      new TakBenchmark(),
-      new TaklBenchmark(),
-      new TowersBenchmark(),
-      new TreeSortBenchmark(),
-    ];
-    if (args.length > 0) {
-      String benchName = args[0];
-      bool foundBenchmark = false;
-      benchmarks.forEach((bench) {
-        if (bench.name == benchName) {
-          foundBenchmark = true;
-          bench.report();
-        }
-      });
-      if (!foundBenchmark) {
-        Error.error("Benchmark not found: $benchName");
-      }
-      return;
-    }
-    double logMean = 0.0;
-    benchmarks.forEach((bench) {
-      double benchScore = bench.measure();
-      String name = bench.name;
-      print("$name: $benchScore");
-      logMean += Math.log(benchScore);
-    });
-    logMean = logMean / benchmarks.length;
-    double score = Math.pow(Math.E, logMean);
-    print("BenchPress (average): $score");
-  }
-
-  // TODO(floitsch): let main accept arguments from the command line.
-  static void main() {
-    mainWithArgs([]);
-  }
-}
-
-class BenchmarkBase {
-  final String name;
-
-  // Empty constructor.
-  const BenchmarkBase(String name) : this.name = name;
-
-  // The benchmark code.
-  // This function is not used, if both [warmup] and [exercise] are overwritten.
-  void run() {}
-
-  // Runs a short version of the benchmark. By default invokes [run] once.
-  void warmup() {
-    run();
-  }
-
-  // Exercises the benchmark. By default invokes [run] 10 times.
-  void exercise() {
-    for (int i = 0; i < 10; i++) {
-      run();
-    }
-  }
-
-  // Not measured setup code executed prior to the benchmark runs.
-  void setup() {}
-
-  // Not measures teardown code executed after the benchmark runs.
-  void teardown() {}
-
-  // Measures the score for this benchmark by executing it repeately until
-  // time minimum has been reached.
-  static double measureFor(Function f, int timeMinimum) {
-    int time = 0;
-    int iter = 0;
-    DateTime start = new DateTime.now();
-    while (time < timeMinimum) {
-      f();
-      time = (new DateTime.now().difference(start)).inMilliseconds;
-      iter++;
-    }
-    // Force double result by using a double constant.
-    return (1000.0 * iter) / time;
-  }
-
-  // Measures the score for the benchmark and returns it.
-  double measure() {
-    setup();
-    // Warmup for at least 100ms. Discard result.
-    measureFor(() {
-      this.warmup();
-    }, -100);
-    // Run the benchmark for at least 2000ms.
-    double result = measureFor(() {
-      this.exercise();
-    }, -2000);
-    teardown();
-    return result;
-  }
-
-  void report() {
-    double score = measure();
-    print("name: $score");
-  }
-}
-
-class Logger {
-  static print(object) {
-    printobject(object);
-  }
-
-  static printobject(obj) {}
-}
-
-//
-// Dromaeo ObjectString
-// Adapted from Mozilla JavaScript performance test suite.
-// Microtests of strings (concatenation, methods).
-
-class ObjectString extends BenchmarkBase {
-  const ObjectString() : super("Dromaeo.ObjectString");
-
-  static void main() {
-    new ObjectString().report();
-  }
-
-  static void print(String str) {
-    print(str);
-  }
-
-  String getRandomString(int characters) {
-    var result = "";
-    for (var i = 0; i < characters; i++) {
-      result +=
-          Strings.createFromCodePoints([(25 * Math.random()).toInt() + 97]);
-    }
-    result += result;
-    result += result;
-    return result;
-  }
-
-  void run() {
-    //JS Dromeaeo uses 16384
-    final ITERATE1 = 384;
-    //JS Dromeaeo uses 80000
-    final ITERATE2 = 80;
-    //JS Dromeaeo uses 5000
-    final ITERATE3 = 50;
-    //JS Dromeaeo uses 5000
-    final ITERATE4 = 1;
-    //JS Dromaeo uses 5000
-    final ITERATE5 = 1000;
-
-    var result;
-    var text = getRandomString(ITERATE1);
-
-    ConcatStringBenchmark.test(ITERATE2);
-    ConcatStringFromCharCodeBenchmark.test(ITERATE2);
-    StringSplitBenchmark.test(text);
-    StringSplitOnCharBenchmark.test(text);
-    text += text;
-    CharAtBenchmark.test(text, ITERATE3);
-    NumberBenchmark.test(text, ITERATE3);
-    CodeUnitAtBenchmark.test(text, ITERATE3);
-    IndexOfBenchmark.test(text, ITERATE3);
-    LastIndexOfBenchmark.test(text, ITERATE3);
-    SliceBenchmark.test(text, ITERATE4);
-    SubstrBenchmark.test(text, ITERATE4);
-    SubstringBenchmark.test(text, ITERATE4);
-    ToLowerCaseBenchmark.test(text, ITERATE5);
-    ToUpperCaseBenchmark.test(text, ITERATE5);
-    ComparingBenchmark.test(text, ITERATE5);
-  }
-}
-
-class ConcatStringBenchmark {
-  ConcatStringBenchmark() {}
-
-  static String test(var iterations) {
-    var str = "";
-    for (var i = 0; i < iterations; i++) {
-      str += "a";
-    }
-    return str;
-  }
-}
-
-class ConcatStringFromCharCodeBenchmark {
-  ConcatStringFromCharCodeBenchmark() {}
-
-  static String test(var iterations) {
-    var str = "";
-    for (var i = 0; i < (iterations / 2); i++) {
-      str += Strings.createFromCodePoints([97]);
-    }
-    return str;
-  }
-}
-
-class StringSplitBenchmark {
-  StringSplitBenchmark() {}
-
-  static List<String> test(String input) {
-    return input.split("");
-  }
-}
-
-class StringSplitOnCharBenchmark {
-  StringSplitOnCharBenchmark() {}
-
-  static List<String> test(String input) {
-    String multiple = input;
-    multiple += multiple;
-    multiple += multiple;
-    multiple += multiple;
-    multiple += multiple;
-    return multiple.split("a");
-  }
-}
-
-class CharAtBenchmark {
-  CharAtBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input[0];
-      str = input[input.length - 1];
-      str = input[150]; //set it to 15000
-      str = input[120]; //set it to 12000
-    }
-    return str;
-  }
-}
-
-class NumberBenchmark {
-  NumberBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input[0];
-      str = input[input.length - 1];
-      str = input[150]; //set it to 15000
-      str = input[100]; //set it to 10000
-      str = input[50]; //set it to 5000
-    }
-    return str;
-  }
-}
-
-class CodeUnitAtBenchmark {
-  CodeUnitAtBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.codeUnitAt(0);
-      str = input.codeUnitAt(input.length - 1);
-      str = input.codeUnitAt(150); //set it to 15000
-      str = input.codeUnitAt(100); //set it to 10000
-      str = input.codeUnitAt(50); //set it to 5000
-    }
-    return str;
-  }
-}
-
-class IndexOfBenchmark {
-  IndexOfBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.indexOf("a", 0);
-      str = input.indexOf("b", 0);
-      str = input.indexOf("c", 0);
-      str = input.indexOf("d", 0);
-    }
-    return str;
-  }
-}
-
-class LastIndexOfBenchmark {
-  LastIndexOfBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.lastIndexOf("a", input.length - 1);
-      str = input.lastIndexOf("b", input.length - 1);
-      str = input.lastIndexOf("c", input.length - 1);
-      str = input.lastIndexOf("d", input.length - 1);
-    }
-    return str;
-  }
-}
-
-class SliceBenchmark {
-  SliceBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.substring(0, input.length - 1);
-      str = input.substring(0, 5);
-      str = input.substring(input.length - 1, input.length - 1);
-      str = input.substring(input.length - 6, input.length - 1);
-      str = input.substring(150, 155); //set to 15000 and 15005
-      str = input.substring(120, input.length - 1); //set to 12000
-    }
-    return str;
-  }
-}
-
-class SubstrBenchmark {
-  SubstrBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.substring(0, input.length - 1);
-      str = input.substring(0, 4);
-      str = input.substring(input.length - 1, input.length - 1);
-      str = input.substring(input.length - 6, input.length - 6);
-      str = input.substring(150, 154); //set to 15000 and 15005
-      str = input.substring(120, 124); //set to 12000
-    }
-    return str;
-  }
-}
-
-class SubstringBenchmark {
-  SubstringBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < iterations; j++) {
-      str = input.substring(0, input.length - 1);
-      str = input.substring(0, 4);
-      str = input.substring(input.length - 1, input.length - 1);
-      str = input.substring(input.length - 6, input.length - 2);
-      str = input.substring(150, 154); //set to 15000 and 15005
-      str = input.substring(120, input.length - 2); //set to 12000
-    }
-    return str;
-  }
-}
-
-class ToLowerCaseBenchmark {
-  ToLowerCaseBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < (iterations / 1000); j++) {
-      str = Ascii.toLowerCase(input);
-    }
-    return str;
-  }
-}
-
-class ToUpperCaseBenchmark {
-  ToUpperCaseBenchmark() {}
-
-  static String test(String input, var iterations) {
-    var str;
-    for (var j = 0; j < (iterations / 1000); j++) {
-      str = Ascii.toUpperCase(input);
-    }
-    return str;
-  }
-}
-
-class ComparingBenchmark {
-  ComparingBenchmark() {}
-
-  static bool test(String input, var iterations) {
-    var tmp = "a${input}a";
-    var tmp2 = "a${input}a";
-    var res;
-    for (var j = 0; j < (iterations / 1000); j++) {
-      res = (tmp.compareTo(tmp2) == 0);
-      res = (tmp.compareTo(tmp2) < 0);
-      res = (tmp.compareTo(tmp2) > 0);
-    }
-    return res;
-  }
-}
-
-// Benchmarks basic message communication between two isolates.
-
-class Benchmark1 {
-  static const MESSAGES = 10000;
-  static const INIT_MESSAGE = 0;
-  static const TERMINATION_MESSAGE = -1;
-  static const WARMUP_TIME = 1000;
-  static const RUN_TIME = 1000;
-  static const RUNS = 5;
-
-  static int run() {
-    return _run;
-  }
-
-  static void add_result(var opsms) {
-    _run++;
-    _opsms += opsms;
-  }
-
-  static void get_result() {
-    return _opsms / _run;
-  }
-
-  static void init() {
-    _run = 0;
-    _opsms = 0.0;
-  }
-
-  static void main() {
-    init();
-    PingPongGame pingPongGame = new PingPongGame();
-  }
-
-  static var _run;
-  static var _opsms;
-}
-
-class PingPongGame {
-  PingPongGame()
-      : _ping = new ReceivePort(),
-        _pingPort = _ping.toSendPort(),
-        _pong = null,
-        _warmedup = false,
-        _iterations = 0 {
-    SendPort _pong = spawnFunction(pong);
-    play();
-  }
-
-  void startRound() {
-    _iterations++;
-    _pong.send(Benchmark1.INIT_MESSAGE, _pingPort);
-  }
-
-  void evaluateRound() {
-    int time = (new DateTime.now().difference(_start)).inMilliseconds;
-    if (!_warmedup && time < Benchmark1.WARMUP_TIME) {
-      startRound();
-    } else if (!_warmedup) {
-      _warmedup = true;
-      _start = new DateTime.now();
-      _iterations = 0;
-      startRound();
-    } else if (_warmedup && time < Benchmark1.RUN_TIME) {
-      startRound();
-    } else {
-      shutdown();
-      Benchmark1.add_result((1.0 * _iterations * Benchmark1.MESSAGES) / time);
-      if (Benchmark1.run() < Benchmark1.RUNS) {
-        new PingPongGame();
-      } else {
-        print("PingPong: ", Benchmark1.get_result());
-      }
-    }
-  }
-
-  void play() {
-    _ping.receive((int message, SendPort replyTo) {
-      if (message < Benchmark1.MESSAGES) {
-        _pong.send(++message, null);
-      } else {
-        evaluateRound();
-      }
-    });
-    _start = new DateTime.now();
-    startRound();
-  }
-
-  void shutdown() {
-    _pong.send(Benchmark1.TERMINATION_MESSAGE, null);
-    _ping.close();
-  }
-
-  DateTime _start;
-  SendPort _pong;
-  SendPort _pingPort;
-  ReceivePort _ping;
-  bool _warmedup;
-  int _iterations;
-}
-
-void pong() {
-  port.receive((message, SendPort replyTo) {
-    if (message == Benchmark1.INIT_MESSAGE) {
-      replyTo.send(message, null);
-    } else if (message == Benchmark1.TERMINATION_MESSAGE) {
-      port.close();
-    } else {
-      replyTo.send(message, null);
-    }
-  });
-}
-
-class ManyGenericInstanceofTest {
-  static testMain() {
-    for (int i = 0; i < 5000; i++) {
-      GenericInstanceof.testMain();
-    }
-  }
-}
-
-// ---------------------------------------------------------------------------
-// THE REST OF THIS FILE COULD BE AUTOGENERATED
-// ---------------------------------------------------------------------------
-
-// ---------------------------------------------------------------------------
-// tests/isolate/spawn_test.dart
-// ---------------------------------------------------------------------------
-
-spawn_test_main() {
-  test("spawn a new isolate", () {
-    SendPort port = spawnFunction(entry);
-    port.call(42).then(expectAsync1((message) {
-      Expect.equals(42, message);
-    }));
-  });
-}
-
-void entry() {
-  port.receive((message, SendPort replyTo) {
-    Expect.equals(42, message);
-    replyTo.send(42, null);
-    port.close();
-  });
-}
-
-// ---------------------------------------------------------------------------
-// tests/isolate/isolate_negative_test.dart
-// ---------------------------------------------------------------------------
-
-void isolate_negative_entry() {
-  port.receive((ignored, replyTo) {
-    replyTo.send("foo", null);
-  });
-}
-
-isolate_negative_test_main() {
-  test("ensure isolate code is executed", () {
-    SendPort port = spawnFunction(isolate_negative_entry);
-    port.call("foo").then(expectAsync1((message) {
-      Expect.equals(true, "Expected fail"); // <=-------- Should fail here.
-    }));
-  });
-}
-
-// ---------------------------------------------------------------------------
-// tests/isolate/message_test.dart
-// ---------------------------------------------------------------------------
-
-// ---------------------------------------------------------------------------
-// Message passing test.
-// ---------------------------------------------------------------------------
-
-class MessageTest {
-  static const List list1 = const ["Hello", "World", "Hello", 0xfffffffffff];
-  static const List list2 = const [null, list1, list1, list1, list1];
-  static const List list3 = const [list2, 2.0, true, false, 0xfffffffffff];
-  static const Map map1 = const {
-    "a=1": 1,
-    "b=2": 2,
-    "c=3": 3,
-  };
-  static const Map map2 = const {
-    "list1": list1,
-    "list2": list2,
-    "list3": list3,
-  };
-  static const List list4 = const [map1, map2];
-  static const List elms = const [
-    list1,
-    list2,
-    list3,
-    list4,
-  ];
-
-  static void VerifyMap(Map expected, Map actual) {
-    Expect.equals(true, expected is Map);
-    Expect.equals(true, actual is Map);
-    Expect.equals(expected.length, actual.length);
-    testForEachMap(key, value) {
-      if (value is List) {
-        VerifyList(value, actual[key]);
-      } else {
-        Expect.equals(value, actual[key]);
-      }
-    }
-
-    expected.forEach(testForEachMap);
-  }
-
-  static void VerifyList(List expected, List actual) {
-    for (int i = 0; i < expected.length; i++) {
-      if (expected[i] is List) {
-        VerifyList(expected[i], actual[i]);
-      } else if (expected[i] is Map) {
-        VerifyMap(expected[i], actual[i]);
-      } else {
-        Expect.equals(expected[i], actual[i]);
-      }
-    }
-  }
-
-  static void VerifyObject(int index, var actual) {
-    var expected = elms[index];
-    Expect.equals(true, expected is List);
-    Expect.equals(true, actual is List);
-    Expect.equals(expected.length, actual.length);
-    VerifyList(expected, actual);
-  }
-}
-
-pingPong() {
-  int count = 0;
-  port.receive((var message, SendPort replyTo) {
-    if (message == -1) {
-      port.close();
-      replyTo.send(count, null);
-    } else {
-      // Check if the received object is correct.
-      if (count < MessageTest.elms.length) {
-        MessageTest.VerifyObject(count, message);
-      }
-      // Bounce the received object back so that the sender
-      // can make sure that the object matches.
-      replyTo.send(message, null);
-      count++;
-    }
-  });
-}
-
-message_test_main() {
-  test("send objects and receive them back", () {
-    SendPort remote = spawnFunction(pingPong);
-    // Send objects and receive them back.
-    for (int i = 0; i < MessageTest.elms.length; i++) {
-      var sentObject = MessageTest.elms[i];
-      remote.call(sentObject).then(expectAsync1((var receivedObject) {
-        MessageTest.VerifyObject(i, receivedObject);
-      }));
-    }
-
-    // Send recursive objects and receive them back.
-    List local_list1 = ["Hello", "World", "Hello", 0xffffffffff];
-    List local_list2 = [null, local_list1, local_list1];
-    List local_list3 = [local_list2, 2.0, true, false, 0xffffffffff];
-    List sendObject = new List(5);
-    sendObject[0] = local_list1;
-    sendObject[1] = sendObject;
-    sendObject[2] = local_list2;
-    sendObject[3] = sendObject;
-    sendObject[4] = local_list3;
-    remote.call(sendObject).then((var replyObject) {
-      Expect.equals(true, sendObject is List);
-      Expect.equals(true, replyObject is List);
-      Expect.equals(sendObject.length, replyObject.length);
-      Expect.equals(true, identical(replyObject[1], replyObject));
-      Expect.equals(true, identical(replyObject[3], replyObject));
-      Expect.equals(true, identical(replyObject[0], replyObject[2][1]));
-      Expect.equals(true, identical(replyObject[0], replyObject[2][2]));
-      Expect.equals(true, identical(replyObject[2], replyObject[4][0]));
-      Expect.equals(true, identical(replyObject[0][0], replyObject[0][2]));
-      // TODO(alexmarkov): Revise this comment.
-      // Bigint literals are not canonicalized so do a == check.
-      Expect.equals(true, replyObject[0][3] == replyObject[4][4]);
-    });
-
-    // Shutdown the MessageServer.
-    remote.call(-1).then(expectAsync1((int message) {
-      Expect.equals(MessageTest.elms.length + 1, message);
-    }));
-  });
-}
-
-// ---------------------------------------------------------------------------
-// tests/isolate/request_reply_test.dart
-// ---------------------------------------------------------------------------
-
-void request_reply_entry() {
-  port.receive((message, SendPort replyTo) {
-    replyTo.send(message + 87);
-    port.close();
-  });
-}
-
-void request_reply_main() {
-  test("call", () {
-    SendPort port = spawnFunction(request_reply_entry);
-    port.call(42).then(expectAsync1((message) {
-      Expect.equals(42 + 87, message);
-    }));
-  });
-
-  test("send", () {
-    SendPort port = spawnFunction(request_reply_entry);
-    ReceivePort reply = new ReceivePort();
-    port.send(99, reply.toSendPort());
-    reply.receive(expectAsync2((message, replyTo) {
-      Expect.equals(99 + 87, message);
-      reply.close();
-    }));
-  });
-}
-
-// ---------------------------------------------------------------------------
-// tests/isolate/count_test.dart
-// ---------------------------------------------------------------------------
-
-void countMessages() {
-  int count = 0;
-  port.receive((int message, SendPort replyTo) {
-    if (message == -1) {
-      Expect.equals(10, count);
-      replyTo.send(-1, null);
-      port.close();
-      return;
-    }
-    Expect.equals(count, message);
-    count++;
-    replyTo.send(message * 2, null);
-  });
-}
-
-void count_main() {
-  test("count 10 consecutive messages", () {
-    int count = 0;
-    SendPort remote = spawnFunction(countMessages);
-    ReceivePort local = new ReceivePort();
-    SendPort reply = local.toSendPort();
-
-    local.receive(expectAsync2((int message, SendPort replyTo) {
-      if (message == -1) {
-        Expect.equals(11, count);
-        local.close();
-        return;
-      }
-
-      Expect.equals((count - 1) * 2, message);
-      remote.send(count++, reply);
-      if (count == 10) {
-        remote.send(-1, reply);
-      }
-    }, 11));
-    remote.send(count++, reply);
-  });
-}
-
-// ---------------------------------------------------------------------------
-// tests/isolate/mandel_isolate_test.dart
-// ---------------------------------------------------------------------------
-
-const TERMINATION_MESSAGE = -1;
-const N = 100;
-const ISOLATES = 20;
-
-mandel_main() {
-  test("Render Mandelbrot in parallel", () {
-    final state = new MandelbrotState();
-    state._validated.future.then(expectAsync1((result) {
-      expect(result, isTrue);
-    }));
-    for (int i = 0; i < Math.min(ISOLATES, N); i++) state.startClient(i);
-  });
-}
-
-class MandelbrotState {
-  MandelbrotState() {
-    _result = new List<List<int>>(N);
-    _lineProcessedBy = new List<LineProcessorClient>(N);
-    _sent = 0;
-    _missing = N;
-    _validated = new Completer<bool>();
-  }
-
-  void startClient(int id) {
-    assert(_sent < N);
-    final client = new LineProcessorClient(this, id);
-    client.processLine(_sent++);
-  }
-
-  void notifyProcessedLine(LineProcessorClient client, int y, List<int> line) {
-    assert(_result[y] == null);
-    _result[y] = line;
-    _lineProcessedBy[y] = client;
-
-    if (_sent != N) {
-      client.processLine(_sent++);
-    } else {
-      client.shutdown();
-    }
-
-    // If all lines have been computed, validate the result.
-    if (--_missing == 0) {
-      _printResult();
-      _validateResult();
-    }
-  }
-
-  void _validateResult() {
-    // TODO(ngeoffray): Implement this.
-    _validated.complete(true);
-  }
-
-  void _printResult() {
-    var output = new StringBuffer();
-    for (int i = 0; i < _result.length; i++) {
-      List<int> line = _result[i];
-      for (int j = 0; j < line.length; j++) {
-        if (line[j] < 10) output.write("0");
-        output.write(line[j]);
-      }
-      output.write("\n");
-    }
-    // print(output);
-  }
-
-  List<List<int>> _result;
-  List<LineProcessorClient> _lineProcessedBy;
-  int _sent;
-  int _missing;
-  Completer<bool> _validated;
-}
-
-class LineProcessorClient {
-  LineProcessorClient(MandelbrotState this._state, int this._id) {
-    _port = spawnFunction(processLines);
-  }
-
-  void processLine(int y) {
-    _port.call(y).then((List<int> message) {
-      _state.notifyProcessedLine(this, y, message);
-    });
-  }
-
-  void shutdown() {
-    _port.send(TERMINATION_MESSAGE, null);
-  }
-
-  MandelbrotState _state;
-  int _id;
-  SendPort _port;
-}
-
-List<int> processLine(int y) {
-  double inverseN = 2.0 / N;
-  double Civ = y * inverseN - 1.0;
-  List<int> result = new List<int>(N);
-  for (int x = 0; x < N; x++) {
-    double Crv = x * inverseN - 1.5;
-
-    double Zrv = Crv;
-    double Ziv = Civ;
-
-    double Trv = Crv * Crv;
-    double Tiv = Civ * Civ;
-
-    int i = 49;
-    do {
-      Ziv = (Zrv * Ziv) + (Zrv * Ziv) + Civ;
-      Zrv = Trv - Tiv + Crv;
-
-      Trv = Zrv * Zrv;
-      Tiv = Ziv * Ziv;
-    } while (((Trv + Tiv) <= 4.0) && (--i > 0));
-
-    result[x] = i;
-  }
-  return result;
-}
-
-void processLines() {
-  port.receive((message, SendPort replyTo) {
-    if (message == TERMINATION_MESSAGE) {
-      assert(replyTo == null);
-      port.close();
-    } else {
-      replyTo.send(processLine(message), null);
-    }
-  });
-}
diff --git a/runtime/vm/snapshot_test_in.dat b/runtime/vm/snapshot_test_in.dat
deleted file mode 100644
index 43cfc18..0000000
--- a/runtime/vm/snapshot_test_in.dat
+++ /dev/null
@@ -1 +0,0 @@
-{{DART_SOURCE}}
diff --git a/runtime/vm/stack_frame.cc b/runtime/vm/stack_frame.cc
index 8e6b4ec..ae8edb8 100644
--- a/runtime/vm/stack_frame.cc
+++ b/runtime/vm/stack_frame.cc
@@ -29,6 +29,7 @@
     /*.first_object_from_fp = */ -1,
     /*.last_fixed_object_from_fp = */ -1,
     /*.param_end_from_fp = */ -1,
+    /*.last_param_from_entry_sp = */ -1,
     /*.first_local_from_fp = */ -1,
     /*.dart_fixed_frame_size = */ -1,
     /*.saved_caller_pp_from_fp = */ -1,
@@ -40,6 +41,7 @@
     /*.first_object_from_fp = */ kFirstObjectSlotFromFp,
     /*.last_fixed_object_from_fp = */ kLastFixedObjectSlotFromFp,
     /*.param_end_from_fp = */ kParamEndSlotFromFp,
+    /*.last_param_from_entry_sp = */ kLastParamSlotFromEntrySp,
     /*.first_local_from_fp = */ kFirstLocalSlotFromFp,
     /*.dart_fixed_frame_size = */ kDartFrameFixedSize,
     /*.saved_caller_pp_from_fp = */ kSavedCallerPpSlotFromFp,
@@ -51,6 +53,7 @@
     /*.last_fixed_object_from_fp = */ kLastFixedObjectSlotFromFp +
         2,  // No saved CODE, PP slots
     /*.param_end_from_fp = */ kParamEndSlotFromFp,
+    /*.last_param_from_entry_sp = */ kLastParamSlotFromEntrySp,
     /*.first_local_from_fp =*/kFirstLocalSlotFromFp +
         2,  // No saved CODE, PP slots.
     /*.dart_fixed_frame_size =*/kDartFrameFixedSize -
diff --git a/runtime/vm/stack_frame_arm.h b/runtime/vm/stack_frame_arm.h
index 1f27cf9..2b5dc3e 100644
--- a/runtime/vm/stack_frame_arm.h
+++ b/runtime/vm/stack_frame_arm.h
@@ -42,6 +42,7 @@
 static const int kSavedCallerPcSlotFromFp = 1;
 static const int kParamEndSlotFromFp = 1;  // One slot past last parameter.
 static const int kCallerSpSlotFromFp = 2;
+static const int kLastParamSlotFromEntrySp = 0;
 
 // Entry and exit frame layout.
 #if defined(TARGET_OS_MACOS) || defined(TARGET_OS_MACOS_IOS)
diff --git a/runtime/vm/stack_frame_arm64.h b/runtime/vm/stack_frame_arm64.h
index 70000da..3b8c726 100644
--- a/runtime/vm/stack_frame_arm64.h
+++ b/runtime/vm/stack_frame_arm64.h
@@ -42,6 +42,7 @@
 
 static const int kParamEndSlotFromFp = 1;  // One slot past last parameter.
 static const int kCallerSpSlotFromFp = 2;
+static const int kLastParamSlotFromEntrySp = 0;
 
 // Entry and exit frame layout.
 static const int kExitLinkSlotFromEntryFp = -22;
diff --git a/runtime/vm/stack_frame_dbc.h b/runtime/vm/stack_frame_dbc.h
index 475d9b7..632f68c 100644
--- a/runtime/vm/stack_frame_dbc.h
+++ b/runtime/vm/stack_frame_dbc.h
@@ -55,6 +55,7 @@
 // these indices during code generation in the backend.
 static const int kParamEndSlotFromFp = 4;  // One slot past last parameter.
 static const int kFirstLocalSlotFromFp = -1;
+static const int kLastParamSlotFromEntrySp = 0;  // Should not be used on DBC.
 
 DART_FORCE_INLINE static intptr_t LocalVarIndex(intptr_t fp_offset,
                                                 intptr_t var_index) {
diff --git a/runtime/vm/stack_frame_ia32.h b/runtime/vm/stack_frame_ia32.h
index 2cfd1c4..b770cf7 100644
--- a/runtime/vm/stack_frame_ia32.h
+++ b/runtime/vm/stack_frame_ia32.h
@@ -38,6 +38,7 @@
 static const int kSavedCallerPcSlotFromFp = 1;
 static const int kParamEndSlotFromFp = 1;  // One slot past last parameter.
 static const int kCallerSpSlotFromFp = 2;
+static const int kLastParamSlotFromEntrySp = 1;  // Skip return address.
 
 // No pool pointer on IA32 (indicated by aliasing saved fp).
 static const int kSavedCallerPpSlotFromFp = kSavedCallerFpSlotFromFp;
diff --git a/runtime/vm/stack_frame_x64.h b/runtime/vm/stack_frame_x64.h
index 84d9652..00d0059 100644
--- a/runtime/vm/stack_frame_x64.h
+++ b/runtime/vm/stack_frame_x64.h
@@ -43,6 +43,7 @@
 
 static const int kParamEndSlotFromFp = 1;  // One slot past last parameter.
 static const int kCallerSpSlotFromFp = 2;
+static const int kLastParamSlotFromEntrySp = 1;  // Skip return address.
 
 // Entry and exit frame layout.
 #if defined(_WIN64)
diff --git a/runtime/vm/stub_code.cc b/runtime/vm/stub_code.cc
index 6b49fce..637d16f 100644
--- a/runtime/vm/stub_code.cc
+++ b/runtime/vm/stub_code.cc
@@ -112,7 +112,7 @@
   if (FLAG_enable_interpreter) {
     if (is_interpreted_frame) {
       // Recognize special marker set up by interpreter in entry frame.
-      return Interpreter::IsEntryFrameMarker(pc);
+      return Interpreter::IsEntryFrameMarker(reinterpret_cast<uint32_t*>(pc));
     }
     {
       uword entry = StubCode::InvokeDartCodeFromBytecode().EntryPoint();
diff --git a/runtime/vm/symbols.h b/runtime/vm/symbols.h
index 771116b..845d780 100644
--- a/runtime/vm/symbols.h
+++ b/runtime/vm/symbols.h
@@ -209,6 +209,7 @@
   V(LanguageError, "LanguageError")                                            \
   V(LeftShiftOperator, "<<")                                                   \
   V(Length, "length")                                                          \
+  V(GetLength, "get:length")                                                   \
   V(LessEqualOperator, "<=")                                                   \
   V(LibraryClass, "Library")                                                   \
   V(LibraryPrefix, "LibraryPrefix")                                            \
diff --git a/runtime/vm/thread.h b/runtime/vm/thread.h
index 49d1ba8..5e771b0 100644
--- a/runtime/vm/thread.h
+++ b/runtime/vm/thread.h
@@ -19,6 +19,7 @@
 #include "vm/handles.h"
 #include "vm/heap/pointer_block.h"
 #include "vm/os_thread.h"
+#include "vm/random.h"
 #include "vm/runtime_entry_list.h"
 #include "vm/thread_stack_resource.h"
 #include "vm/thread_state.h"
@@ -771,6 +772,8 @@
 
   void InitVMConstants();
 
+  uint64_t GetRandomUInt64() { return thread_random_.NextUInt64(); }
+
 #ifndef PRODUCT
   void PrintJSON(JSONStream* stream) const;
 #endif
@@ -799,11 +802,11 @@
   Heap* heap_;
   uword top_;
   uword end_;
-  uword top_exit_frame_info_;
+  uword volatile top_exit_frame_info_;
   StoreBufferBlock* store_buffer_block_;
   MarkingStackBlock* marking_stack_block_;
   MarkingStackBlock* deferred_marking_stack_block_;
-  uword vm_tag_;
+  uword volatile vm_tag_;
   RawStackTrace* async_stack_trace_;
   // Memory location dedicated for passing unboxed int64 values from
   // generated code to runtime.
@@ -868,6 +871,8 @@
 
   RawError* sticky_error_;
 
+  Random thread_random_;
+
 // Reusable handles support.
 #define REUSABLE_HANDLE_FIELDS(object) object* object##_handle_;
   REUSABLE_HANDLE_LIST(REUSABLE_HANDLE_FIELDS)
diff --git a/runtime/vm/unit_test.cc b/runtime/vm/unit_test.cc
index 1a28815..23b42ee 100644
--- a/runtime/vm/unit_test.cc
+++ b/runtime/vm/unit_test.cc
@@ -411,7 +411,7 @@
   const char* resolved_url_chars = url_chars;
   if (IsPackageSchemeURL(url_chars)) {
     resolved_url = ResolvePackageUri(url_chars);
-    DART_CHECK_VALID(resolved_url);
+    EXPECT_VALID(resolved_url);
     if (Dart_IsError(Dart_StringToCString(resolved_url, &resolved_url_chars))) {
       return Dart_NewApiError("unable to convert resolved uri to string");
     }
@@ -429,8 +429,10 @@
   }
 }
 
-static intptr_t BuildSourceFilesArray(Dart_SourceFile** sourcefiles,
-                                      const char* script) {
+static intptr_t BuildSourceFilesArray(
+    Dart_SourceFile** sourcefiles,
+    const char* script,
+    const char* script_url = RESOLVED_USER_TEST_URI) {
   ASSERT(sourcefiles != NULL);
   ASSERT(script != NULL);
 
@@ -440,7 +442,7 @@
   }
 
   *sourcefiles = new Dart_SourceFile[num_test_libs + 1];
-  (*sourcefiles)[0].uri = RESOLVED_USER_TEST_URI;
+  (*sourcefiles)[0].uri = script_url;
   (*sourcefiles)[0].source = script;
   for (intptr_t i = 0; i < num_test_libs; ++i) {
     (*sourcefiles)[i + 1].uri = test_libs_->At(i).url;
@@ -469,7 +471,7 @@
     }
 #endif  // ifndef PRODUCT
     Dart_SourceFile* sourcefiles = NULL;
-    intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script);
+    intptr_t num_sources = BuildSourceFilesArray(&sourcefiles, script, lib_url);
     Dart_Handle result =
         LoadTestScriptWithDFE(num_sources, sourcefiles, resolver,
                               finalize_classes, true, allow_compile_errors);
@@ -501,9 +503,9 @@
 
     // TODO(32618): Kernel doesn't correctly represent the root library.
     lib = Dart_LookupLibrary(Dart_NewStringFromCString(sourcefiles[0].uri));
-    DART_CHECK_VALID(lib);
+    EXPECT_VALID(lib);
     Dart_Handle result = Dart_SetRootLibrary(lib);
-    DART_CHECK_VALID(result);
+    EXPECT_VALID(result);
 
     Dart_SetNativeResolver(lib, resolver, NULL);
     return lib;
@@ -534,7 +536,7 @@
 
   Dart_Handle lib =
       Dart_LoadLibraryFromKernel(kernel_buffer, kernel_buffer_size);
-  DART_CHECK_VALID(lib);
+  EXPECT_VALID(lib);
 
   // Ensure kernel buffer isn't leaked after test is run.
   AddToKernelBuffers(kernel_buffer);
@@ -542,15 +544,15 @@
   // BOGUS: Kernel doesn't correctly represent the root library.
   lib = Dart_LookupLibrary(Dart_NewStringFromCString(
       entry_script_uri != NULL ? entry_script_uri : sourcefiles[0].uri));
-  DART_CHECK_VALID(lib);
+  EXPECT_VALID(lib);
   result = Dart_SetRootLibrary(lib);
-  DART_CHECK_VALID(result);
+  EXPECT_VALID(result);
 
   result = Dart_SetNativeResolver(lib, resolver, NULL);
-  DART_CHECK_VALID(result);
+  EXPECT_VALID(result);
   if (finalize) {
     result = Dart_FinalizeLoading(false);
-    DART_CHECK_VALID(result);
+    EXPECT_VALID(result);
   }
   return lib;
 }
@@ -641,7 +643,7 @@
 Dart_Handle TestCase::lib() {
   Dart_Handle url = NewString(TestCase::url());
   Dart_Handle lib = Dart_LookupLibrary(url);
-  DART_CHECK_VALID(lib);
+  EXPECT_VALID(lib);
   ASSERT(Dart_IsLibrary(lib));
   return lib;
 }
diff --git a/runtime/vm/unit_test.h b/runtime/vm/unit_test.h
index e8f1391..c4855d2 100644
--- a/runtime/vm/unit_test.h
+++ b/runtime/vm/unit_test.h
@@ -303,15 +303,16 @@
                                         bool allow_compile_errors = false,
                                         const char* multiroot_filepaths = NULL,
                                         const char* multiroot_scheme = NULL);
-  static Dart_Handle LoadTestScript(const char* script,
-                                    Dart_NativeEntryResolver resolver,
-                                    const char* lib_uri = USER_TEST_URI,
-                                    bool finalize = true,
-                                    bool allow_compile_errors = false);
+  static Dart_Handle LoadTestScript(
+      const char* script,
+      Dart_NativeEntryResolver resolver,
+      const char* lib_uri = RESOLVED_USER_TEST_URI,
+      bool finalize = true,
+      bool allow_compile_errors = false);
   static Dart_Handle LoadTestScriptWithErrors(
       const char* script,
       Dart_NativeEntryResolver resolver = NULL,
-      const char* lib_uri = USER_TEST_URI,
+      const char* lib_uri = RESOLVED_USER_TEST_URI,
       bool finalize = true);
   static Dart_Handle LoadTestLibrary(const char* lib_uri,
                                      const char* script,
diff --git a/runtime/vm/visitor.h b/runtime/vm/visitor.h
index a951b9a..4eac814 100644
--- a/runtime/vm/visitor.h
+++ b/runtime/vm/visitor.h
@@ -66,27 +66,6 @@
   DISALLOW_COPY_AND_ASSIGN(ObjectVisitor);
 };
 
-class ExtensibleObjectVisitor : public ObjectVisitor {
- public:
-  explicit ExtensibleObjectVisitor(GrowableArray<ObjectVisitor*>* visitors)
-      : visitors_(visitors) {}
-
-  virtual ~ExtensibleObjectVisitor() {}
-
-  virtual void VisitObject(RawObject* obj) {
-    for (intptr_t i = 0; i < visitors_->length(); i++) {
-      visitors_->At(i)->VisitObject(obj);
-    }
-  }
-
-  void Add(ObjectVisitor* visitor) { visitors_->Add(visitor); }
-
- private:
-  GrowableArray<ObjectVisitor*>* visitors_;
-
-  DISALLOW_COPY_AND_ASSIGN(ExtensibleObjectVisitor);
-};
-
 // An object finder visitor interface.
 class FindObjectVisitor {
  public:
diff --git a/runtime/vm/vm_sources.gni b/runtime/vm/vm_sources.gni
index eadae4d..f4aa3ef 100644
--- a/runtime/vm/vm_sources.gni
+++ b/runtime/vm/vm_sources.gni
@@ -46,8 +46,8 @@
   "constants_arm64.cc",
   "constants_arm64.h",
   "constants_dbc.h",
-  "constants_ia32.h",
   "constants_ia32.cc",
+  "constants_ia32.h",
   "constants_kbc.h",
   "constants_x64.cc",
   "constants_x64.h",
diff --git a/sdk/BUILD.gn b/sdk/BUILD.gn
index 50c2682..78cd365 100644
--- a/sdk/BUILD.gn
+++ b/sdk/BUILD.gn
@@ -20,8 +20,10 @@
   # Build a SDK with less stuff. It excludes dart2js, ddc, and web libraries.
   dart_platform_sdk = true
 
-  # Path to stripped dart binary relative to build output directory.
+  # Path to stripped dart binaries relative to build output directory.
   dart_stripped_binary = "dart"
+  dartaotruntime_stripped_binary = "dartaotruntime"
+  gen_snapshot_stripped_binary = "gen_snapshot"
 }
 
 # The directory layout of the SDK is as follows:
@@ -30,11 +32,14 @@
 # ....bin/
 # ......dart or dart.exe (executable)
 # ......dart.lib (import library for VM native extensions on Windows)
+# ......dartaotruntime or dartaotruntime.exe (executable)
 # ......dartdoc
 # ......dartfmt
+# ......dart2aot
 # ......dart2js
 # ......dartanalyzer
 # ......dartdevc
+# ......utils/gen_snapshot or utils/gen_snapshot.exe (executable)
 # ......pub
 # ......snapshots/
 # ........analysis_server.dart.snapshot
@@ -43,6 +48,7 @@
 # ........dartdoc.dart.snapshot
 # ........dartfmt.dart.snapshot
 # ........dartdevc.dart.snapshot
+# ........gen_kernel.dart.snapshot
 # ........kernel_worker.dart.snapshot
 # ........pub.dart.snapshot
 #.........resources/
@@ -341,6 +347,75 @@
   }
 }
 
+copy("copy_dartaotruntime") {
+  deps = [
+    "../runtime/bin:dartaotruntime",
+  ]
+  dartaotruntime_out = get_label_info("../runtime/bin:dartaotruntime", "root_out_dir")
+  if (is_win) {
+    sources = [
+      "$dartaotruntime_out/dartaotruntime.exe",
+    ]
+  } else {
+    sources = [
+      "$dartaotruntime_out/$dartaotruntime_stripped_binary",
+    ]
+  }
+  if (is_win) {
+    sources += [ "$dartaotruntime_out/dartaotruntime.lib" ]
+  }
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+  ]
+}
+
+copy("copy_gen_snapshot") {
+  deps = [
+    "../runtime/bin:gen_snapshot",
+  ]
+  gen_snapshot_out = get_label_info("../runtime/bin:gen_snapshot", "root_out_dir")
+  if (is_win) {
+    sources = [
+      "$gen_snapshot_out/gen_snapshot.exe",
+    ]
+  } else {
+    sources = [
+      "$gen_snapshot_out/$gen_snapshot_stripped_binary",
+    ]
+  }
+  if (is_win) {
+    sources += [ "$gen_snapshot_out/gen_snapshot.lib" ]
+  }
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/utils/{{source_file_part}}",
+  ]
+}
+
+copy("copy_dart2aot") {
+  ext = ""
+  if (is_win) {
+    ext = ".bat"
+  }
+  sources = [
+    "bin/dart2aot$ext",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/{{source_file_part}}",
+  ]
+}
+
+copy("copy_gen_kernel_snapshot") {
+  deps = [
+    "../utils/gen_kernel",
+  ]
+  sources = [
+    "$root_gen_dir/gen_kernel.dart.snapshot",
+  ]
+  outputs = [
+    "$root_out_dir/dart-sdk/bin/snapshots/{{source_file_part}}",
+  ]
+}
+
 # A template for copying the things in _platform_sdk_scripts and
 # _full_sdk_scripts into bin/
 template("copy_sdk_script") {
diff --git a/sdk/bin/dart2aot b/sdk/bin/dart2aot
new file mode 100755
index 0000000..9390db6
--- /dev/null
+++ b/sdk/bin/dart2aot
@@ -0,0 +1,111 @@
+#!/usr/bin/env bash
+# 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.
+
+# Script for generating AOT snapshot in two steps:
+# - Compilation to kernel with additional AOT specific transformations.
+# - Compilation of kernel into snapshot using gen_snapshot.
+
+# Parse incoming arguments and extract the value of --packages option if any
+# was passed. Split options (--xyz) and non-options into two separate arrays.
+# All options will be passed to gen_snapshot, while --packages will be
+# passed to the CFE (Common Front-End).
+
+set -e
+
+OPTIONS=()
+GEN_KERNEL_OPTIONS=()
+PACKAGES=
+BUILD_ELF=0
+
+ARGV=()
+for arg in "$@"; do
+  case $arg in
+    --packages=*)
+    PACKAGES="$arg"
+    ;;
+    --enable-asserts)
+    GEN_KERNEL_OPTIONS+=("$arg")
+    OPTIONS+=("$arg")
+    ;;
+    --tfa | \
+    --no-tfa | \
+    -D* )
+    GEN_KERNEL_OPTIONS+=("$arg")
+    ;;
+    --build-elf)
+    BUILD_ELF=1
+    ;;
+    --*)
+    OPTIONS+=("$arg")
+    ;;
+    *)
+    ARGV+=("$arg")
+    ;;
+  esac
+done
+
+if [ "${#ARGV[@]}" -ne 2 ]; then
+    echo "Usage: $0 [options] <dart-source-file> <dart-aot-file>"
+    echo ""
+    echo "Dart AOT (ahead-of-time) compile Dart source code into native machine code."
+    exit 1
+fi
+
+SOURCE_FILE="${ARGV[0]}"
+SNAPSHOT_FILE="${ARGV[1]}"
+
+if [ $BUILD_ELF -eq 1 ]; then
+  GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-assembly"
+  GEN_SNAPSHOT_FILENAME="--assembly=${SNAPSHOT_FILE}.S"
+else
+  GEN_SNAPSHOT_OPTION="--snapshot-kind=app-aot-blobs"
+  GEN_SNAPSHOT_FILENAME="--blobs_container_filename=${SNAPSHOT_FILE}"
+fi
+
+function follow_links() {
+  file="$1"
+  while [ -h "$file" ]; do
+    # On Mac OS, readlink -f doesn't work.
+    file="$(readlink "$file")"
+  done
+  echo "$file"
+}
+
+# Unlike $0, $BASH_SOURCE points to the absolute path of this file.
+PROG_NAME="$(follow_links "$BASH_SOURCE")"
+
+# Handle the case where dart-sdk/bin has been symlinked to.
+BIN_DIR="$(cd "${PROG_NAME%/*}" ; pwd -P)"
+
+SDK_DIR="$(cd "${BIN_DIR}/.." ; pwd -P)"
+
+DART="$BIN_DIR/dart"
+GEN_SNAPSHOT="$BIN_DIR/utils/gen_snapshot"
+
+SNAPSHOT_DIR="$BIN_DIR/snapshots"
+SNAPSHOT="$SNAPSHOT_DIR/gen_kernel.dart.snapshot"
+
+# Step 1: Generate Kernel binary from the input Dart source.
+"$DART"                                                                        \
+     "${SNAPSHOT}"                                                             \
+     --platform "${SDK_DIR}/lib/_internal/vm_platform_strong.dill"             \
+     --aot                                                                     \
+     -Ddart.vm.product=true                                                    \
+     "${GEN_KERNEL_OPTIONS[@]}"                                                \
+     $PACKAGES                                                                 \
+     -o "$SNAPSHOT_FILE.dill"                                                  \
+     "$SOURCE_FILE"
+
+# Step 2: Generate snapshot from the Kernel binary.
+"$GEN_SNAPSHOT"                                                                \
+     "$GEN_SNAPSHOT_OPTION"                                                    \
+     "$GEN_SNAPSHOT_FILENAME"                                                  \
+     "${OPTIONS[@]}"                                                           \
+     "$SNAPSHOT_FILE.dill"
+
+# Step 3: Assemble the assembly file into an ELF object.
+if [ $BUILD_ELF -eq 1 ]; then
+    gcc -shared -o "$SNAPSHOT_FILE" "${SNAPSHOT_FILE}.S"
+fi
diff --git a/sdk/bin/dart2aot.bat b/sdk/bin/dart2aot.bat
new file mode 100644
index 0000000..321e867
--- /dev/null
+++ b/sdk/bin/dart2aot.bat
@@ -0,0 +1,58 @@
+@echo off
+REM Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+REM for details. All rights reserved. Use of this source code is governed by a
+REM BSD-style license that can be found in the LICENSE file.
+
+setlocal
+rem Handle the case where dart-sdk/bin has been symlinked to.
+set DIR_NAME_WITH_SLASH=%~dp0
+set DIR_NAME=%DIR_NAME_WITH_SLASH:~0,-1%%
+call :follow_links "%DIR_NAME%", RETURNED_BIN_DIR
+rem Get rid of surrounding quotes.
+for %%i in ("%RETURNED_BIN_DIR%") do set BIN_DIR=%%~fi
+
+rem Get absolute full name for SDK_DIR.
+for %%i in ("%BIN_DIR%\..\") do set SDK_DIR=%%~fi
+
+rem Remove trailing backslash if there is one
+IF %SDK_DIR:~-1%==\ set SDK_DIR=%SDK_DIR:~0,-1%
+
+rem Get absolute full name for DART_ROOT.
+for %%i in ("%SDK_DIR%\..\") do set DART_ROOT=%%~fi
+
+rem Remove trailing backslash if there is one
+if %DART_ROOT:~-1%==\ set DART_ROOT=%DART_ROOT:~0,-1%
+
+set DART=%BIN_DIR%\dart.exe
+set GEN_KERNEL=%BIN_DIR%\snapshots\gen_kernel.dart.snapshot
+set VM_PLATFORM_STRONG=%SDK_DIR%\lib\_internal\vm_platform_strong.dill
+set GEN_SNAPSHOT=%BIN_DIR%\utils\gen_snapshot.exe
+
+set SOURCE_FILE=%1
+set SNAPSHOT_FILE=%2
+set GEN_SNAPSHOT_OPTION=--snapshot-kind=app-aot-blobs
+set GEN_SNAPSHOT_FILENAME=--blobs_container_filename=%SNAPSHOT_FILE%
+
+REM Step 1: Generate Kernel binary from the input Dart source.
+%DART% %GEN_KERNEL% --platform %VM_PLATFORM_STRONG% --aot -Ddart.vm.product=true -o %SNAPSHOT_FILE%.dill %SOURCE_FILE%
+
+REM Step 2: Generate snapshot from the Kernel binary.
+%GEN_SNAPSHOT% %GEN_SNAPSHOT_OPTION% %GEN_SNAPSHOT_FILENAME% %SNAPSHOT_FILE%.dill
+
+endlocal
+
+exit /b %errorlevel%
+
+:follow_links
+setlocal
+for %%i in (%1) do set result=%%~fi
+set current=
+for /f "usebackq tokens=2 delims=[]" %%i in (`dir /a:l "%~dp1" 2^>nul ^
+                                             ^| %SystemRoot%\System32\find.exe ">     %~n1 [" 2^>nul`) do (
+  set current=%%i
+)
+if not "%current%"=="" call :follow_links "%current%", result
+endlocal & set %~2=%result%
+goto :eof
+
+:end
diff --git a/sdk/lib/_internal/js_runtime/lib/js_helper.dart b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
index 9ad339a..7205568 100644
--- a/sdk/lib/_internal/js_runtime/lib/js_helper.dart
+++ b/sdk/lib/_internal/js_runtime/lib/js_helper.dart
@@ -2663,11 +2663,9 @@
 /// and casts. We specialize each primitive type (eg int, bool), and use the
 /// compiler's convention to do is-checks on regular objects.
 boolConversionCheck(value) {
-  if (value is bool) return value;
-  // One of the following checks will always fail.
-  boolTypeCheck(value);
-  assert(value != null);
-  return false;
+  // The value from kernel should always be true, false, or null.
+  if (value == null) assertThrow('boolean expression must not be null');
+  return value;
 }
 
 stringTypeCheck(value) {
diff --git a/sdk/lib/convert/base64.dart b/sdk/lib/convert/base64.dart
index 1b31387..ce522be 100644
--- a/sdk/lib/convert/base64.dart
+++ b/sdk/lib/convert/base64.dart
@@ -15,6 +15,9 @@
 ///     var encoded = base64.encode([0x62, 0x6c, 0xc3, 0xa5, 0x62, 0xc3, 0xa6,
 ///                                  0x72, 0x67, 0x72, 0xc3, 0xb8, 0x64]);
 ///     var decoded = base64.decode("YmzDpWLDpnJncsO4ZAo=");
+///
+/// The top-level [base64Encode] and [base64Decode] functions may be used
+/// instead if a local variable shadows the [base64] constant.
 const Base64Codec base64 = Base64Codec();
 
 /// A [base64url](https://tools.ietf.org/html/rfc4648) encoder and decoder.
@@ -32,7 +35,8 @@
 
 /// Encodes [bytes] using [base64](https://tools.ietf.org/html/rfc4648) encoding.
 ///
-/// Shorthand for [base64.encode].
+/// Shorthand for [base64.encode]. Useful if a local variable shadows the global
+/// [base64] constant.
 String base64Encode(List<int> bytes) => base64.encode(bytes);
 
 /// Encodes [bytes] using [base64url](https://tools.ietf.org/html/rfc4648) encoding.
@@ -42,7 +46,8 @@
 
 /// Decodes [base64](https://tools.ietf.org/html/rfc4648) or [base64url](https://tools.ietf.org/html/rfc4648) encoded bytes.
 ///
-/// Shorthand for [base64.decode].
+/// Shorthand for [base64.decode]. Useful if a local variable shadows the
+/// global [base64] constant.
 Uint8List base64Decode(String source) => base64.decode(source);
 
 // Constants used in more than one class.
diff --git a/sdk/lib/convert/json.dart b/sdk/lib/convert/json.dart
index efd450d..5746e52 100644
--- a/sdk/lib/convert/json.dart
+++ b/sdk/lib/convert/json.dart
@@ -59,6 +59,9 @@
 ///
 ///     var encoded = json.encode([1, 2, { "a": null }]);
 ///     var decoded = json.decode('["foo", { "bar": 499 }]');
+///
+/// The top-level [jsonEncode] and [jsonDecode] functions may be used instead if
+/// a local variable shadows the [json] constant.
 const JsonCodec json = JsonCodec();
 
 /// Converts [value] to a JSON string.
@@ -71,7 +74,8 @@
 /// If [toEncodable] is omitted, it defaults to a function that returns the
 /// result of calling `.toJson()` on the unencodable object.
 ///
-/// Shorthand for [json.encode].
+/// Shorthand for [json.encode]. Useful if a local variable shadows the global
+/// [json] constant.
 String jsonEncode(Object object, {Object toEncodable(Object nonEncodable)}) =>
     json.encode(object, toEncodable: toEncodable);
 
@@ -84,7 +88,8 @@
 ///
 /// The default [reviver] (when not provided) is the identity function.
 ///
-/// Shorthand for [json.decode].
+/// Shorthand for [json.decode]. Useful if a local variable shadows the global
+/// [json] constant.
 dynamic jsonDecode(String source, {Object reviver(Object key, Object value)}) =>
     json.decode(source, reviver: reviver);
 
diff --git a/sdk/lib/vmservice/vmservice.dart b/sdk/lib/vmservice/vmservice.dart
index 72db816..4237f28 100644
--- a/sdk/lib/vmservice/vmservice.dart
+++ b/sdk/lib/vmservice/vmservice.dart
@@ -41,9 +41,6 @@
 // The randomly generated auth token used to access the VM service.
 final String serviceAuthToken = _makeAuthToken();
 
-// TODO(johnmccutchan): Enable the auth token and drop the origin check.
-final bool useAuthToken = const bool.fromEnvironment('DART_SERVICE_USE_AUTH');
-
 // This is for use by the embedder. It is a map from the isolateId to
 // anything implementing IsolateEmbedderData. When an isolate goes away,
 // the cleanup method will be invoked after being removed from the map.
@@ -596,62 +593,6 @@
     return encodeSuccess(message);
   }
 
-  Future<String> _getCrashDump(Message message) async {
-    var client = message.client;
-    final perIsolateRequests = [
-      // ?isolateId=<isolate id> will be appended to each of these requests.
-      // Isolate information.
-      Uri.parse('getIsolate'),
-      // State of heap.
-      Uri.parse('_getAllocationProfile'),
-      // Call stack + local variables.
-      Uri.parse('getStack?_full=true'),
-    ];
-
-    // Snapshot of running isolates.
-    var isolates = runningIsolates.isolates.values.toList();
-
-    // Collect the mapping from request uris to responses.
-    var responses = {};
-
-    // Request VM.
-    var getVM = Uri.parse('getVM');
-    var getVmResponse =
-        (await new Message.fromUri(client, getVM).sendToVM()).decodeJson();
-    responses[getVM.toString()] = getVmResponse['result'];
-
-    // Request command line flags.
-    var getFlagList = Uri.parse('getFlagList');
-    var getFlagListResponse =
-        (await new Message.fromUri(client, getFlagList).sendToVM())
-            .decodeJson();
-    responses[getFlagList.toString()] = getFlagListResponse['result'];
-
-    // Make requests to each isolate.
-    for (var isolate in isolates) {
-      for (var request in perIsolateRequests) {
-        var message = new Message.forIsolate(client, request, isolate);
-        // Decode the JSON and and insert it into the map. The map key
-        // is the request Uri.
-        var response = (await isolate.routeRequest(this, message)).decodeJson();
-        responses[message.toUri().toString()] = response['result'];
-      }
-      // Dump the object id ring requests.
-      var message =
-          new Message.forIsolate(client, Uri.parse('_dumpIdZone'), isolate);
-      var response = (await isolate.routeRequest(this, message)).decodeJson();
-      // Insert getObject requests into responses map.
-      for (var object in response['result']['objects']) {
-        final requestUri =
-            'getObject&isolateId=${isolate.serviceId}?objectId=${object["id"]}';
-        responses[requestUri] = object;
-      }
-    }
-
-    // Encode the entire crash dump.
-    return encodeResult(message, responses);
-  }
-
   Future<Response> routeRequest(VMService _, Message message) async {
     return new Response.from(await _routeRequestImpl(message));
   }
@@ -661,10 +602,6 @@
       if (message.completed) {
         return await message.response;
       }
-      // TODO(turnidge): Update to json rpc.  BEFORE SUBMIT.
-      if (message.method == '_getCrashDump') {
-        return await _getCrashDump(message);
-      }
       if (message.method == 'streamListen') {
         return await _streamListen(message);
       }
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index 108c0ed..3126f6a 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -10,6 +10,9 @@
 Language/Classes/Abstract_Instance_Members/override_default_value_t05: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
 Language/Classes/Getters/type_object_t01: CompileTimeError # Issue 33995
 Language/Classes/Getters/type_object_t02: CompileTimeError # Issue 33995
+Language/Classes/Instance_Methods/Operators/allowed_names_t01: CompileTimeError # triple shift
+Language/Classes/Instance_Methods/Operators/allowed_names_t23: CompileTimeError # triple shift
+Language/Classes/Instance_Methods/Operators/arity_1_t19: CompileTimeError # triple shift
 Language/Classes/Instance_Methods/override_different_default_values_t01: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
 Language/Classes/Instance_Methods/override_different_default_values_t02: MissingCompileTimeError # https://github.com/dart-lang/co19/issues/234
 Language/Classes/Static_Methods/same_name_method_and_setter_t01: CompileTimeError # Invalid test, see #33237
@@ -17,8 +20,17 @@
 Language/Enums/syntax_t08: CompileTimeError # Issue 33995
 Language/Enums/syntax_t09: CompileTimeError # Issue 33995
 Language/Errors_and_Warnings/static_warning_t01: CompileTimeError # issue #34319
+Language/Expressions/Assignment/Compound_Assignment/expression_assignment_t12: CompileTimeError # triple shift
+Language/Expressions/Assignment/Compound_Assignment/indexed_expression_assignment_t12: CompileTimeError # triple shift
+Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_static_t12: CompileTimeError # triple shift
+Language/Expressions/Assignment/Compound_Assignment/null_aware_compound_assignment_t12: CompileTimeError # triple shift
+Language/Expressions/Assignment/Compound_Assignment/setter_assignment_t12: CompileTimeError # triple shift
+Language/Expressions/Assignment/Compound_Assignment/variable_assignment_t12: CompileTimeError # triple shift
+Language/Expressions/Bitwise_Expressions/syntax_t01: CompileTimeError # triple shift
+Language/Expressions/Constants/bitwise_operators_t01: CompileTimeError # triple shift
 Language/Expressions/Constants/constant_list_t02: MissingCompileTimeError # Please triage this failure
 Language/Expressions/Constants/constant_map_t02: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Equality/syntax_t01: CompileTimeError # triple shift
 Language/Expressions/Function_Invocation/Unqualified_Invocation/function_expr_invocation_t05: CompileTimeError # Please triage this failure
 Language/Expressions/Function_Invocation/async_cleanup_t01: CompileTimeError # Issue 33995
 Language/Expressions/Function_Invocation/async_cleanup_t02: CompileTimeError # Issue 33995
@@ -33,11 +45,24 @@
 Language/Expressions/Instance_Creation/Const/parameterized_type_t01: CompileTimeError # Please triage this failure
 Language/Expressions/Instance_Creation/Const/parameterized_type_t02: CompileTimeError # Please triage this failure
 Language/Expressions/Instance_Creation/New/syntax_t04: MissingCompileTimeError # Please triage this failure
+Language/Expressions/Instance_Creation/New/type_t08: CompileTimeError
+Language/Expressions/Instance_Creation/New/type_t09: CompileTimeError
 Language/Expressions/Lists/constant_list_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Lists/syntax_t01: CompileTimeError # triple shift
 Language/Expressions/Maps/constant_map_t02: MissingCompileTimeError # Please triage this failure
 Language/Expressions/Maps/constant_map_type_t01: CompileTimeError # Please triage this failure
+Language/Expressions/Maps/syntax_t01: CompileTimeError # triple shift
+Language/Expressions/Relational_Expressions/syntax_t01: CompileTimeError # triple shift
+Language/Expressions/Shift/allowed_characters_t02: CompileTimeError # triple shift
+Language/Expressions/Shift/integer_t03: CompileTimeError # triple shift
+Language/Expressions/Shift/syntax_t01: CompileTimeError # triple shift
+Language/Expressions/Shift/syntax_t15: CompileTimeError # triple shift
+Language/Expressions/Strings/String_Interpolation/syntax_t01: CompileTimeError # triple shift
+Language/Expressions/Symbols/syntax_t02: CompileTimeError # triple shift
+Language/Expressions/parentheses_t01: CompileTimeError # triple shift
 Language/Functions/generator_return_type_t02: MissingCompileTimeError # Issue 32192
 Language/Functions/generator_return_type_t06: MissingCompileTimeError # Issue 32192
+Language/Functions/syntax_t03: CompileTimeError # triple shift
 Language/Generics/scope_t03: CompileTimeError # Please triage this failure
 Language/Generics/syntax_t02: CompileTimeError # Please triage this failure
 Language/Generics/syntax_t03: Crash # Issue 29388
@@ -60,6 +85,9 @@
 Language/Mixins/declaring_constructor_t05: MissingCompileTimeError # Issue 24767
 Language/Mixins/declaring_constructor_t06: MissingCompileTimeError # Issue 24767
 Language/Overview/Privacy/private_and_public_t11: CompileTimeError
+Language/Reference/Operator_Precedence/precedence_01_assignment_t14: CompileTimeError # triple shift
+Language/Reference/Operator_Precedence/precedence_12_Shift_t04: CompileTimeError # triple shift
+Language/Reference/Operator_Precedence/precedence_t05: CompileTimeError # triple shift
 Language/Statements/Continue/async_loops_t01: CompileTimeError # Issue 33995
 Language/Statements/Continue/async_loops_t02: CompileTimeError # Issue 33995
 Language/Statements/Continue/async_loops_t03: CompileTimeError # Issue 33995
@@ -72,6 +100,7 @@
 Language/Statements/Continue/async_loops_t10: CompileTimeError # Issue 33995
 Language/Statements/Continue/control_transfer_t08: CompileTimeError # Issue 33995
 Language/Statements/Continue/control_transfer_t09: CompileTimeError # Issue 33995
+Language/Statements/Expression_Statements/syntax_t06: CompileTimeError # triple shift
 Language/Statements/Return/many_return_statements_t01: CompileTimeError # co19 issue 157
 Language/Statements/Return/many_return_statements_t02: CompileTimeError # issue #34319
 Language/Statements/Return/no_expression_function_t01: CompileTimeError # issue #34319
diff --git a/tests/co19_2/co19_2-dart2js.status b/tests/co19_2/co19_2-dart2js.status
index aefe426..c4f2692 100644
--- a/tests/co19_2/co19_2-dart2js.status
+++ b/tests/co19_2/co19_2-dart2js.status
@@ -2,9 +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.
 
-[ $compiler == dartdevk ]
-LanguageFeatures/Control-flow-collections/*: Skip
-
 [ $builder_tag != run_webgl_tests && $compiler == dart2js ]
 LayoutTests/fast/canvas/webgl*: Skip # Only run WebGL on special builders, issue 29961
 
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index 2508fca..44a9352 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -3,32 +3,7 @@
 # BSD-style license that can be found in the LICENSE file.
 
 [ $compiler == dartk ]
-LanguageFeatures/Control-flow-collections/*: Skip
 LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A06_t01: CompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A07_t01: CompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A07_t02: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t02: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t03: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t04: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t02: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t03: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t02: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t03: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t04: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A05_t01/none: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A05_t02/none: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t02: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t06: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t07: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A02_t12: CompileTimeError
 
 [ $compiler == dartkp ]
 Language/Expressions/Instance_Creation/New/evaluation_t20: RuntimeError
@@ -41,37 +16,7 @@
 Language/Statements/Yield_and_Yield_Each/Yield_Each/execution_async_t09: RuntimeError
 Language/Types/Interface_Types/subtype_t03: RuntimeError
 Language/Types/Interface_Types/subtype_t26: RuntimeError
-LanguageFeatures/Control-flow-collections/*: Skip
 LanguageFeatures/Set-literals/syntax_compatibility_A01_t02: RuntimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A01_t01: DartkCrash
-LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/02: MissingCompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/06: MissingCompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/07: MissingCompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A04_t01/08: MissingCompileTimeError
-LanguageFeatures/Spread-collections/ConstSpreads_A06_t01: DartkCrash
-LanguageFeatures/Spread-collections/ConstSpreads_A07_t01: DartkCrash
-LanguageFeatures/Spread-collections/ConstSpreads_A07_t02: DartkCrash
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t02: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t03: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_List_A02_t04: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t02: CompileTimeError
-LanguageFeatures/Spread-collections/DynamicSemantics_Map_A02_t03: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t02: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t03: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A01_t04: CompileTimeError
-LanguageFeatures/Spread-collections/NullAware_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A02_t01: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A05_t01/none: CompileTimeError
-LanguageFeatures/Spread-collections/StaticSemantic_A05_t02/none: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t01: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t02: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t05: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t06: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A01_t07: CompileTimeError
-LanguageFeatures/Spread-collections/Syntax_A02_t12: CompileTimeError
 LanguageFeatures/Subtyping/static/generated/left_bottom_global_variable_A02_t01: DartkCrash
 LanguageFeatures/Subtyping/static/generated/left_promoted_variable_global_variable_A02_t01: DartkCrash
 LibTest/collection/DoubleLinkedQueue/removeWhere_A02_t02: RuntimeError
@@ -119,18 +64,7 @@
 Language/Statements/For/syntax_t13: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
 Language/Statements/For/syntax_t20: Crash # Assertion error: kernel_shadow_ast.dart: 'receiver == null': is not true.
 LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: CompileTimeError
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: CompileTimeError
-LanguageFeatures/Control-flow-collections/const_collections_A02_t02/01: MissingCompileTimeError
-LanguageFeatures/Control-flow-collections/const_collections_A02_t02/03: MissingCompileTimeError
-LanguageFeatures/Control-flow-collections/const_collections_A02_t02/04: MissingCompileTimeError
-LanguageFeatures/Control-flow-collections/static_errors_A04_t01/01: MissingCompileTimeError
-LanguageFeatures/Control-flow-collections/static_errors_A04_t01/02: MissingCompileTimeError
-LanguageFeatures/Control-flow-collections/type_promotion_A01_t01: CompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t01/03: MissingCompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t01/06: MissingCompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t01/07: MissingCompileTimeError
-LanguageFeatures/Set-literals/type_inference_A01_t03: Crash
-LanguageFeatures/Set-literals/type_inference_A01_t04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/none: Crash
 LanguageFeatures/Set-literals/type_inference_A04_t02/02: MissingCompileTimeError
 LanguageFeatures/Set-literals/type_inference_A04_t02/03: MissingCompileTimeError
 LanguageFeatures/Set-literals/type_inference_A06_t02/03: MissingCompileTimeError
@@ -323,9 +257,37 @@
 Language/Types/Type_Aliases/syntax_t21: CompileTimeError
 LanguageFeatures/Constant-update-2018/EqualityOperator_A01_t09: MissingCompileTimeError
 LanguageFeatures/Constant-update-2018/EqualityOperator_A01_t10: MissingCompileTimeError
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: CompileTimeError
-LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: CompileTimeError
-LanguageFeatures/Control-flow-collections/scoping_A01_t01: CompileTimeError # co19 test error.
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t03/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t04/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/05: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/06: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t05/none: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/01: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/02: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/03: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/04: Crash
+LanguageFeatures/Constant-update-2018/NewOperators_A01_t06/05: Crash
+LanguageFeatures/Constant-update-2018/TypeTestOperator_A01_t01: CompileTimeError
+LanguageFeatures/Control-flow-collections/type_inference_A09_t01: Crash
+LanguageFeatures/Control-flow-collections/type_inference_A11_t01: CompileTimeError
+LanguageFeatures/Control-flow-collections/type_inference_A13_t01: CompileTimeError
+LanguageFeatures/Control-flow-collections/type_inference_A13_t02: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t01: Crash
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t02: CompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/dynamic/class_FutureOr_l1_t03: Crash
@@ -587,21 +549,7 @@
 LanguageFeatures/Set-literals/constant_set_literals_A02_t03/03: MissingCompileTimeError
 LanguageFeatures/Set-literals/disambiguating_A02_t02: CompileTimeError
 LanguageFeatures/Set-literals/disambiguating_A02_t03: Crash
-LanguageFeatures/Set-literals/disambiguating_A04_t02: Crash
-LanguageFeatures/Set-literals/disambiguating_A05_t02: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t01/02: Crash, MissingCompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t01/04: MissingCompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t01/05: MissingCompileTimeError
-LanguageFeatures/Set-literals/disambiguating_A06_t02/01: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/02: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/03: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/04: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/05: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/06: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/07: Crash
-LanguageFeatures/Set-literals/disambiguating_A06_t02/none: Crash
 LanguageFeatures/Set-literals/exact_types_of_literals_A01_t03: RuntimeError
-LanguageFeatures/Set-literals/type_inference_A01_t02: Crash
 LanguageFeatures/Set-literals/type_inference_A07_t01: CompileTimeError
 LanguageFeatures/Set-literals/type_inference_A08_t01: CompileTimeError
 LanguageFeatures/Set-literals/type_inference_A09_t01: CompileTimeError
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
index 84e646c..7694ba4 100644
--- a/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set.dart
@@ -4,55 +4,55 @@
 
 /*element: main:calls=*,params=0*/
 main() {
-  method1(new Class1a());
-  method2(new Class2a<int>());
-  method3(new Class3a());
-  method3(new Class3b());
-  method4(new Class4a());
-  method4(new Class4b());
+  method1(new Class1a()..field1);
+  method2(new Class2a<int>()..field2);
+  method3(new Class3a()..field3);
+  method3(new Class3b()..field3);
+  method4(new Class4a()..field4);
+  method4(new Class4b()..field4);
 }
 
 class Class1a {
-  /*element: Class1a.field1:elided*/
+  /*element: Class1a.field1:emitted*/
   int field1;
 }
 
-/*element: method1:params=1*/
+/*element: method1:assign=[field1],params=1*/
 @pragma('dart2js:noInline')
 method1(dynamic c) {
   c.field1 = 42;
 }
 
 class Class2a<T> {
-  /*strong.element: Class2a.field2:checked,elided*/
-  /*omit.element: Class2a.field2:elided*/
-  /*strongConst.element: Class2a.field2:checked,elided*/
-  /*omitConst.element: Class2a.field2:elided*/
+  /*strong.element: Class2a.field2:checked,emitted*/
+  /*omit.element: Class2a.field2:emitted*/
+  /*strongConst.element: Class2a.field2:checked,emitted*/
+  /*omitConst.element: Class2a.field2:emitted*/
   T field2;
 }
 
 /*strong.element: method2:calls=[set$field2(1)],params=1*/
-/*omit.element: method2:params=1*/
+/*omit.element: method2:assign=[field2],params=1*/
 /*strongConst.element: method2:calls=[set$field2(1)],params=1*/
-/*omitConst.element: method2:params=1*/
+/*omitConst.element: method2:assign=[field2],params=1*/
 @pragma('dart2js:noInline')
 method2(dynamic c) {
   c.field2 = 42;
 }
 
 class Class3a {
-  /*strong.element: Class3a.field3:checked,elided*/
-  /*omit.element: Class3a.field3:elided,set=simple*/
-  /*strongConst.element: Class3a.field3:checked,elided*/
-  /*omitConst.element: Class3a.field3:elided,set=simple*/
+  /*strong.element: Class3a.field3:checked,emitted*/
+  /*omit.element: Class3a.field3:emitted,set=simple*/
+  /*strongConst.element: Class3a.field3:checked,emitted*/
+  /*omitConst.element: Class3a.field3:emitted,set=simple*/
   int field3;
 }
 
 class Class3b {
-  /*strong.element: Class3b.field3:checked,elided*/
-  /*omit.element: Class3b.field3:elided,set=simple*/
-  /*strongConst.element: Class3b.field3:checked,elided*/
-  /*omitConst.element: Class3b.field3:elided,set=simple*/
+  /*strong.element: Class3b.field3:checked,emitted*/
+  /*omit.element: Class3b.field3:emitted,set=simple*/
+  /*strongConst.element: Class3b.field3:checked,emitted*/
+  /*omitConst.element: Class3b.field3:emitted,set=simple*/
   int field3;
 }
 
@@ -63,18 +63,18 @@
 }
 
 class Class4a {
-  /*strong.element: Class4a.field4:checked,elided*/
-  /*omit.element: Class4a.field4:elided,set=simple*/
-  /*strongConst.element: Class4a.field4:checked,elided*/
-  /*omitConst.element: Class4a.field4:elided,set=simple*/
+  /*strong.element: Class4a.field4:checked,emitted*/
+  /*omit.element: Class4a.field4:emitted,set=simple*/
+  /*strongConst.element: Class4a.field4:checked,emitted*/
+  /*omitConst.element: Class4a.field4:emitted,set=simple*/
   int field4;
 }
 
 class Class4b implements Class4a {
-  /*strong.element: Class4b.field4:checked,elided*/
-  /*omit.element: Class4b.field4:elided,set=simple*/
-  /*strongConst.element: Class4b.field4:checked,elided*/
-  /*omitConst.element: Class4b.field4:elided,set=simple*/
+  /*strong.element: Class4b.field4:checked,emitted*/
+  /*omit.element: Class4b.field4:emitted,set=simple*/
+  /*strongConst.element: Class4b.field4:checked,emitted*/
+  /*omitConst.element: Class4b.field4:emitted,set=simple*/
   @override
   int field4;
 }
diff --git a/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
new file mode 100644
index 0000000..84e646c
--- /dev/null
+++ b/tests/compiler/dart2js/codegen/model_data/dynamic_set_unread.dart
@@ -0,0 +1,86 @@
+// 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.
+
+/*element: main:calls=*,params=0*/
+main() {
+  method1(new Class1a());
+  method2(new Class2a<int>());
+  method3(new Class3a());
+  method3(new Class3b());
+  method4(new Class4a());
+  method4(new Class4b());
+}
+
+class Class1a {
+  /*element: Class1a.field1:elided*/
+  int field1;
+}
+
+/*element: method1:params=1*/
+@pragma('dart2js:noInline')
+method1(dynamic c) {
+  c.field1 = 42;
+}
+
+class Class2a<T> {
+  /*strong.element: Class2a.field2:checked,elided*/
+  /*omit.element: Class2a.field2:elided*/
+  /*strongConst.element: Class2a.field2:checked,elided*/
+  /*omitConst.element: Class2a.field2:elided*/
+  T field2;
+}
+
+/*strong.element: method2:calls=[set$field2(1)],params=1*/
+/*omit.element: method2:params=1*/
+/*strongConst.element: method2:calls=[set$field2(1)],params=1*/
+/*omitConst.element: method2:params=1*/
+@pragma('dart2js:noInline')
+method2(dynamic c) {
+  c.field2 = 42;
+}
+
+class Class3a {
+  /*strong.element: Class3a.field3:checked,elided*/
+  /*omit.element: Class3a.field3:elided,set=simple*/
+  /*strongConst.element: Class3a.field3:checked,elided*/
+  /*omitConst.element: Class3a.field3:elided,set=simple*/
+  int field3;
+}
+
+class Class3b {
+  /*strong.element: Class3b.field3:checked,elided*/
+  /*omit.element: Class3b.field3:elided,set=simple*/
+  /*strongConst.element: Class3b.field3:checked,elided*/
+  /*omitConst.element: Class3b.field3:elided,set=simple*/
+  int field3;
+}
+
+/*element: method3:calls=[set$field3(1)],params=1*/
+@pragma('dart2js:noInline')
+method3(dynamic c) {
+  c.field3 = 42;
+}
+
+class Class4a {
+  /*strong.element: Class4a.field4:checked,elided*/
+  /*omit.element: Class4a.field4:elided,set=simple*/
+  /*strongConst.element: Class4a.field4:checked,elided*/
+  /*omitConst.element: Class4a.field4:elided,set=simple*/
+  int field4;
+}
+
+class Class4b implements Class4a {
+  /*strong.element: Class4b.field4:checked,elided*/
+  /*omit.element: Class4b.field4:elided,set=simple*/
+  /*strongConst.element: Class4b.field4:checked,elided*/
+  /*omitConst.element: Class4b.field4:elided,set=simple*/
+  @override
+  int field4;
+}
+
+/*element: method4:calls=[set$field4(1)],params=1*/
+@pragma('dart2js:noInline')
+method4(Class4a c) {
+  c.field4 = 42;
+}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
new file mode 100644
index 0000000..d85a4a0
--- /dev/null
+++ b/tests/compiler/dart2js/field_analysis/jdata/constant_fields.dart
@@ -0,0 +1,30 @@
+// 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.
+
+main() {
+  print(const Class1().field1);
+  print(const Class2(field2: true).field2);
+  print(const Class3().field3);
+  print(const Class3(field3: true).field3);
+}
+
+class Class1 {
+  /*element: Class1.field1:constant=BoolConstant(false)*/
+  final bool field1;
+
+  const Class1({this.field1: false});
+}
+
+class Class2 {
+  /*strongConst.element: Class2.field2:constant=BoolConstant(true)*/
+  final bool field2;
+
+  const Class2({this.field2: false});
+}
+
+class Class3 {
+  final bool field3;
+
+  const Class3({this.field3: false});
+}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
new file mode 100644
index 0000000..b228203
--- /dev/null
+++ b/tests/compiler/dart2js/field_analysis/jdata/dynamic_set.dart
@@ -0,0 +1,63 @@
+// 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.
+
+main() {
+  method1(new Class1a());
+  method2(new Class2a<int>());
+  method3(new Class3a());
+  method3(new Class3b());
+  method4(new Class4a());
+  method4(new Class4b());
+}
+
+class Class1a {
+  /*element: Class1a.field1:elided*/
+  int field1;
+}
+
+@pragma('dart2js:noInline')
+method1(dynamic c) {
+  c.field1 = 42;
+}
+
+class Class2a<T> {
+  /*element: Class2a.field2:elided*/
+  T field2;
+}
+
+@pragma('dart2js:noInline')
+method2(dynamic c) {
+  c.field2 = 42;
+}
+
+class Class3a {
+  /*element: Class3a.field3:elided*/
+  int field3;
+}
+
+class Class3b {
+  /*element: Class3b.field3:elided*/
+  int field3;
+}
+
+@pragma('dart2js:noInline')
+method3(dynamic c) {
+  c.field3 = 42;
+}
+
+class Class4a {
+  /*element: Class4a.field4:elided*/
+  int field4;
+}
+
+class Class4b implements Class4a {
+  /*element: Class4b.field4:elided*/
+  @override
+  int field4;
+}
+
+@pragma('dart2js:noInline')
+method4(Class4a c) {
+  c.field4 = 42;
+}
diff --git a/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.dart
new file mode 100644
index 0000000..219c643
--- /dev/null
+++ b/tests/compiler/dart2js/field_analysis/jdata/unused_constructors.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 Class1 {
+  /*element: Class1.field:constant=IntConstant(87)*/
+  final int field;
+
+  Class1.constructor1({this.field = 42});
+  Class1.constructor2({this.field = 87});
+  Class1.constructor3({this.field = 123});
+}
+
+class Class2 {
+  final int field;
+
+  const Class2([this.field]);
+}
+
+main() {
+  print(new Class1.constructor2().field);
+  print(const Class2(42).field);
+  print(new Class2().field);
+}
diff --git a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
index 79b4cb0..a28477b 100644
--- a/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
+++ b/tests/compiler/dart2js/field_analysis/jfield_analysis_test.dart
@@ -30,6 +30,7 @@
   static const String eagerCreationIndex = 'index';
   static const String isLazy = 'lazy';
   static const String isEffectivelyFinal = 'final';
+  static const String isElided = 'elided';
 }
 
 class JAllocatorAnalysisDataComputer extends DataComputer<Features> {
@@ -45,6 +46,9 @@
       ir.Member node = closedWorld.elementMap.getMemberDefinition(member).node;
       Features features = new Features();
       FieldAnalysisData fieldData = fieldAnalysis.getFieldData(member);
+      if (fieldData.isElided && !fieldData.isEffectivelyConstant) {
+        features.add(Tags.isElided);
+      }
       if (fieldData.isInitializedInAllocator) {
         features.add(Tags.isInitializedInAllocator);
       }
diff --git a/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.dart
new file mode 100644
index 0000000..df9b18b
--- /dev/null
+++ b/tests/compiler/dart2js/field_analysis/kdata/constant_fields.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.
+
+main() {
+  print(const Class1().field1);
+  print(const Class2(field2: true).field2);
+  print(const Class3().field3);
+  print(const Class3(field3: true).field3);
+}
+
+class Class1 {
+  /*element: Class1.field1:Class1.=field1:BoolConstant(false),initial=NullConstant*/
+  final bool field1;
+
+  const Class1({this.field1: false});
+}
+
+class Class2 {
+  /*element: Class2.field2:Class2.=field2:BoolConstant(false),initial=NullConstant*/
+  final bool field2;
+
+  const Class2({this.field2: false});
+}
+
+class Class3 {
+  /*element: Class3.field3:Class3.=field3:BoolConstant(false),initial=NullConstant*/
+  final bool field3;
+
+  const Class3({this.field3: false});
+}
diff --git a/tests/compiler/dart2js/impact/data/classes.dart b/tests/compiler/dart2js/impact/data/classes.dart
index c7f1e97..5a067d6 100644
--- a/tests/compiler/dart2js/impact/data/classes.dart
+++ b/tests/compiler/dart2js/impact/data/classes.dart
@@ -207,7 +207,20 @@
 }
 
 /*strong.element: testEnum:static=[Enum.A]*/
-/*strongConst.element: testEnum:static=[init:Enum._name,init:Enum.index],type=[const:Enum,inst:JSDouble,inst:JSInt,inst:JSNumber,inst:JSPositiveInt,inst:JSString,inst:JSUInt31,inst:JSUInt32]*/
+/*strongConst.element: testEnum:
+ static=[
+  Enum._name=StringConstant("Enum.A"),
+  Enum.index=IntConstant(0)],
+ type=[
+  const:Enum,
+  inst:JSDouble,
+  inst:JSInt,
+  inst:JSNumber,
+  inst:JSPositiveInt,
+  inst:JSString,
+  inst:JSUInt31,
+  inst:JSUInt32]
+*/
 testEnum() => Enum.A;
 
 /*element: staticGenericMethod:
diff --git a/tests/compiler/dart2js/impact/data/constants.dart b/tests/compiler/dart2js/impact/data/constants.dart
index 91feb99..12db520 100644
--- a/tests/compiler/dart2js/impact/data/constants.dart
+++ b/tests/compiler/dart2js/impact/data/constants.dart
@@ -102,7 +102,10 @@
 setLiteral() => const {true, false};
 
 /*strong.element: instanceConstant:static=[Class.(2)],type=[inst:JSBool]*/
-/*strongConst.element: instanceConstant:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class,inst:JSBool]*/
+/*strongConst.element: instanceConstant:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class,inst:JSBool]
+*/
 instanceConstant() => const Class(true, false);
 
 /*element: typeLiteral:static=[createRuntimeType(1)],type=[inst:Type,inst:TypeImpl,lit:String]*/
@@ -170,7 +173,10 @@
 setLiteralRef() => setLiteralField;
 
 /*strong.element: instanceConstantRef:static=[instanceConstantField]*/
-/*strongConst.element: instanceConstantRef:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class,inst:JSBool]*/
+/*strongConst.element: instanceConstantRef:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class,inst:JSBool]
+*/
 instanceConstantRef() => instanceConstantField;
 
 /*strong.element: typeLiteralRef:static=[typeLiteralField]*/
@@ -235,7 +241,10 @@
 setLiteralDeferred() => defer.setLiteralField;
 
 /*strong.element: instanceConstantDeferred:static=[instanceConstantField{defer}]*/
-/*strongConst.element: instanceConstantDeferred:static=[init:Class.field2,init:SuperClass.field1],type=[const:Class{defer},inst:JSBool]*/
+/*strongConst.element: instanceConstantDeferred:
+ static=[Class.field2=BoolConstant(false),SuperClass.field1=BoolConstant(true)],
+ type=[const:Class{defer},inst:JSBool]
+*/
 instanceConstantDeferred() => defer.instanceConstantField;
 
 /*strong.element: typeLiteralDeferred:static=[typeLiteralField{defer}]*/
diff --git a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
index 1c553b0..8a1f1ec 100644
--- a/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
+++ b/tests/compiler/dart2js/model/cfe_constant_evaluation_test.dart
@@ -75,6 +75,17 @@
     const ConstantData('proxy', 'ConstructedConstant(_Proxy())'),
     const ConstantData('const [] == null', 'BoolConstant(false)'),
     const ConstantData('proxy == null', 'BoolConstant(false)'),
+    const ConstantData('proxy != null', 'BoolConstant(true)'),
+    const ConstantData('null == proxy', 'BoolConstant(false)'),
+    const ConstantData('null != proxy', 'BoolConstant(true)'),
+    const ConstantData('true == proxy', 'BoolConstant(false)'),
+    const ConstantData('true != proxy', 'BoolConstant(true)'),
+    const ConstantData('0 == proxy', 'BoolConstant(false)'),
+    const ConstantData('0 != proxy', 'BoolConstant(true)'),
+    const ConstantData('0.5 == proxy', 'BoolConstant(false)'),
+    const ConstantData('0.5 != proxy', 'BoolConstant(true)'),
+    const ConstantData('"" == proxy', 'BoolConstant(false)'),
+    const ConstantData('"" != proxy', 'BoolConstant(true)'),
     const ConstantData('Object', 'TypeConstant(Object)'),
     const ConstantData('null ?? 0', 'IntConstant(0)'),
     const ConstantData(
@@ -380,11 +391,10 @@
         expectedErrors: 'ConstEvalFailedAssertionWithMessage'),
     const ConstantData('const Class6(2)', 'ConstructedConstant(Class6())'),
     const ConstantData('const Class7()', 'ConstructedConstant(Class7())'),
-    // TODO(johnniwinther): Expect a NonConstant and errors when 31799 is fixed.
-    const ConstantData(
-      'const Class7() == const Class7()',
-      'BoolConstant(true)',
-    ),
+    const ConstantData('const Class7() == const Class7()', 'NonConstant',
+        expectedErrors: 'ConstEvalInvalidEqualsOperandType'),
+    const ConstantData('const Class7() != const Class7()', 'NonConstant',
+        expectedErrors: 'ConstEvalInvalidEqualsOperandType'),
     const ConstantData('const Class8(not_string.length)', 'NonConstant',
         expectedErrors: 'ConstEvalInvalidPropertyGet'),
     const ConstantData(
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
new file mode 100644
index 0000000..3db4d67
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*strong.class: A:checkedInstance,checkedTypeArgument,checks=[],typeArgument*/
+/*omit.class: A:checkedTypeArgument,checks=[],typeArgument*/
+class A {}
+
+/*strong.class: B:checkedInstance,checks=[$isA],typeArgument*/
+/*omit.class: B:checks=[$isA],typeArgument*/
+class B implements A {}
+
+/*class: C:checks=[],indirectInstance*/
+class C<T> {
+  @pragma('dart2js:noInline')
+  method(void Function(T) f) {}
+}
+
+/*strong.class: D:checks=[$asC],instance*/
+/*omit.class: D:checks=[],instance*/
+class D extends C<B> {}
+
+main() {
+  C<A> c = new D();
+  c.method(
+      /*strong.checks=[$signature],instance*/
+      /*omit.checks=[],instance*/
+      (A a) {});
+}
diff --git a/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
new file mode 100644
index 0000000..0b22968
--- /dev/null
+++ b/tests/compiler/dart2js/rti/emission/fixed_type_argument_implements.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// 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.
+
+/*strong.class: A:checkedTypeArgument,checks=[],typeArgument*/
+class A {}
+
+/*strong.class: B:checks=[$isA],typeArgument*/
+/*omit.class: B:checks=[],typeArgument*/
+class B implements A {}
+
+/*strong.class: C:checkedInstance*/
+/*omit.class: C:*/
+class C<T> {}
+
+/*strong.class: D:checks=[$asC,$isC],instance*/
+/*omit.class: D:checks=[],instance*/
+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/compiler/dart2js/rti/emission/mixin_type_arguments.dart b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
index cc6f668..9644a40 100644
--- a/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
+++ b/tests/compiler/dart2js/rti/emission/mixin_type_arguments.dart
@@ -4,19 +4,19 @@
 
 import 'package:expect/expect.dart' show Expect;
 
-/*class: A:checks=[]*/
+/*class: A:checks=[],typeArgument*/
 class A {}
 
-/*class: B:checks=[]*/
+/*class: B:checks=[],typeArgument*/
 class B {}
 
-/*class: C:checks=[]*/
+/*class: C:checks=[],typeArgument*/
 class C {}
 
-/*class: D:checks=[]*/
+/*class: D:checks=[],typeArgument*/
 class D {}
 
-/*class: E:checks=[]*/
+/*class: E:checks=[],typeArgument*/
 class E {}
 
 /*class: F:checks=[],typeArgument*/
diff --git a/tests/compiler/dart2js/static_type/data/null_access.dart b/tests/compiler/dart2js/static_type/data/null_access.dart
new file mode 100644
index 0000000..de65e93
--- /dev/null
+++ b/tests/compiler/dart2js/static_type/data/null_access.dart
@@ -0,0 +1,44 @@
+// 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.
+
+main() {
+  test1();
+  test2();
+  test3();
+}
+
+class Class1 {
+  const Class1();
+
+  void method1() {}
+}
+
+test1() {
+  const Class1 c = null;
+  return /*Null*/ c. /*invoke: void*/ method1();
+}
+
+class Class2<T> {
+  const Class2();
+
+  T method2() => null;
+}
+
+test2() {
+  const Class2<int> c = null;
+  // TODO(johnniwinther): Track the unreachable code properly.
+  return /*Null*/ c. /*invoke: <bottom>*/ method2();
+}
+
+class Class3<T> {
+  const Class3();
+
+  Class3<T> method3() => null;
+}
+
+test3() {
+  const Class3<int> c = null;
+  // TODO(johnniwinther): Track the unreachable code properly.
+  return /*Null*/ c. /*invoke: Class3<<bottom>>*/ method3();
+}
diff --git a/tests/compiler/dart2js_extra/boolean_conversion_test.dart b/tests/compiler/dart2js_extra/boolean_conversion_test.dart
new file mode 100644
index 0000000..46a8994
--- /dev/null
+++ b/tests/compiler/dart2js_extra/boolean_conversion_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.
+
+// SharedOptions=--enable-experiment=control-flow-collections
+// 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/compiler/dart2js_extra/constant_folding_test.dart b/tests/compiler/dart2js_extra/constant_folding_test.dart
index cc88f68..393994a 100644
--- a/tests/compiler/dart2js_extra/constant_folding_test.dart
+++ b/tests/compiler/dart2js_extra/constant_folding_test.dart
@@ -4,6 +4,8 @@
 
 import "package:expect/expect.dart";
 
+// SharedOptions=--enable-experiment=constant-update-2018
+
 void main() {
   const BitNot(42, 4294967253).check();
   const BitNot(4294967253, 42).check();
@@ -12,6 +14,8 @@
   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();
@@ -50,6 +54,10 @@
   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();
@@ -65,6 +73,12 @@
   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();
@@ -77,6 +91,12 @@
   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();
@@ -88,6 +108,12 @@
   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();
@@ -104,6 +130,14 @@
   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();
@@ -127,6 +161,14 @@
   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();
@@ -346,9 +388,7 @@
   const TruncatingDivide(9007199254740991, -0.5, -18014398509481982).check();
   const TruncatingDivide(-9007199254740991, 0.5, -18014398509481982).check();
   const TruncatingDivide(-9007199254740991, -0.5, 18014398509481982).check();
-  const TruncatingDivide(
-          0x80000000 * 0x100000000, -1, -0x80000000 * 0x100000000)
-      .check();
+  const TruncatingDivide(0x8000000000000000, -1, -0x8000000000000000).check();
   const TruncatingDivide(2.71828, 3.14159, 0).check();
   const TruncatingDivide(2.71828, 1, 2).check();
   const TruncatingDivide(2.71828, -1, -2).check();
@@ -837,6 +877,8 @@
   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();
@@ -848,8 +890,7 @@
   const Identity(false, true, false).check();
   const Identity(0, false, false).check();
   const Identity(true, 1, false).check();
-  // TODO(36194)
-  //const Identity(double.nan, double.nan, 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();
@@ -868,6 +909,8 @@
   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();
diff --git a/tests/compiler/dart2js_extra/fixed_type_argument_implements_test.dart b/tests/compiler/dart2js_extra/fixed_type_argument_implements_test.dart
new file mode 100644
index 0000000..f0c397e
--- /dev/null
+++ b/tests/compiler/dart2js_extra/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/compiler/dart2js_extra/fixed_type_argument_test.dart b/tests/compiler/dart2js_extra/fixed_type_argument_test.dart
new file mode 100644
index 0000000..74ac892
--- /dev/null
+++ b/tests/compiler/dart2js_extra/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/language_2/abstract_equal_test.dart b/tests/language_2/abstract_equal_test.dart
new file mode 100644
index 0000000..2ff5b59
--- /dev/null
+++ b/tests/language_2/abstract_equal_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.
+
+// SharedOptions=--enable-experiment=constant-update-2018
+
+class A {
+  bool operator ==(other);
+  const A();
+}
+
+class B implements A {
+  const B();
+}
+
+class C extends A {
+  const C();
+}
+
+class Invalid {
+  bool operator ==(other) => false;
+  const Invalid();
+}
+
+class D implements Invalid {
+  const D();
+}
+
+main() {
+  print(const {A(): 1});
+  print(const {B(): 2});
+  print(const {C(): 3});
+  print(const {D(): 4});
+}
diff --git a/tests/language_2/const_inference_test.dart b/tests/language_2/const_inference_test.dart
new file mode 100644
index 0000000..2e556bf
--- /dev/null
+++ b/tests/language_2/const_inference_test.dart
@@ -0,0 +1,140 @@
+// 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";
+
+R constFunction<T, R>(T _) => null;
+
+C<T> getC<T>() => const C(constFunction);
+
+List<T> getList<T>() => const [];
+
+Set<T> getSet<T>() => const {};
+
+Map<K, V> getMap<K, V>() => const {};
+
+R Function(T) getFunction<T, R>() {
+  List<R Function(T)> list = const [constFunction];
+  return list[0];
+}
+
+C<T> getImplicitConstC<T>() {
+  List<C<T>> list = const [C(constFunction)];
+  return list[0];
+}
+
+List<T> getImplicitConstList<T>() {
+  List<List<T>> list = const [[]];
+  return list[0];
+}
+
+Set<T> getImplicitConstSet<T>() {
+  List<Set<T>> list = const [{}];
+  return list[0];
+}
+
+Map<K, V> getImplicitConstMap<K, V>() {
+  List<Map<K, V>> list = const [{}];
+  return list[0];
+}
+
+class C<T> {
+  final Object fn;
+  const C(T Function(T) this.fn);
+}
+
+void expectOfType<T>(Object obj) {
+  // An exact type test would be better, but since `Null` is a subtype of all
+  // types that can be written in Dart 2.0, it should not matter in practice.
+  //
+  // (`obj.runtimeType == T` does not work for List/Map/Sets because the runtime
+  // type is an implementation-specific subtype of those interfaces.)
+  Expect.isTrue(obj is T, "`$obj` should be of type `$T`");
+}
+
+testClassInstance() {
+  expectOfType<C<Null>>(getC<int>());
+  expectOfType<C<Null>>(getC<String>());
+  expectOfType<C<Null>>(getC());
+}
+
+testImplicitConstClassInstance() {
+  expectOfType<C<Null>>(getImplicitConstC<int>());
+  expectOfType<C<Null>>(getImplicitConstC<String>());
+  expectOfType<C<Null>>(getImplicitConstC());
+}
+
+testDownwardsClassInference() {
+  expectOfType<Null Function(Null)>(getC<int>().fn);
+  expectOfType<Null Function(Null)>(getC<String>().fn);
+  expectOfType<Null Function(Null)>(getC().fn);
+}
+
+testList() {
+  expectOfType<List<Null>>(getList<int>());
+  expectOfType<List<Null>>(getList<String>());
+  expectOfType<List<Null>>(getList());
+}
+
+testImplicitConstList() {
+  expectOfType<List<Null>>(getImplicitConstList<int>());
+  expectOfType<List<Null>>(getImplicitConstList<String>());
+  expectOfType<List<Null>>(getImplicitConstList());
+}
+
+testImplicitConstSet() {
+  expectOfType<Set<Null>>(getImplicitConstSet<int>());
+  expectOfType<Set<Null>>(getImplicitConstSet<String>());
+  expectOfType<Set<Null>>(getImplicitConstSet());
+}
+
+testSet() {
+  expectOfType<Set<Null>>(getSet<int>());
+  expectOfType<Set<Null>>(getSet<String>());
+  expectOfType<Set<Null>>(getSet());
+}
+
+testMap() {
+  expectOfType<Map<Null, Null>>(getMap<int, int>());
+  expectOfType<Map<Null, Null>>(getMap<int, String>());
+  expectOfType<Map<Null, Null>>(getMap<String, int>());
+  expectOfType<Map<Null, Null>>(getMap<String, String>());
+  expectOfType<Map<Null, Null>>(getMap<Null, Null>());
+  expectOfType<Map<Null, Null>>(getMap());
+}
+
+testImplicitConstMap() {
+  expectOfType<Map<Null, Null>>(getImplicitConstMap<int, int>());
+  expectOfType<Map<Null, Null>>(getImplicitConstMap<int, String>());
+  expectOfType<Map<Null, Null>>(getImplicitConstMap<String, int>());
+  expectOfType<Map<Null, Null>>(getImplicitConstMap<String, String>());
+  expectOfType<Map<Null, Null>>(getImplicitConstMap<Null, Null>());
+  expectOfType<Map<Null, Null>>(getImplicitConstMap());
+}
+
+testFunction() {
+  expectOfType<Null Function(Object)>(getFunction<int, int>());
+  expectOfType<Null Function(Object)>(getFunction<int, String>());
+  expectOfType<Null Function(Object)>(getFunction<String, int>());
+  expectOfType<Null Function(Object)>(getFunction<String, String>());
+  expectOfType<Null Function(Object)>(getFunction<Null, Null>());
+  expectOfType<Null Function(Object)>(getFunction());
+}
+
+/// Tests that type inference for constants does not reference the type
+/// parameter. Instead, free type parameters should substituted to obtain the
+/// least closure (e.g. `List<T>` becomes `List<Null>` and `R Function(T)`
+/// becomes `Null Function(Object)`).
+main() {
+  testClassInstance();
+  testImplicitConstClassInstance();
+  testDownwardsClassInference();
+  testList();
+  testImplicitConstList();
+  testSet();
+  testImplicitConstSet();
+  testMap();
+  testImplicitConstMap();
+  testFunction();
+}
diff --git a/tests/language_2/const_list_test.dart b/tests/language_2/const_list_test.dart
index b848c9e..cdc0fb3 100644
--- a/tests/language_2/const_list_test.dart
+++ b/tests/language_2/const_list_test.dart
@@ -16,32 +16,32 @@
       growableList.add(i);
       growableList2.add(i);
     }
-    Expect.equals(true, growableList == growableList);
-    Expect.equals(false, growableList == growableList2);
-    Expect.equals(true, fixedList == fixedList);
-    Expect.equals(false, fixedList == fixedList2);
-    Expect.equals(false, fixedList == growableList);
+    Expect.equals(growableList, growableList);
+    Expect.notEquals(growableList, growableList2);
+    Expect.equals(fixedList, fixedList);
+    Expect.notEquals(fixedList, fixedList2);
+    Expect.notEquals(fixedList, growableList);
     growableList.add(4);
-    Expect.equals(false, fixedList == growableList);
+    Expect.notEquals(fixedList, growableList);
     Expect.equals(4, growableList.removeLast());
-    Expect.equals(false, fixedList == growableList);
+    Expect.notEquals(fixedList, growableList);
     fixedList[3] = 0;
-    Expect.equals(false, fixedList == growableList);
+    Expect.notEquals(fixedList, growableList);
   }
 
   static testLiterals() {
     dynamic a = [1, 2, 3.1];
     dynamic b = [1, 2, 3.1];
-    Expect.equals(false, a == b);
+    Expect.notEquals(a, b);
     a = const [1, 2, 3.1];
     b = const [1, 2, 3.1];
-    Expect.equals(true, a == b);
+    Expect.identical(a, b);
     a = const <num>[1, 2, 3.1];
     b = const [1, 2, 3.1];
-    Expect.equals(false, a == b);
+    Expect.identical(a, b);
     a = const <dynamic>[1, 2, 3.1];
     b = const [1, 2, 3.1];
-    Expect.equals(true, a == b);
+    Expect.notEquals(a, b);
   }
 }
 
diff --git a/tests/language_2/constants_2018/constant_type_literal_test.dart b/tests/language_2/constants_2018/constant_type_literal_test.dart
index 717825a..33cf4a9 100644
--- a/tests/language_2/constants_2018/constant_type_literal_test.dart
+++ b/tests/language_2/constants_2018/constant_type_literal_test.dart
@@ -8,12 +8,16 @@
 
 import "dart:core";
 import "dart:core" as core;
-import "dart:core" deferred as dcore;
+// No reloading support for deferred loading.
+// See https://github.com/dart-lang/sdk/issues/33118,
+import "dart:core" deferred as dcore; //# 01: crash on reload
 
 // Declares F function type alias, M mixin and C class.
 import "constant_type_literal_types.dart";
 import "constant_type_literal_types.dart" as p;
-import "constant_type_literal_types.dart" deferred as d;
+// No reloading support for deferred loading.
+// See https://github.com/dart-lang/sdk/issues/33118,
+import "constant_type_literal_types.dart" deferred as d; //# 02: crash on reload
 
 main() {
   const Test(int, core.int);
diff --git a/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart b/tests/language_2/control_flow_collections/for_non_bool_condition_test.dart
new file mode 100644
index 0000000..fbc3834
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_non_bool_condition_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.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Non-bool condition expression.
+  dynamic nonBool = 3;
+  Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (; nonBool;) 1});
+}
diff --git a/tests/language_2/control_flow_collections/for_null_condition_test.dart b/tests/language_2/control_flow_collections/for_null_condition_test.dart
new file mode 100644
index 0000000..6b890fd
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_null_condition_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.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Null condition expression.
+  bool nullBool = null;
+  Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]);
+  Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1});
+  Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1});
+}
diff --git a/tests/language_2/control_flow_collections/for_runtime_error_test.dart b/tests/language_2/control_flow_collections/for_runtime_error_test.dart
new file mode 100644
index 0000000..f036a94
--- /dev/null
+++ b/tests/language_2/control_flow_collections/for_runtime_error_test.dart
@@ -0,0 +1,29 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+
+import 'package:expect/expect.dart';
+
+void main() {
+  // Cast for variable.
+  dynamic nonInt = "string";
+  Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1});
+
+  // Cast for-in variable.
+  dynamic nonIterable = 3;
+  Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]);
+  Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1});
+  Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1});
+
+  // Wrong element type.
+  Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]);
+  Expect.throwsTypeError(
+      () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1});
+  Expect.throwsTypeError(
+      () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt});
+  Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt});
+}
diff --git a/tests/language_2/control_flow_collections/for_test.dart b/tests/language_2/control_flow_collections/for_test.dart
index 17730bc..8df9d75 100644
--- a/tests/language_2/control_flow_collections/for_test.dart
+++ b/tests/language_2/control_flow_collections/for_test.dart
@@ -241,42 +241,10 @@
 }
 
 void testRuntimeErrors() {
-  // Non-bool condition expression.
-  dynamic nonBool = 3;
-  Expect.throwsTypeError(() => <int>[for (; nonBool;) 1]);
-  Expect.throwsTypeError(() => <int, int>{for (; nonBool;) 1: 1});
-  Expect.throwsTypeError(() => <int>{for (; nonBool;) 1});
-
-  // Null condition expression.
-  bool nullBool = null;
-  Expect.throwsAssertionError(() => <int>[for (; nullBool;) 1]);
-  Expect.throwsAssertionError(() => <int, int>{for (; nullBool;) 1: 1});
-  Expect.throwsAssertionError(() => <int>{for (; nullBool;) 1});
-
-  // Cast for variable.
-  dynamic nonInt = "string";
-  Expect.throwsTypeError(() => <int>[for (int i = nonInt; false;) 1]);
-  Expect.throwsTypeError(() => <int, int>{for (int i = nonInt; false;) 1: 1});
-  Expect.throwsTypeError(() => <int>{for (int i = nonInt; false;) 1});
-
-  // Cast for-in variable.
-  dynamic nonIterable = 3;
-  Expect.throwsTypeError(() => <int>[for (int i in nonIterable) 1]);
-  Expect.throwsTypeError(() => <int, int>{for (int i in nonIterable) 1: 1});
-  Expect.throwsTypeError(() => <int>{for (int i in nonIterable) 1});
-
   // Null iterable.
   Iterable<int> nullIterable = null;
   Expect.throwsNoSuchMethodError(() => <int>[for (var i in nullIterable) 1]);
   Expect.throwsNoSuchMethodError(
       () => <int, int>{for (var i in nullIterable) 1: 1});
   Expect.throwsNoSuchMethodError(() => <int>{for (var i in nullIterable) 1});
-
-  // Wrong element type.
-  Expect.throwsTypeError(() => <int>[for (var i = 0; i < 1; i++) nonInt]);
-  Expect.throwsTypeError(
-      () => <int, int>{for (var i = 0; i < 1; i++) nonInt: 1});
-  Expect.throwsTypeError(
-      () => <int, int>{for (var i = 0; i < 1; i++) 1: nonInt});
-  Expect.throwsTypeError(() => <int>{for (var i = 0; i < 1; i++) nonInt});
 }
diff --git a/tests/language_2/control_flow_collections/if_null_condition_test.dart b/tests/language_2/control_flow_collections/if_null_condition_test.dart
new file mode 100644
index 0000000..10cbb6b
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_null_condition_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.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+
+import 'package:expect/expect.dart';
+
+void main() {
+  bool nullBool = null;
+  Expect.throwsAssertionError(() => <int>[if (nullBool) 1]);
+  Expect.throwsAssertionError(() => <int, int>{if (nullBool) 1: 1});
+  Expect.throwsAssertionError(() => <int>{if (nullBool) 1});
+}
diff --git a/tests/language_2/control_flow_collections/if_runtime_error_test.dart b/tests/language_2/control_flow_collections/if_runtime_error_test.dart
new file mode 100644
index 0000000..8bf5469
--- /dev/null
+++ b/tests/language_2/control_flow_collections/if_runtime_error_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.
+
+// SharedOptions=--enable-experiment=control-flow-collections,spread-collections,constant-update-2018
+
+import 'package:expect/expect.dart';
+
+void main() {
+  dynamic nonBool = 3;
+  Expect.throwsTypeError(() => <int>[if (nonBool) 1]);
+  Expect.throwsTypeError(() => <int, int>{if (nonBool) 1: 1});
+  Expect.throwsTypeError(() => <int>{if (nonBool) 1});
+}
diff --git a/tests/language_2/control_flow_collections/if_test.dart b/tests/language_2/control_flow_collections/if_test.dart
index 99b3d39..4a922f8 100644
--- a/tests/language_2/control_flow_collections/if_test.dart
+++ b/tests/language_2/control_flow_collections/if_test.dart
@@ -19,7 +19,6 @@
   testShortCircuit();
   testDuplicateKeys();
   testKeyOrder();
-  testRuntimeFailures();
 }
 
 void testList() {
@@ -229,15 +228,3 @@
   };
   Expect.equals("1:a,2:a", set.join(","));
 }
-
-void testRuntimeFailures() {
-  dynamic nonBool = 3;
-  Expect.throwsTypeError(() => <int>[if (nonBool) 1]);
-  Expect.throwsTypeError(() => <int, int>{if (nonBool) 1: 1});
-  Expect.throwsTypeError(() => <int>{if (nonBool) 1});
-
-  bool nullBool = null;
-  Expect.throwsAssertionError(() => <int>[if (nullBool) 1]);
-  Expect.throwsAssertionError(() => <int, int>{if (nullBool) 1: 1});
-  Expect.throwsAssertionError(() => <int>{if (nullBool) 1});
-}
diff --git a/tests/language_2/control_flow_collections/type_error_test.dart b/tests/language_2/control_flow_collections/type_error_test.dart
index 4e98549..533dc18 100644
--- a/tests/language_2/control_flow_collections/type_error_test.dart
+++ b/tests/language_2/control_flow_collections/type_error_test.dart
@@ -34,9 +34,9 @@
   var _ = <int>{for (int i in s) 1}; //# 22: compile-time error
 
   // Wrong for declaration element type.
-  var _ = <int>[for (int i = "s";;) 1]; //# 23: compile-time error
-  var _ = <int, int>{for (int i = "s";;) 1: 1}; //# 24: compile-time error
-  var _ = <int>{for (int i = "s";;) 1}; //# 25: compile-time error
+  var _ = <int>[for (int i = "s"; false;) 1]; //# 23: compile-time error
+  var _ = <int, int>{for (int i = "s"; false;) 1: 1}; //# 24: compile-time error
+  var _ = <int>{for (int i = "s"; false;) 1}; //# 25: compile-time error
 
   // Wrong for body element type.
   var _ = <int>[for (; false;) "s"]; //# 26: compile-time error
diff --git a/tests/language_2/control_flow_collections/utils.dart b/tests/language_2/control_flow_collections/utils.dart
index b240e24..e2d6ade 100644
--- a/tests/language_2/control_flow_collections/utils.dart
+++ b/tests/language_2/control_flow_collections/utils.dart
@@ -34,37 +34,37 @@
 }
 
 T expectDynamic<T>(dynamic value) {
-  Expect.identical(dynamic, T);
+  Expect.equals(dynamic, T);
   return value;
 }
 
 T expectInt<T>(dynamic value) {
-  Expect.identical(int, T);
+  Expect.equals(int, T);
   return value;
 }
 
 T expectString<T>(dynamic value) {
-  Expect.identical(String, T);
+  Expect.equals(String, T);
   return value;
 }
 
 Iterable<T> expectIntIterable<T>(dynamic value) {
-  Expect.identical(int, T);
+  Expect.equals(int, T);
   return value;
 }
 
 Set<T> expectIntSet<T>() {
-  Expect.identical(int, T);
+  Expect.equals(int, T);
   return Set();
 }
 
 Stream<T> expectIntStream<T>(dynamic elements) {
-  Expect.identical(int, T);
+  Expect.equals(int, T);
   return Stream<T>.fromIterable(elements);
 }
 
 Set<T> expectDynamicSet<T>() {
-  Expect.identical(dynamic, T);
+  Expect.equals(dynamic, T);
   return Set();
 }
 
diff --git a/tests/language_2/emit_const_fields_test.dart b/tests/language_2/emit_const_fields_test.dart
index 1a3d7a5..8264c50 100644
--- a/tests/language_2/emit_const_fields_test.dart
+++ b/tests/language_2/emit_const_fields_test.dart
@@ -17,5 +17,5 @@
 
 main() {
   Expect.isTrue(42 == Guide.LTUAE);
-  Expect.isTrue("1978-03-08" == Guide.EARTH["Status"][1]);
+  Expect.isTrue("1978-03-08" == (Guide.EARTH["Status"] as List)[1]);
 }
diff --git a/tests/language_2/function_propagation_test.dart b/tests/language_2/function_propagation_test.dart
index 83e37d6..9c6f7e6 100644
--- a/tests/language_2/function_propagation_test.dart
+++ b/tests/language_2/function_propagation_test.dart
@@ -12,14 +12,12 @@
 
 main() {
   var a = new A();
-  Expect.isFalse(a is A);
-
-  var a2 = new A();
-  Expect.isFalse(a is F);
+  Expect.type<A>(a);
+  Expect.notType<F>(a);
 
   Function a3 = new A();
-  Expect.isFalse(a3 is A);
+  Expect.notType<A>(a3);
 
   F a4 = new A();
-  Expect.isFalse(a4 is A);
+  Expect.notType<A>(a4);
 }
diff --git a/tests/language_2/function_subtype_inline2_test.dart b/tests/language_2/function_subtype_inline2_test.dart
index 3a67be1..147bd4a 100644
--- a/tests/language_2/function_subtype_inline2_test.dart
+++ b/tests/language_2/function_subtype_inline2_test.dart
@@ -27,8 +27,8 @@
 
 int m1() => null;
 String m2() => null;
-m3() => null;
-m4(int i) => null;
+Null m3() => null;
+Null m4(int i) => null;
 
 main() {
   test((m) => new C.c1(m), 'c1');
diff --git a/tests/language_2/issue34147_test.dart b/tests/language_2/issue34147_test.dart
new file mode 100644
index 0000000..69ac743
--- /dev/null
+++ b/tests/language_2/issue34147_test.dart
@@ -0,0 +1,72 @@
+// 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 conditionalTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() => x ? 1 : 0);
+}
+
+void orTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() => x || x);
+  Expect.throwsAssertionError(() => x || false);
+  Expect.throwsAssertionError(() => x || true);
+  Expect.throwsAssertionError(() => false || x);
+  Expect.isTrue(true || x);
+}
+
+void andTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() => x && x);
+  Expect.throwsAssertionError(() => x && false);
+  Expect.throwsAssertionError(() => x && true);
+  Expect.isFalse(false && x);
+  Expect.throwsAssertionError(() => true && x);
+}
+
+void ifTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() {
+    if (x) {}
+  });
+}
+
+void forTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() {
+    for (; x;) {}
+  });
+}
+
+void whileTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() {
+    while (x) {}
+  });
+}
+
+void doTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() {
+    do {} while (x);
+  });
+}
+
+void notTest() {
+  bool x = null;
+  Expect.throwsAssertionError(() => !x);
+}
diff --git a/tests/language_2/language_2_analyzer.status b/tests/language_2/language_2_analyzer.status
index d7c1115..2a073ac 100644
--- a/tests/language_2/language_2_analyzer.status
+++ b/tests/language_2/language_2_analyzer.status
@@ -17,7 +17,6 @@
 const_cast2_test/none: CompileTimeError # failing-by-design: Not a const expression, see Issue #34334
 covariant_subtyping_with_mixin_test: CompileTimeError # Issue 34329
 dynamic_prefix_core_test/01: MissingCompileTimeError # failing-by-design: #34339
-emit_const_fields_test: CompileTimeError # failing-by-design: #34340
 enum_syntax_test/05: Fail # Issue 34341
 enum_syntax_test/06: Fail # Issue 34341
 f_bounded_quantification2_test: CompileTimeError # Issue 34583
diff --git a/tests/language_2/language_2_dart2js.status b/tests/language_2/language_2_dart2js.status
index 851a895..7f34dad 100644
--- a/tests/language_2/language_2_dart2js.status
+++ b/tests/language_2/language_2_dart2js.status
@@ -22,7 +22,6 @@
 config_import_test: RuntimeError # Test flag is not passed to the compiler.
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
 const_dynamic_type_literal_test/03: Pass # but it shouldn't until we fix issue 17207
-control_flow_collections/*: Skip
 deopt_inlined_function_lazy_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 deopt_smi_op_test: CompileTimeError, OK # Error if web int literal cannot be represented exactly, see http://dartbug.com/33351
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in dart2js; bug #11551.
@@ -68,6 +67,9 @@
 [ $compiler != dart2js ]
 minify_closure_variable_collision_test: SkipByDesign # Regression test for dart2js
 
+[ $builder_tag == dart2js_production && $compiler == dart2js ]
+control_flow_collections/for_non_bool_condition_test: Crash # Issue 36442
+
 [ $compiler == dart2js && $runtime == chrome ]
 field_override_optimization_test: RuntimeError
 
@@ -478,7 +480,6 @@
 deferred_redirecting_factory_test: RuntimeError
 double_int_to_string_test: RuntimeError, OK # non JS number semantics
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError
 enum_mirror_test: RuntimeError
 example_constructor_test: RuntimeError
 expect_test: RuntimeError, OK # Issue 13080
diff --git a/tests/language_2/language_2_dartdevc.status b/tests/language_2/language_2_dartdevc.status
index f6296b7..3047a9d 100644
--- a/tests/language_2/language_2_dartdevc.status
+++ b/tests/language_2/language_2_dartdevc.status
@@ -35,7 +35,6 @@
 deferred_load_library_wrong_args_test/01: MissingRuntimeError, RuntimeError # Issue 29920
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddc
 dynamic_prefix_core_test/01: MissingCompileTimeError
-emit_const_fields_test: CompileTimeError
 enum_syntax_test/05: MissingCompileTimeError
 enum_syntax_test/06: MissingCompileTimeError
 execute_finally6_test: RuntimeError # Issue 29920
@@ -175,12 +174,10 @@
 const_optional_args_test/01: MissingCompileTimeError
 const_syntax_test/05: MissingCompileTimeError
 constants_test/05: MissingCompileTimeError
-control_flow_collections/*: Skip
 covariant_subtyping_test: RuntimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
 double_identical_test: RuntimeError # Negative and positive zero are distinct, but not in ddk
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError # Issue 31533
 external_test/21: CompileTimeError
 external_test/24: CompileTimeError
 function_propagation_test: RuntimeError
diff --git a/tests/language_2/language_2_kernel.status b/tests/language_2/language_2_kernel.status
index 53267cd..96c638e 100644
--- a/tests/language_2/language_2_kernel.status
+++ b/tests/language_2/language_2_kernel.status
@@ -37,7 +37,6 @@
 const_nested_test: RuntimeError
 const_string_test: RuntimeError
 constructor12_test: RuntimeError
-control_flow_collections/*: Skip
 covariant_subtyping_test: RuntimeError
 ct_const_test: RuntimeError
 cyclic_type2_test: CompileTimeError
@@ -49,7 +48,6 @@
 deferred_redirecting_factory_test: RuntimeError
 deferred_static_seperate_test: RuntimeError
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError
 example_constructor_test: RuntimeError
 external_test/10: MissingRuntimeError
 external_test/13: MissingRuntimeError
@@ -124,12 +122,6 @@
 regress_29025_test: CompileTimeError
 regress_29405_test: CompileTimeError
 regress_30339_test: CompileTimeError
-spread_collections/await_test: CompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
 string_interpolation_and_buffer_test: RuntimeError
 super_bound_closure_test/none: CompileTimeError
 super_test: RuntimeError
@@ -146,32 +138,9 @@
 mixin_method_override_test/G5: Skip # Issue 34354
 private_method_tearoff_test: RuntimeError
 
-[ $compiler == dartk ]
-control_flow_collections/*: Skip
-
 [ $compiler == dartkp ]
-control_flow_collections/*: Skip
 covariant_subtyping_test: RuntimeError
 generic_no_such_method_dispatcher_test: RuntimeError # Issue 31424
-spread_collections/await_test: CompileTimeError
-spread_collections/const_error_test/02: MissingCompileTimeError
-spread_collections/const_error_test/03: MissingCompileTimeError
-spread_collections/const_error_test/05: MissingCompileTimeError
-spread_collections/const_error_test/06: MissingCompileTimeError
-spread_collections/const_error_test/07: MissingCompileTimeError
-spread_collections/const_error_test/08: MissingCompileTimeError
-spread_collections/const_error_test/10: MissingCompileTimeError
-spread_collections/const_error_test/11: MissingCompileTimeError
-spread_collections/const_error_test/12: MissingCompileTimeError
-spread_collections/const_error_test/13: MissingCompileTimeError
-spread_collections/const_error_test/14: MissingCompileTimeError
-spread_collections/const_error_test/15: MissingCompileTimeError
-spread_collections/const_error_test/16: MissingCompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
 web_int_literals_test/*: SkipByDesign # Test applies only to JavaScript targets
 
 [ $compiler == fasta ]
@@ -191,24 +160,6 @@
 const_constructor_nonconst_param_test/01: MissingCompileTimeError
 constructor5_test: CompileTimeError # Verification error
 constructor6_test: CompileTimeError # Verification error
-control_flow_collections/await_for_inference_test: CompileTimeError
-control_flow_collections/await_for_test: CompileTimeError
-control_flow_collections/if_const_error_test/21: MissingCompileTimeError
-control_flow_collections/if_const_error_test/22: MissingCompileTimeError
-control_flow_collections/if_const_error_test/23: MissingCompileTimeError
-control_flow_collections/if_const_error_test/24: MissingCompileTimeError
-control_flow_collections/if_const_error_test/35: MissingCompileTimeError
-control_flow_collections/if_const_error_test/36: MissingCompileTimeError
-control_flow_collections/if_const_error_test/37: MissingCompileTimeError
-control_flow_collections/if_promotion_test/none: CompileTimeError
-control_flow_collections/type_error_test/00: MissingCompileTimeError
-control_flow_collections/type_error_test/01: MissingCompileTimeError
-control_flow_collections/type_error_test/02: MissingCompileTimeError
-control_flow_collections/type_error_test/10: MissingCompileTimeError
-control_flow_collections/type_error_test/13: MissingCompileTimeError
-control_flow_collections/type_error_test/23: MissingCompileTimeError
-control_flow_collections/type_error_test/24: MissingCompileTimeError
-control_flow_collections/type_error_test/25: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e1: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e10: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e11: MissingCompileTimeError
@@ -230,10 +181,6 @@
 implicit_creation/implicit_const_not_default_values_test/e7: MissingCompileTimeError
 implicit_creation/implicit_const_not_default_values_test/e8: MissingCompileTimeError
 mixin_method_override_test/G4: Crash # Assertion error: mixin_full_resolution.dart': 'src.typeParameters.length == dst.typeParameters.length': is not true.
-spread_collections/const_error_test/12: MissingCompileTimeError
-spread_collections/const_error_test/13: Crash
-spread_collections/const_error_test/13: MissingCompileTimeError
-spread_collections/const_error_test/14: MissingCompileTimeError
 vm/regress_33469_test/01: MissingCompileTimeError
 vm/regress_33469_test/02: MissingCompileTimeError
 vm/regress_33469_test/03: MissingCompileTimeError
@@ -247,10 +194,6 @@
 async_return_types_test/nestedFuture: MissingCompileTimeError # Issue 33068
 const_cast2_test/01: CompileTimeError # Issue 32517
 const_cast2_test/none: CompileTimeError # Issue 32517
-constants_2018/equals_test/01: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
-constants_2018/equals_test/02: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
-constants_2018/equals_test/03: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
-constants_2018/equals_test/04: MissingCompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
 constants_2018/potential_const_dynamic_test/sh3: CompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
 constants_2018/potential_const_type_test/sh3: CompileTimeError # New test introduced in https://dart-review.googlesource.com/c/sdk/+/97510
 deferred_inheritance_constraints_test/extends: MissingCompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
@@ -447,22 +390,6 @@
 vm/debug_break_enabled_vm_test/none: CompileTimeError # KernelVM bug: Bad test using extended break syntax.
 vm/regress_27201_test: CompileTimeError # Fasta/KernelVM bug: Deferred loading kernel issue 30273.
 
-[ $arch != simarm && $arch != simarm64 && $arch != simdbc64 && $compiler == dartk ]
-spread_collections/await_test: CompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
-
-[ $arch == simdbc64 && $compiler == dartk ]
-spread_collections/await_test: CompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
-
 [ $builder_tag == obfuscated && $compiler == dartkp ]
 generic_function_dcall_test/01: SkipByDesign # Prints type names
 invocation_mirror_test: RuntimeError # Issue 34911
@@ -555,33 +482,14 @@
 assertion_initializer_const_error2_test/cc09: MissingCompileTimeError # Not reporting failed assert() at compile time.
 assertion_initializer_const_error2_test/cc10: MissingCompileTimeError # Not reporting failed assert() at compile time.
 
-[ $compiler == dartk && ($arch == simarm || $arch == simarm64) ]
-spread_collections/await_test: CompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
-
 [ $compiler == dartkb && $runtime == vm && $strong ]
 async_star_test/03: Pass, RuntimeError # Please triage
 async_star_test/04: Pass, RuntimeError # Please triage
 compile_time_constant_o_test/01: Pass
 compile_time_constant_o_test/02: Pass
 const_dynamic_type_literal_test/02: Pass
-control_flow_collections/*: Skip
 map_literal3_test/01: Pass
 map_literal3_test/02: Pass
-spread_collections/await_test: CompileTimeError
-spread_collections/const_test: CompileTimeError
-spread_collections/inference_test: CompileTimeError
-spread_collections/map_set_ambiguity_test: CompileTimeError
-spread_collections/spread_test: CompileTimeError
-spread_collections/syntax_test: CompileTimeError
-spread_collections/type_error_test/00: DartkCrash
-spread_collections/type_error_test/02: DartkCrash
-spread_collections/type_error_test/03: DartkCrash
-spread_collections/type_error_test/05: DartkCrash
 vm/bool_check_stack_traces_test/02: Pass
 vm/causal_async_exception_stack2_test: RuntimeError # Please triage
 vm/causal_async_exception_stack_test: RuntimeError # Please triage
@@ -744,7 +652,6 @@
 deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
 deopt_inlined_function_lazy_test: Skip # Incompatible flag: --deoptimize-alot
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError # Issue 31533
 enum_mirror_test: SkipByDesign
 example_constructor_test: Fail, OK
 export_ambiguous_main_test: Skip # Issue 29895 Fail Issue 14763
@@ -901,7 +808,6 @@
 constants_test/05: MissingCompileTimeError
 deferred_load_library_wrong_args_test/01: CompileTimeError
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError
 external_test/21: CompileTimeError
 external_test/24: CompileTimeError
 generic_no_such_method_dispatcher_simple_test: CompileTimeError
@@ -1291,7 +1197,6 @@
 deferred_static_seperate_test: RuntimeError # KernelVM bug: Deferred loading kernel issue 30273.
 disassemble_test: Pass, Slow, Crash # dartbug.com/34971
 dynamic_prefix_core_test/none: CompileTimeError
-emit_const_fields_test: CompileTimeError # Issue 31533
 example_constructor_test: Fail, OK
 external_test/10: MissingRuntimeError # KernelVM bug: Unbound external.
 external_test/13: MissingRuntimeError # KernelVM bug: Unbound external.
diff --git a/tests/language_2/super_test.dart b/tests/language_2/super_test.dart
index 7394989..f96f4fe 100644
--- a/tests/language_2/super_test.dart
+++ b/tests/language_2/super_test.dart
@@ -17,10 +17,10 @@
   Expect.equals(3, sub.u);
 
   sub = new Sub.stat();
-  Expect.equals(0, sub.x);
-  Expect.equals(1, sub.y);
-  Expect.equals(2, sub.v);
-  Expect.equals(3, sub.w);
+  Expect.equals(2, sub.x);
+  Expect.equals(3, sub.y);
+  Expect.equals(0, sub.v);
+  Expect.equals(1, sub.w);
   Expect.equals(4, sub.z);
   Expect.equals(5, sub.u);
 }
diff --git a/tests/language_2/unevaluated_field.dart b/tests/language_2/unevaluated_field.dart
new file mode 100644
index 0000000..d674af5
--- /dev/null
+++ b/tests/language_2/unevaluated_field.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.
+
+// SharedOptions=--enable-experiment=constant-update-2018
+
+// Test that environment constants in field initializers work properly.
+
+import "package:expect/expect.dart";
+
+const int gx = const int.fromEnvironment("x");
+
+class A {
+  final int x = gx;
+  final int y = const int.fromEnvironment("y");
+  const A();
+}
+
+main() {
+  const a = const A();
+  Expect.isTrue(a.x == null || a.x != null);
+  Expect.isTrue(a.y == null || a.y != null);
+}
diff --git a/tests/lib_2/lib_2_kernel.status b/tests/lib_2/lib_2_kernel.status
index a709997..04313d4 100644
--- a/tests/lib_2/lib_2_kernel.status
+++ b/tests/lib_2/lib_2_kernel.status
@@ -16,6 +16,9 @@
 async/timer_not_available_test: RuntimeError
 isolate/ping_pause_test: Skip # Timeout
 
+[ $compiler == dartkb ]
+mirrors/*: Skip # Mirrors are not yet supported in bytecode modes.
+
 [ $compiler == fasta ]
 html/*: Skip # TODO(ahe): Make dart:html available.
 isolate/browser/*: Skip # TODO(ahe): Make dart:html available.
diff --git a/tests/standalone_2/io/secure_socket_renegotiate_test.dart b/tests/standalone_2/io/secure_socket_renegotiate_test.dart
index e527da9..d10e743 100644
--- a/tests/standalone_2/io/secure_socket_renegotiate_test.dart
+++ b/tests/standalone_2/io/secure_socket_renegotiate_test.dart
@@ -4,6 +4,7 @@
 //
 // OtherResources=certificates/server_chain.pem
 // OtherResources=certificates/server_key.pem
+// OtherResources=secure_socket_renegotiate_client.dart
 
 // This test verifies that client certificates work, if the client and server
 // are in separate processes, and that connection renegotiation works, and
@@ -66,10 +67,10 @@
 void main() {
   runServer().then((SecureServerSocket server) {
     var clientScript =
-        Platform.script.toFilePath().replaceFirst("_test.dart", "_client.dart");
-    Expect.isTrue(clientScript.endsWith("_client.dart"));
+        Platform.script.resolve('secure_socket_renegotiate_client.dart').toFilePath();
     Process
-        .run(Platform.executable, [clientScript, server.port.toString()]).then(
+        .run(Platform.executable,
+        []..addAll(Platform.executableArguments)..addAll([clientScript, server.port.toString()])).then(
             (ProcessResult result) {
       if (result.exitCode != 0) {
         print("Client failed, stdout:");
diff --git a/tests/standalone_2/standalone_2.status b/tests/standalone_2/standalone_2.status
index cf60651..74d303c 100644
--- a/tests/standalone_2/standalone_2.status
+++ b/tests/standalone_2/standalone_2.status
@@ -86,7 +86,7 @@
 no_assert_test: Fail, OK # This is testing a vm flag.
 
 [ $mode == product && $runtime == dart_precompiled ]
-dwarf_stack_trace_test: Pass, RuntimeError
+dwarf_stack_trace_test: SkipByDesign # Due to instruction canonicalization we can end up having the wrong names in stack traces.
 
 [ $mode == release && $runtime == vm && $system == macos ]
 io/named_pipe_script_test: Pass, RuntimeError # Issue 28737
diff --git a/third_party/.gitignore b/third_party/.gitignore
index 836a11d..28a6f8a 100644
--- a/third_party/.gitignore
+++ b/third_party/.gitignore
@@ -12,6 +12,5 @@
 !clang.tar.gz.sha1
 !unittest.tar.gz.sha1
 !update.sh
-!/googletest
 # but ignore a subfolder of tcmalloc (some client ignores /tcmalloc/.gitignore)
 /tcmalloc/gperftools
diff --git a/tools/FAKE_COMMITS b/tools/FAKE_COMMITS
index c11b0c2..32518f9 100644
--- a/tools/FAKE_COMMITS
+++ b/tools/FAKE_COMMITS
@@ -28,3 +28,4 @@
 Analyzer branch commits:
 Force build on new analyzer-branch linux build with new workflow
 Trigger bots
+Switch benchmark builders to Ubuntu 16.04
diff --git a/tools/VERSION b/tools/VERSION
index 83fcfb8..d0461b8 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -33,7 +33,7 @@
 MAJOR 2
 MINOR 2
 PATCH 1
-PRERELEASE 3
-PRERELEASE_PATCH 1
-ABI_VERSION 1
-OLDEST_SUPPORTED_ABI_VERSION 0
+PRERELEASE 4
+PRERELEASE_PATCH 0
+ABI_VERSION 2
+OLDEST_SUPPORTED_ABI_VERSION 1
diff --git a/tools/addlatexhash.dart b/tools/addlatexhash.dart
index 21f8d52..c1cbddc 100755
--- a/tools/addlatexhash.dart
+++ b/tools/addlatexhash.dart
@@ -22,11 +22,11 @@
 // NB: This utility assumes UN*X style line endings, \n, in the LaTeX
 // source file received as input; it will not work with other styles.
 
+import 'dart:convert';
 import 'dart:io';
 
-import 'package:crypto/crypto.dart';
 import 'package:convert/convert.dart';
-import 'package:utf/utf.dart';
+import 'package:crypto/crypto.dart';
 
 // ----------------------------------------------------------------------
 // Normalization of the text: removal or normalization of parts that
@@ -491,7 +491,7 @@
   final gatheredLine = gatherLines(lines, startIndex, nextIndex);
   final simplifiedLine = simplifyLine(gatheredLine);
   listSink.write("  % $simplifiedLine\n");
-  var digest = sha1.convert(encodeUtf8(simplifiedLine));
+  var digest = sha1.convert(utf8.encode(simplifiedLine));
   return digest.bytes;
 }
 
diff --git a/tools/bots/dart_sdk.py b/tools/bots/dart_sdk.py
index f9688a9..301f269 100755
--- a/tools/bots/dart_sdk.py
+++ b/tools/bots/dart_sdk.py
@@ -66,10 +66,19 @@
       sdk_path = os.path.join(bot_utils.DART_DIR,
                               utils.GetBuildRoot(BUILD_OS, 'release', arch),
                               'dart-sdk')
+      product_sdk_path = os.path.join(bot_utils.DART_DIR,
+                              utils.GetBuildRoot(BUILD_OS, 'product', arch),
+                              'dart-sdk')
       sdk_zip = os.path.join(bot_utils.DART_DIR,
                              utils.GetBuildRoot(BUILD_OS, 'release', arch),
                              'dartsdk-%s-%s.zip' % (BUILD_OS, arch))
       FileDelete(sdk_zip)
+      # We don't support precompilation on ia32.
+      if arch != 'ia32':
+        # Patch in all the PRODUCT built AOT binaries.
+        CopyBetween(product_sdk_path, sdk_path, 'bin', 'utils', GuessExtension('gen_snapshot'))
+        CopyBetween(product_sdk_path, sdk_path, 'bin', GuessExtension('dartaotruntime'))
+      # Zip it up.
       CreateZip(sdk_path, sdk_zip)
       DartArchiveUploadSDKs(BUILD_OS, arch, sdk_zip)
 
@@ -186,6 +195,21 @@
   if os.path.exists(f):
     os.remove(f)
 
+def CopyBetween(src_path, dst_path, *relatives):
+  try:
+    os.makedirs(os.path.join(dst_path, *relatives[:-1]))
+  except OSError:
+    # This is fine.
+    pass
+  shutil.copy2(
+      os.path.join(src_path, *relatives),
+      os.path.join(dst_path, *relatives[:-1]))
+
+def GuessExtension(binary):
+  if 'win' in BUILD_OS:
+    return binary + '.exe'
+  return binary
+
 def DartArchiveFile(local_path, remote_path, checksum_files=False):
   gsutil = bot_utils.GSUtil()
   gsutil.upload(local_path, remote_path, public=True)
diff --git a/tools/bots/test_matrix.json b/tools/bots/test_matrix.json
index 16e0f7d..78e10bc 100644
--- a/tools/bots/test_matrix.json
+++ b/tools/bots/test_matrix.json
@@ -266,6 +266,7 @@
     }},
     "dart2js-production-(linux|mac|win)-d8": {
       "options": {
+        "builder-tag": "dart2js_production",
         "use-sdk": true,
         "dart2js-options": ["-O3"]
     }},
@@ -323,7 +324,7 @@
     "dartk-optcounter-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {
       "options": {
         "builder-tag": "optimization_counter_threshold",
-        "vm-options": ["--optimization-counter-threshold=5"]
+        "vm-options": ["--optimization-counter-threshold=5", "--random-seed=__RANDOM__"]
     }},
     "dartk-reload-(linux|mac|win)-(debug|product|release)-(ia32|x64)": {
       "options": {
@@ -441,12 +442,7 @@
         {
           "name": "vm mixed mode tests",
           "arguments": [
-            "-ndartkb-mixed-linux-${mode}-${arch}",
-            "language_2",
-            "corelib_2",
-            "lib_2",
-            "standalone_2",
-            "ffi"
+            "-ndartkb-mixed-linux-${mode}-${arch}"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -454,12 +450,7 @@
         {
           "name": "vm bytecode compiler tests",
           "arguments": [
-            "-ndartkb-compile-linux-${mode}-${arch}",
-            "language_2",
-            "corelib_2",
-            "lib_2",
-            "standalone_2",
-            "ffi"
+            "-ndartkb-compile-linux-${mode}-${arch}"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -467,12 +458,7 @@
         {
           "name": "vm interpreter tests",
           "arguments": [
-            "-ndartkb-interpret-linux-${mode}-${arch}",
-            "language_2",
-            "corelib_2",
-            "lib_2",
-            "standalone_2",
-            "ffi"
+            "-ndartkb-interpret-linux-${mode}-${arch}"
           ],
           "fileset": "vm-kernel",
           "shards": 10
@@ -1328,6 +1314,18 @@
                         "--mode=release", "create_sdk"]
         },
         {
+          "name": "build gen_kernel.dart.snapshot and dart2aot",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64,arm,arm64", "--mode=release",
+                        "copy_gen_kernel_snapshot", "copy_dart2aot"]
+        },
+        {
+          "name": "build gen_snapshot and dartaotruntime",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64,arm,arm64", "--mode=product",
+                        "copy_gen_snapshot", "copy_dartaotruntime"]
+        },
+        {
           "name": "upload sdk",
           "script": "tools/bots/dart_sdk.py"
         },
@@ -1360,6 +1358,18 @@
                         "--mode=release", "create_sdk"]
         },
         {
+          "name": "build gen_kernel.dart.snapshot and dart2aot",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64", "--mode=release",
+                        "copy_gen_kernel_snapshot", "copy_dart2aot"]
+        },
+        {
+          "name": "build gen_snapshot and dartaotruntime",
+          "script": "tools/build.py",
+          "arguments": ["--arch=x64", "--mode=product",
+                        "copy_gen_snapshot", "copy_dartaotruntime"]
+        },
+        {
           "name": "upload sdk",
           "script": "tools/bots/dart_sdk.py"
         }
@@ -1714,14 +1724,23 @@
           "arguments": ["noop"]
         },
         {
-          "name": "remove out directory to do a clean build",
+          "name": "remove out directory to do a clean linux-ia32 build",
           "script": "tools/bots/try_benchmarks.sh",
           "arguments": ["clean"]
         },
         {
           "name": "build linux-ia32 for benchmarking",
+          "script": "tools/build.py",
+          "arguments": [
+            "--mode=release",
+            "--arch=ia32",
+            "create_sdk",
+            "runtime"]
+        },
+        {
+          "name": "archive linux-ia32 for benchmarking",
           "script": "tools/bots/try_benchmarks.sh",
-          "arguments": ["linux-ia32-build"]
+          "arguments": ["linux-ia32-archive"]
         },
         {
           "name": "try linux-ia32 benchmarking",
@@ -1729,14 +1748,69 @@
           "arguments": ["linux-ia32-benchmark"]
         },
         {
-          "name": "build linux-x64 for benchmarking",
+          "name": "remove out directory to do a clean linux-x64 build",
           "script": "tools/bots/try_benchmarks.sh",
-          "arguments": ["linux-x64-build"]
+          "arguments": ["clean"]
+        },
+        {
+          "name": "build linux-x64 for benchmarking",
+          "script": "tools/build.py",
+          "arguments": [
+            "--mode=release",
+            "--arch=x64",
+            "create_sdk",
+            "runtime",
+            "gen_snapshot",
+            "dart_precompiled_runtime"]
+        },
+        {
+          "name": "build linux-x64 simdbc for benchmarking",
+          "script": "tools/build.py",
+          "arguments": ["--mode=release", "--arch=simdbc64", "runtime"]
+        },
+        {
+          "name": "archive linux-x64 for benchmarking",
+          "script": "tools/bots/try_benchmarks.sh",
+          "arguments": ["linux-x64-archive"]
         },
         {
           "name": "try linux-x64 benchmarking",
           "script": "tools/bots/try_benchmarks.sh",
           "arguments": ["linux-x64-benchmark"]
+        },
+        {
+          "name": "remove out directory to do a clean linux-x64-bytecode build",
+          "script": "tools/bots/try_benchmarks.sh",
+          "arguments": ["clean"]
+        },
+        {
+          "name": "generate ninja for linux-x64-bytecode",
+          "script": "tools/gn.py",
+          "arguments": [
+            "--mode=release",
+            "--arch=x64",
+            "--bytecode"]
+        },
+        {
+          "name": "build linux-x64-bytecode for benchmarking",
+          "script": "tools/build.py",
+          "arguments": [
+            "--mode=release",
+            "--arch=x64",
+            "create_sdk",
+            "runtime",
+            "gen_snapshot",
+            "dart_precompiled_runtime"]
+        },
+        {
+          "name": "archive linux-x64-bytecode for benchmarking",
+          "script": "tools/bots/try_benchmarks.sh",
+          "arguments": ["linux-x64-bytecode-archive"]
+        },
+        {
+          "name": "try linux-x64-bytecode benchmarking",
+          "script": "tools/bots/try_benchmarks.sh",
+          "arguments": ["linux-x64-bytecode-benchmark"]
         }
       ]
     },
diff --git a/tools/bots/try_benchmarks.sh b/tools/bots/try_benchmarks.sh
index 5f0aa28..a501a0d 100755
--- a/tools/bots/try_benchmarks.sh
+++ b/tools/bots/try_benchmarks.sh
@@ -13,16 +13,23 @@
 owner=sortie
 
 if [ $# -lt 1 ]; then
-  echo "Usage: $0 COMMAND ..."
-  echo
-  echo "Where COMMAND is one of:"
-  echo
-  echo "    noop - Just print description."
-  echo "    clean - Remove out/ directory."
-  echo "    linux-ia32-build - Build linux-ia32 for benchmarking."
-  echo "    linux-ia32-benchmark - Try linux-ia32 benchmarking."
-  echo "    linux-x64-build - Build linux-x64 for benchmarking."
-  echo "    linux-x64-benchmark - Try linux-x64 benchmarking."
+cat << EOF
+Usage: $0 COMMAND ..."
+
+Where COMMAND is one of:"
+
+    noop - Just print description.
+    clean - Remove out/ directory.
+    linux-ia32-build - Build linux-ia32 for benchmarking.
+    linux-ia32-archive - Archive linux-ia32.
+    linux-ia32-benchmark - Try linux-ia32 benchmarking.
+    linux-x64-build - Build linux-x64 for benchmarking.
+    linux-x64-archive - Archive linux-x64.
+    linux-x64-benchmark - Try linux-x64 benchmarking.
+    linux-x64-bytecode-build - Build linux-x64 with bytecode for benchmarking.
+    linux-x64-bytecode-archive - Archive linux-x64 with bytecode.
+    linux-x64-bytecode-benchmark - Try linux-x64 with bytecode benchmarking.
+EOF
   exit 1
 fi
 
@@ -64,13 +71,16 @@
     :
   elif [ "$command" = clean ]; then
     rm -rf out
+    rm -rf tmp
     rm -f linux-ia32.tar.gz
     rm -f linux-ia32_profile.tar.gz
     rm -f linux-x64.tar.gz
     rm -f linux-x64_profile.tar.gz
   elif [ "$command" = linux-ia32-build ]; then
+    # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync.
     ./tools/build.py --mode=release --arch=ia32 create_sdk
     ./tools/build.py --mode=release --arch=ia32 runtime
+  elif [ "$command" = linux-ia32-archive ]; then
     tar -czf linux-ia32_profile.tar.gz \
       --exclude .git \
       --exclude .gitignore \
@@ -208,12 +218,24 @@
     out/ReleaseIA32/run_vm_tests GenKernelKernelLoadKernel
     cd ..
     rm -rf tmp
-  elif [ "$command" = linux-x64-build ]; then
+  elif [ "$command" = linux-x64-build ] ||
+       [ "$command" = linux-x64-bytecode-build ]; then
+    # NOTE: These are duplicated in tools/bots/test_matrix.json, keep in sync.
+    if [ "$command" = linux-x64-bytecode-build ]; then
+      # Beware: Don't mix --bytecode with a non-bytecode out/.
+      ./tools/gn.py --mode=release --arch=x64 --bytecode
+    fi
     ./tools/build.py --mode=release --arch=x64 create_sdk
     ./tools/build.py --mode=release --arch=x64 runtime
     ./tools/build.py --mode=release --arch=x64 gen_snapshot
     ./tools/build.py --mode=release --arch=x64 dart_precompiled_runtime
     ./tools/build.py --mode=release --arch=simdbc64 runtime
+  elif [ "$command" = linux-x64-archive ] ||
+       [ "$command" = linux-x64-bytecode-archive ]; then
+    simdbc_dart=out/ReleaseSIMDBC64/dart
+    if [ "$command" = linux-x64-bytecode-archive ]; then
+      simdbc_dart=
+    fi
     tar -czf linux-x64_profile.tar.gz \
       --exclude .git \
       --exclude .gitignore \
@@ -223,7 +245,7 @@
       out/ReleaseX64/vm_outline_strong.dill \
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/dart-sdk \
-      out/ReleaseSIMDBC64/dart \
+      $simdbc_dart \
       out/ReleaseX64/dart \
       out/ReleaseX64/gen_snapshot \
       out/ReleaseX64/gen_kernel_bytecode.dill \
@@ -324,7 +346,7 @@
       out/ReleaseX64/vm_outline_strong.dill \
       out/ReleaseX64/vm_platform_strong.dill \
       out/ReleaseX64/dart-sdk \
-      out/ReleaseSIMDBC64/dart \
+      $simdbc_dart \
       out/ReleaseX64/dart \
       out/ReleaseX64/gen_snapshot \
       out/ReleaseX64/gen_kernel_bytecode.dill \
@@ -340,7 +362,8 @@
       runtime/bin \
       runtime/lib \
       || (rm -f linux-x64.tar.gz; exit 1)
-  elif [ "$command" = linux-x64-benchmark ]; then
+  elif [ "$command" = linux-x64-benchmark ] ||
+       [ "$command" = linux-x64-bytecode-benchmark ]; then
     rm -rf tmp
     mkdir tmp
     cd tmp
@@ -358,7 +381,9 @@
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --enable-interpreter --compilation-counter-threshold=-1 hello.dart
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler hello.dart
     out/ReleaseX64/dart --profile-period=10000 --packages=.packages --use-bytecode-compiler --optimization-counter-threshold=-1 hello.dart
-    out/ReleaseSIMDBC64/dart --profile-period=10000 --packages=.packages hello.dart
+    if [ "$command" = linux-x64-benchmark ]; then
+      out/ReleaseSIMDBC64/dart --profile-period=10000 --packages=.packages hello.dart
+    fi
     out/ReleaseX64/dart pkg/front_end/tool/perf.dart parse hello.dart
     out/ReleaseX64/dart pkg/front_end/tool/perf.dart scan hello.dart
     out/ReleaseX64/dart pkg/front_end/tool/fasta_perf.dart --legacy kernel_gen_e2e hello.dart
diff --git a/tools/download_abi_dills.py b/tools/download_abi_dills.py
index fb77a55..6eaa9e6 100644
--- a/tools/download_abi_dills.py
+++ b/tools/download_abi_dills.py
@@ -6,22 +6,50 @@
 import utils
 
 
-def main():
-  abi_version = int(utils.GetAbiVersion())
-  oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
+def procWait(p):
+  while p.returncode is None:
+    p.communicate()
+    p.poll()
+  return p.returncode
+
+
+def findAbiVersion(version):
+  cmd = ['cipd', 'instances', 'dart/abiversions/%d' % version]
+  p = subprocess.Popen(cmd,
+                       stdout = subprocess.PIPE,
+                       stderr = subprocess.PIPE,
+                       shell = utils.IsWindows(),
+                       cwd = utils.DART_DIR)
+  return procWait(p) == 0
+
+
+def downloadAbiDills(oldest_abi_version, abi_version):
   cmd = ['cipd', 'ensure', '-root', 'tools/abiversions', '-ensure-file', '-']
   ensure_file = ''
-  for i in xrange(oldest_abi_version, abi_version):
+  for i in xrange(oldest_abi_version, abi_version + 1):
     ensure_file += '@Subdir %d\ndart/abiversions/%d latest\n\n' % (i, i)
   if not ensure_file:
     return 0
   p = subprocess.Popen(cmd,
                        stdin = subprocess.PIPE,
+                       stdout = subprocess.PIPE,
+                       stderr = subprocess.PIPE,
                        shell = utils.IsWindows(),
                        cwd = utils.DART_DIR)
   p.communicate(ensure_file)
   p.stdin.close()
-  return p.wait()
+  return procWait(p)
+
+
+def main():
+  abi_version = int(utils.GetAbiVersion())
+  oldest_abi_version = int(utils.GetOldestSupportedAbiVersion())
+
+  # The latest abi version may not have an entry in CIPD yet, so check first.
+  if not findAbiVersion(abi_version):
+    abi_version -= 1
+
+  return downloadAbiDills(oldest_abi_version, abi_version)
 
 
 if __name__ == '__main__':
diff --git a/tools/gn.py b/tools/gn.py
index bc05a61..fbd1814 100755
--- a/tools/gn.py
+++ b/tools/gn.py
@@ -245,6 +245,8 @@
   if not args.platform_sdk and not gn_args['target_cpu'].startswith('arm'):
     gn_args['dart_platform_sdk'] = args.platform_sdk
   gn_args['dart_stripped_binary'] = 'exe.stripped/dart'
+  gn_args['dartaotruntime_stripped_binary'] = 'exe.stripped/dartaotruntime'
+  gn_args['gen_snapshot_stripped_binary'] = 'exe.stripped/gen_snapshot'
 
   # Setup the user-defined sysroot.
   if UseSysroot(args, gn_args):
diff --git a/tools/infra/config/OWNERS b/tools/infra/config/OWNERS
deleted file mode 100644
index 90c8c15..0000000
--- a/tools/infra/config/OWNERS
+++ /dev/null
@@ -1,6 +0,0 @@
-agable@google.com
-athom@google.com
-iannucci@google.com
-kustermann@google.com
-tandrii@google.com
-whesse@google.com
diff --git a/tools/infra/config/README.md b/tools/infra/config/README.md
deleted file mode 100644
index a46a2e7..0000000
--- a/tools/infra/config/README.md
+++ /dev/null
@@ -1 +0,0 @@
-This directory contains configuration files for chrome infrastructure services.
diff --git a/tools/infra/config/cq.cfg b/tools/infra/config/cq.cfg
deleted file mode 100644
index dd1680c..0000000
--- a/tools/infra/config/cq.cfg
+++ /dev/null
@@ -1,42 +0,0 @@
-# See http://luci-config.appspot.com/schemas/projects/refs:cq.cfg for the
-# documentation of this file format.
-version: 1
-cq_status_url: "https://chromium-cq-status.appspot.com"
-git_repo_url: "https://dart.googlesource.com/sdk.git"
-max_commit_burst: 2
-gerrit {}
-verifiers {
-  gerrit_cq_ability {
-     committer_list: "project-dart-committers"
-     dry_run_access_list: "project-dart-tryjob-access"
-     allow_submit_with_open_deps: true
-  }
-  tree_status {
-    tree_status_url: "https://dart-status.appspot.com"
-  }
-  try_job {
-    buckets {
-      name: "luci.dart.try"
-      builders { name: "analyzer-analysis-server-linux-try" }
-      builders { name: "analyzer-linux-release-try" }
-      builders { name: "benchmark-linux-try" }
-      builders { name: "dart-sdk-windows-try" }
-      builders { name: "dart2js-strong-linux-x64-chrome-try" }
-      builders { name: "dart2js-minified-strong-linux-x64-d8-try" }
-      builders { name: "dart2js-strong-hostasserts-linux-ia32-d8-try" }
-      builders { name: "dart2js-unit-linux-x64-release-try" }
-      builders { name: "ddc-linux-release-chrome-try" }
-      builders { name: "front-end-linux-release-x64-try" }
-      builders { name: "gclient-try" }
-      builders { name: "pkg-linux-release-try" }
-      builders { name: "vm-canary-linux-debug-try" }
-      builders { name: "vm-kernel-linux-release-simdbc64-try" }
-      builders { name: "vm-kernel-linux-release-x64-try" }
-      builders { name: "vm-kernel-mac-release-x64-try" experiment_percentage: 5 }
-      builders { name: "vm-kernel-linux-product-x64-try" }
-    }
-    try_job_retry_config {
-      try_job_retry_quota: 0
-    }
-  }
-}
diff --git a/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch b/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch
deleted file mode 100644
index 9d4241f..0000000
--- a/tools/patches/flutter-engine/75b2f9f919e5728902aff39a09223d1cc9402585.patch
+++ /dev/null
@@ -1,28 +0,0 @@
-diff --git a/BUILD.gn b/BUILD.gn
-index 2766d1b98..828196f8d 100644
---- a/BUILD.gn
-+++ b/BUILD.gn
-@@ -60,8 +60,8 @@ group("flutter") {
- 
-     if (is_linux) {
-       public_deps += [
--        "$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper_unittests",
--        "$flutter_root/shell/platform/glfw/client_wrapper:client_wrapper_glfw_unittests",
-+#        "$flutter_root/shell/platform/common/cpp/client_wrapper:client_wrapper_unittests",
-+#        "$flutter_root/shell/platform/glfw/client_wrapper:client_wrapper_glfw_unittests",
-       ]
-     }
-   }
-diff --git a/shell/platform/BUILD.gn b/shell/platform/BUILD.gn
-index c3bd7569c..30abe167a 100644
---- a/shell/platform/BUILD.gn
-+++ b/shell/platform/BUILD.gn
-@@ -13,7 +13,7 @@ group("platform") {
-     ]
-   } else if (is_linux) {
-     deps = [
--      "linux",
-+#      "linux",
-     ]
-   } else if (is_win) {
-     deps = [
diff --git a/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch b/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch
new file mode 100644
index 0000000..5e81c49
--- /dev/null
+++ b/tools/patches/flutter-engine/cc63d6e647df1cfd34a54adb63aba7f937ce6f6b.patch
@@ -0,0 +1,31 @@
+diff --git a/DEPS b/DEPS
+index d7973695e..1113c3101 100644
+--- a/DEPS
++++ b/DEPS
+@@ -52,7 +52,7 @@ vars = {
+   'dart_dartdoc_tag': 'v0.28.2',
+   'dart_fixnum_tag': '0.10.9',
+   'dart_glob_tag': '1.1.7',
+-  'dart_html_tag': '0.13.4+1',
++  'dart_html_tag': '0.14.0',
+   'dart_http_multi_server_tag': '2.0.5',
+   'dart_http_parser_tag': '3.1.3',
+   'dart_http_retry_tag': '0.1.1',
+@@ -94,7 +94,6 @@ vars = {
+   'dart_test_tag': '1.3.4',
+   'dart_typed_data_tag': '1.1.6',
+   'dart_usage_tag': '3.4.0',
+-  'dart_utf_tag': '0.9.0+5',
+   'dart_watcher_rev': '0.9.7+12',
+   'dart_web_socket_channel_tag': '1.0.9',
+   'dart_yaml_tag': '2.1.15',
+@@ -341,9 +340,6 @@ deps = {
+   'src/third_party/dart/third_party/pkg/test':
+    Var('dart_git') + '/test.git' + '@' + Var('dart_test_tag'),
+ 
+-  'src/third_party/dart/third_party/pkg/utf':
+-   Var('dart_git') + '/utf.git' + '@' + Var('dart_utf_tag'),
+-
+   'src/third_party/dart/third_party/pkg/usage':
+    Var('dart_git') + '/usage.git' + '@' + Var('dart_usage_tag'),
+ 
diff --git a/tools/testing/dart/compiler_configuration.dart b/tools/testing/dart/compiler_configuration.dart
index 852f8e7..6f6c394 100644
--- a/tools/testing/dart/compiler_configuration.dart
+++ b/tools/testing/dart/compiler_configuration.dart
@@ -109,7 +109,14 @@
   CompilerConfiguration._subclass(this._configuration);
 
   /// A multiplier used to give tests longer time to run.
-  int get timeoutMultiplier => 1;
+  int get timeoutMultiplier {
+    if (_configuration.configuration.vmOptions
+        .any((s) => s.contains("optimization-counter-threshold"))) {
+      return 2;
+    } else {
+      return 1;
+    }
+  }
 
   // TODO(ahe): It shouldn't be necessary to pass [buildDir] to any of these
   // functions. It is fixed for a given configuration.
diff --git a/tools/testing/dart/test_suite.dart b/tools/testing/dart/test_suite.dart
index db2ceb1..b3ad21d 100644
--- a/tools/testing/dart/test_suite.dart
+++ b/tools/testing/dart/test_suite.dart
@@ -14,6 +14,7 @@
  */
 import 'dart:async';
 import 'dart:io';
+import 'dart:math';
 
 import "package:status_file/expectation.dart";
 
@@ -468,9 +469,10 @@
 
     var args = configuration.standardOptions.toList();
     if (configuration.compilerConfiguration.previewDart2) {
-      final dfePath = new Path("$buildDir/gen/kernel-service.dart.snapshot")
-          .absolute
-          .toNativePath();
+      final filename = configuration.architecture == Architecture.x64
+          ? '$buildDir/gen/kernel-service.dart.snapshot'
+          : '$buildDir/gen/kernel_service.dill';
+      final dfePath = new Path(filename).absolute.toNativePath();
       // '--dfe' has to be the first argument for run_vm_test to pick it up.
       args.insert(0, '--dfe=$dfePath');
     }
@@ -871,6 +873,11 @@
       return commands;
     }
 
+    vmOptions = vmOptions
+        .map((s) =>
+            s.replaceAll("__RANDOM__", "${Random().nextInt(0x7fffffff)}"))
+        .toList();
+
     List<String> runtimeArguments =
         compilerConfiguration.computeRuntimeArguments(
             configuration.runtimeConfiguration,
diff --git a/tools/utils.py b/tools/utils.py
index a3657f2..d6878bc 100644
--- a/tools/utils.py
+++ b/tools/utils.py
@@ -907,7 +907,9 @@
         "Existing files which *did not* match the pattern inside the search "
         "directory are are:\n  %s"
         % (missing_as_string, self._search_dir, '\n  '.join(other_files)))
-    if throw:
+    # TODO: Figure out why windows coredump generation does not work.
+    # See http://dartbug.com/36469
+    if throw and GuessOS() != 'win32':
       raise Exception('Missing crash dumps for: %s' % missing_as_string)
 
   def _get_file_name(self, file):
diff --git a/utils/gen_kernel/BUILD.gn b/utils/gen_kernel/BUILD.gn
new file mode 100644
index 0000000..d69281f
--- /dev/null
+++ b/utils/gen_kernel/BUILD.gn
@@ -0,0 +1,22 @@
+# Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+# for details. All rights reserved. Use of this source code is governed by a
+# BSD-style license that can be found in the LICENSE file.
+
+import("../application_snapshot.gni")
+
+application_snapshot("gen_kernel") {
+  main_dart = "../../pkg/vm/bin/gen_kernel.dart"
+  deps = [
+    "../../runtime/vm:vm_platform",
+  ]
+  # NOTE: The output filename must be kept in sync with the output of the
+  # vm_platform rule.
+  vm_platform_out = get_label_info("../../runtime/vm:vm_platform", "root_out_dir")
+  vm_platform = "$vm_platform_out/vm_platform_strong.dill"
+  training_args = [
+      "--platform",
+      rebase_path(vm_platform),
+      rebase_path("../../pkg/vm/bin/gen_kernel.dart"),
+      "-o -",
+  ]
+}